~fusonic/chive/1.1

« back to all changes in this revision

Viewing changes to yii/zii/widgets/CMenu.php

  • Committer: Matthias Burtscher
  • Date: 2010-02-12 09:12:35 UTC
  • Revision ID: matthias.burtscher@fusonic.net-20100212091235-jqxrb62klx872ajc
* Updated Yii to 1.1.0
* Removed CodePress and CodeMirror
* Updated jQuery and some plugins
* Cleaned some code ...

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * CMenu class file.
 
4
 *
 
5
 * @author Jonah Turnquist <poppitypop@gmail.com>
 
6
 * @author Qiang Xue <qiang.xue@gmail.com>
 
7
 * @link http://www.yiiframework.com/
 
8
 * @copyright Copyright &copy; 2008-2010 Yii Software LLC
 
9
 * @license http://www.yiiframework.com/license/
 
10
 */
 
11
 
 
12
/**
 
13
 * CMenu displays a multi-level menu using nested HTML lists.
 
14
 *
 
15
 * The main property of CMenu is {@link items}, which specifies the possible items in the menu.
 
16
 * A menu item has three main properties: visible, active and items. The "visible" property
 
17
 * specifies whether the menu item is currently visible. The "active" property specifies whether
 
18
 * the menu item is currently selected. And the "items" property specifies the child menu items.
 
19
 *
 
20
 * The following example shows how to use CMenu:
 
21
 * <pre>
 
22
 * $this->widget('zii.widgets.CMenu', array(
 
23
 *     'items'=>array(
 
24
 *         array('label'=>'Home', 'url'=>array('site/index')),
 
25
 *         array('label'=>'Products', 'url'=>array('product/index'), 'items=>array(
 
26
 *             array('label'=>'New Arrivals', 'url'=>array('product/new', 'tag'=>'new')),
 
27
 *             array('label'=>'Most Popular', 'url'=>array('product/index', 'tag'=>'popular')),
 
28
 *         )),
 
29
 *         array('label'=>'Login', 'url'=>array('site/login'), 'visible'=>Yii::app()->user->isGuest),
 
30
 *     ),
 
31
 * ));
 
32
 * </pre>
 
33
 *
 
34
 * @author Jonah Turnquist <poppitypop@gmail.com>
 
35
 * @author Qiang Xue <qiang.xue@gmail.com>
 
36
 * @version $Id: CMenu.php 102 2010-01-09 20:38:42Z qiang.xue $
 
37
 * @package zii.widgets
 
38
 * @since 1.1
 
39
 */
 
40
class CMenu extends CWidget
 
