Turba_ListView -> Turba_View_List
authorJan Schneider <jan@horde.org>
Fri, 2 Jul 2010 11:16:17 +0000 (13:16 +0200)
committerJan Schneider <jan@horde.org>
Mon, 5 Jul 2010 10:34:44 +0000 (12:34 +0200)
turba/lib/Forms/EditContact.php
turba/lib/ListView.php [deleted file]
turba/lib/View/Browse.php
turba/lib/View/List.php [new file with mode: 0644]
turba/lib/tests/ListViewTest.php
turba/lib/tests/ViewListTest.php [new file with mode: 0644]
turba/search.php

index 9830d29..65bf063 100644 (file)
@@ -135,10 +135,8 @@ class Turba_EditContactGroupForm extends Turba_EditContactForm {
         $sources = Turba::getColumns();
         $columns = isset($sources[$source]) ? $sources[$source] : array();
 
-        require_once TURBA_BASE . '/lib/List.php';
-        require_once TURBA_BASE . '/lib/ListView.php';
         $results = new Turba_List($vars->get('objectkeys'));
-        $listView = new Turba_ListView($results, array('Group' => true), $columns);
+        $listView = new Turba_View_List($results, array('Group' => true), $columns);
         echo '<br />' . $listView->getPage($numDisplayed);
     }
 
