~ubuntu-branches/ubuntu/vivid/php-horde-nag/vivid

« back to all changes in this revision

Viewing changes to nag-4.1.3/lib/View/List.php

  • Committer: Package Import Robot
  • Author(s): Mathieu Parent
  • Date: 2013-10-29 22:01:43 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20131029220143-k16crjhccwr56jxq
Tags: 4.1.3-1
New upstream version 4.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Task list view.
 
4
 *
 
5
 * Copyright 2011-2013 Horde LLC (http://www.horde.org/)
 
6
 *
 
7
 * See the enclosed file LICENSE for license information (BSD). If you did not
 
8
 * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
 
9
 *
 
10
 * @author  Michael J Rubinsky <mrubinsk@horde.org>
 
11
 * @package Nag
 
12
 */
 
13
class Nag_View_List
 
14
{
 
15
    /**
 
16
     * The loaded tasks.
 
17
     *
 
18
     * @var Nag_Task
 
19
     */
 
20
    protected $_tasks;
 
21
 
 
22
    /**
 
23
     * Page title
 
24
     *
 
25
     * @var string
 
26
     */
 
27
    protected $_title;
 
28
 
 
29
    /**
 
30
     * Flag to indicate whether or not to show the tag browser
 
31
     *
 
32
     * @var boolean
 
33
     */
 
34
    protected $_showTagBrowser = true;
 
35
 
 
36
    /**
 
37
     * Tag browser
 
38
     *
 
39
     * @var Nag_TagBrowser
 
40
     */
 
41
    protected $_browser;
 
42
 
 
43
    /**
 
44
     * Share representing the current smarlist (if being viewed).
 
45
     *
 
46
     * @var Horde_Share_Object_Base
 
47
     */
 
48
    protected $_smartShare;
 
49
 
 
50
    /**
 
51
     * Horde_Variables
 
52
     *
 
53
     * @var Horde_Variables
 
54
     */
 
55
    protected $_vars;
 
56
 
 
57
    /**
 
58
     * Const'r
 
59
     *
 
60
     * @param Horde_Variables $vars  Variables for the view.
 
61
     *
 
62
     * @return Nag_View_List
 
63
     */
 
64
    public function __construct($vars)
 
65
    {
 
66
        $this->_vars = $vars;
 
67
        $this->_title = _("My Tasks");
 
68
        $this->_browser = $GLOBALS['injector']
 
69
            ->getInstance('Nag_Factory_TagBrowser')
 
70
            ->create();
 
71
        $this->_checkSortValue();
 
72
        $this->_handleActions();
 
73
    }
 
74
 
 
75
    /**
 
76
     * Renders the view.
 
77
     *
 
78
     * @param Horde_PageOutput $output  The output object.
 
79
     *
 
80
     * @return string  The HTML needed to render the view.
 
81
     */
 
82
    public function render($output)
 
83
    {
 
84
        global $injector, $prefs;
 
85
 
 
86
        $output->addScriptFile('tooltips.js', 'horde');
 
87
        $output->addScriptFile('scriptaculous/effects.js', 'horde');
 
88
        $output->addScriptFile('quickfinder.js', 'horde');
 
89
        $output->header(array(
 
90
            'title' => $this->_title
 
91
        ));
 
92
 
 
93
        $tabs = new Horde_Core_Ui_Tabs('tab_name', $this->_vars);
 
94
        if (!$GLOBALS['prefs']->isLocked('show_completed')) {
 
95
            $listurl = Horde::url('list.php');
 
96
            $tabs->addTab(_("_All tasks"), $listurl->add('show_completed', Nag::VIEW_ALL), Nag::VIEW_ALL);
 
97
            $tabs->addTab(_("Incom_plete tasks"), $listurl->add('show_completed', Nag::VIEW_INCOMPLETE), Nag::VIEW_INCOMPLETE);
 
98
            $tabs->addTab(_("_Future tasks"), $listurl->add('show_completed', Nag::VIEW_FUTURE), Nag::VIEW_FUTURE);
 
99
            $tabs->addTab(_("_Completed tasks"), $listurl->add('show_completed', Nag::VIEW_COMPLETE), Nag::VIEW_COMPLETE);
 
100
        }
 
101
 
 
102
        foreach (Nag::listTasklists() as $list) {
 
103
            if ($list->get('issmart')) {
 
104
                $tabs->addTab(
 
105
                    $list->get('name'),
 
106
                    $listurl->add(array('actionID' => 'smart', 'list' => $list->getName())),
 
107
                    array('img' => 'search.png', 'tabname' => $list->getName()));
 
108
            }
 
109
        }
 
110
 
 
111
        // Set up the view
 
112
        $view = $GLOBALS['injector']->createInstance('Horde_View');
 
113
        $view->addHelper(new Nag_View_Helper_List($view));
 
114
        $view->tasks = $this->_tasks;
 
115
        $view->tabs = $tabs->render($this->_vars->get('tab_name', $prefs->getValue('show_completed')));
 
116
        $view->browser = empty($this->_smartShare) && $this->_showTagBrowser ? $this->_getRelatedTags() . $this->_getTagTrail() : '';
 
117
        $view->title = $this->_title;
 
118
        $view->sortby = $prefs->getValue('sortby');
 
119
        $view->sortdir = $prefs->getValue('sortdir');
 
120
        $view->sortdirclass = $view->sortdir ? 'sortup' : 'sortdown';
 
121
        $view->dateFormat = $prefs->getValue('date_format');
 
122
        $view->columns = @unserialize($prefs->getValue('tasklist_columns'));
 
123
        $view->smartShare = $this->_smartShare;
 
124
        if (empty($view->columns)) {
 
125
            $view->columns = array();
 
126
        }
 
127
        $view->dynamic_sort = true;
 
128
 
 
129
        $view->baseurl = Horde::url('list.php');
 
130
        if ($this->_vars->actionID == 'search_tasks') {
 
131
            $view->baseurl->add(
 
132
                array('actionID' => 'search_tasks',
 
133
                      'search_pattern' => $search_pattern,
 
134
                      'search_name' => $search_name ? 'on' : 'off',
 
135
                      'search_desc' => $search_desc ? 'on' : 'off')
 
136
            );
 
137
        }
 
138
 
 
139
        $view->tasks->reset();
 
140
        Horde::startBuffer();
 
141
        Nag::status();
 
142
        echo $view->render('list');
 
143
        $output->footer();
 
144
 
 
145
        return Horde::endBuffer();
 
146
    }
 
147
 
 
148
    /**
 
149
     * Helper to check/update the sort prefs
 
150
     */
 
151
    protected function _checkSortValue()
 
152
    {
 
153
        global $prefs;
 
154
 
 
155
        // First check for any passed in sorting value changes.
 
156
        if ($this->_vars->exists('sortby')) {
 
157
            $prefs->setValue('sortby', $this->_vars->sortby);
 
158
        }
 
159
        if ($this->_vars->exists('sortdir')) {
 
160
            $prefs->setValue('sortdir', $this->_vars->sortdir);
 
161
        }
 
162
        if ($this->_vars->exists('show_completed')) {
 
163
            $prefs->setValue('show_completed', $this->_vars->get('show_completed'));
 
164
        } else {
 
165
            $this->_vars->set('show_completed', $prefs->getValue('show_completed'));
 
166
        }
 
167
    }
 
168
 
 
169
    /**
 
170
     * Helper to handle any incoming actions.
 
171
     */
 
172
    protected function _handleActions($action = null)
 
173
    {
 
174
        $lists = null;
 
175
        if (is_null($action)) {
 
176
            $action = $this->_vars->actionID;
 
177
        }
 
178
        switch ($action) {
 
179
        case 'search_tasks':
 
180
            if ($this->_vars->deletebutton) {
 
181
                $this->_doDeleteSmartList();
 
182
                $this->_handleActions(false);
 
183
            } else {
 
184
                $this->_doSearch();
 
185
            }
 
186
            break;
 
187
        case 'browse_add':
 
188
        case 'browse_remove':
 
189
        case 'browse':
 
190
            // The tag to add|remove from the browse search.
 
191
            $tag = trim($this->_vars->get('tag'));
 
192
            if (!empty($tag)) {
 
193
                if ($this->_vars->actionID == 'browse_add') {
 
194
                    $this->_browser->addTag($tag);
 
195
                } else {
 
196
                    $this->_browser->removeTag($tag);
 
197
                }
 
198
                $this->_browser->save();
 
199
            }
 
200
            if ($this->_browser->tagCount() < 1) {
 
201
                $this->_browser->clearSearch();
 
202
                $this->_loadTasks();
 
203
            } else {
 
204
                $this->_browser->setFilter($this->_vars->show_completed);
 
205
                $this->_tasks = $this->_browser->getSlice();
 
206
            }
 
207
            break;
 
208
        case 'smart':
 
209
            $lists = array($this->_vars->get('list'));
 
210
            $list = $GLOBALS['nag_shares']->getShare($this->_vars->get('list'));
 
211
            $this->_title = $list->get('name');
 
212
            $this->_smartShare = $list;
 
213
            $this->_loadTasks($lists);
 
214
            break;
 
215
        default:
 
216
            // If we have an active tag browse, use it.
 
217
            if ($this->_browser->tagCount() >= 1) {
 
218
                $this->_handleActions('browse');
 
219
            } else {
 
220
                $this->_loadTasks($lists);
 
221
            }
 
222
            break;
 
223
        }
 
224
    }
 
225
 
 
226
    /**
 
227
     * Load the full, sorted task list.
 
228
     */
 
229
    protected function _loadTasks($lists = null)
 
230
    {
 
231
        try {
 
232
            $this->_tasks = Nag::listTasks(array(
 
233
                'tasklists' => $lists,
 
234
                'include_tags' => true,
 
235
                'completed' => $this->_vars->show_completed,
 
236
                'include_history' => false)
 
237
            );
 
238
        } catch (Nag_Exception $e) {
 
239
            $GLOBALS['notification']->push($e, 'horde.error');
 
240
            $this->_tasks = new Nag_Task();
 
241
        }
 
242
    }
 
243
 
 
244
    /**
 
245
     * Performs a Task search. self::_tasks is populated with the results.
 
246
     *
 
247
     * @throws Nag_Exception
 
248
     */
 
249
    protected function _doSearch()
 
250
    {
 
251
        // Clear the tag browser in case we have an active browse set.
 
252
        $this->_browser->clearSearch();
 
253
 
 
254
        // Don't show the tag browser.
 
255
        $this->_showTagBrowser = false;
 
256
 
 
257
        $form = new Nag_Form_Search($this->_vars);
 
258
        if ($form->validate($this->_vars, true)) {
 
259
            $form->getInfo($this->_vars, $info);
 
260
        } else {
 
261
            throw new Nag_Exception(current($form->getErrors()));
 
262
        }
 
263
 
 
264
        // Text filter
 
265
        $search_pattern = $this->_vars->search_pattern;
 
266
        $search_in = empty($this->_vars->search_in) ? array() : $this->_vars->search_in;
 
267
        $search_name = in_array('search_name', $search_in) ? Nag_Search::MASK_NAME : 0;
 
268
        $search_desc = in_array('search_desc', $search_in) ? Nag_Search::MASK_DESC : 0;
 
269
        $search_tags = !empty($this->_vars->search_tags) ? Nag_Search::MASK_TAGS : 0;
 
270
        $search_completed = $this->_vars->search_completed;
 
271
 
 
272
        $this->_vars->set('show_completed', $search_completed);
 
273
        $mask = $search_name | $search_desc | $search_tags;
 
274
 
 
275
        // Date filter
 
276
        $date = $info['due_date'];
 
277
        if (empty($date)) {
 
278
            $date = array();
 
279
        }
 
280
 
 
281
        // Prepare the search
 
282
        $search = new Nag_Search(
 
283
            $search_pattern,
 
284
            $mask,
 
285
            array(
 
286
                'completed' => $search_completed,
 
287
                'due' => $date,
 
288
                'tags' => empty($this->_vars->search_tags) ? array() : $GLOBALS['injector']->getInstance('Nag_Tagger')->split($this->_vars->search_tags))
 
289
        );
 
290
        try {
 
291
            $tasks = $search->getSlice();
 
292
        } catch (Nag_Exception $e) {
 
293
            $GLOBALS['notification']->push($tasks, 'horde.error');
 
294
            $tasks = new Nag_Task();
 
295
        }
 
296
 
 
297
        // Save as a smart list?
 
298
        if ($id = $this->_vars->get('smart_id')) {
 
299
            // Existing list.
 
300
            $smartlist = $GLOBALS['nag_shares']->getShare($id);
 
301
            Nag::updateTasklist(
 
302
                $smartlist,
 
303
                array(
 
304
                    'name' => $this->_vars->get('smartlist_name'),
 
305
                    'search' => serialize($search))
 
306
            );
 
307
            $this->_title = $smartlist->get('name');
 
308
            $this->_smartShare = $smartlist;
 
309
        } elseif ($this->_vars->get('save_smartlist')) {
 
310
            $this->_smartShare = Nag::addTasklist(
 
311
                array('name' => $this->_vars->get('smartlist_name'),
 
312
                      'search' => serialize($search)),
 
313
                false
 
314
            );
 
315
            $this->_title = $this->_vars->get('smartlist_name');
 
316
        } else {
 
317
            // Build a page title based on criteria.
 
318
            $this->_title = sprintf(_("Search: Results for"));
 
319
            $have_title = false;
 
320
            if (!empty($search_pattern)) {
 
321
                $have_title = true;
 
322
                $this->_title .= ' "' . $search_pattern . '" ';
 
323
            } else {
 
324
                $this->_title .= ' ' . _("tasks") . ' ';
 
325
            }
 
326
            if (!empty($date)) {
 
327
                if ($have_title) {
 
328
                    $this->_title .= _("and") . ' ';
 
329
                } else {
 
330
                    $this->_title .= _("with") . ' ';
 
331
                    $have_title = true;
 
332
                }
 
333
                $this->_title .= sprintf(_("due date within %d days of %s"), $date[0], $date[1]) . ' ';
 
334
            }
 
335
            if (!empty($search_tags)) {
 
336
                if ($have_title) {
 
337
                    $this->_title .= _("and") . ' ';
 
338
                } else {
 
339
                    $this->_title .= _("with") . ' ';
 
340
                }
 
341
                $this->_title .= sprintf(_("and tagged with %s"), $this->_vars->search_tags);
 
342
            }
 
343
        }
 
344
 
 
345
        $this->_tasks = $tasks;
 
346
    }
 
347
 
 
348
    /**
 
349
     * Delete a SmartList.
 
350
     *
 
351
     */
 
352
    protected function _doDeleteSmartList()
 
353
    {
 
354
        try {
 
355
            $sl = $GLOBALS['nag_shares']->getShare($this->_vars->smart_id);
 
356
            Nag::deleteTasklist($sl);
 
357
        } catch (Horde_Exception $e) {
 
358
            $GLOBALS['notification']->push($e->getMessage(), 'horde.error');
 
359
            Horde::url('list.php')->redirect();
 
360
            exit;
 
361
        }
 
362
        $GLOBALS['notification']->push(_("Smart List deleted successfully"), 'horde.success');
 
363
    }
 
364
 
 
365
    /**
 
366
     * Get HTML to display the related tags links.
 
367
     *
 
368
     * @return string
 
369
     */
 
370
    protected function _getRelatedTags()
 
371
    {
 
372
        $this->_tasks->reset();
 
373
        $ids = array();
 
374
        while ($t = $this->_tasks->each()) {
 
375
            $ids[] = $t->uid;
 
376
        }
 
377
        $rtags = $this->_browser->getRelatedTags($ids);
 
378
        if (count($rtags)) {
 
379
            $html = '<div class="nag-tags-related">'
 
380
                . Horde::img('tags.png')
 
381
                . ' <ul class="horde-tags">';
 
382
            foreach ($rtags as $id => $taginfo) {
 
383
                $html .= '<li>'
 
384
                    . $this->_linkAddTag($taginfo['tag_name'])->link()
 
385
                    . htmlspecialchars($taginfo['tag_name']) . '</a></li>';
 
386
            }
 
387
            return $html . '</ul></div>';
 
388
        }
 
389
 
 
390
        return '';
 
391
    }
 
392
 
 
393
    /**
 
394
     * Get HTML to represent the currently selected tags.
 
395
     *
 
396
     * @return string
 
397
     */
 
398
    protected function _getTagTrail()
 
399
    {
 
400
        if ($this->_browser->tagCount() >= 1) {
 
401
            $html = '<div class="nag-tags-browsing">' . Horde::img('filter.png') . '<ul class="horde-tags">';
 
402
            foreach ($this->_browser->getTags() as $tag => $id) {
 
403
                $html .= '<li>' . htmlspecialchars($tag)
 
404
                    . $this->_linkRemoveTag($tag)->link()
 
405
                    . Horde::img('delete-small.png', _("Remove from search"))
 
406
                    . '</a></li>';
 
407
            }
 
408
            return $html .= '</ul></div>';
 
409
        }
 
410
 
 
411
        return '';
 
412
    }
 
413
 
 
414
    /**
 
415
     * Get HTML for a link to remove a tag from the current search.
 
416
     *
 
417
     * @param  string $tag  The tag we want the link for.
 
418
     *
 
419
     * @return string
 
420
     */
 
421
    protected function _linkRemoveTag($tag)
 
422
    {
 
423
        return Horde::url('list.php')
 
424
            ->add(array('actionID' => 'browse_remove', 'tag' => $tag));
 
425
    }
 
426
 
 
427
    /**
 
428
     * Get HTML for a link to add a new tag to the current search.
 
429
     *
 
430
     * @param string $tag  The tag we want to add.
 
431
     *
 
432
     * @return string
 
433
     */
 
434
    protected function _linkAddTag($tag)
 
435
    {
 
436
        return Horde::url('list.php')->add(array('actionID' => 'browse_add', 'tag' => $tag));
 
437
    }
 
438
 
 
439
}