41
{
 
42
        /**
 
43
         * @var array list of menu items. Each menu item is specified as an array of name-value pairs.
 
44
         * Possible option names include the following:
 
45
         * <ul>
 
46
         * <li>label: string, optional, specifies the menu item label. When {@link encodeLabel} is true, the label
 
47
         * will be HTML-encoded.</li>
 
48
         * <li>url: string or array, optional, specifies the URL of the menu item. It is passed to {@link CHtml::normalizeUrl}
 
49
         * to generate a valid URL. If this is not set, the menu item will be rendered as a span text.</li>
 
50
         * <li>visible: boolean, optional, whether this menu item is visible. Defaults to true.
 
51
         * This can be used to control the visibility of menu items based on user permissions.</li>
 
52
         * <li>items: array, optional, specifies the sub-menu items. Its format is the same as the parent items.</li>
 
53
         * <li>active: boolean, optional, whether this menu item is in active state (currently selected).
 
54
         * If a menu item is active and {@link activeClass} is not empty, its CSS class will be appended with {@link activeClass}.
 
55
         * If this option is not set, the menu item will be set active automatically when the current request
 
56
         * is triggered by {@link url}.</li>
 
57
         * <li>linkOptions: array, optional, additional HTML attributes to be rendered for the link or span tag of the menu item.</li>
 
58
         * <li>itemOptions: array, optional, additional HTML attributes to be rendered for the container tag of the menu item.</li>
 
59
         * </ul>
 
60
         */
 
61
        public $items=array();
 
62
        /**
 
63
         * @var boolean whether the labels for menu items should be HTML-encoded. Defaults to true.
 
64
         */
 
65
        public $encodeLabel=true;
 
66
        /**
 
67
         * @var string the CSS class to be appended to the active menu item. Defaults to 'active'.
 
68
         * If empty, the CSS class of menu items will not be changed.
 
69
         */
 
70
        public $activeCssClass='active';
 
71
        /**
 
72
         * @var boolean whether to activate parent menu items when one of the corresponding child menu items is active.
 
73
         * The activated parent menu items will also have its CSS classes appended with {@link activeCssClass}.
 
74
         * Defaults to false.
 
75
         */
 
76
        public $activateParents=false;
 
77
        /**
 
78
         * @var boolean whether to hide empty menu items. An empty menu item is one whose 'url' option is not
 
79
         * set and which doesn't contain visible child menu items. Defaults to true.
 
80
         */
 
81
        public $hideEmptyItems=true;
 
82
        /**
 
83
         * @var array HTML attributes for the menu's root container tag
 
84
         */
 
85
        public $htmlOptions=array();
 
86
        /**
 
87
         * @var array HTML attributes for the submenu's container tag.
 
88
         */
 
89
        public $submenuHtmlOptions=array();
 
90
 
 
91
        /**
 
92
         * Initializes the menu widget.
 
93
         * This method mainly normalizes the {@link items} property.
 
94
         * If this method is overridden, make sure the parent implementation is invoked.
 
95
         */
 
96
        public function init()
 
97
        {
 
98
                $this->htmlOptions['id']=$this->getId();
 
99
                $route=$this->getController()->getRoute();
 
100
                $this->items=$this->normalizeItems($this->items,$route,$hasActiveChild);
 
101
        }
 
102
 
 
103
        /**
 
104
         * Calls {@link renderMenu} to render the menu.
 
105
         */
 
106
        public function run()
 
107
        {
 
108
                $this->renderMenu($this->items);
 
109
        }
 
110
 
 
111
        /**
 
112
         * Renders the menu items.
 
113
         * @param array menu items. Each menu item will be an array with at least two elements: 'label' and 'active'.
 
114
         * It may have three other optional elements: 'items', 'linkOptions' and 'itemOptions'.
 
115
         */
 
116
        protected function renderMenu($items)
 
117
        {
 
118
                if(count($items))
 
119
                {
 
120
                        echo CHtml::openTag('ul',$this->htmlOptions)."\n";
 
121
                        $this->renderMenuRecursive($items);
 
122
                        echo CHtml::closeTag('ul');
 
123
                }
 
124
        }
 
125
 
 
126
        /**
 
127
         * Recursively renders the menu items.
 
128
         * @param array the menu items to be rendered recursively
 
129
         */
 
130
        protected function renderMenuRecursive($items)
 
131
        {
 
132
                foreach($items as $item)
 
133
                {
 
134
                        echo CHtml::openTag('li', isset($item['itemOptions']) ? $item['itemOptions'] : array());
 
135
                        if(isset($item['url']))
 
136
                                echo CHtml::link($item['label'],$item['url'],isset($item['linkOptions']) ? $item['linkOptions'] : array());
 
137
                        else
 
138
                                echo CHtml::tag('span',isset($item['linkOptions']) ? $item['linkOptions'] : array(), $item['label']);
 
139
                        if(isset($item['items']) && count($item['items']))
 
140
                        {
 
141
                                echo "\n".CHtml::openTag('ul',$this->submenuHtmlOptions)."\n";
 
142
                                $this->renderMenuRecursive($item['items']);
 
143
                                echo CHtml::closeTag('ul')."\n";
 
144
                        }
 
145
                        echo CHtml::closeTag('li')."\n";
 
146
                }
 
147
        }
 
148
 
 
149
        /**
 
150
         * Normalizes the {@link items} property so that the 'active' state is properly identified for every menu item.
 
151
         * @param array the items to be normalized.
 
152
         * @param string the route of the current request.
 
153
         * @param boolean whether there is an active child menu item.
 
154
         * @return array the normalized menu items
 
155
         */
 
156
        protected function normalizeItems($items,$route,&$active)
 
157
        {
 
158
                foreach($items as $i=>$item)
 
159
                {
 
160
                        if(isset($item['visible']) && !$item['visible'])
 
161
                        {
 
162
                                unset($items[$i]);
 
163
                                continue;
 
164
                        }
 
165
                        if($this->encodeLabel)
 
166
                                $items[$i]['label']=CHtml::encode($item['label']);
 
167
                        $hasActiveChild=false;
 
168
                        if(isset($item['items']))
 
169
                        {
 
170
                                $items[$i]['items']=$this->normalizeItems($item['items'],$route,$hasActiveChild);
 
171
                                if(empty($items[$i]['items']) && $this->hideEmptyItems)
 
172
                                        unset($items[$i]['items']);
 
173
                        }
 
174
                        if(!isset($item['active']))
 
175
                        {
 
176
                                if($this->activateParents && $hasActiveChild || $this->isItemActive($item,$route))
 
177
                                        $active=$items[$i]['active']=true;
 
178
                                else
 
179
                                        $items[$i]['active']=false;
 
180
                        }
 
181
                        else if($item['active'])
 
182
                                $active=true;
 
183
                        if($items[$i]['active'] && $this->activeCssClass!='')
 
184
                        {
 
185
                                if(isset($item['linkOptions']['class']))
 
186
                                        $items[$i]['linkOptions']['class'].=' '.$this->activeCssClass;
 
187
                                else
 
188
                                        $items[$i]['linkOptions']['class']=$this->activeCssClass;
 
189
                        }
 
190
                }
 
191
                return array_values($items);
 
192
        }
 
193
 
 
194
        /**
 
195
         * Checks whether a menu item is active.
 
196
         * This is done by checking if the currently requested URL is generated by the 'url' option
 
197
         * of the menu item.
 
198
         * @param array the menu item to be checked
 
199
         * @param string the route of the current request
 
200
         * @return boolean whether the menu item is active
 
201
         */
 
202
        protected function isItemActive($item,$route)
 
203
        {
 
204
                if(isset($item['url']) && is_array($item['url']) && !strcasecmp(trim($item['url'][0],'/'),$route))
 
205
                {
 
206
                        if(count($item['url'])>1)
 
207
                        {
 
208
                                foreach(array_splice($item['url'],1) as $name=>$value)
 
209
                                {
 
210
                                        if(!isset($_GET[$name]) || $_GET[$name]!=$value)
 
211
                                                return false;
 
212
                                }
 
213
                        }
 
214
                        return true;
 
215
                }
 
216
                return false;
 
217
        }
 
218
}
 
 
b'\\ No newline at end of file'