Overview

Packages

  • Auth
  • Core
  • Horde
    • Imsp
  • None
  • Notification

Classes

  • Horde
  • Horde_Config
  • Horde_Config_Form
  • Horde_Core_ActiveSync_Connector
  • Horde_Core_ActiveSync_Driver
  • Horde_Core_Ajax_Application
  • Horde_Core_Ajax_Imple
  • Horde_Core_Ajax_Imple_AutoCompleter
  • Horde_Core_Ajax_Imple_Geocoder_Geonames
  • Horde_Core_Ajax_Imple_SpellChecker
  • Horde_Core_Alarm_Handler_Notify
  • Horde_Core_Auth_Application
  • Horde_Core_Auth_Composite
  • Horde_Core_Auth_Ldap
  • Horde_Core_Auth_Msad
  • Horde_Core_Auth_Shibboleth
  • Horde_Core_Auth_Signup_Base
  • Horde_Core_Auth_Signup_Form
  • Horde_Core_Auth_Signup_Null
  • Horde_Core_Auth_Signup_Sql
  • Horde_Core_Auth_Signup_SqlObject
  • Horde_Core_Autoloader_Callback_Mime
  • Horde_Core_Autoloader_Callback_Nls
  • Horde_Core_Block
  • Horde_Core_Block_Collection
  • Horde_Core_Block_Layout
  • Horde_Core_Block_Layout_Manager
  • Horde_Core_Block_Layout_View
  • Horde_Core_Block_Upgrade
  • Horde_Core_Browser
  • Horde_Core_Bundle
  • Horde_Core_Cli
  • Horde_Core_Controller_NotFound
  • Horde_Core_Controller_RequestConfiguration
  • Horde_Core_Controller_RequestMapper
  • Horde_Core_Controller_SettingsFinder
  • Horde_Core_Db_Migration
  • Horde_Core_Factory_ActiveSyncBackend
  • Horde_Core_Factory_ActiveSyncServer
  • Horde_Core_Factory_ActiveSyncState
  • Horde_Core_Factory_Ajax
  • Horde_Core_Factory_Alarm
  • Horde_Core_Factory_Auth
  • Horde_Core_Factory_AuthSignup
  • Horde_Core_Factory_Base
  • Horde_Core_Factory_BlockCollection
  • Horde_Core_Factory_Browser
  • Horde_Core_Factory_Cache
  • Horde_Core_Factory_Crypt
  • Horde_Core_Factory_Data
  • Horde_Core_Factory_Db
  • Horde_Core_Factory_DbBase
  • Horde_Core_Factory_DbPear
  • Horde_Core_Factory_Dns
  • Horde_Core_Factory_Editor
  • Horde_Core_Factory_Facebook
  • Horde_Core_Factory_Group
  • Horde_Core_Factory_History
  • Horde_Core_Factory_HttpClient
  • Horde_Core_Factory_Identity
  • Horde_Core_Factory_Image
  • Horde_Core_Factory_Imple
  • Horde_Core_Factory_Imsp
  • Horde_Core_Factory_ImspAuth
  • Horde_Core_Factory_Injector
  • Horde_Core_Factory_KolabServer
  • Horde_Core_Factory_KolabSession
  • Horde_Core_Factory_KolabStorage
  • Horde_Core_Factory_Ldap
  • Horde_Core_Factory_Lock
  • Horde_Core_Factory_Logger
  • Horde_Core_Factory_LoginTasks
  • Horde_Core_Factory_Mail
  • Horde_Core_Factory_Mapper
  • Horde_Core_Factory_Matcher
  • Horde_Core_Factory_Memcache
  • Horde_Core_Factory_MimeViewer
  • Horde_Core_Factory_Notification
  • Horde_Core_Factory_Perms
  • Horde_Core_Factory_PermsCore
  • Horde_Core_Factory_Prefs
  • Horde_Core_Factory_Request
  • Horde_Core_Factory_Secret
  • Horde_Core_Factory_SessionHandler
  • Horde_Core_Factory_Share
  • Horde_Core_Factory_ShareBase
  • Horde_Core_Factory_Template
  • Horde_Core_Factory_TextFilter
  • Horde_Core_Factory_ThemesCache
  • Horde_Core_Factory_Token
  • Horde_Core_Factory_Tree
  • Horde_Core_Factory_Twitter
  • Horde_Core_Factory_UrlShortener
  • Horde_Core_Factory_Vfs
  • Horde_Core_Factory_View
  • Horde_Core_Factory_Weather
  • Horde_Core_Group_Ldap
  • Horde_Core_Log_Logger
  • Horde_Core_LoginTasks
  • Horde_Core_LoginTasks_Backend_Horde
  • Horde_Core_LoginTasks_SystemTask_Upgrade
  • Horde_Core_Mime_Viewer_Syntaxhighlighter
  • Horde_Core_Mime_Viewer_Vcard
  • Horde_Core_Notification_Event_Status
  • Horde_Core_Notification_Handler_Decorator_Hordelog
  • Horde_Core_Notification_Storage_Session
  • Horde_Core_Perms
  • Horde_Core_Perms_Ui
  • Horde_Core_Prefs_Cache_Session
  • Horde_Core_Prefs_Identity
  • Horde_Core_Prefs_Storage_Configuration
  • Horde_Core_Prefs_Storage_Hooks
  • Horde_Core_Prefs_Storage_Upgrade
  • Horde_Core_Prefs_Ui
  • Horde_Core_Prefs_Ui_Widgets
  • Horde_Core_Share_Driver
  • Horde_Core_Share_FactoryCallback
  • Horde_Core_Sidebar
  • Horde_Core_Text_Filter_Bbcode
  • Horde_Core_Text_Filter_Emails
  • Horde_Core_Text_Filter_Emoticons
  • Horde_Core_Text_Filter_Highlightquotes
  • Horde_Core_Translation
  • Horde_Core_Tree_Html
  • Horde_Core_Tree_Javascript
  • Horde_Core_Tree_Simplehtml
  • Horde_Core_Ui_FlagImage
  • Horde_Core_Ui_JsCalendar
  • Horde_Core_Ui_Language
  • Horde_Core_Ui_Layout
  • Horde_Core_Ui_ModalFormRenderer
  • Horde_Core_Ui_Pager
  • Horde_Core_Ui_Tabs
  • Horde_Core_Ui_TagCloud
  • Horde_Core_Ui_VarRenderer
  • Horde_Core_Ui_VarRenderer_Html
  • Horde_Core_Ui_VarRenderer_TablesetHtml
  • Horde_Core_Ui_Widget
  • Horde_ErrorHandler
  • Horde_Help
  • Horde_Menu
  • Horde_Registry
  • Horde_Registry_Api
  • Horde_Registry_Application
  • Horde_Registry_Caller
  • Horde_Registry_Nlsconfig
  • Horde_Script_Files
  • Horde_Session
  • Horde_Session_Null
  • Horde_Themes
  • Horde_Themes_Cache
  • Horde_Themes_Css
  • Horde_Themes_Element
  • Horde_Themes_Image
  • Horde_Themes_Sound

