* @copyright 2010 Luracast * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link http://luracast.com/products/restler/ * */ class Nav { protected static $tree = array(); public static $root = 'home'; /** * @var array all paths beginning with any of the following will be excluded * from documentation. if an empty string is given it will exclude the root */ public static $excludedPaths = array(''); /** * @var array prefix additional menu items with one of the following syntax * [$path => $text] * [$path] * [$path => ['text' => $text, 'url' => $url, 'trail'=> $trail]] */ public static $prepends = array(); /** * @var array suffix additional menu items with one of the following syntax * [$path => $text] * [$path] * [$path => ['text' => $text, 'url' => $url, 'trail'=> $trail]] */ public static $appends = array(); public static $addExtension = true; protected static $extension = ''; protected static $activeTrail = ''; protected static $url; public static function get($for = '', $activeTrail = null) { if (empty(static::$tree)) { /** @var Restler $restler */ $restler = Scope::get('Restler'); if (static::$addExtension) static::$extension = isset($restler->responseFormat) ? '.' . $restler->responseFormat->getExtension() : '.html'; static::$url = $restler->getBaseUrl(); if (empty(static::$url)) static::$url = ''; static::$activeTrail = $activeTrail = empty($activeTrail) ? (empty($restler->url) || $restler->url == 'index' ? static::$root : $restler->url ) : $activeTrail; if (static::$addExtension) static::$extension = isset($restler->responseFormat) ? '.' . $restler->responseFormat->getExtension() : '.html'; static::addUrls(static::$prepends); $map = Routes::findAll( static::$excludedPaths, array('POST', 'DELETE', 'PUT', 'PATCH'), $restler->getRequestedApiVersion() ); foreach ($map as $path => $data) { foreach ($data as $item) { $access = $item['access']; $route = $item['route']; $url = $route['url']; if ($access && !Text::contains($url, '{')) { $label = Util::nestedValue( $route, 'metadata', CommentParser::$embeddedDataName, 'label' ); if (!empty($url)) { $url .= static::$extension; } static::add($url, $label); } } } static::addUrls(static::$appends); } elseif (empty($activeTrail)) { $activeTrail = static::$activeTrail; } $tree = static::$tree; $activeTrail = explode('/', $activeTrail); $nested = & static::nested($tree, $activeTrail); if (is_array($nested)) { $nested['active'] = true; } if (!empty($for)) { $for = explode('/', $for); $tree = static::nested($tree, $for)['children']; } return array_filter($tree); } protected static function & nested(array & $tree, array $parts) { if (!empty($parts)) { $part = array_shift($parts); if (empty($tree[$part])) { return $tree[$part]; } elseif (empty($parts)) { return static::nested($tree[$part], $parts); } elseif (!empty($tree[$part]['children'])) { return static::nested($tree[$part]['children'], $parts); } } else { return $tree; } $value = null; return $value; } public static function addUrls(array $urls) { foreach ($urls as $url => $label) { $trail = null; if (is_array($label)) { if (isset($label['trail'])) { $trail = $label['trail']; } if (isset($label['url'])) { $url = $label['url']; $label = isset($label['label']) ? $label['label'] : null; } else { $url = current(array_keys($label)); $label = current($label); } } if (is_numeric($url)) { $url = $label; $label = null; } static::add($url, $label, $trail); } return static::$tree; } public static function add($url, $label = null, $trail = null) { $r = parse_url($url); if (is_null($trail)) { $trail = isset($r['path']) ? $r['path'] : static::$root; } //remove / prefix and / suffixes and any extension $trail = strtok(trim($trail, '/'), '.'); $parts = explode('/', $trail); if (count($parts) == 1 && empty($parts[0])) $parts = array(static::$root); if (isset($r['fragment'])) { $parts[] = $r['fragment']; if (is_null($label)) { $label = Text::title($r['fragment']); } } if (empty($r['scheme'])) { //relative url found if (empty($url)) { $label = Text::title(static::$root); $url = static::$url; } else { $url = static::$url . '/' . ltrim($url, '/'); } } if (is_null($label)) { $label = Text::title(strtok(end($parts), '.')); } $r['url'] = $url; $r['path'] = $trail; $r['parts'] = $parts; $r['label'] = $label; static::build($r); return $r; } public static function build(array $r) { $p = & static::$tree; $parts = $r['parts']; $last = count($parts) - 1; foreach ($parts as $i => $part) { if ($i == $last) { $p[$part]['text'] = $r['label']; $p[$part]['href'] = $r['url']; $p[$part]['class'] = Text::slug($part); /* dynamically do it at run time instead if ($r['path'] == static::$activeTrail) $p[$part]['active'] = true; */ } elseif (!isset($p[$part])) { $p[$part] = array(); $p[$part]['text'] = Text::title($part); $p[$part]['href'] = '#'; $p[$part]['children'] = array(); } $p = & $p[$part]['children']; } } }