Overview

Packages

  • Nag
  • None

Classes

  • Nag_Application
  • Nag_Block_Summary
  • Nag_QuickParser
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Nag application API.
  4:  *
  5:  * This file defines Horde's core API interface. Other core Horde libraries
  6:  * can interact with Horde through this API.
  7:  *
  8:  * See the enclosed file COPYING for license information (GPL). If you
  9:  * did not receive this file, see http://www.horde.org/licenses/gpl.
 10:  *
 11:  * @package Nag
 12:  */
 13: 
 14: /* Determine the base directories. */
 15: if (!defined('NAG_BASE')) {
 16:     define('NAG_BASE', dirname(__FILE__) . '/..');
 17: }
 18: 
 19: if (!defined('HORDE_BASE')) {
 20:     /* If Horde does not live directly under the app directory, the HORDE_BASE
 21:      * constant should be defined in config/horde.local.php. */
 22:     if (file_exists(NAG_BASE . '/config/horde.local.php')) {
 23:         include NAG_BASE . '/config/horde.local.php';
 24:     } else {
 25:         define('HORDE_BASE', NAG_BASE . '/..');
 26:     }
 27: }
 28: 
 29: /* Load the Horde Framework core (needed to autoload
 30:  * Horde_Registry_Application::). */
 31: require_once HORDE_BASE . '/lib/core.php';
 32: 
 33: class Nag_Application extends Horde_Registry_Application
 34: {
 35:     /**
 36:      */
 37:     public $version = 'H4 (3.0.10-git)';
 38: 
 39:     /**
 40:      */
 41:     public $mobileView = true;
 42: 
 43:     /**
 44:      * Global variables defined:
 45:      *   $nag_shares - TODO
 46:      */
 47:     protected function _init()
 48:     {
 49:         // Set the timezone variable.
 50:         $GLOBALS['registry']->setTimeZone();
 51: 
 52:         // Create a share instance.
 53:         $GLOBALS['nag_shares'] = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Share')->create();
 54: 
 55:         Nag::initialize();
 56:     }
 57: 
 58:     /**
 59:      */
 60:     public function perms()
 61:     {
 62:         return array(
 63:             'max_tasks' => array(
 64:                 'title' => _("Maximum Number of Tasks"),
 65:                 'type' => 'int'
 66:             )
 67:         );
 68:     }
 69: 
 70:     /**
 71:      */
 72:     public function menu($menu)
 73:     {
 74:         global $conf, $injector;
 75: 
 76:         $menu->add(Horde::url('list.php'), _("_List Tasks"), 'nag.png', null, null, null, basename($_SERVER['PHP_SELF']) == 'index.php' ? 'current' : null);
 77: 
 78:         if (Nag::getDefaultTasklist(Horde_Perms::EDIT) &&
 79:             ($injector->getInstance('Horde_Core_Perms')->hasAppPermission('max_tasks') === true ||
 80:              $injector->getInstance('Horde_Core_Perms')->hasAppPermission('max_tasks') > Nag::countTasks())) {
 81:             $menu->add(Horde::url('task.php')->add('actionID', 'add_task'), _("_New Task"), 'add.png', null, null, null, Horde_Util::getFormData('task') ? '__noselection' : null);
 82:             if ($GLOBALS['browser']->hasFeature('dom')) {
 83:                 Horde::addScriptFile('effects.js', 'horde');
 84:                 Horde::addScriptFile('redbox.js', 'horde');
 85:                 $menu->add(new Horde_Url(''), _("_Quick Add"), 'add.png', null, null, 'RedBox.showInline(\'quickAddInfoPanel\'); $(\'quickText\').focus(); return false;', Horde_Util::getFormData('task') ? 'quickAdd __noselection' : 'quickAdd');
 86:             }
 87:         }
 88: 
 89:         /* Search. */
 90:         $menu->add(Horde::url('search.php'), _("_Search"), 'search.png');
 91: 
 92:         /* Import/Export. */
 93:         if ($conf['menu']['import_export']) {
 94:             $menu->add(Horde::url('data.php'), _("_Import/Export"), 'data.png');
 95:         }
 96:     }
 97: 
 98:     /**
 99:      */
100:     public function hasPermission($permission, $allowed, $opts = array())
101:     {
102:         if (is_array($allowed)) {
103:             switch ($permission) {
104:             case 'max_tasks':
105:                 $allowed = max($allowed);
106:                 break;
107:             }
108:         }
109:         return $allowed;
110:     }
111: 
112:     public function prefsInit($ui)
113:     {
114:         global $registry;
115:         if ($registry->hasMethod('getListTypes', 'whups')) {
116:             $ui->override['show_external'] = array(
117:                 'whups' => $registry->get('name', 'whups')
118:             );
119:         } else {
120:             $ui->suppress[] = 'show_external';
121:         }
122:     }
123: 
124:     /**
125:      */
126:     public function prefsGroup($ui)
127:     {
128:         global $conf, $prefs, $registry;
129: 
130:         foreach ($ui->getChangeablePrefs() as $val) {
131:             switch ($val) {
132:             case 'default_due_time':
133:                 $twentyfour = $prefs->getValue('twentyFour');
134: 
135:                 $vals = array('now' => _("The current hour"));
136:                 for ($i = 0; $i < 24; ++$i) {
137:                     $value = sprintf('%02d:00', $i);
138:                     $vals[$value] = ($twentyfour)
139:                         ? $value
140:                         : sprintf('%02d:00 ' . ($i >= 12 ? _("pm") : _("am")), ($i % 12 ? $i % 12 : 12));
141:                 }
142:                 $ui->override['default_due_time'] = $vals;
143:                 break;
144: 
145:             case 'default_tasklist':
146:                 $vals = array();
147:                 foreach (Nag::listTasklists() as $id => $tasklist) {
148:                     $vals[htmlspecialchars($id)] = htmlspecialchars($tasklist->get('name'));
149:                 }
150:                 $ui->override['default_tasklist'] = $vals;
151:                 break;
152: 
153:             case 'sync_lists':
154:                 $sync = @unserialize($prefs->getValue('sync_lists'));
155:                 if (empty($sync)) {
156:                     $prefs->setValue('sync_lists', serialize(array(Nag::getDefaultTasklist())));
157:                 }
158:                 $out = array();
159:                 foreach (Nag::listTasklists(false, Horde_Perms::EDIT) as $key => $list) {
160:                     if ($list->getName() != Nag::getDefaultTasklist(Horde_Perms::EDIT)) {
161:                         $out[$key] = $list->get('name');
162:                     }
163:                 }
164:                 $ui->override['sync_lists'] = $out;
165:                 break;
166: 
167:             case 'show_external':
168:                 if ($registry->hasMethod('getListTypes', 'whups')) {
169:                     $ui->override['show_external'] = array(
170:                         'whups' => $registry->get('name', 'whups')
171:                     );
172:                 } else {
173:                     $ui->suppress[] = 'show_external';
174:                 }
175:                 break;
176: 
177:             case 'task_alarms_select':
178:                 if (empty($conf['alarms']['driver']) ||
179:                     $prefs->isLocked('task_alarms_select')) {
180:                     $ui->suppress[] = 'task_alarms';
181:                 } else {
182:                     Horde_Core_Prefs_Ui_Widgets::alarmInit();
183:                 }
184:                 break;
185:             }
186:         }
187:     }
188: 
189:     /**
190:      */
191:     public function prefsSpecial($ui, $item)
192:     {
193:         switch ($item) {
194:         case 'task_alarms_select':
195:             return Horde_Core_Prefs_Ui_Widgets::alarm(array(
196:                 'label' => _("Choose how you want to receive reminders for tasks with alarms:"),
197:                 'pref' => 'task_alarms'
198:             ));
199:         }
200: 
201:         return '';
202:     }
203: 
204:     /**
205:      */
206:     public function prefsSpecialUpdate($ui, $item)
207:     {
208:         switch ($item) {
209:         case 'task_alarms_select':
210:             $data = Horde_Core_Prefs_Ui_Widgets::alarmUpdate($ui, array('pref' => 'task_alarms'));
211:             if (!is_null($data)) {
212:                 $GLOBALS['prefs']->setValue('task_alarms', serialize($data));
213:                 return true;
214:             }
215:             break;
216:         }
217: 
218:         return false;
219:     }
220: 
221:     /**
222:      */
223:     public function prefsCallback($ui)
224:     {
225:         // Ensure that the current default_share is included in sync_calendars
226:         if ($GLOBALS['prefs']->isDirty('sync_lists') || $GLOBALS['prefs']->isDirty('default_tasklist')) {
227:             $sync = @unserialize($GLOBALS['prefs']->getValue('sync_lists'));
228:             $haveDefault = false;
229:             $default = Nag::getDefaultTasklist(Horde_Perms::EDIT);
230:             foreach ($sync as $cid) {
231:                 if ($cid == $default) {
232:                     $haveDefault = true;
233:                     break;
234:                 }
235:             }
236:             if (!$haveDefault) {
237:                 $sync[] = $default;
238:                 $GLOBALS['prefs']->setValue('sync_lists', serialize($sync));
239:             }
240:         }
241: 
242:         if ($GLOBALS['conf']['activesync']['enabled'] && $GLOBALS['prefs']->isDirty('sync_lists')) {
243:             try {
244:                 $stateMachine = $GLOBALS['injector']->getInstance('Horde_ActiveSyncState');
245:                 $stateMachine->setLogger($GLOBALS['injector']->getInstance('Horde_Log_Logger'));
246:                 $devices = $stateMachine->listDevices($GLOBALS['registry']->getAuth());
247:                 foreach ($devices as $device) {
248:                     $stateMachine->removeState(null, $device['device_id'], $GLOBALS['registry']->getAuth());
249:                 }
250:                 $GLOBALS['notification']->push(_("All state removed for your ActiveSync devices. They will resynchronize next time they connect to the server."));
251:             } catch (Horde_ActiveSync_Exception $e) {
252:                 $GLOBALS['notification']->push(_("There was an error communicating with the ActiveSync server: %s"), $e->getMessage(), 'horde.err');
253:             }
254:         }
255:     }
256: 
257:     /**
258:      */
259:     public function removeUserData($user)
260:     {
261:         /* Get the shares for later deletion */
262:         try {
263:             $shares = $GLOBALS['nag_shares']->listShares($user, array('attributes' => $user));
264:         } catch (Horde_Share_Exception $e) {
265:             Horde::logMessage($e, 'ERR');
266:             throw new Nag_Exception($e);
267:         }
268: 
269:         $error = false;
270:         foreach ($shares as $share) {
271:             $storage = Nag_Driver::singleton($share->getName());
272:             $result = $storage->deleteAll();
273:             try {
274:                 $GLOBALS['nag_shares']->removeShare($share);
275:             } catch (Horde_Share_Exception $e) {
276:                 Horde::logMessage($e, 'NOTICE');
277:                 $error = true;
278:             }
279:         }
280: 
281:         /* Now remove perms for this user from all other shares */
282:         try {
283:             $shares = $GLOBALS['nag_shares']->listShares($user);
284:             foreach ($shares as $share) {
285:                $share->removeUser($user);
286:             }
287:         } catch (Horde_Share_Exception $e) {
288:             Horde::logMessage($e, 'NOTICE');
289:             $error = true;
290:         }
291: 
292:         if ($error) {
293:             throw new Nag_Exception(sprintf(_("There was an error removing tasks for %s. Details have been logged."), $user));
294:         }
295:     }
296: 
297:     /* Alarm method. */
298: 
299:     /**
300:      */
301:     public function listAlarms($time, $user = null)
302:     {
303:         if ((empty($user) || $user != $GLOBALS['registry']->getAuth()) &&
304:             !$GLOBALS['registry']->isAdmin()) {
305: 
306:             throw new Horde_Exception_PermissionDenied(_("Permission Denied"));
307:         }
308: 
309:         $storage = Nag_Driver::singleton();
310:         $group = $GLOBALS['injector']->getInstance('Horde_Group');
311:         $alarm_list = array();
312:         $tasklists = is_null($user) ?
313:             array_keys($GLOBALS['nag_shares']->listAllShares()) :
314:             $GLOBALS['display_tasklists'];
315: 
316:         $alarms = Nag::listAlarms($time, $tasklists);
317:         foreach ($alarms as $alarm) {
318:             try {
319:                 $share = $GLOBALS['nag_shares']->getShare($alarm->tasklist);
320:             } catch (Horde_Share_Exception $e) {
321:                 continue;
322:             }
323:             if (empty($user)) {
324:                 $users = $share->listUsers(Horde_Perms::READ);
325:                 $groups = $share->listGroups(Horde_Perms::READ);
326:                 foreach ($groups as $gid) {
327:                     $users = array_merge($users, $group->listUsers($gid));
328:                 }
329:                 $users = array_unique($users);
330:             } else {
331:                 $users = array($user);
332:             }
333:             foreach ($users as $alarm_user) {
334:                 $prefs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Prefs')->create('nag', array(
335:                     'cache' => false,
336:                     'user' => $alarm_user
337:                 ));
338:                 $GLOBALS['registry']->setLanguageEnvironment($prefs->getValue('language'));
339:                 $alarm_list[] = $alarm->toAlarm($alarm_user, $prefs);
340:             }
341:         }
342: 
343:         return $alarm_list;
344:     }
345: 
346: 
347:     /* Sidebar method. */
348: 
349:     /**
350:      */
351:     public function sidebarCreate(Horde_Tree_Base $tree, $parent = null,
352:                                   array $params = array())
353:     {
354:         global $registry;
355: 
356:         switch ($params['id']) {
357:         case 'alarms':
358:             // Get any alarms in the next hour.
359:             $now = time();
360:             $alarms = Nag::listAlarms($now);
361:             $alarmCount = 0;
362:             $horde_alarm = $GLOBALS['injector']->getInstance('Horde_Alarm');
363:             foreach ($alarms as $taskId => $task) {
364:                 if ($horde_alarm->isSnoozed($task->uid, $registry->getAuth())) {
365:                     continue;
366:                 }
367:                 ++$alarmCount;
368: 
369:                 $differential = $task->due - $now;
370:                 $title = ($differential >= 60)
371:                     ? sprintf(_("%s is due in %s"), $task->name, Nag::secondsToString($differential))
372:                     : sprintf(_("%s is due now."), $task->name);
373:                 $url = Horde::url('view.php')->add(array(
374:                     'task' => $task->id,
375:                     'tasklist' => $task->tasklist
376:                 ));
377: 
378:                 $tree->addNode(
379:                     $parent . $taskId,
380:                     $parent,
381:                     $task->name,
382:                     1,
383:                     false,
384:                     array(
385:                         'icon' => Horde_Themes::img('alarm.png'),
386:                         'title' => $title,
387:                         'url' => $url
388:                     )
389:                 );
390:             }
391: 
392:             if ($registry->get('url', $parent)) {
393:                 $purl = $registry->get('url', $parent);
394:             } elseif ($registry->get('status', $parent) == 'heading' ||
395:                       !$registry->get('webroot')) {
396:                 $purl = null;
397:             } else {
398:                 $purl = Horde::url($registry->getInitialPage($parent));
399:             }
400: 
401:             $pnode_name = $registry->get('name', $parent);
402:             if ($alarmCount) {
403:                 $pnode_name = '<strong>' . $pnode_name . '</strong>';
404:             }
405: 
406:             $tree->addNode(
407:                 $parent,
408:                 $registry->get('menu_parent', $parent),
409:                 $pnode_name,
410:                 0,
411:                 false,
412:                 array(
413:                     'icon' => strval($registry->get('icon', $parent)),
414:                     'url' => $purl
415:                 )
416:             );
417:             break;
418: 
419:         case 'menu':
420:             $add = Horde::url('task.php')->add('actionID', 'add_task');
421: 
422:             $tree->addNode(
423:                 $parent . '__new',
424:                 $parent,
425:                 _("New Task"),
426:                 1,
427:                 false,
428:                 array(
429:                     'icon' => Horde_Themes::img('add.png'),
430:                     'url' => $add
431:                 )
432:             );
433: 
434:             foreach (Nag::listTasklists() as $name => $tasklist) {
435:                 $tree->addNode(
436:                     $parent . $name . '__new',
437:                     $parent . '__new',
438:                     sprintf(_("in %s"), $tasklist->get('name')),
439:                     2,
440:                     false,
441:                     array(
442:                         'icon' => Horde_Themes::img('add.png'),
443:                         'url' => $add->copy()->add('tasklist_id', $name)
444:                     )
445:                 );
446:             }
447: 
448:             $tree->addNode(
449:                 $parent . '__search',
450:                 $parent,
451:                 _("Search"),
452:                 1,
453:                 false,
454:                 array(
455:                     'icon' => Horde_Themes::img('search.png'),
456:                     'url' => Horde::url('search.php')
457:                 )
458:             );
459:             break;
460:         }
461:     }
462: 
463: }
464: 
API documentation generated by ApiGen