diff --git a/turba/lib/ListView.php b/turba/lib/ListView.php
deleted file mode 100644 (file)
index 32bdcc7..0000000
+++ /dev/null
@@ -1,500 +0,0 @@
-<?php
-/**
- * The Turba_ListView:: class provides an interface for objects that
- * visualize Turba_lists.
- *
- * @author  Chuck Hagenbuch <chuck@horde.org>
- * @author  Jon Parise <jon@csh.rit.edu>
- * @package Turba
- */
-class Turba_ListView {
-
-    /**
-     * The Turba_List object that we are visualizing.
-     *
-     * @var Turba_List
-     */
-    var $list;
-
-    /**
-     * Show/hide "mark" column in the display.
-     *
-     * @var boolean
-     */
-    var $showMark = false;
-
-    /**
-     * Show/hide "edit" column in the display.
-     *
-     * @var boolean
-     */
-    var $showEdit = false;
-
-    /**
-     * Show/hide "vcard" column in the display.
-     *
-     * @var boolean
-     */
-    var $showVcard = false;
-
-    /**
-     * Show/hide "group" column in the display.
-     *
-     * @var boolean
-     */
-    var $showGroup = false;
-
-    /**
-     * Show/hide "sort" column in the display.
-     *
-     * @var boolean
-     */
-    var $showSort = false;
-
-    /**
-     * Type of list.
-     *
-     * @var string
-     */
-    var $type;
-
-    /**
-     * The HTML renderer.
-     *
-     * @var Horde_Ui_VarRenderer_Html
-     */
-    var $renderer;
-
-    /**
-     * A Horde_Variables object.
-     *
-     * @var Horde_Variables
-     */
-    var $vars;
-
-    /**
-     * A list of Horde_Form_Variable objects.
-     *
-     * @var array
-     */
-    var $variables = array();
-
-    /**
-     * A dummy form object.
-     *
-     * @var Horde_Form
-     */
-    var $form = null;
-
-    /**
-     * Which columns to render
-     *
-     * @var array
-     */
-    var $columns;
-
-    /**
-     * Constructs a new Turba_ListView object.
-     *
-     * @param Turba_List $list  List of contacts to display.
-     * @param array $controls   Which icons to display
-     * @param array $columns    The list of columns to display
-     */
-    function Turba_ListView(&$list, $controls = null, $columns = null)
-    {
-        if ($controls === null) {
-            $controls = array('Mark' => true,
-                              'Edit' => true,
-                              'Vcard' => true,
-                              'Group' => true,
-                              'Sort' => true);
-        }
-        $this->columns = $columns;
-
-        $this->list = &$list;
-        $this->setControls($controls);
-
-        $this->renderer = Horde_Ui_VarRenderer::factory('Html');
-        $this->vars = new Horde_Variables();
-    }
-
-    /**
-     * Set which controls are shown by the display templates.
-     *
-     * @param array $controls
-     */
-    function setControls($controls)
-    {
-        foreach ($controls as $control => $show) {
-            $key = 'show' . $control;
-            $this->$key = (bool)$show;
-        }
-    }
-
-    function setType($type)
-    {
-        $this->type = $type;
-    }
-
-    function getType()
-    {
-        return $this->type;
-    }
-
-    /**
-     * Returns the number of Turba_Objects that are in the list. Use this to
-     * hide internal implementation details from client objects.
-     *
-     * @return integer  The number of objects in the list.
-     */
-    function count()
-    {
-        return $this->list->count();
-    }
-
-    function display()
-    {
-        global $prefs, $default_source, $copymove_source_options;
-
-        $driver = Turba_Driver::singleton($default_source);
-        $hasDelete = false;
-        $hasEdit = false;
-        $hasExport = false;
-        if (!is_a($driver, 'PEAR_Error')) {
-            if ($driver->hasPermission(Horde_Perms::DELETE)) {
-                $hasDelete = true;
-            }
-            if ($driver->hasPermission(Horde_Perms::EDIT)) {
-                $hasEdit = true;
-            }
-            if ($GLOBALS['conf']['menu']['import_export']
-                && !empty($GLOBALS['cfgSources'][$default_source]['export'])) {
-                $hasExport = true;
-            }
-        }
-        list($addToList, $addToListSources) = $this->getAddSources();
-
-        $viewurl = urldecode(Horde_Util::addParameter(
-            'browse.php',
-            array('key' => Horde_Util::getFormData('key'),
-                  'url' => Horde::selfUrl(true, false, true))));
-
-        if ($this->type == 'search') {
-            $page = Horde_Util::getFormData('page', 0);
-            $numitem = $this->count();
-            $maxpage = $prefs->getValue('maxpage');
-            $perpage = $prefs->getValue('perpage');
-
-            $min = $page * $perpage;
-            while ($min > $numitem) {
-                $page--;
-                $min = $page * $perpage;
-            }
-
-            $max = $min + $perpage;
-            $start = ($page * $perpage) + 1;
-            $end = min($numitem, $start + $perpage - 1);
-
-            $listHtml = $this->getPage($numDisplayed, $min, $max);
-
-            $crit = array();
-            if ($_SESSION['turba']['search_mode'] == 'advanced') {
-                $map = $driver->getCriteria();
-                foreach ($map as $key => $value) {
-                    if ($key != '__key') {
-                        $val = Horde_Util::getFormData($key);
-                        if (!empty($val)) {
-                            $crit[$key] = $val;
-                        }
-                    }
-                }
-            }
-            $params = array_merge($crit, array(
-                'criteria' => Horde_Util::getFormData('criteria'),
-                'val' => Horde_Util::getFormData('val'),
-                'source' => Horde_Util::getFormData('source', $default_source)
-            ));
-            $viewurl = urldecode(Horde_Util::addParameter('search.php', $params));
-
-            $vars = Horde_Variables::getDefaultVariables();
-            $pager = new Horde_Ui_Pager('page', $vars,
-                                        array('num' => $numitem,
-                                              'url' => $viewurl,
-                                              'page_limit' => $maxpage,
-                                              'perpage' => $perpage));
-
-            $pagerHeader = 'numPager.inc';
-        } else {
-            $page = Horde_Util::getFormData('page', '*');
-            if (!preg_match('/^[A-Za-z*]$/', $page)) {
-                $page = '*';
-            }
-            if ($this->count() > $prefs->getValue('perpage')) {
-                $page = Horde_Util::getFormData('page', 'A');
-                if (!preg_match('/^[A-Za-z*]$/', $page)) {
-                    $page = 'A';
-                }
-            }
-
-            $listHtml = $this->getAlpha($numDisplayed, $page);
-            $pagerHeader = 'alphaPager.inc';
-        }
-
-        if ($numDisplayed) {
-            require TURBA_TEMPLATES . '/browse/actions.inc';
-            require TURBA_TEMPLATES . '/list/' . $pagerHeader;
-            echo $listHtml;
-        } else {
-            require TURBA_TEMPLATES . '/list/' . $pagerHeader;
-            echo '<p><em>' . _("No matching contacts") . '</em></p>';
-        }
-    }
-
-    /**
-     * Renders the list contents into an HTML view.
-     *
-     * @param integer $numDisplayed  Ouptut parameter - the number of rows
-     *                               rendered.
-     * @param integer $min           Minimum number of rows to display.
-     * @param integer $max           Maximum number of rows to display.
-     * @return string  HTML to echo.
-     */
-    function getPage(&$numDisplayed, $min = 0, $max = null)
-    {
-        if (is_null($max)) {
-            $max = $this->list->count();
-        }
-        return $this->_get($numDisplayed,
-                           new Turba_ListView_PageFilter($min, $max));
-    }
-
-    /**
-     * Renders the list contents that match $alpha into an HTML view.
-     *
-     * @param integer $numDisplayed  This will be set to the number of contacts
-     *                               in the view.
-     * @param string $alpha The letter to display.
-     *
-     * @return string HTML of the list.
-     */
-    function getAlpha(&$numDisplayed, $alpha)
-    {
-        return $this->_get($numDisplayed,
-                           new Turba_ListView_AlphaFilter($alpha));
-    }
-
-    /**
-     * Retrieves a column's name
-     *
-     * @param integer $i  The zero-basd index of the column
-     * @return string
-     */
-    function getColumnName($i)
-    {
-        return Turba::getColumnName($i, $this->columns);
-    }
-
-    /**
-     * @param integer $i  The zero-based index of the column
-     */
-    function getSortInfoForColumn($i)
-    {
-        $sortorder = Turba::getPreferredSortOrder();
-        $column_name = $this->getColumnName($i);
-        $i = 0;
-        foreach ($sortorder as $sortfield) {
-            if ($column_name == $sortfield['field']) {
-                return array_merge($sortfield, array('rank' => $i));
-            }
-            $i++;
-        }
-        return null;
-    }
-
-    function getColumnSortImage($i, $title = null)
-    {
-        if (is_null($title)) {
-            $title = _("Sort Direction");
-        }
-        $sortdir = $this->getColumnSortDirection($i);
-        if ($this->isPrimarySortColumn($i)) {
-            return Horde::img($sortdir ? 'za.png' : 'az.png', $title);
-        } else {
-            return Horde::img($sortdir ? 'za_secondary.png' : 'az_secondary.png', _("Sort Direction"));
-        }
-    }
-
-    /**
-     * Retrieves a natural language description of the sort order
-     * @return string
-     */
-    function getSortOrderDescription()
-    {
-        $description = array();
-        $sortorder = Turba::getPreferredSortOrder();
-        foreach ($sortorder as $elt) {
-            $field = $elt['field'];
-            if ($field == 'lastname') {
-                $field = 'name';
-            }
-            $description[] = $GLOBALS['attributes'][$field]['label'];
-        }
-        return join(', ', $description);
-    }
-
-    /**
-     * @param integer $i  The zero-based index of the column
-     */
-    function getColumnSortDirection($i)
-    {
-        $result = $this->getSortInfoForColumn($i);
-        if (is_null($result)) {
-            return null;
-        }
-        return $result['ascending'] ? 0 : 1;
-    }
-
-    /**
-     * Determines whether we are sorting on the specified column
-     *
-     * @param integer $i  The zero-based column index
-     * @return boolean
-     */
-    function isSortColumn($i)
-    {
-        return !is_null($this->getSortInfoForColumn($i));
-    }
-
-    /**
-     * Determines whether this is the first column to sort by
-     * @param integer $i  The zero-based column index
-     * @return boolean
-     */
-    function isPrimarySortColumn($i)
-    {
-        $result = $this->getSortInfoForColumn($i);
-        if (is_null($result)) {
-            return false;
-        }
-        return ($result['rank'] == 0);
-    }
-
-    function _get(&$numDisplayed, $filter)
-    {
-        ob_start();
-        $width = floor(90 / (count($this->columns) + 1));
-        @list($own_source, $own_id) = explode(';', $GLOBALS['prefs']->getValue('own_contact'));
-
-        include TURBA_TEMPLATES . '/browse/column_headers.inc';
-
-        $numDisplayed = 0;
-        $this->list->reset();
-        while ($ob = $this->list->next()) {
-            if ($filter->skip($ob)) {
-                continue;
-            }
-
-            include TURBA_TEMPLATES . '/browse/row.inc';
-            $numDisplayed++;
-        }
-
-        include TURBA_TEMPLATES . '/browse/column_footers.inc';
-        return ob_get_clean();
-    }
-
-    function getAddSources()
-    {
-        global $addSources;
-
-        // Create list of lists for Add to.
-        $addToList = array();
-        $addToListSources = array();
-        foreach ($addSources as $src => $srcConfig) {
-            if (!empty($srcConfig['map']['__type'])) {
-                $addToListSources[] = array('key' => '',
-                                            'name' => '&nbsp;&nbsp;' . htmlspecialchars($srcConfig['title']),
-                                            'source' => htmlspecialchars($src));
-
-                $srcDriver = &Turba_Driver::singleton($src);
-                $listList = $srcDriver->search(array('__type' => 'Group'),
-                                               array(array('field' => 'name',
-                                                           'ascending' => true)),
-                                               'AND', array('name'));
-                if (is_a($listList, 'PEAR_Error')) {
-                    $GLOBALS['notification']->push($listList, 'horde.error');
-                } else {
-                    $listList->reset();
-                    $currentList = Horde_Util::getFormData('key');
-                    while ($listObject = $listList->next()) {
-                        if ($listObject->getValue('__key') != $currentList) {
-                            $addToList[] = array('name' => htmlspecialchars($listObject->getValue('name')),
-                                                 'source' => htmlspecialchars($src),
-                                                 'key' => htmlspecialchars($listObject->getValue('__key')));
-                        }
-                    }
-                }
-            }
-        }
-        if ($addToListSources) {
-            if ($addToList) {
-                array_unshift($addToList, '- - - - - - - - -');
-            }
-            $addToList = array_merge(array(_("Create a new Contact List in:")), $addToListSources, $addToList);
-            $addToListSources = null;
-        }
-
-        return array($addToList, $addToListSources);
-    }
-
-}
-
-/**
- * Skips objects whose name does not start with the specified letter
- */
-class Turba_ListView_AlphaFilter {
-
-    var $_alpha;
-    var $_format;
-
-    function Turba_ListView_AlphaFilter($alpha)
-    {
-        $this->_alpha = Horde_String::lower($alpha);
-        $this->_format = $GLOBALS['prefs']->getValue('name_sort');
-    }
-
-    function skip(&$ob)
-    {
-        $name = Turba::formatName($ob, $this->_format);
-        if ($this->_alpha != '*' &&
-            Horde_String::lower(substr($name, 0, 1)) != $this->_alpha) {
-            return true;
-        }
-        return false;
-    }
-
-}
-
-/**
- * Skips objects which are not on the current page
- */
-class Turba_ListView_PageFilter {
-
-    var $_min;
-    var $_max;
-    var $_count = 0;
-
-    function Turba_ListView_PageFilter($min, $max)
-    {
-        $this->_min = $min;
-        $this->_max = $max;
-    }
-
-    function skip(&$ob)
-    {
-        if ($this->_count++ < $this->_min) {
-            return true;
-        }
-        return ($this->_count > $this->_max);
-    }
-
-}
index e77548e..50f4140 100644 (file)
@@ -362,7 +362,7 @@ class Turba_View_Browse {
                             $count = $list->count() - $results->count();
                             $notification->push(sprintf(ngettext("There is %d contact in this list that is not viewable to you", "There are %d contacts in this list that are not viewable to you", $count), $count), 'horde.message');
                         }
