File: Menu.php

package info (click to toggle)
horde3 3.1.3-4etch7
  • links: PTS
  • area: main
  • in suites: etch
  • size: 22,876 kB
  • ctags: 18,071
  • sloc: php: 75,151; xml: 2,979; sql: 1,069; makefile: 79; sh: 64
file content (308 lines) | stat: -rw-r--r-- 10,673 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
<?php

define('HORDE_MENU_POS_LAST', 999);

define('HORDE_MENU_MASK_NONE',     0);
define('HORDE_MENU_MASK_HELP',     1);
define('HORDE_MENU_MASK_LOGIN',    2);
define('HORDE_MENU_MASK_PREFS',    4);
define('HORDE_MENU_MASK_PROBLEM',  8);
define('HORDE_MENU_MASK_ALL',     15);

/**
 * The Menu:: class provides standardized methods for creating menus in
 * Horde applications.
 *
 * $Horde: framework/Horde/Horde/Menu.php,v 1.35.2.11 2006/07/20 04:31:27 slusarz Exp $
 *
 * Copyright 1999-2006 Chuck Hagenbuch <chuck@horde.org>
 * Copyright 1999-2006 Jon Parise <jon@horde.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Chuck Hagenbuch <chuck@horde.org>
 * @author  Jon Parise <jon@horde.org>
 * @since   Horde 1.3
 * @package Horde_Framework
 */
class Menu {

    /**
     * Menu array.
     *
     * @var array
     */
    var $_menu = array();

    /**
     * Mask defining what general Horde links are shown in this Menu.
     *
     * @var integer
     */
    var $_mask;

    /**
     * Constructor
     */
    function Menu($mask = HORDE_MENU_MASK_ALL)
    {
        /* Menuitem mask. */
        $this->_mask = $mask;

        /* Location of the menufile. */
        $this->_menufile = $GLOBALS['registry']->get('fileroot') . '/config/menu.php';
    }

    /**
     * Add an item to the menu array.
     *
     * @param string $url        String containing the value for the hyperlink.
     * @param string $text       String containing the label for this menu
     *                           item.
     * @param string $icon       String containing the filename of the image
     *                           icon to display for this menu item.
     * @param string $icon_path  If the icon lives in a non-default directory,
     *                           where is it?
     * @param string $target     If the link needs to open in another frame or
     *                           window, what is its name?
     * @param string $onclick    Onclick javascript, if desired.
     * @param string $class      CSS class for the menu item.
     *
     * @return integer  The id (NOT guaranteed to be an array index) of the
     *                  item just added to the menu.
     */
    function add($url, $text, $icon = '', $icon_path = null,
                 $target = '', $onclick = null, $class = null)
    {
        $pos = count($this->_menu);
        if (!$pos || ($pos - 1 != max(array_keys($this->_menu)))) {
            $pos = count($this->_menu);
        }

        $this->_menu[$pos] =
            array(
                'url' => $url,
                'text' => $text,
                'icon' => $icon,
                'icon_path' => $icon_path,
                'target' => $target,
                'onclick' => $onclick,
                'class' => $class
            );

        return $pos;
    }

    /**
     * Add an item to the menu array.
     *
     * @param string $url        String containing the value for the hyperlink.
     * @param string $text       String containing the label for this menu
     *                           item.
     * @param string $icon       String containing the filename of the image
     *                           icon to display for this menu item.
     * @param string $icon_path  If the icon lives in a non-default directory,
     *                           where is it?
     * @param string $target     If the link needs to open in another frame or
     *                           window, what is its name?
     * @param string $onclick    Onclick javascript, if desired.
     * @param string $class      CSS class for the menu item.
     *
     * @return integer  The id (NOT guaranteed to be an array index) of the item
     *                  just added to the menu.
     */
    function addArray($item)
    {
        $pos = count($this->_menu);
        if (!$pos || ($pos - 1 != max(array_keys($this->_menu)))) {
            $pos = count($this->_menu);
        }

        $this->_menu[$pos] = $item;

        return $pos;
    }

    function setPosition($id, $pos)
    {
        if (!isset($this->_menu[$id]) || isset($this->_menu[$pos])) {
            return false;
        }

        $item = $this->_menu[$id];
        unset($this->_menu[$id]);
        $this->_menu[$pos] = $item;

        return true;
    }