Exceptions

  • Horde_Exception_HookNotSet
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The Horde_Menu:: class provides standardized methods for creating menus in
  4:  * Horde applications.
  5:  *
  6:  * Copyright 1999-2012 Horde LLC (http://www.horde.org/)
  7:  *
  8:  * See the enclosed file COPYING for license information (LGPL). If you
  9:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 10:  *
 11:  * @author   Chuck Hagenbuch <chuck@horde.org>
 12:  * @author   Jon Parise <jon@horde.org>
 13:  * @category Horde
 14:  * @package  Core
 15:  */
 16: class Horde_Menu
 17: {
 18:     /**
 19:      * Don't show any menu items.
 20:      */
 21:     const MASK_NONE = 0;
 22: 
 23:     /**
 24:      * Show help menu item.
 25:      */
 26:     const MASK_HELP = 1;
 27: 
 28:     /**
 29:      * Show login/logout menu item.
 30:      */
 31:     const MASK_LOGIN = 2;
 32: 
 33:     /**
 34:      * Show preferences menu item.
 35:      */
 36:     const MASK_PREFS = 4;
 37: 
 38:     /**
 39:      * Show problem reporting menu item.
 40:      */
 41:     const MASK_PROBLEM = 8;
 42: 
 43:     /**
 44:      * Only show application specific menu items.
 45:      */
 46:     const MASK_BASE = 16;
 47: 
 48:     /**
 49:      * Show all menu items.
 50:      */
 51:     const MASK_ALL = 31;
 52: 
 53:     /* TODO */
 54:     const POS_LAST = 999;
 55: 
 56:     /**
 57:      * Mask defining what menu items to show.
 58:      *
 59:      * @var integer
 60:      */
 61:     protected $_mask;
 62: 
 63:     /**
 64:      * Menu array.
 65:      *
 66:      * @var array
 67:      */
 68:     protected $_menu = array();
 69: 
 70:     /**
 71:      * Constructor.
 72:      *
 73:      * @param integer $mask  Display mask.
 74:      */
 75:     public function __construct($mask = self::MASK_ALL)
 76:     {
 77:         $this->setMask($mask);
 78:     }
 79: 
 80:     /**
 81:      * Sets the display mask.
 82:      *
 83:      * @since Horde_Core 1.3.0
 84:      *
 85:      * @param integer $mask  Display mask.
 86:      */
 87:     public function setMask($mask)
 88:     {
 89:         $this->_mask = $mask;
 90:     }
 91: 
 92:     /**
 93:      * Add an item to the menu array.
 94:      *
 95:      * @param string $url        String containing the value for the hyperlink.
 96:      * @param string $text       String containing the label for this menu
 97:      *                           item.
 98:      * @param string $icon       String containing the filename of the image
 99:      *                           icon to display for this menu item.
100:      * @param string $icon_path  If the icon lives in a non-default directory,
101:      *                           where is it?
102:      * @param string $target     If the link needs to open in another frame or
103:      *                           window, what is its name?
104:      * @param string $onclick    Onclick javascript, if desired.
105:      * @param string $class      CSS class for the menu item.
106:      *
107:      * @return integer  The id (NOT guaranteed to be an array index) of the
108:      *                  item just added to the menu.
109:      */
110:     public function add($url, $text, $icon = '', $icon_path = null,
111:                         $target = '', $onclick = null, $class = null)
112:     {
113:         $pos = count($this->_menu);
114:         if (!$pos || ($pos - 1 != max(array_keys($this->_menu)))) {
115:             $pos = count($this->_menu);
116:         }
117: 
118:         $this->_menu[$pos] = array(
119:             'url' => ($url instanceof Horde_Url) ? $url : new Horde_Url($url),
120:             'text' => $text,
121:             'icon' => $icon,
122:             'icon_path' => $icon_path,
123:             'target' => $target,
124:             'onclick' => $onclick,
125:             'class' => $class
126:         );
127: 
128:         return $pos;
129:     }
130: 
131:     /**
132:      * Add an item to the menu array.
133:      *
134:      * @param array $item  The item to add.  Valid keys:
135:      * <pre>
136:      * 'class' - (string) CSS classname.
137:      * 'icon' - (string) Filename of the image icon.
138:      * 'icon_path' - (string) Non-default directory path for icon.
139:      * 'onclick' - (string) Onclick javascript.
140:      * 'target' - (string) HREF target parameter.
141:      * 'text' - (string) Label.
142:      * 'url' - (string) Hyperlink.
143:      * </pre>
144:      *
145:      * @return integer  The id (NOT guaranteed to be an array index) of the
146:      *                  item just added to the menu.
147:      */
148:     public function addArray($item)
149:     {
150:         $pos = count($this->_menu);
151:         if (!$pos || ($pos - 1 != max(array_keys($this->_menu)))) {
152:             $pos = count($this->_menu);
153:         }
154: 
155:         if (!isset($item['url'])) {
156:             $item['url'] = new Horde_Url();
157:         } elseif (!($item['url'] instanceof Horde_Url)) {
158:             $item['url'] = new Horde_Url($item['url']);
159:         }
160: 
161:         $this->_menu[$pos] = array_merge(array(
162:             'class' => '',
163:             'icon' => '',
164:             'icon_path' => null,
165:             'onclick' => null,
166:             'target' => '',
167:             'text' => ''
168:         ), $item);
169: 
170:         return $pos;
171:     }
172: 
173:     /**
174:      * TODO
175:      */
176:     public function setPosition($id, $pos)
177:     {
178:         if (!isset($this->_menu[$id]) || isset($this->_menu[$pos])) {
179:             return false;
180:         }
181: 
182:         $item = $this->_menu[$id];
183:         unset($this->_menu[$id]);
184:         $this->_menu[$pos] = $item;
185: 
186:         return true;
187:     }
188: 
189:     /**
190:      * Return the rendered representation of the menu items.
191:      *
192:      * @return string  The rendered representation.
193:      */
194:     public function render()
195:     {
196:         global $conf, $registry, $prefs;
197: 
198:         $app = $registry->getApp();
199: 
200:         if ($this->_mask !== self::MASK_NONE) {
201:             /* Add any custom menu items. */
202:             $this->addSiteLinks();
203: 
204:             /* Add any app menu items. */
205:             $this->addAppLinks();
206:         }
207: 
208:         /* Add preferences link. */
209:         if (($this->_mask & self::MASK_PREFS) &&
210:             $this->showService('prefs') &&
211:             ($url = Horde::getServiceLink('prefs', $app))) {
212:             $this->add($url, Horde_Core_Translation::t("_Preferences"), 'prefs.png');
213:         }
214: 
215:         /* Add problem link. */
216:         if (($this->_mask & self::MASK_PROBLEM) &&
217:             $this->showService('problem') &&
218:             ($problem_link = Horde::getServiceLink('problem', $app))) {
219:             $this->add($problem_link, Horde_Core_Translation::t("Problem"), 'problem.png');
220:         }
221: 
222:         /* Add help link. */
223:         if (($this->_mask & self::MASK_HELP) &&
224:             $this->showService('help') &&
225:             ($help_link = Horde::getServiceLink('help', $app))) {
226:             Horde::
227:             $this->add($help_link, Horde_Core_Translation::t("Help"), 'help_index.png', null, 'help', Horde::popupJs($help_link, array('urlencode' => true)) . 'return false;', 'helplink');
228:         }
229: 
230:         /* Login/Logout. */
231:         if ($this->_mask & self::MASK_LOGIN) {
232:             /* If the sidebar isn't always shown, but is sometimes
233:              * shown, then logout links should be to the parent
234:              * frame. */
235:             $auth_target = null;
236:             if ($conf['menu']['always'] || $prefs->getValue('show_sidebar')) {
237:                 $auth_target = '_parent';
238:             }
239: 
240:             if ($registry->getAuth()) {
241:                 if ((!$prefs->getValue('show_sidebar') || $this->showService('logout')) &&
242:                     ($logout_link = Horde::getServiceLink('logout', $app))) {
243:                     $this->add($logout_link, Horde_Core_Translation::t("_Log out"), 'logout.png', null, $auth_target, null, '__noselection');
244:                 }
245:             } else {
246:                 if ($this->showService('login') &&
247:                     ($login_link = Horde::getServiceLink('login', $app))) {
248:                     $this->add($login_link->add('url', Horde::selfUrl(true, true, true)), Horde_Core_Translation::t("_Log in"), 'login.png', null, $auth_target, null, '__noselection');
249:                 }
250:             }
251:         }
252: 
253:         /* No need to return an empty list if there are no menu
254:          * items. */
255:         if (!count($this->_menu)) {
256:             return '';
257:         }
258: 
259:         /* Sort to match explicitly set positions. */
260:         ksort($this->_menu);
261:         if ($registry->nlsconfig->curr_rtl) {
262:             $this->_menu = array_reverse($this->_menu);
263:         }
264: 
265:         return $this->_render();
266:     }
267: 
268:     /**
269:      * Unordered list representing the list of menu items. Styling is done
270:      * through CSS.
271:      *
272:      * @return string  An unordered list of menu elements that can be entirely
273:      *                 styled with CSS.
274:      */
275:     protected function _render()
276:     {
277:         $menu_view = $GLOBALS['prefs']->getValue('menu_view');
278:         $output = '<ul>';
279: 
280:         foreach ($this->_menu as $m) {
281:             /* Check for separators. */
282:             if ($m == 'separator') {
283:                 $output .= "\n<li class=\"separator\">&nbsp;</li>";
284:                 continue;
285:             }
286: 
287:             /* Item class and selected indication. */
288:             if (!isset($m['class'])) {
289:                 /* Try to match the item's path against the current
290:                  * script filename as well as other possible URLs to
291:                  * this script. */
292:                 if ($this->isSelected($m['url'])) {
293:                     $m['class'] = 'current';
294:                 }
295:             } elseif ($m['class'] === '__noselection') {
296:                 unset($m['class']);
297:             }
298: 
299:             /* Icon. */
300:             $icon = '';
301:             if ($menu_view == 'icon' || $menu_view == 'both') {
302:                 if (empty($m['icon_path'])) {
303:                     $m['icon_path'] = null;
304:                 }
305:                 $icon = Horde::img($m['icon'], Horde::stripAccessKey($m['text']), '', $m['icon_path']) . '<br />';
306:             }
307: 
308:             /* Link. */
309:             $accesskey = Horde::getAccessKey($m['text']);
310:             $link = $m['url']->setRaw(false)->link(
311:                 array('title' => $menu_view == 'icon' ? Horde::stripAccessKey($m['text']) : '',
312:                       'class' => isset($m['class']) ? $m['class'] : '',
313:                       'target' => $m['target'],
314:                       'onclick' => $m['onclick'],
315:                       'accesskey' => $accesskey));
316: 
317:             $output .= sprintf("\n<li>%s%s%s</a></li>",
318:                                $link, $icon, ($menu_view != 'icon') ? Horde::highlightAccessKey($m['text'], $accesskey) : '');
319:         }
320: 
321:         return $output . '</ul>';
322:     }
323: 
324:     /**
325:      * Add links to other Horde applications defined in an application's
326:      * config file.
327:      */
328:     public function addAppLinks()
329:     {
330:         global $registry;
331: 
332:         foreach ($this->getAppLinks() as $app) {
333:             try {
334:                 $this->add(Horde::url($registry->getInitialPage($app)), $registry->get('name', $app), $registry->get('icon', $app), '');
335:             } catch (Horde_Exception $e) {}
336:         }
337:     }
338: 
339:     /**
340:      * List any links to other Horde applications defined in an application's
341:      * config file.
342:      *
343:      * @return array  A list of applications to create menu items for.
344:      */
345:     public function getAppLinks()
346:     {
347:         global $conf, $registry;
348: 
349:         $out = array();
350: 
351:         if (isset($conf['menu']['apps']) && is_array($conf['menu']['apps'])) {
352:             foreach ($conf['menu']['apps'] as $app) {
353:                 if (!$registry->isInactive($app) &&
354:                     $registry->hasPermission($app, Horde_Perms::SHOW)) {
355:                     $out[] = $app;
356:                 }
357:             }
358:         }
359: 
360:         return $out;
361:     }
362: 
363:     /**
364:      * Add links found in the application's menu configuration.
365:      */
366:     public function addSiteLinks()
367:     {
368:         foreach ($this->getSiteLinks() as $item) {
369:             $this->addArray($item);
370:         }
371:     }
372: 
373:     /**
374:      * Get the list of site links to add to the menu.
375:      *
376:      * @return array  A list of menu items to add.
377:      */
378:     public function getSiteLinks()
379:     {
380:         $menufile = $GLOBALS['registry']->get('fileroot') . '/config/menu.php';
381: 
382:         if (is_readable($menufile)) {
383:             include $menufile;
384:             if (isset($_menu) && is_array($_menu)) {
385:                 return $_menu;
386:             }
387:         }
388: 
389:         return array();
390:     }
391: 
392:     /**
393:      * Checks to see if the current url matches the given url.
394:      *
395:      * @return boolean  Whether the given URL is the current location.
396:      */
397:     static public function isSelected($url)
398:     {
399:         $server_url = parse_url($_SERVER['PHP_SELF']);
400:         $check_url = parse_url($url);
401: 
402:         /* Try to match the item's path against the current script
403:            filename as well as other possible URLs to this script. */
404:         return isset($check_url['path']) &&
405:             (($check_url['path'] == $server_url['path']) ||
406:              ($check_url['path'] . 'index.php' == $server_url['path']) ||
407:              ($check_url['path'] . '/index.php' == $server_url['path']));
408:     }
409: 
410:     /**
411:      * TODO
412:      *
413:      * @param string $type       The type of link.
414:      * <pre>
415:      * The following must be defined in Horde's menu config, or else they
416:      * won't be displayed in the menu:
417:      * 'help', 'problem', 'logout', 'login', 'prefs'
418:      * </pre>
419:      *
420:      * @return boolean  True if the link is to be shown.
421:      */
422:     static public function showService($type)
423:     {
424:         global $conf;
425: 
426:         if (!in_array($type, array('help', 'problem', 'logout', 'login', 'prefs'))) {
427:             return true;
428:         }
429: 
430:         if (empty($conf['menu']['links'][$type])) {
431:             return false;
432:         }
433: 
434:         switch ($conf['menu']['links'][$type]) {
435:         case 'all':
436:             return true;
437: 
438:         case 'authenticated':
439:             return (bool)$GLOBALS['registry']->getAuth();
440: 
441:         default:
442:         case 'never':
443:             return false;
444:         }
445:     }
446: 
447: }
448: 
API documentation generated by ApiGen