-                        $view = new Turba_ListView($results, null, $columns);
+                        $view = new Turba_View_List($results, null, $columns);
                         $view->setType('list');
                     }
                 } else {
@@ -391,7 +391,7 @@ class Turba_View_Browse {
                     } elseif (is_a($results, 'PEAR_Error')) {
                         $notification->push($results, 'horde.error');
                     } else {
-                        $view = new Turba_ListView($results, null, $columns);
+                        $view = new Turba_View_List($results, null, $columns);
                         $view->setType('directory');
                     }
                 }
diff --git a/turba/lib/View/List.php b/turba/lib/View/List.php
new file mode 100644 (file)
index 0000000..1d13796
--- /dev/null
@@ -0,0 +1,500 @@
+<?php
+/**
+ * The Turba_View_List:: class provides an interface for objects that
+ * visualize Turba_lists.
+ *
+ * @author  Chuck Hagenbuch <chuck@horde.org>
+ * @author  Jon Parise <jon@csh.rit.edu>
+ * @package Turba
+ */
+class Turba_View_List {
+
+    /**
+     * The Turba_List object that we are visualizing.
+     *
+     * @var Turba_List
+     */
+    var $list;
+
+    /**
+     * Show/hide "mark" column in the display.
+     *
+     * @var boolean
+     */
+    var $showMark = false;
+
+    /**
+     * Show/hide "edit" column in the display.
+     *
+     * @var boolean
+     */
+    var $showEdit = false;
+
+    /**
+     * Show/hide "vcard" column in the display.
+     *
+     * @var boolean
+     */
+    var $showVcard = false;
+
+    /**
+     * Show/hide "group" column in the display.
+     *
+     * @var boolean
+     */
+    var $showGroup = false;
+
+    /**
+     * Show/hide "sort" column in the display.
+     *
+     * @var boolean
+     */
+    var $showSort = false;
+
+    /**
+     * Type of list.
+     *
+     * @var string
+     */
+    var $type;
+
+    /**
+     * The HTML renderer.
+     *
+     * @var Horde_Ui_VarRenderer_Html
+     */
+    var $renderer;
+
+    /**
+     * A Horde_Variables object.
+     *
+     * @var Horde_Variables
+     */
+    var $vars;
+
+    /**
+     * A list of Horde_Form_Variable objects.
+     *
+     * @var array
+     */
+    var $variables = array();
+
+    /**
+     * A dummy form object.
+     *
+     * @var Horde_Form
+     */
+    var $form = null;
+
+    /**
+     * Which columns to render
+     *
+     * @var array
+     */
+    var $columns;
+
+    /**
+     * Constructs a new Turba_View_List object.
+     *
+     * @param Turba_List $list  List of contacts to display.
+     * @param array $controls   Which icons to display
+     * @param array $columns    The list of columns to display
+     */
+    function Turba_View_List(&$list, $controls = null, $columns = null)
+    {
+        if ($controls === null) {
+            $controls = array('Mark' => true,
+                              'Edit' => true,
+                              'Vcard' => true,
+                              'Group' => true,
+                              'Sort' => true);
+        }
+        $this->columns = $columns;
+
+        $this->list = &$list;
+        $this->setControls($controls);
+
+        $this->renderer = Horde_Ui_VarRenderer::factory('Html');
+        $this->vars = new Horde_Variables();
+    }
+
+    /**
+     * Set which controls are shown by the display templates.
+     *
+     * @param array $controls
+     */
+    function setControls($controls)
+    {
+        foreach ($controls as $control => $show) {
+            $key = 'show' . $control;
+            $this->$key = (bool)$show;
+        }
+    }
+
+    function setType($type)
+    {
+        $this->type = $type;
+    }
+
+    function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Returns the number of Turba_Objects that are in the list. Use this to
+     * hide internal implementation details from client objects.
+     *
+     * @return integer  The number of objects in the list.
+     */
+    function count()
+    {
+        return $this->list->count();
+    }
+
+    function display()
+    {
+        global $prefs, $default_source, $copymove_source_options;
+
+        $driver = Turba_Driver::singleton($default_source);
+        $hasDelete = false;
+        $hasEdit = false;
+        $hasExport = false;
+        if (!is_a($driver, 'PEAR_Error')) {
+            if ($driver->hasPermission(Horde_Perms::DELETE)) {
+                $hasDelete = true;
+            }
+            if ($driver->hasPermission(Horde_Perms::EDIT)) {
+                $hasEdit = true;
+            }
+            if ($GLOBALS['conf']['menu']['import_export']
+                && !empty($GLOBALS['cfgSources'][$default_source]['export'])) {
+                $hasExport = true;
+            }
+        }
+        list($addToList, $addToListSources) = $this->getAddSources();
+
+        $viewurl = urldecode(Horde_Util::addParameter(
+            'browse.php',
+            array('key' => Horde_Util::getFormData('key'),
+                  'url' => Horde::selfUrl(true, false, true))));
+
+        if ($this->type == 'search') {
+            $page = Horde_Util::getFormData('page', 0);
+            $numitem = $this->count();
+            $maxpage = $prefs->getValue('maxpage');
+            $perpage = $prefs->getValue('perpage');
+
+            $min = $page * $perpage;
+            while ($min > $numitem) {
+                $page--;
+                $min = $page * $perpage;
+            }
+
+            $max = $min + $perpage;
+            $start = ($page * $perpage) + 1;
+            $end = min($numitem, $start + $perpage - 1);
+
+            $listHtml = $this->getPage($numDisplayed, $min, $max);
+
+            $crit = array();
+            if ($_SESSION['turba']['search_mode'] == 'advanced') {
+                $map = $driver->getCriteria();
+                foreach ($map as $key => $value) {
+                    if ($key != '__key') {
+                        $val = Horde_Util::getFormData($key);
+                        if (!empty($val)) {
+                            $crit[$key] = $val;
+                        }
+                    }
+                }
+            }
+            $params = array_merge($crit, array(
+                'criteria' => Horde_Util::getFormData('criteria'),
+                'val' => Horde_Util::getFormData('val'),
+                'source' => Horde_Util::getFormData('source', $default_source)
+            ));
+            $viewurl = urldecode(Horde_Util::addParameter('search.php', $params));
+
+            $vars = Horde_Variables::getDefaultVariables();
+            $pager = new Horde_Ui_Pager('page', $vars,
+                                        array('num' => $numitem,
+                                              'url' => $viewurl,
+                                              'page_limit' => $maxpage,
+                                              'perpage' => $perpage));
+
+            $pagerHeader = 'numPager.inc';
+        } else {
+            $page = Horde_Util::getFormData('page', '*');
+            if (!preg_match('/^[A-Za-z*]$/', $page)) {
+                $page = '*';
+            }
+            if ($this->count() > $prefs->getValue('perpage')) {
+                $page = Horde_Util::getFormData('page', 'A');
+                if (!preg_match('/^[A-Za-z*]$/', $page)) {
+                    $page = 'A';
+                }
+            }
+
+            $listHtml = $this->getAlpha($numDisplayed, $page);
+            $pagerHeader = 'alphaPager.inc';
+        }
+
+        if ($numDisplayed) {
+            require TURBA_TEMPLATES . '/browse/actions.inc';
+            require TURBA_TEMPLATES . '/list/' . $pagerHeader;
+            echo $listHtml;
+        } else {
+            require TURBA_TEMPLATES . '/list/' . $pagerHeader;
+            echo '<p><em>' . _("No matching contacts") . '</em></p>';
+        }
+    }
+
+    /**
+     * Renders the list contents into an HTML view.
+     *
+     * @param integer $numDisplayed  Ouptut parameter - the number of rows
+     *                               rendered.
+     * @param integer $min           Minimum number of rows to display.
+     * @param integer $max           Maximum number of rows to display.
+     * @return string  HTML to echo.
+     */
+    function getPage(&$numDisplayed, $min = 0, $max = null)
+    {
+        if (is_null($max)) {
+            $max = $this->list->count();
+        }
+        return $this->_get($numDisplayed,
+                           new Turba_View_List_PageFilter($min, $max));
+    }
+
+    /**
+     * Renders the list contents that match $alpha into an HTML view.
+     *
+     * @param integer $numDisplayed  This will be set to the number of contacts
+     *                               in the view.
+     * @param string $alpha The letter to display.
+     *
+     * @return string HTML of the list.
+     */
+    function getAlpha(&$numDisplayed, $alpha)
+    {
+        return $this->_get($numDisplayed,
+                           new Turba_View_List_AlphaFilter($alpha));
+    }
+
+    /**
+     * Retrieves a column's name
+     *
+     * @param integer $i  The zero-basd index of the column
+     * @return string
+     */
+    function getColumnName($i)
+    {
+        return Turba::getColumnName($i, $this->columns);
+    }
+
+    /**
+     * @param integer $i  The zero-based index of the column
+     */
+    function getSortInfoForColumn($i)
+    {
+        $sortorder = Turba::getPreferredSortOrder();
+        $column_name = $this->getColumnName($i);
+        $i = 0;
+        foreach ($sortorder as $sortfield) {
+            if ($column_name == $sortfield['field']) {
+                return array_merge($sortfield, array('rank' => $i));
+            }
+            $i++;
+        }
+        return null;
+    }
+
+    function getColumnSortImage($i, $title = null)
+    {
+        if (is_null($title)) {
+            $title = _("Sort Direction");
+        }
+        $sortdir = $this->getColumnSortDirection($i);
+        if ($this->isPrimarySortColumn($i)) {
+            return Horde::img($sortdir ? 'za.png' : 'az.png', $title);
+        } else {
+            return Horde::img($sortdir ? 'za_secondary.png' : 'az_secondary.png', _("Sort Direction"));
+        }
+    }
+
+    /**
+     * Retrieves a natural language description of the sort order
+     * @return string
+     */
+    function getSortOrderDescription()
+    {
+        $description = array();
+        $sortorder = Turba::getPreferredSortOrder();
+        foreach ($sortorder as $elt) {
+            $field = $elt['field'];
+            if ($field == 'lastname') {
+                $field = 'name';
+            }
+            $description[] = $GLOBALS['attributes'][$field]['label'];
+        }
+        return join(', ', $description);
+    }
+
+    /**
+     * @param integer $i  The zero-based index of the column
+     */
+    function getColumnSortDirection($i)
+    {
+        $result = $this->getSortInfoForColumn($i);
+        if (is_null($result)) {
+            return null;
+        }
+        return $result['ascending'] ? 0 : 1;
+    }
+
+    /**
+     * Determines whether we are sorting on the specified column
+     *
+     * @param integer $i  The zero-based column index
+     * @return boolean
+     */
+    function isSortColumn($i)
+    {
+        return !is_null($this->getSortInfoForColumn($i));
+    }
+
+    /**
+     * Determines whether this is the first column to sort by
+     * @param integer $i  The zero-based column index
+     * @return boolean
+     */
+    function isPrimarySortColumn($i)
+    {
+        $result = $this->getSortInfoForColumn($i);
+        if (is_null($result)) {
+            return false;
+        }
+        return ($result['rank'] == 0);
+    }
+
+    function _get(&$numDisplayed, $filter)
+    {
+        ob_start();
+        $width = floor(90 / (count($this->columns) + 1));
+        @list($own_source, $own_id) = explode(';', $GLOBALS['prefs']->getValue('own_contact'));
+
+        include TURBA_TEMPLATES . '/browse/column_headers.inc';
+
+        $numDisplayed = 0;
+        $this->list->reset();
+        while ($ob = $this->list->next()) {
+            if ($filter->skip($ob)) {
+                continue;
+            }
+
+            include TURBA_TEMPLATES . '/browse/row.inc';
+            $numDisplayed++;
+        }
+
+        include TURBA_TEMPLATES . '/browse/column_footers.inc';
+        return ob_get_clean();
+    }
+
+    function getAddSources()
+    {
+        global $addSources;
+
+        // Create list of lists for Add to.
+        $addToList = array();
+        $addToListSources = array();
+        foreach ($addSources as $src => $srcConfig) {
+            if (!empty($srcConfig['map']['__type'])) {
+                $addToListSources[] = array('key' => '',
+                                            'name' => '&nbsp;&nbsp;' . htmlspecialchars($srcConfig['title']),
+                                            'source' => htmlspecialchars($src));
+
+                $srcDriver = &Turba_Driver::singleton($src);
+                $listList = $srcDriver->search(array('__type' => 'Group'),
+                                               array(array('field' => 'name',
+                                                           'ascending' => true)),
+                                               'AND', array('name'));
+                if (is_a($listList, 'PEAR_Error')) {
+                    $GLOBALS['notification']->push($listList, 'horde.error');
+                } else {
+                    $listList->reset();
+                    $currentList = Horde_Util::getFormData('key');
+                    while ($listObject = $listList->next()) {
+                        if ($listObject->getValue('__key') != $currentList) {
+                            $addToList[] = array('name' => htmlspecialchars($listObject->getValue('name')),
+                                                 'source' => htmlspecialchars($src),
+                                                 'key' => htmlspecialchars($listObject->getValue('__key')));
+                        }
+                    }
+                }
+            }
+        }
+        if ($addToListSources) {
+            if ($addToList) {
+                array_unshift($addToList, '- - - - - - - - -');
+            }
+            $addToList = array_merge(array(_("Create a new Contact List in:")), $addToListSources, $addToList);
+            $addToListSources = null;
+        }
+
+        return array($addToList, $addToListSources);
+    }
+
+}
+
+/**
+ * Skips objects whose name does not start with the specified letter
+ */
+class Turba_View_List_AlphaFilter {
+
+    var $_alpha;
+    var $_format;
+
+    function Turba_View_List_AlphaFilter($alpha)
+    {
+        $this->_alpha = Horde_String::lower($alpha);
+        $this->_format = $GLOBALS['prefs']->getValue('name_sort');
+    }
+
+    function skip(&$ob)
+    {
+        $name = Turba::formatName($ob, $this->_format);
+        if ($this->_alpha != '*' &&
+            Horde_String::lower(substr($name, 0, 1)) != $this->_alpha) {
+            return true;
+        }
+        return false;
+    }
+
+}
+
+/**
+ * Skips objects which are not on the current page
+ */
+class Turba_View_List_PageFilter {
+
+    var $_min;
+    var $_max;
+    var $_count = 0;
+
+    function Turba_View_List_PageFilter($min, $max)
+    {
+        $this->_min = $min;
+        $this->_max = $max;
+    }
+
+    function skip(&$ob)
+    {
+        if ($this->_count++ < $this->_min) {
+            return true;
+        }
+        return ($this->_count > $this->_max);
+    }
+
+}
index 62531c1..ed388d8 100644 (file)
@@ -7,16 +7,16 @@ require_once dirname(__FILE__) . '/TestBase.php';
  * @package Turba
  * @subpackage UnitTests
  */
