Overview

Packages

  • IMP
  • None

Classes

  • IMP_Application
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * IMP application API.
  4:  *
  5:  * This file defines Horde's core API interface. Other core Horde libraries
  6:  * can interact with IMP through this API.
  7:  *
  8:  * Copyright 2010-2012 Horde LLC (http://www.horde.org/)
  9:  *
 10:  * See the enclosed file COPYING for license information (GPL). If you
 11:  * did not receive this file, see http://www.horde.org/licenses/gpl.
 12:  *
 13:  * @author   Michael Slusarz <slusarz@horde.org>
 14:  * @category Horde
 15:  * @license  http://www.horde.org/licenses/gpl GPL
 16:  * @package  IMP
 17:  */
 18: 
 19: /* Determine the base directories. */
 20: if (!defined('IMP_BASE')) {
 21:     define('IMP_BASE', dirname(__FILE__) . '/..');
 22: }
 23: 
 24: if (!defined('HORDE_BASE')) {
 25:     /* If Horde does not live directly under the app directory, the HORDE_BASE
 26:      * constant should be defined in config/horde.local.php. */
 27:     if (file_exists(IMP_BASE . '/config/horde.local.php')) {
 28:         include IMP_BASE . '/config/horde.local.php';
 29:     } else {
 30:         define('HORDE_BASE', IMP_BASE . '/..');
 31:     }
 32: }
 33: 
 34: /* Load the Horde Framework core (needed to autoload
 35:  * Horde_Registry_Application::). */
 36: require_once HORDE_BASE . '/lib/core.php';
 37: 
 38: class IMP_Application extends Horde_Registry_Application
 39: {
 40:     /**
 41:      */
 42:     public $ajaxView = true;
 43: 
 44:     /**
 45:      */
 46:     public $auth = array(
 47:         'add',
 48:         'authenticate',
 49:         'list',
 50:         'remove',
 51:         'transparent'
 52:     );
 53: 
 54:     /**
 55:      */
 56:     public $mobileView = true;
 57: 
 58:     /**
 59:      */
 60:     public $version = 'H4 (5.0.25-git)';
 61: 
 62:     /**
 63:      * Cached values to add to the session after authentication.
 64:      *
 65:      * @var array
 66:      */
 67:     protected $_cacheSess = array();
 68: 
 69:     /**
 70:      * Server key used in logged out session.
 71:      *
 72:      * @var string
 73:      */
 74:     protected $_oldserver = null;
 75: 
 76:     /**
 77:      * Constructor.
 78:      */
 79:     public function __construct()
 80:     {
 81:         /* Methods only available if admin config is set for this
 82:          * server/login. */
 83:         if (!isset($GLOBALS['session']) ||
 84:             !$GLOBALS['session']->get('imp', 'imap_admin')) {
 85:             $this->auth = array_diff($this->auth, array('add', 'list', 'remove'));
 86:         }
 87:     }
 88: 
 89:     /**
 90:      */
 91:     public function appInitFailure($e)
 92:     {
 93:         if (($e->getCode() == Horde_Registry::AUTH_FAILURE) &&
 94:             Horde_Util::getFormData('composeCache')) {
 95:             $GLOBALS['injector']->getInstance('IMP_Factory_Compose')->create()->sessionExpireDraft(Horde_Variables::getDefaultVariables());
 96:         }
 97:     }
 98: 
 99:     /**
100:      */
101:     protected function _init()
102:     {
103:         /* Add IMP-specific factories. */
104:         $factories = array(
105:             'IMP_AuthImap' => 'IMP_Factory_AuthImap',
106:             'IMP_Crypt_Pgp' => 'IMP_Factory_Pgp',
107:             'IMP_Crypt_Smime' => 'IMP_Factory_Smime',
108:             'IMP_Flags' => 'IMP_Factory_Flags',
109:             'IMP_Identity' => 'IMP_Factory_Identity',
110:             'IMP_Imap_Tree' => 'IMP_Factory_Imaptree',
111:             'IMP_Mail' => 'IMP_Factory_Mail',
112:             'IMP_Quota' => 'IMP_Factory_Quota',
113:             'IMP_Search' => 'IMP_Factory_Search',
114:             'IMP_Sentmail' => 'IMP_Factory_Sentmail'
115:         );
116: 
117:         foreach ($factories as $key => $val) {
118:             $GLOBALS['injector']->bindFactory($key, $val, 'create');
119:         }
120: 
121:         // Set default message character set.
122:         if ($GLOBALS['registry']->getAuth()) {
123:             if ($def_charset = $GLOBALS['prefs']->getValue('default_msg_charset')) {
124:                 Horde_Mime_Part::$defaultCharset = $def_charset;
125:                 Horde_Mime_Headers::$defaultCharset = $def_charset;
126:             }
127: 
128:             // Always use Windows-1252 in place of ISO-8859-1 for MIME
129:             // decoding.
130:             Horde_Mime::$decodeWindows1252 = true;
131:         }
132: 
133:         IMP::setCurrentMailboxInfo();
134: 
135:         $redirect = false;
136: 
137:         switch (IMP::getViewMode()) {
138:         case 'dimp':
139:             $redirect = (!empty($this->initParams['impmode']) &&
140:                          ($this->initParams['impmode'] != 'dimp'));
141:             break;
142: 
143:         case 'mimp':
144:             $redirect = (empty($this->initParams['impmode']) ||
145:                          ($this->initParams['impmode'] != 'mimp'));
146:             break;
147: 
148:         case 'mobile':
149:             $redirect = (!empty($this->initParams['impmode']) &&
150:                          ($this->initParams['impmode'] != 'mobile'));
151:             break;
152: 
153:         case 'imp':
154:             $redirect = (!empty($this->initParams['impmode']) &&
155:                          ($this->initParams['impmode'] != 'imp'));
156:             break;
157:         }
158: 
159:         if ($redirect && ($GLOBALS['registry']->initialApp == 'imp')) {
160:             IMP_Auth::getInitialPage()->url->redirect();
161:         }
162:     }
163: 
164:     /**
165:      */
166:     public function logout()
167:     {
168:         /* Clean up dangling IMP_Compose objects. */
169:         foreach (array_keys($GLOBALS['session']->get('imp', 'compose_cache', Horde_Session::TYPE_ARRAY)) as $key) {
170:             $GLOBALS['injector']->getInstance('IMP_Factory_Compose')->create($key)->destroy('cancel');
171:         }
172: 
173:         /* No need to keep Tree object in cache - it will be recreated next
174:          * login. */
175:         if ($treeob = $GLOBALS['session']->get('imp', 'treeob')) {
176:             $GLOBALS['injector']->getInstance('Horde_Cache')->expire($treeob);
177:         }
178: 
179:         /* Grab the current server from the session to correctly populate
180:          * login form. */
181:         $this->_oldserver = $GLOBALS['session']->get('imp', 'server_key');
182:     }
183: 
184:     /* Horde permissions. */
185: 
186:     /**
187:      */
188:     public function perms()
189:     {
190:         return array(
191:             'create_folders' => array(
192:                 'title' => _("Allow Folder Creation?"),
193:                 'type' => 'boolean'
194:             ),
195:             'max_folders' => array(
196:                 'title' => _("Maximum Number of Folders"),
197:                 'type' => 'int'
198:             ),
199:             'max_recipients' => array(
200:                 'title' => _("Maximum Number of Recipients per Message"),
201:                 'type' => 'int'
202:             ),
203:             'max_timelimit' => array(
204:                 'title' => _("Maximum Number of Recipients per Time Period"),
205:                 'type' => 'int'
206:             )
207:         );
208:     }
209: 
210:     /**
211:      */
212:     public function hasPermission($permission, $allowed, $opts = array())
213:     {
214:         if (is_array($allowed)) {
215:             $allowed = max($allowed);
216:         }
217:         return $allowed;
218:     }
219: 
220:     /* Menu methods. */
221: 
222:     /**
223:      */
224:     public function menu($menu)
225:     {
226:         global $injector, $prefs, $registry;
227: 
228:         $menu_mailbox_url = Horde::url('mailbox.php');
229:         $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create();
230: 
231:         $menu->addArray(array(
232:             'icon' => 'folders/inbox.png',
233:             'text' => _("_Inbox"),
234:             'url' => IMP_Mailbox::get('INBOX')->url($menu_mailbox_url)
235:         ));
236: 
237:         if ($imp_imap->access(IMP_Imap::ACCESS_TRASH) &&
238:             $prefs->getValue('use_trash') &&
239:             $prefs->getValue('empty_trash_menu') &&
240:             ($trash_folder = IMP_Mailbox::getPref('trash_folder')) &&
241:             ($trash_folder->vtrash || $trash_folder->access_expunge)) {
242:             $menu->addArray(array(
243:                 'class' => '__noselection',
244:                 'icon' => 'empty_trash.png',
245:                 'onclick' => 'return window.confirm(' . Horde_Serialize::serialize(_("Are you sure you wish to empty your trash folder?"), Horde_Serialize::JSON, 'UTF-8') . ')',
246:                 'text' => _("Empty _Trash"),
247:                 'url' => $trash_folder->url($menu_mailbox_url)->add(array('actionID' => 'empty_mailbox', 'mailbox_token' => $injector->getInstance('Horde_Token')->get('imp.mailbox')))
248:             ));
249:         }
250: 
251:         if ($imp_imap->access(IMP_Imap::ACCESS_FOLDERS) &&
252:             $prefs->getValue('empty_spam_menu') &&
253:             ($spam_folder = IMP_Mailbox::getPref('spam_folder')) &&
254:             $spam_folder->access_expunge) {
255:             $menu->addArray(array(
256:                 'class' => '__noselection',
257:                 'icon' =>  'empty_spam.png',
258:                 'onclick' => 'return window.confirm(' . Horde_Serialize::serialize(_("Are you sure you wish to empty your spam folder?"), Horde_Serialize::JSON, 'UTF-8') . ')',
259:                 'text' => _("Empty _Spam"),
260:                 'url' => $spam_folder->url($menu_mailbox_url)->add(array('actionID' => 'empty_mailbox', 'mailbox_token' => $injector->getInstance('Horde_Token')->get('imp.mailbox')))
261:             ));
262:         }
263: 
264:         if (IMP::canCompose()) {
265:             $menu->addArray(array(
266:                 'icon' => 'compose.png',
267:                 'text' => _("_New Message"),
268:                 'url' => IMP::composeLink()
269:             ));
270:         }
271: 
272:         if ($imp_imap->access(IMP_Imap::ACCESS_FOLDERS)) {
273:             $menu->addArray(array(
274:                 'icon' => 'folders/folder.png',
275:                 'text' => _("_Folders"),
276:                 'url' => Horde::url('folders.php')->unique()
277:             ));
278:         }
279: 
280:         if ($imp_imap->access(IMP_Imap::ACCESS_SEARCH)) {
281:             $menu->addArray(array(
282:                 'icon' => 'search.png',
283:                 'text' =>_("_Search"),
284:                 'url' => Horde::url('search.php')
285:             ));
286:         }
287: 
288:         if ($prefs->getValue('filter_menuitem')) {
289:             $menu->addArray(array(
290:                 'icon' => 'filters.png',
291:                 'text' => _("Fi_lters"),
292:                 'url' => Horde::getServiceLink('prefs', 'imp')->add('group', 'filters')
293:             ));
294:         }
295:     }
296: 
297: 
298:     // Horde_Notification methods.
299: 
300:     /**
301:      * Modifies the global notification handler.
302:      *
303:      * @param Horde_Notification_Handler $handler  A notification handler.
304:      */
305:     public function setupNotification(Horde_Notification_Handler $handler)
306:     {
307:         $handler->addDecorator(new IMP_Notification_Handler_Decorator_ImapAlerts());
308:         $handler->addDecorator(new IMP_Notification_Handler_Decorator_NewmailNotify());
309:         $handler->addType('status', 'imp.*', 'IMP_Notification_Event_Status');
310:     }
311: 
312:     /* Horde_Core_Auth_Application methods. */
313: 
314:     /**
315:      */
316:     public function authLoginParams()
317:     {
318:         $params = array();
319: 
320:         if ($GLOBALS['conf']['server']['server_list'] == 'shown') {
321:             $servers = IMP_Imap::loadServerConfig();
322:             $server_list = array();
323:             $selected = is_null($this->_oldserver)
324:                 ? Horde_Util::getFormData('imp_server_key', IMP_Auth::getAutoLoginServer())
325:                 : $this->_oldserver;
326: 
327:             foreach ($servers as $key => $val) {
328:                 $server_list[$key] = array(
329:                     'name' => $val['name'],
330:                     'selected' => ($selected == $key)
331:                 );
332:             }
333:             $params['imp_server_key'] = array(
334:                 'label' => _("Server"),
335:                 'type' => 'select',
336:                 'value' => $server_list
337:             );
338:         }
339: 
340:         /* Show selection of alternate views. */
341:         $js_code = array(
342:             'ImpLogin.server_key_error' => _("Please choose a mail server.")
343:         );
344: 
345:         return array(
346:             'js_code' => $js_code,
347:             'js_files' => array(
348:                 array('login.js', 'imp')
349:             ),
350:             'params' => $params
351:         );
352:     }
353: 
354:     /**
355:      * @param array $credentials  Credentials of the user. Allowed keys:
356:      *                            'imp_server_key', 'password'.
357:      */
358:     public function authAuthenticate($userId, $credentials)
359:     {
360:         $this->init();
361: 
362:         if (isset($credentials['server'])) {
363:             $server = $credentials['server'];
364:         } else {
365:             $server = empty($credentials['imp_server_key'])
366:                 ? IMP_Auth::getAutoLoginServer()
367:                 : $credentials['imp_server_key'];
368:         }
369: 
370:         $new_session = IMP_Auth::authenticate(array(
371:             'password' => $credentials['password'],
372:             'server' => $server,
373:             'userId' => $userId
374:         ));
375: 
376:         if ($new_session) {
377:             $this->_cacheSess = $new_session;
378:         }
379:     }
380: 
381:     /**
382:      */
383:     public function authTransparent($auth_ob)
384:     {
385:         $this->init();
386: 
387:         if ($result = IMP_Auth::transparent($auth_ob)) {
388:             $this->_cacheSess = $result;
389:             return true;
390:         }
391: 
392:         return false;
393:     }
394: 
395:     /**
396:      */
397:     public function authAuthenticateCallback()
398:     {
399:         if ($GLOBALS['registry']->getAuth()) {
400:             $this->init();
401: 
402:             foreach ($this->_cacheSess as $key => $val) {
403:                 $GLOBALS['session']->set('imp', $key, $val);
404:             }
405:             $this->_cacheSess = array();
406: 
407:             IMP_Auth::authenticateCallback();
408:         }
409:     }
410: 
411:     /**
412:      * @param array $credentials  An array of login credentials. For IMP,
413:      *                            this must contain a password entry.
414:      */
415:     public function authAddUser($userId, $credentials)
416:     {
417:         try {
418:             $GLOBALS['injector']->getInstance('IMP_AuthImap')->addUser($userId, $credentials);
419:         } catch (Exception $e) {
420:             throw new Horde_Auth_Exception($e);
421:         }
422:     }
423: 
424:     /**
425:      */
426:     public function authRemoveUser($userId)
427:     {
428:         try {
429:             $GLOBALS['injector']->getInstance('IMP_AuthImap')->removeUser($userId);
430:         } catch (Exception $e) {
431:             throw new Horde_Auth_Exception($e);
432:         }
433:     }
434: 
435:     /**
436:      */
437:     public function authUserList()
438:     {
439:         try {
440:             return $GLOBALS['injector']->getInstance('IMP_AuthImap')->listUsers();
441:         } catch (Exception $e) {
442:             throw new Horde_Auth_Exception($e);
443:         }
444:     }
445: 
446:     /* Preferences display/handling methods. Code is contained in
447:      * IMP_Prefs_Ui so it doesn't have to be loaded on every page load. */
448: 
449:     /**
450:      */
451:     public function prefsInit($ui)
452:     {
453:         $GLOBALS['injector']->getInstance('IMP_Prefs_Ui')->prefsInit($ui);
454:     }
455: 
456:     /**
457:      */
458:     public function prefsGroup($ui)
459:     {
460:         $GLOBALS['injector']->getInstance('IMP_Prefs_Ui')->prefsGroup($ui);
461:     }
462: 
463:     /**
464:      */
465:     public function prefsSpecial($ui, $item)
466:     {
467:         return $GLOBALS['injector']->getInstance('IMP_Prefs_Ui')->prefsSpecial($ui, $item);
468:     }
469: 
470:     /**
471:      */
472:     public function prefsSpecialUpdate($ui, $item)
473:     {
474:         return $GLOBALS['injector']->getInstance('IMP_Prefs_Ui')->prefsSpecialUpdate($ui, $item);
475:     }
476: 
477:     /**
478:      */
479:     public function prefsCallback($ui)
480:     {
481:         $GLOBALS['injector']->getInstance('IMP_Prefs_Ui')->prefsCallback($ui);
482:     }
483: 
484:     /* Sidebar method. */
485: 
486:     /**
487:      */
488:     public function sidebarCreate(Horde_Tree_Base $tree, $parent = null,
489:                                   array $params = array())
490:     {
491:         global $injector, $registry;
492: 
493:         IMP_Mailbox::get('INBOX')->filterOnDisplay();
494: 
495:         if (IMP::canCompose()) {
496:             $tree->addNode(
497:                 strval($parent) . 'compose',
498:                 $parent,
499:                 _("New Message"),
500:                 0,
501:                 false,
502:                 array(
503:                     'icon' => Horde_Themes::img('compose.png'),
504:                     'url' => IMP::composeLink()
505:                 )
506:             );
507:         }
508: 
509:         $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create();
510:         if ($imp_imap->access(IMP_Imap::ACCESS_SEARCH)) {
511:             $tree->addNode(
512:                 strval($parent) . 'search',
513:                 $parent,
514:                 _("Search"),
515:                 0,
516:                 false,
517:                 array(
518:                     'icon' => Horde_Themes::img('search.png'),
519:                     'url' => IMP::getViewMode() == 'dimp'
520:                         ? Horde::url('index.php')->setAnchor('search')
521:                         : Horde::url('search.php')
522:                 )
523:             );
524:         }
525: 
526:         if (!$imp_imap->access(IMP_Imap::ACCESS_FOLDERS)) {
527:             return;
528:         }
529: 
530:         $name_url = Horde::url('mailbox.php');
531: 
532:         /* Initialize the IMP_Tree object. */
533:         $imaptree = $injector->getInstance('IMP_Imap_Tree');
534:         $imaptree->setIteratorFilter(IMP_Imap_Tree::FLIST_VFOLDER);
535:         $imaptree->createTree($tree, array(
536:             'open' => false,
537:             'parent' => $parent,
538:             'poll_info' => true
539:         ));
540: 
541:         if (!($url = $registry->get('url', $parent))) {
542:             $url = (($registry->get('status', $parent) == 'heading') || !$registry->get('webroot'))
543:                 ? null
544:                 : $registry->getInitialPage($parent);
545:         }
546: 
547:         $node_params = array(
548:             'icon' => $registry->get('icon', $parent),
549:             'url' => $url
550:         );
551:         $name = $registry->get('name', $parent);
552: 
553:         if ($imaptree->unseen) {
554:             $node_params['icon'] = Horde_Themes::img('newmail.png');
555:             $name = sprintf('<strong>%s</strong> (%s)', $name, $imaptree->unseen);
556:         }
557: 
558:         $tree->addNode(
559:             strval($parent),
560:             $registry->get('menu_parent', $parent),
561:             $name,
562:             0,
563:             $imaptree->isOpen($parent),
564:             $node_params
565:         );
566:     }
567: 
568:     /* Language change callback. */
569: 
570:     /**
571:      */
572:     public function changeLanguage()
573:     {
574:         $this->init();
575:         $this->mailboxesChanged();
576:     }
577: 
578:     /* Helper methods. */
579: 
580:     /**
581:      * Run tasks when the mailbox list has changed.
582:      */
583:     public function mailboxesChanged()
584:     {
585:         $GLOBALS['injector']->getInstance('IMP_Imap_Tree')->init();
586:     }
587: 
588:     /**
589:      * Callback, called from common-template-mobile.inc that sets up the
590:      * jquery mobile init hanler.
591:      */
592:     public function mobileInitCallback()
593:     {
594:         Horde::addScriptFile('mobile.js');
595:         require IMP_TEMPLATES . '/mobile/javascript_defs.php';
596: 
597:         /* Inline script. */
598:         Horde::addInlineScript(
599:           '$(window.document).bind("mobileinit", function() {
600:               $.mobile.page.prototype.options.addBackBtn = true;
601:               $.mobile.page.prototype.options.backBtnText = "' . _("Back") .'";
602:               $.mobile.loadingMessage = "' . _("loading") . '";
603:            });'
604:         );
605:     }
606: 
607: }
608: 
API documentation generated by ApiGen