Overview

Namespaces

  • Sleepy
  • Module
    • Authentication
    • CSV
    • DB
    • FormBuilder
    • FSDB
    • IP2Country
    • Mailer
    • MobiDetect
    • Navigation
    • StaticCache
  • PHP

Classes

  • Sleepy\Debug
  • Sleepy\Hook
  • Sleepy\Router
  • Sleepy\SM
  • Sleepy\Template

Exceptions

  • Sleepy\RouteNotFound
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: namespace Module\Navigation;
  3: 
  4: /**
  5:  * Creates a Navigation UL based on a JSON file
  6:  *
  7:  * Uses JSON to structure navigation pages and attributes. It can
  8:  * detect what page is active and assign classes to them for special treatment.
  9:  *
 10:  * ### Usage
 11:  *
 12:  * <code>
 13:  *  $topNavData = '{
 14:  *    "pages": [
 15:  *      {
 16:  *        "title": "Nav 1",
 17:  *        "link": "/nav1/"
 18:  *      }, {
 19:  *        "title": "Nav 2",
 20:  *        "link": "/nav2/",
 21:  *        "pages": [
 22:  *          {
 23:  *            "title": "Subnav 1",
 24:  *            "link": "/downloads/fpo.pdf",
 25:  *            "target": "_blank"
 26:  *          }
 27:  *        ]
 28:  *      }
 29:  *    ]
 30:  *  }';
 31:  *
 32:  *  $topNav = new \Module\Navigation\Builder($topNavData);
 33:  *
 34:  *  // In body somewhere...
 35:  *  <nav class="top">
 36:  *    <?= $topNav->show(); ?>
 37:  *  </nav>
 38:  * </code>
 39:  *
 40:  * ### Changelog
 41:  * # Version 1.4
 42:  * * Now automatically sets $_SERVER['SCRIPT_NAME'] as current page
 43:  * * Added multiple hook points for manipulating navigations
 44:  *
 45:  * ## Version 1.2
 46:  * * Added a track parameter
 47:  *
 48:  * @date June 16, 2014
 49:  * @author Jaime A. Rodriguez <hi.i.am.jaime@gmail.com>
 50:  * @version 1.1
 51:  * @license  http://opensource.org/licenses/MIT
 52:  */
 53: class Builder {
 54:     /**
 55:      * string Use this string to determine currently active page
 56:      * @private
 57:      */
 58:     private $current;
 59: 
 60:     /**
 61:      * mixed Navigation data
 62:      */
 63:     private $data;
 64: 
 65:     /**
 66:      * mixed Level
 67:      */
 68:     private $_level = 0;
 69: 
 70:     /**
 71:      * Constructor
 72:      * @param string $json json data containing the Navigation data
 73:      */
 74:     public function __construct($json='') {
 75:         if (!is_object($json)) {
 76:             if (class_exists('\Sleepy\Hook')) {
 77:                 $json = \Sleepy\Hook::addFilter('navigation_raw_json', $json);
 78:             }
 79: 
 80:             $json = json_decode($json);
 81:         }
 82: 
 83:         if (class_exists('\Sleepy\Hook')) {
 84:             $json = \Sleepy\Hook::addFilter('navigation_rendered_json', $json);
 85:         }
 86: 
 87:         $this->data = $json;
 88:         $this->setCurrent($_SERVER['SCRIPT_NAME']);
 89:     }
 90: 
 91:     /**
 92:      * Is this page or its children an active page?
 93:      * @param  object  $page An object containing page data
 94:      * @return int     0=none;1=active;2=activeChild
 95:      * @private
 96:      */
 97:     private function hasActive($page) {
 98:         // are there subpages? check those too...
 99:         if (isset($page->pages)) {
100:             foreach ($page->pages as $subPage) {
101:                 if ($this->hasActive($subPage)) {
102:                     return 2;
103:                 }
104:             }
105:         }
106: 
107:         // can we find a match?
108:         if (substr($page->link, strlen($page->link) * -1) === $this->current) {
109:             if (class_exists('\Sleepy\Hook')) {
110:                 \Sleepy\Hook::addAction('navigation_has_active');
111:             }
112: 
113:             return 1;
114:         }
115: 
116:         // no match...
117:         if (class_exists('\Sleepy\Hook')) {
118:             \Sleepy\Hook::addAction('navigation_no_active');
119:         }
120: 
121:         return 0;
122:     }
123: 
124:     /**
125:      * Renders the $pages as an unordered list
126:      * @param  object $pages the page data
127:      * @return string        The string containing the unordered list
128:      */
129:     private function renderNav($pages, $class="") {
130:         $this->_level = $this->_level + 1;
131:         $buffer = array();
132: 
133:         if ($this->_level > 1) {
134:             $class = "submenu " . $class;
135:         } else {
136:             $class = "menu " . $class;
137:         }
138: 
139:         $class = trim($class);
140: 
141:         $buffer[] = "<ul class=\"{$class}\">";
142: 
143:         foreach ($pages as $page) {
144:             if (class_exists('\Sleepy\Hook')) {
145:                 $page = \Sleepy\Hook::addFilter('navigation_page', $page);
146: 
147:                 if (!empty($page->id)) {
148:                     $page = \Sleepy\Hook::addFilter('navigation_page_' . $page->id, $page);
149:                 }
150:             }
151: 
152:             if (!isset($page->class)) {
153:                 $page->class = "";
154:             }
155: 
156:             if (isset($page->pages)) {
157:                 $page->class = $page->class . " has-children";
158:             }
159: 
160:             $active     = $this->hasActive($page);
161:             $classy     = (!empty($page->class))    ? true                              : false;
162:             $track      = (!empty($page->track))    ? "data-track=\"{$page->track}\" "  : "";
163:             $id         = (!empty($page->id))       ? "id=\"{$page->id}\" "             : "";
164:             $target     = (!empty($page->target))   ? "target=\"{$page->target}\" "     : "";
165:             $href       = (!empty($page->link))     ? "href=\"{$page->link}\" "         : "";
166:             $attributes = trim($id . $track . $target . $href);
167: 
168:             $buffer[] = "<li";
169: 
170:             if ($active || $classy) {
171:                 $buffer[] = " class=\"";
172: 
173:                 switch ($active) {
174:                 case 1:
175:                     $page->class = $page->class . " active";
176:                     break;
177:                 case 2:
178:                     $page->class = $page->class . " active-child";
179:                 }
180: 
181:                 $buffer[] = trim($page->class);
182: 
183:                 $buffer[] = "\"";
184:             }
185: 
186:             $buffer[] = ">";
187: 
188:             $buffer[] = "<a {$attributes}>{$page->title}</a>";
189: 
190:             if (isset($page->pages)) {
191:                 $buffer[] = $this->renderNav($page->pages);
192:             }
193: 
194:             $buffer[] = "</li>";
195:         }
196:         $buffer[] = "</ul>";
197: 
198:         return implode("", $buffer);
199:     }
200: 
201:     /**
202:      * Renders the Navigation
203:      * @return string The rendered navigation
204:      */
205:     public function show($class="") {
206:         $rendered = $this->renderNav($this->data->pages, $class);
207: 
208:         if (class_exists('\Sleepy\Hook')) {
209:             $rendered = \Sleepy\Hook::addFilter('navigation_rendered', $rendered);
210:         }
211: 
212:         return $rendered;
213:     }
214: 
215:     /**
216:      * Sets the current page search string
217:      * @param string $string A string used to determine if a page is current
218:      */
219:     public function setCurrent($string) {
220:         $this->current = str_replace(@URLBASE, "/", str_replace("index.php", "", $string));
221: 
222:         if (class_exists('\Sleepy\Hook')) {
223:             $this->current = \Sleepy\Hook::addFilter('navigation_current_page', $this->current);
224:         }
225:     }
226: }
sleepyMUSTACHE v.0.8 API documentation generated by ApiGen