-class Turba_ListViewTest extends Turba_TestBase {
+class Turba_ViewListTest extends Turba_TestBase {
 
     function setUp()
     {
         parent::setUp();
         $this->setUpDatabase();
-        require_once dirname(__FILE__) . '/../ListView.php';
+        require_once dirname(__FILE__) . '/../View/List.php';
     }
 
-    function callListView($method, &$numDisplayed, $param = null)
+    function callView_List($method, &$numDisplayed, $param = null)
     {
         $GLOBALS['source'] = '_test_sql';
         $GLOBALS['cfgSources'] = array('_test_sql' => $this->getDriverConfig());
@@ -24,7 +24,7 @@ class Turba_ListViewTest extends Turba_TestBase {
         $list = $this->getList();
         $sources = Turba::getColumns();
         $columns = isset($sources['_test_sql']) ? $sources['_test_sql'] : array();
-        $view = new Turba_ListView($list, null, $columns);
+        $view = new Turba_View_List($list, null, $columns);
         $this->_output = $view->$method($numDisplayed, $param);
         $this->assertOk($this->_output);
         $this->assertNoUnwantedPattern('/Fatal error/', $this->_output);
@@ -34,7 +34,7 @@ class Turba_ListViewTest extends Turba_TestBase {
 
     function test_getAddSources_returns_sources_sorted_by_name()
     {
-        $result = Turba_ListView::getAddSources();
+        $result = Turba_View_List::getAddSources();
         if (!$this->assertOk($result)) {
             return;
         }
@@ -56,7 +56,7 @@ class Turba_ListViewTest extends Turba_TestBase {
 
     function test_getPage_renders_all_list_items()
     {
-        $this->callListView('getPage', $numDisplayed);
+        $this->callView_List('getPage', $numDisplayed);
         foreach ($this->_sortedByLastname as $name) {
             $this->assertWantedPattern('/' . preg_quote($name, '/') . '/',
                                        $this->_output);
@@ -67,7 +67,7 @@ class Turba_ListViewTest extends Turba_TestBase {
 
     function test_getAlpha_renders_filtered_items()
     {
-        $this->callListView('getAlpha', $numDisplayed, 'j');
+        $this->callView_List('getAlpha', $numDisplayed, 'j');
         $count = 0;
         foreach ($this->_sortedByLastname as $name) {
             if (Horde_String::lower($name{0}) == 'j') {
diff --git a/turba/lib/tests/ViewListTest.php b/turba/lib/tests/ViewListTest.php
new file mode 100644 (file)
index 0000000..c1bc565
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+
+require_once dirname(__FILE__) . '/TestBase.php';
+
+/**
+ * @author  Jason M. Felice <jason.m.felice@gmail.com>
+ * @package Turba
+ * @subpackage UnitTests
+ */
+class Turba_View_ListTest extends Turba_TestBase {
+
+    function setUp()
+    {
+        parent::setUp();
+        $this->setUpDatabase();
+        require_once dirname(__FILE__) . '/../View/List.php';
+    }
+
+    function callView_List($method, &$numDisplayed, $param = null)
+    {
+        $GLOBALS['source'] = '_test_sql';
+        $GLOBALS['cfgSources'] = array('_test_sql' => $this->getDriverConfig());
+
+        $list = $this->getList();
+        $sources = Turba::getColumns();
+        $columns = isset($sources['_test_sql']) ? $sources['_test_sql'] : array();
+        $view = new Turba_View_List($list, null, $columns);
+        $this->_output = $view->$method($numDisplayed, $param);
+        $this->assertOk($this->_output);
+        $this->assertNoUnwantedPattern('/Fatal error/', $this->_output);
+        $this->assertNoUnwantedPattern('/Warning/', $this->_output);
+        return $view;
+    }
+
+    function test_getAddSources_returns_sources_sorted_by_name()
+    {
+        $result = Turba_View_List::getAddSources();
+        if (!$this->assertOk($result)) {
+            return;
+        }
+
+        list($addToList, $addToListSources) = $result;
+
+        $groups = $this->_groups;
+        sort($groups);
+        foreach ($addToList as $item) {
+            if (!empty($groups) && !empty($item['name']) &&
+                $groups[0] == $item['name']) {
+                array_shift($groups);
+            }
+        }
+
+        $this->assertTrue(empty($groups),
+                          "Some group not found or not found in right order.");
+    }
+
+    function test_getPage_renders_all_list_items()
+    {
+        $this->callView_List('getPage', $numDisplayed);
+        foreach ($this->_sortedByLastname as $name) {
+            $this->assertWantedPattern('/' . preg_quote($name, '/') . '/',
+                                       $this->_output);
+        }
+
+        $this->assertEqual(count($this->_sortedByLastname), $numDisplayed);
+    }
+
+    function test_getAlpha_renders_filtered_items()
+    {
+        $this->callView_List('getAlpha', $numDisplayed, 'j');
+        $count = 0;
+        foreach ($this->_sortedByLastname as $name) {
+            if (Horde_String::lower($name{0}) == 'j') {
+                $this->assertWantedPattern('/' . preg_quote($name, '/') . '/',
+                                           $this->_output);
+                $count++;
+            } else {
+                $this->assertNoUnwantedPattern('/' . preg_quote($name, '/') .
+                                               '/', $this->_output);
+            }
+        }
+
+        $this->assertEqual($count, $numDisplayed);
+        $this->assertNotEqual(0, $count);
+    }
+
+}
index 1c2bd41..8ff728f 100644 (file)
@@ -168,7 +168,7 @@ if (is_a($driver, 'PEAR_Error')) {
                 $columns = isset($sources[$source]) ? $sources[$source] : array();
                 $results->sort(Turba::getPreferredSortOrder());
 
-                $view = new Turba_ListView($results, null, $columns);
+                $view = new Turba_View_List($results, null, $columns);
                 $view->setType('search');
             }
         } else {