224 lines
7.5 KiB
PHP
224 lines
7.5 KiB
PHP
<?php
|
|
namespace Luracast\Restler\UI;
|
|
|
|
use Luracast\Restler\CommentParser;
|
|
use Luracast\Restler\Data\Text;
|
|
use Luracast\Restler\Restler;
|
|
use Luracast\Restler\Routes;
|
|
use Luracast\Restler\Scope;
|
|
use Luracast\Restler\Util;
|
|
|
|
|
|
/**
|
|
* Utility class for automatically creating data to build an navigation interface
|
|
* based on available routes that are accessible by the current user
|
|
*
|
|
* @category Framework
|
|
* @package Restler
|
|
* @author R.Arul Kumaran <arul@luracast.com>
|
|
* @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'];
|
|
}
|
|
}
|
|
}
|