Overview

Namespaces

  • Menu
    • Items
      • Contents
    • Traits

Classes

  • Menu\Items\Contents\Link
  • Menu\Items\Contents\Raw
  • Menu\Items\Item
  • Menu\Items\ItemList
  • Menu\Menu
  • Menu\MenuHandler
  • Menu\MenuServiceProvider
  • Menu\Traits\Content
  • Menu\Traits\MenuObject
  • Overview
  • Namespace
  • Class
  1: <?php
  2: namespace Menu\Items;
  3: 
  4: use HtmlObject\Element;
  5: use HtmlObject\Traits\Tag;
  6: 
  7: use Menu\Menu;
  8: use Menu\Traits\Content;
  9: use Menu\Traits\MenuObject;
 10: use Menu\MenuHandler;
 11: 
 12: use Underscore\Methods\ArraysMethods;
 13: 
 14: /**
 15:  * An Item in a list
 16:  */
 17: class Item extends MenuObject
 18: {
 19:   /**
 20:    * Array of patterns to match the active state
 21:    *
 22:    * @var array
 23:    */
 24:   protected $patterns = array();
 25: 
 26:   /**
 27:    * Create a new item instance
 28:    *
 29:    * @param ItemList $parent   The parent
 30:    * @param Tag      $value    The content
 31:    * @param array    $children Facultative children ItemLists
 32:    * @param array    $element  The Item element
 33:    * @param string   $beforeContent  String to add before the content
 34:    * @param string   $afterContent   String to add after the content
 35:    */
 36:   public function __construct(ItemList $parent, Tag $value, $children = null, $element = null, $beforeContent = null, $afterContent = null)
 37:   {
 38:     $this->parent   = $parent;
 39:     $this->children = is_null($children) ? new ItemList() : $children;
 40:     $this->element = $element;
 41:     $this->beforeContent = $beforeContent;
 42:     $this->afterContent = $afterContent;
 43: 
 44:     // Create content
 45:     $this->value = $value->setParent($this);
 46:   }
 47: 
 48:   /**
 49:    * Add an pattern to $patterns array
 50:    *
 51:    * @param string|array  $pattern The pattern
 52:    * @param string        $name  Its name
 53:    *
 54:    */
 55:   public function setActivePatterns($pattern, $name = null)
 56:   {
 57:     if (!$name) $name = sizeof($this->patterns);
 58:     $this->patterns[$name] = $pattern;
 59:   }
 60: 
 61:   /**
 62:    * Break off a chain
 63:    *
 64:    * @return ItemList
 65:    */
 66:   public function stop()
 67:   {
 68:     return $this->getParent();
 69:   }
 70: 
 71:   /**
 72:    * Get the Item's content
 73:    *
 74:    * @return Content
 75:    */
 76:   public function getContent()
 77:   {
 78:     return $this->value;
 79:   }
 80: 
 81:   /**
 82:    * Set the value to be inserted before the item's content
 83:    *
 84:    * @param string $value The value to insert
 85:    */
 86:   public function setBeforeContent($value)
 87:   {
 88:     $this->beforeContent = $value;
 89:     return $this;
 90:   }
 91: 
 92:   /**
 93:    * Set the value to be inserted after the item's content
 94:    *
 95:    * @param string $value The value to insert
 96:    */
 97:   public function setAfterContent($value)
 98:   {
 99:     $this->beforeContent = $value;
100:     return $this;
101:   }
102: 
103:   /**
104:    * Set the Item's element
105:    *
106:    * @param string $element
107:    */
108:   public function setElement($element = null)
109:   {
110:     $this->setOption('item.element', $element);
111: 
112:     return $this;
113:   }
114: 
115:   /**
116:    * Get the Item's element
117:    *
118:    * @return string
119:    */
120:   public function getElement()
121:   {
122:     if(is_null($this->element))
123:     {
124:       return $this->getOption('item.element');
125:     }
126: 
127:     return $this->element;
128:   }
129: 
130:   /**
131:    * Render the item
132:    *
133:    * @param array
134:    *
135:    * @return string
136:    */
137:   public function render($depth = 0)
138:   {
139:     // Add the active classes
140:     $value = is_null($this->beforeContent) ? '' : $this->beforeContent;
141:     $value .= $this->value->render();
142:     $value .= is_null($this->afterContent) ? '' : $this->afterContent;
143: 
144:     $this->addActiveClasses();
145: 
146:     // Render children if any
147:     if ($this->hasChildren()) {
148:       $value .= $this->children->render($depth);
149:     }
150: 
151:     // Facultatively render an element around the item
152:     $element = $this->getElement();
153:     if ($element) $value = Element::create($element, $value, $this->attributes)->render();
154:     return html_entity_decode($value, ENT_QUOTES, 'UTF-8');
155:   }
156: 
157:   ////////////////////////////////////////////////////////////////////
158:   ///////////////////////// PUBLIC INTERFACE /////////////////////////
159:   ////////////////////////////////////////////////////////////////////
160: 
161:   /**
162:    * Check if this item is active
163:    *
164:    * @return boolean
165:    */
166:   public function isActive()
167:   {
168:     if( ! $this->value->isLink()) {
169:       return false;
170:     }
171: 
172:     return
173:       trim($this->getUrl(), '/') == trim($this->getRequest()->getPathInfo(), '/') or
174:       $this->getUrl() == $this->getRequest()->fullUrl() or
175:       $this->getUrl() == $this->getRequest()->url() or
176:       $this->hasActivePatterns();
177:   }
178: 
179:   public function hasChildren()
180:   {
181:     return count($this->children->getChildren()) > 0;
182:   }
183: 
184:   /**
185:    * Check if this item has an active pattern
186:    *
187:    * @return boolean
188:    */
189:   protected function hasActivePatterns()
190:   {
191:     foreach ($this->patterns as $pattern) {
192:       $path = $this->getRequest()->getPathInfo();
193: 
194:       if (is_array($pattern)) {
195:         foreach ($pattern as $p)
196:           $isActive = preg_match('/'.$p.'/i', $path);
197:       } else {
198:         $isActive = preg_match('/'.$pattern.'/i', $path);
199:       }
200: 
201:       if($isActive) return true;
202:     }
203: 
204:     return false;
205:   }
206: 
207:   /**
208:    * Check if this item has an active child
209:    *
210:    * @return boolean
211:    */
212:   public function hasActiveChild()
213:   {
214:     if (!$this->hasChildren()) {
215:       return false;
216:     }
217: 
218:     foreach ($this->children->getChildren() as $child) {
219:       if ($child->isActive()) {
220:         return true;
221:       }
222: 
223:       if ($child->hasChildren()) {
224:         return $child->hasActiveChild();
225:       }
226:     }
227: 
228:     return false;
229:   }
230: 
231:   /**
232:    * Get the url of the Item's content
233:    *
234:    * @return string
235:    */
236:   protected function getUrl()
237:   {
238:     return $this->value->isLink() ? $this->value->getEvaluatedUrl() : null;
239:   }
240: 
241:   ////////////////////////////////////////////////////////////////////
242:   ////////////////////////////// HELPERS /////////////////////////////
243:   ////////////////////////////////////////////////////////////////////
244: 
245:   /**
246:    * Add the various active classes to an array of attributes
247:    */
248:   private function addActiveClasses()
249:   {
250:     if ($this->isActive()) {
251:       $this->addClass($this->getOption('item.active_class'));
252:     }
253: 
254:     if ($this->hasActiveChild()) {
255:       $this->addClass($this->getOption('item.active_child_class'));
256:     }
257:   }
258: 
259:   ////////////////////////////////////////////////////////////////////
260:   //////////////////////////// DEPENDENCIES //////////////////////////
261:   ////////////////////////////////////////////////////////////////////
262: 
263:   /**
264:    * Get the Request instance
265:    *
266:    * @return Request
267:    */
268:   public function getRequest()
269:   {
270:     return Menu::getContainer('request');
271:   }
272: 
273: }
274: 
API documentation generated by ApiGen