    /**
     * Return the unordered list representing the list of menu items. Styling
     * is done through CSS.
     *
     * @return string  An unordered list of menu elements that can be entirely
     *                 styled with CSS.
     */
    function render()
    {
        global $conf, $registry, $prefs;

        $graphics = $registry->getImageDir('horde');
        $app = $registry->getApp();

        if ($this->_mask !== HORDE_MENU_MASK_NONE) {
            /* Add any custom menu items. */
            $this->addSiteLinks();

            /* Add any app menu items. */
            $this->addAppLinks();
        }

        /* Add settings link. */
        if ($this->_mask & HORDE_MENU_MASK_PREFS && $url = Horde::getServiceLink('options', $app)) {
            $this->add($url, _("_Options"), 'prefs.png', $graphics);
        }

        /* Add problem link. */
        if ($this->_mask & HORDE_MENU_MASK_PROBLEM && $problem_link = Horde::getServiceLink('problem', $app)) {
            $this->add($problem_link, _("Problem"), 'problem.png', $graphics);
        }

        /* Add help link. */
        require_once 'Horde/Help.php';
        if ($this->_mask & HORDE_MENU_MASK_HELP && $help_link = Horde::getServiceLink('help', $app)) {
            $this->add($help_link, _("Help"), 'help_index.png', $graphics, 'help', 'popup(this.href); return false;');
        }

        /* Login/Logout. */
        if ($this->_mask & HORDE_MENU_MASK_LOGIN) {
            /* If the sidebar isn't always shown, but is sometimes
             * shown, then logout links should be to the parent
             * frame. */
            $auth_target = null;
            if ($conf['menu']['always'] || $prefs->getValue('show_sidebar')) {
                $auth_target = '_parent';
            }

            if (Auth::getAuth()) {
                if ($logout_link = Horde::getServiceLink('logout', $app, !$prefs->getValue('show_sidebar'))) {
                    $this->add($logout_link, _("_Log out"), 'logout.png', $graphics, $auth_target, null, '__noselection');
                }
            } else {
                if ($login_link = Horde::getServiceLink('login', $app)) {
                    $this->add($login_link, _("_Log in"), 'login.png', $graphics, $auth_target, null, '__noselection');
                }
            }
        }

        /* No need to return an empty list if there are no menu
         * items. */
        if (!count($this->_menu)) {
            return '';
        }

        /* Sort to match explicitly set positions. */
        ksort($this->_menu);
        if (!empty($GLOBALS['nls']['rtl'][$GLOBALS['language']]))  {
            $this->_menu = array_reverse($this->_menu) ;
        }

        $menu_view = $prefs->getValue('menu_view');
        $output = '<ul>';
        foreach ($this->_menu as $m) {
            /* Item class and selected indication. */
            if (!isset($m['class'])) {
                /* Try to match the item's path against the current
                 * script filename as well as other possible URLs to
                 * this script. */
                if (Menu::isSelected($m['url'])) {
                    $m['class'] = 'current';
                }
            } elseif ($m['class'] === '__noselection') {
                unset($m['class']);
            }

            /* Icon. */
            $icon = '';
            if ($menu_view == 'icon' || $menu_view == 'both') {
                if (!isset($m['icon_path'])) {
                    $m['icon_path'] = null;
                }
                $icon = Horde::img($m['icon'], Horde::stripAccessKey($m['text']), '', $m['icon_path']);
            }

            /* Link. */
            $accesskey = Horde::getAccessKey($m['text']);
            $link = Horde::link($m['url'], $menu_view == 'icon' ? $m['text'] : '',
                                isset($m['class']) ? $m['class'] : '',
                                isset($m['target']) ? $m['target'] : '',
                                isset($m['onclick']) ? $m['onclick'] : '',
                                '', $accesskey);

            $output .= sprintf("\n<li>%s%s<br />%s</a></li>",
                               $link, $icon, ($menu_view != 'icon') ? Horde::highlightAccessKey($m['text'], $accesskey) : '');
        }

        return $output . '</ul>';
    }

    /**
     * Any links to other Horde applications defined in an application's config
     * file by the $conf['menu']['apps'] array are added to the menu array.
     */
    function addAppLinks()
    {
        global $conf, $registry;

        if (isset($conf['menu']['apps']) && is_array($conf['menu']['apps'])) {
            foreach ($conf['menu']['apps'] as $app) {
                if ($registry->get('status', $app) != 'inactive' && $registry->hasPermission($app, PERMS_SHOW)) {
                    $url = $registry->getInitialPage($app);
                    if (!is_a($url, 'PEAR_Error')) {
                        $this->add(Horde::url($url), $registry->get('name', $app), $registry->get('icon', $app), '');
                    }
                }
            }
        }
    }

    /**
     * Add any other links found in $this->_menufile to be included in the
     * menu.
     */
    function addSiteLinks()
    {
        if (@is_readable($this->_menufile)) {
            include $this->_menufile;
            if (isset($_menu) && is_array($_menu)) {
                foreach ($_menu as $menuitem) {
                    $this->addArray($menuitem);
                }
            }
        }
    }

    /**
     * Checks to see if the current url matches the given url.
     *
     * @return boolean  Whether the given URL is the current location.
     */
    function isSelected($url)
    {
        $server_url = parse_url($_SERVER['PHP_SELF']);
        $check_url = parse_url($url);

        /* Try to match the item's path against the current script
           filename as well as other possible URLs to this script. */
        if (isset($check_url['path']) &&
            (($check_url['path'] == $server_url['path']) ||
             ($check_url['path'] . 'index.php' == $server_url['path']) ||
             ($check_url['path'] . '/index.php' == $server_url['path']))) {
            return true;
        }

        return false;
    }

}