diff --git a/src/Builder.php b/src/Builder.php
index 9e898f6..f49cae7 100755
--- a/src/Builder.php
+++ b/src/Builder.php
@@ -8,597 +8,602 @@
class Builder
{
- /**
- * @var array
- */
- protected $items;
-
- /**
- * @var Collective\Html\HtmlBuilder
- */
- protected $html;
-
- /**
- * @var string
- */
- protected $name;
-
- /**
- * @var array
- */
- protected $config;
-
- /**
- * @var array
- */
- protected $reserved = ['route', 'action', 'url', 'prefix', 'parent', 'secure', 'raw'];
-
- /**
- * @var int
- */
- protected $lastId;
-
- /**
- * @var Illuminate\Routing\UrlGenerator
- */
- protected $url;
-
- /**
- * Create a new Builder instance.
- *
- * @param string $name
- * @param array $config
- * @param Collective\Html\HtmlBuilder $html
- * @param Illuminate\Routing\UrlGenerator $url
- */
- public function __construct($name, $config, HtmlBuilder $html, UrlGenerator $url)
- {
- $this->name = $name;
- $this->config = $config;
- $this->html = $html;
- $this->url = $url;
- $this->items = new Collection;
- }
-
- /**
- * Add an item to the defined menu.
- *
- * @param string $title
- * @param array|string $options
- *
- * @return Item
- */
- public function add($title, $options = '')
- {
- $item = new Item($this, $this->id(), $title, $options);
-
- $this->items->push($item);
-
- $this->lastId = $item->id;
-
- return $item;
- }
-
- /**
- * Generate a unique ID for every item added to the menu.
- *
- * @return int
- */
- protected function id()
- {
- return $this->lastId + 1;
- }
-
- /**
- * Extract the valid attributes from the passed options.
- *
- * @param array $options
- *
- * @return array
- */
- public function extractAttributes($options = array())
- {
- if (is_array($options)) {
- if (count($this->groupStack) > 0) {
- $options = $this->mergeWithLastGroup($options);
- }
-
- return array_except($options, $this->reserved);
- }
-
- return array();
- }
-
- /**
- * Converts the defined attributes into HTML.
- *
- * @param array $attributes
- *
- * @return string
- */
- public function attributes($attributes = array())
- {
- return $this->html->attributes($attributes);
- }
-
- /**
- * Insert a divider after the item.
- *
- * @param array $attributes
- *
- * @return void
- */
- public function divide($attributes = array())
- {
- $attributes['class'] = self::formatGroupClass(['class' => 'divider'], $attributes);
-
- $this->items->last()->divider = $attributes;
- }
-
- /**
- * Return the configuration value by key.
- *
- * @param string $key
- *
- * @return string
- */
- public function config($key)
- {
- return $this->config[$key];
- }
-
- /**
- * Get the prefix from the last group of the stack.
- *
- * @return mixed
- */
- public function getLastGroupPrefix()
- {
- if (count($this->groupStack) > 0) {
- return array_get(last($this->groupStack), 'prefix', '');
- }
-
- return null;
- }
-
- /**
- * Format the groups class.
- *
- * @return mixed
- */
- public static function formatGroupClass($new, $old)
- {
- if (isset($new['class'])) {
- $classes = trim(trim(array_get($old, 'class')).' '.trim(array_get($new, 'class')));
-
- return implode(' ', array_unique(explode(' ', $classes)));
- }
-
- return array_get($old, 'class');
- }
-
- /*
- |--------------------------------------------------------------------------
- | Fetching Methods
- |--------------------------------------------------------------------------
- |
- */
-
- /**
- * Fetches and returns all menu items.
- *
- * @return Collection
- */
- public function all()
- {
- return $this->items;
- }
-
- /**
- * Returns all items with no parents.
- *
- * @return Collection
- */
- public function roots()
- {
- return $this->whereParent();
- }
-
- /**
- * Fetches and returns a menu item by it's slug.
- *
- * @param string $slug
- *
- * @return Item
- */
- public function get($slug)
- {
- return $this->whereSlug($slug)->first();
- }
-
- /**
- * Facade method for the get() method.
- *
- * @param string $slug
- *
- * @return Item
- */
- public function item($slug)
- {
- return $this->get($slug);
- }
-
- /**
- * Fetches and returns a menu item by it's ID.
- *
- * @param integer $id
- *
- * @return Item
- */
- public function find($id)
- {
- return $this->whereId($id)->first();
- }
-
- /**
- * Fetches and returns the first menu item.
- *
- * @return Item
- */
- public function first()
- {
- return $this->items->first();
- }
-
- /**
- * Fetches and returns the last menu item.
- *
- * @return Item
- */
- public function last()
- {
- return $this->items->last();
- }
-
- /**
- * Fetches and returns all active state menu items.
- *
- * @return Collection
- */
- public function active()
- {
- $activeItems = array();
-
- foreach ($this->items as $item) {
- if ($item->data('active')) {
- $activeItems[] = $item;
- }
- }
-
- return $activeItems;
- }
-
- /*
- |--------------------------------------------------------------------------
- | Dispatch Methods
- |--------------------------------------------------------------------------
- |
- */
-
- /**
- * Get the action type from the options.
- *
- * @param array $options
- *
- * @return string
- */
- public function dispatch($options)
- {
- if (isset($options['url'])) {
- return $this->getUrl($options);
- } elseif (isset($options['route'])) {
- return $this->getRoute($options['route']);
- } elseif (isset($options['action'])) {
- return $this->getAction($options['action']);
- }
-
- return null;
- }
-
- /**
- * Get the action for a "url" option.
- *
- * @param array|string $options
- *
- * @return string
- */
- protected function getUrl($options)
- {
- foreach ($options as $key => $value) {
- $$key = $value;
- }
-
- $secure = (isset($options['secure']) and $options['secure'] === true) ? true : false;
-
- if (is_array($url)) {
- if (self::isAbsolute($url[0])) {
- return $url[0];
- }
-
- return $this->url->to($prefix.'/'.$url[0], array_slice($url, 1), $secure);
- }
-
- if (self::isAbsolute($url)) {
- return $url;
- }
-
- return $this->url->to($prefix.'/'.$url, array(), $secure);
- }
-
- /**
- * Get the route action for a "route" option.
- *
- * @param array|string $route
- *
- * @return string
- */
- protected function getRoute($route)
- {
- if (is_array($route)) {
- return $this->url->route($route[0], array_slice($route, 1));
- }
-
- return $this->url->route($route);
- }
-
- /**
- * Get the controller action for a "action" option.
- *
- * @param array|string $action
- *
- * @return string
- */
- protected function getAction($action)
- {
- if (is_array($action)) {
- return $this->url->action($action[0], array_slice($action, 1));
- }
-
- return $this->url->action($action);
- }
-
- /**
- * Determines if the given URL is absolute.
- *
- * @param string $url
- *
- * @return bool
- */
- public static function isAbsolute($url)
- {
- return parse_url($url, PHP_URL_SCHEME) or false;
- }
-
- /*
- |--------------------------------------------------------------------------
- | Filter Methods
- |--------------------------------------------------------------------------
- |
- */
-
- /**
- * Filter menu items through a callback.
- *
- * Since menu items are stored as a collection, this will
- * simply forward the callback to the Laravel Collection
- * filter() method and return the results.
- *
- * @param callable $callback
- *
- * @return Builder
- */
- public function filter($callback)
- {
- if (is_callable($callback)) {
- $this->items = $this->items->filter($callback);
- }
-
- return $this;
- }
-
- /**
- * Filter menu items recursively.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return Collection
- */
- public function filterRecursively($attribute, $value)
- {
- $collection = new Collection;
-
- $this->items->each(function($item) use ($attribute, $value, &$collection) {
- if (! property_exists($item, $attribute)) {
- return false;
- }
-
- if ($item->$attribute == $value) {
- $collection->push($item);
-
- if ($item->hasChildren()) {
- $collection = $collection->merge($this->filterRecursively($attribute, $item->id));
- }
- }
- });
-
- return $collection;
- }
-
- /**
- * Sorts the menu based on key given in ascending order.
- *
- * @param string $key
- *
- * @return Builder
- */
- public function sortBy($key)
- {
- $this->items = $this->items->sortBy(function($item) use ($key) {
- return $item->$key;
- });
-
- return $this;
- }
-
- /**
- * Sorts the menu based on key given in descending order.
- *
- * @param string $key
- *
- * @return Builder
- */
- public function sortByDesc($key)
- {
- $this->items = $this->items->sortByDesc(function($item) use ($key) {
- return $item->$key;
- });
-
- return $this;
- }
-
- /**
- * Filter menu items based on Shinobi permissions.
- *
- * @return Builder
- */
- public function guard()
- {
- if (class_exists('Caffeinated\Shinobi\Shinobi')) {
- $this->filter(function ($item) {
- if (! $item->data('can') and ! $item->data('canatleast')) {
- return true;
- } elseif ($item->data('canatleast')) {
- return \Shinobi::canAtLeast($item->data('canatleast'));
- } else {
- return \Shinobi::can($item->data('can'));
- }
- });
- }
-
- return $this;
- }
-
- /*
- |--------------------------------------------------------------------------
- | Rendering Methods
- |--------------------------------------------------------------------------
- |
- */
-
- /**
- * Renders the menu as an unordered list.
- *
- * @param array $attributes
- * @return string
- */
- public function asUl($attributes = array())
- {
- return "
attributes($attributes)}>{$this->render('ul')}
";
- }
-
- /**
- * Generate the menu items as list items, recursively.
- *
- * @param string $type
- * @param int $parent
- * @return string
- */
- protected function render($type = 'ul', $parent = null)
- {
- $items = '';
- $itemTag = in_array($type, ['ul', 'ol']) ? 'li' : $type;
-
- foreach ($this->whereParent($parent) as $item) {
- $items .= "<{$itemTag}{$item->attributes()}>";
-
- if ($item->link) {
- $items .= "attributes($item->link->attr())} href=\"{$item->url()}\">{$item->title}";
- } else {
- $items .= $item->title;
- }
-
- if ($item->hasChildren()) {
- $items .= "<{$type}>";
- $items .= $this->render($type, $item->id);
- $items .= "{$type}>";
- }
-
- $items .= "{$itemTag}>";
-
- if ($item->divider) {
- $items .= "<{$itemTag}{$this->attributes($item->divider)}>{$itemTag}>";
- }
- }
-
- return $items;
- }
-
- /**
- * Dynamic search method against a menu attribute.
- *
- * @param string $method
- * @param array $args
- *
- * @return Item|bool
- */
- public function __call($method, $args)
- {
- preg_match('/^[W|w]here([a-zA-Z0-9_]+)$/', $method, $matches);
-
- if ($matches) {
- $attribute = Str::lower($matches[1]);
- } else {
- throw new BadMethodCallException('Call to undefined method '.$method);
- }
-
- $value = $args ? $args[0] : null;
- $recursive = isset($args[1]) ? $args[1] : false;
-
- if ($recursive) {
- return $this->filterRecursively($attribute, $value);
- }
-
- return $this->items->filter(function($item) use ($attribute, $value) {
- if (isset($item->data[$attribute]) && $item->data[$attribute] == $value) {
- return true;
- }
-
- if (! property_exists($item, $attribute)) {
- return false;
- }
-
- if ($item->$attribute == $value) {
- return true;
- }
-
- return false;
- })->values();
- }
-
- /**
- * Returns menu item by name.
- *
- * @param string $property
- *
- * @return Item
- */
- public function __get($property)
- {
- if (property_exists($this, $property)) {
- return $this->$property;
- }
-
- return $this->whereSlug($property)->first();
- }
+ /**
+ * @var array
+ */
+ protected $items;
+
+ /**
+ * @var array
+ */
+ protected $groupStack = [];
+
+ /**
+ * @var Collective\Html\HtmlBuilder
+ */
+ protected $html;
+
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var array
+ */
+ protected $config;
+
+ /**
+ * @var array
+ */
+ protected $reserved = ['route', 'action', 'url', 'prefix', 'parent', 'secure', 'raw'];
+
+ /**
+ * @var int
+ */
+ protected $lastId;
+
+ /**
+ * @var Illuminate\Routing\UrlGenerator
+ */
+ protected $url;
+
+ /**
+ * Create a new Builder instance.
+ *
+ * @param string $name
+ * @param array $config
+ * @param Collective\Html\HtmlBuilder $html
+ * @param Illuminate\Routing\UrlGenerator $url
+ */
+ public function __construct($name, $config, HtmlBuilder $html, UrlGenerator $url)
+ {
+ $this->name = $name;
+ $this->config = $config;
+ $this->html = $html;
+ $this->url = $url;
+ $this->items = new Collection;
+ }
+
+ /**
+ * Add an item to the defined menu.
+ *
+ * @param string $title
+ * @param array|string $options
+ *
+ * @return Item
+ */
+ public function add($title, $options = '')
+ {
+ $item = new Item($this, $this->id(), $title, $options);
+
+ $this->items->push($item);
+
+ $this->lastId = $item->id;
+
+ return $item;
+ }
+
+ /**
+ * Generate a unique ID for every item added to the menu.
+ *
+ * @return int
+ */
+ protected function id()
+ {
+ return $this->lastId + 1;
+ }
+
+ /**
+ * Extract the valid attributes from the passed options.
+ *
+ * @param array $options
+ *
+ * @return array
+ */
+ public function extractAttributes($options = array())
+ {
+ if (is_array($options)) {
+ if (count($this->groupStack) > 0) {
+ $options = $this->mergeWithLastGroup($options);
+ }
+
+ return array_except($options, $this->reserved);
+ }
+
+ return array();
+ }
+
+ /**
+ * Converts the defined attributes into HTML.
+ *
+ * @param array $attributes
+ *
+ * @return string
+ */
+ public function attributes($attributes = array())
+ {
+ return $this->html->attributes($attributes);
+ }
+
+ /**
+ * Insert a divider after the item.
+ *
+ * @param array $attributes
+ *
+ * @return void
+ */
+ public function divide($attributes = array())
+ {
+ $attributes['class'] = self::formatGroupClass(['class' => 'divider'], $attributes);
+
+ $this->items->last()->divider = $attributes;
+ }
+
+ /**
+ * Return the configuration value by key.
+ *
+ * @param string $key
+ *
+ * @return string
+ */
+ public function config($key)
+ {
+ return $this->config[$key];
+ }
+
+ /**
+ * Get the prefix from the last group of the stack.
+ *
+ * @return mixed
+ */
+ public function getLastGroupPrefix()
+ {
+ if (count($this->groupStack) > 0) {
+ return array_get(last($this->groupStack), 'prefix', '');
+ }
+
+ return null;
+ }
+
+ /**
+ * Format the groups class.
+ *
+ * @return mixed
+ */
+ public static function formatGroupClass($new, $old)
+ {
+ if (isset($new['class'])) {
+ $classes = trim(trim(array_get($old, 'class')).' '.trim(array_get($new, 'class')));
+
+ return implode(' ', array_unique(explode(' ', $classes)));
+ }
+
+ return array_get($old, 'class');
+ }
+
+ /*
+ |--------------------------------------------------------------------------
+ | Fetching Methods
+ |--------------------------------------------------------------------------
+ |
+ */
+
+ /**
+ * Fetches and returns all menu items.
+ *
+ * @return Collection
+ */
+ public function all()
+ {
+ return $this->items;
+ }
+
+ /**
+ * Returns all items with no parents.
+ *
+ * @return Collection
+ */
+ public function roots()
+ {
+ return $this->whereParent();
+ }
+
+ /**
+ * Fetches and returns a menu item by it's slug.
+ *
+ * @param string $slug
+ *
+ * @return Item
+ */
+ public function get($slug)
+ {
+ return $this->whereSlug($slug)->first();
+ }
+
+ /**
+ * Facade method for the get() method.
+ *
+ * @param string $slug
+ *
+ * @return Item
+ */
+ public function item($slug)
+ {
+ return $this->get($slug);
+ }
+
+ /**
+ * Fetches and returns a menu item by it's ID.
+ *
+ * @param integer $id
+ *
+ * @return Item
+ */
+ public function find($id)
+ {
+ return $this->whereId($id)->first();
+ }
+
+ /**
+ * Fetches and returns the first menu item.
+ *
+ * @return Item
+ */
+ public function first()
+ {
+ return $this->items->first();
+ }
+
+ /**
+ * Fetches and returns the last menu item.
+ *
+ * @return Item
+ */
+ public function last()
+ {
+ return $this->items->last();
+ }
+
+ /**
+ * Fetches and returns all active state menu items.
+ *
+ * @return Collection
+ */
+ public function active()
+ {
+ $activeItems = array();
+
+ foreach ($this->items as $item) {
+ if ($item->data('active')) {
+ $activeItems[] = $item;
+ }
+ }
+
+ return $activeItems;
+ }
+
+ /*
+ |--------------------------------------------------------------------------
+ | Dispatch Methods
+ |--------------------------------------------------------------------------
+ |
+ */
+
+ /**
+ * Get the action type from the options.
+ *
+ * @param array $options
+ *
+ * @return string
+ */
+ public function dispatch($options)
+ {
+ if (isset($options['url'])) {
+ return $this->getUrl($options);
+ } elseif (isset($options['route'])) {
+ return $this->getRoute($options['route']);
+ } elseif (isset($options['action'])) {
+ return $this->getAction($options['action']);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the action for a "url" option.
+ *
+ * @param array|string $options
+ *
+ * @return string
+ */
+ protected function getUrl($options)
+ {
+ foreach ($options as $key => $value) {
+ $$key = $value;
+ }
+
+ $secure = (isset($options['secure']) and $options['secure'] === true) ? true : false;
+
+ if (is_array($url)) {
+ if (self::isAbsolute($url[0])) {
+ return $url[0];
+ }
+
+ return $this->url->to($prefix.'/'.$url[0], array_slice($url, 1), $secure);
+ }
+
+ if (self::isAbsolute($url)) {
+ return $url;
+ }
+
+ return $this->url->to($prefix.'/'.$url, array(), $secure);
+ }
+
+ /**
+ * Get the route action for a "route" option.
+ *
+ * @param array|string $route
+ *
+ * @return string
+ */
+ protected function getRoute($route)
+ {
+ if (is_array($route)) {
+ return $this->url->route($route[0], array_slice($route, 1));
+ }
+
+ return $this->url->route($route);
+ }
+
+ /**
+ * Get the controller action for a "action" option.
+ *
+ * @param array|string $action
+ *
+ * @return string
+ */
+ protected function getAction($action)
+ {
+ if (is_array($action)) {
+ return $this->url->action($action[0], array_slice($action, 1));
+ }
+
+ return $this->url->action($action);
+ }
+
+ /**
+ * Determines if the given URL is absolute.
+ *
+ * @param string $url
+ *
+ * @return bool
+ */
+ public static function isAbsolute($url)
+ {
+ return parse_url($url, PHP_URL_SCHEME) or false;
+ }
+
+ /*
+ |--------------------------------------------------------------------------
+ | Filter Methods
+ |--------------------------------------------------------------------------
+ |
+ */
+
+ /**
+ * Filter menu items through a callback.
+ *
+ * Since menu items are stored as a collection, this will
+ * simply forward the callback to the Laravel Collection
+ * filter() method and return the results.
+ *
+ * @param callable $callback
+ *
+ * @return Builder
+ */
+ public function filter($callback)
+ {
+ if (is_callable($callback)) {
+ $this->items = $this->items->filter($callback);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Filter menu items recursively.
+ *
+ * @param string $attribute
+ * @param mixed $value
+ *
+ * @return Collection
+ */
+ public function filterRecursively($attribute, $value)
+ {
+ $collection = new Collection;
+
+ $this->items->each(function ($item) use ($attribute, $value, &$collection) {
+ if (! property_exists($item, $attribute)) {
+ return false;
+ }
+
+ if ($item->$attribute == $value) {
+ $collection->push($item);
+
+ if ($item->hasChildren()) {
+ $collection = $collection->merge($this->filterRecursively($attribute, $item->id));
+ }
+ }
+ });
+
+ return $collection;
+ }
+
+ /**
+ * Sorts the menu based on key given in ascending order.
+ *
+ * @param string $key
+ *
+ * @return Builder
+ */
+ public function sortBy($key)
+ {
+ $this->items = $this->items->sortBy(function ($item) use ($key) {
+ return $item->$key;
+ });
+
+ return $this;
+ }
+
+ /**
+ * Sorts the menu based on key given in descending order.
+ *
+ * @param string $key
+ *
+ * @return Builder
+ */
+ public function sortByDesc($key)
+ {
+ $this->items = $this->items->sortByDesc(function ($item) use ($key) {
+ return $item->$key;
+ });
+
+ return $this;
+ }
+
+ /**
+ * Filter menu items based on Shinobi permissions.
+ *
+ * @return Builder
+ */
+ public function guard()
+ {
+ if (class_exists('Caffeinated\Shinobi\Shinobi')) {
+ $this->filter(function ($item) {
+ if (! $item->data('can') and ! $item->data('canatleast')) {
+ return true;
+ } elseif ($item->data('canatleast')) {
+ return \Shinobi::canAtLeast($item->data('canatleast'));
+ } else {
+ return \Shinobi::can($item->data('can'));
+ }
+ });
+ }
+
+ return $this;
+ }
+
+ /*
+ |--------------------------------------------------------------------------
+ | Rendering Methods
+ |--------------------------------------------------------------------------
+ |
+ */
+
+ /**
+ * Renders the menu as an unordered list.
+ *
+ * @param array $attributes
+ * @return string
+ */
+ public function asUl($attributes = array())
+ {
+ return "attributes($attributes)}>{$this->render('ul')}
";
+ }
+
+ /**
+ * Generate the menu items as list items, recursively.
+ *
+ * @param string $type
+ * @param int $parent
+ * @return string
+ */
+ protected function render($type = 'ul', $parent = null)
+ {
+ $items = '';
+ $itemTag = in_array($type, ['ul', 'ol']) ? 'li' : $type;
+
+ foreach ($this->whereParent($parent) as $item) {
+ $items .= "<{$itemTag}{$item->attributes()}>";
+
+ if ($item->link) {
+ $items .= "attributes($item->link->attr())} href=\"{$item->url()}\">{$item->title}";
+ } else {
+ $items .= $item->title;
+ }
+
+ if ($item->hasChildren()) {
+ $items .= "<{$type}>";
+ $items .= $this->render($type, $item->id);
+ $items .= "{$type}>";
+ }
+
+ $items .= "{$itemTag}>";
+
+ if ($item->divider) {
+ $items .= "<{$itemTag}{$this->attributes($item->divider)}>{$itemTag}>";
+ }
+ }
+
+ return $items;
+ }
+
+ /**
+ * Dynamic search method against a menu attribute.
+ *
+ * @param string $method
+ * @param array $args
+ *
+ * @return Item|bool
+ */
+ public function __call($method, $args)
+ {
+ preg_match('/^[W|w]here([a-zA-Z0-9_]+)$/', $method, $matches);
+
+ if ($matches) {
+ $attribute = Str::lower($matches[1]);
+ } else {
+ throw new BadMethodCallException('Call to undefined method '.$method);
+ }
+
+ $value = $args ? $args[0] : null;
+ $recursive = isset($args[1]) ? $args[1] : false;
+
+ if ($recursive) {
+ return $this->filterRecursively($attribute, $value);
+ }
+
+ return $this->items->filter(function ($item) use ($attribute, $value) {
+ if (isset($item->data[$attribute]) && $item->data[$attribute] == $value) {
+ return true;
+ }
+
+ if (! property_exists($item, $attribute)) {
+ return false;
+ }
+
+ if ($item->$attribute == $value) {
+ return true;
+ }
+
+ return false;
+ })->values();
+ }
+
+ /**
+ * Returns menu item by name.
+ *
+ * @param string $property
+ *
+ * @return Item
+ */
+ public function __get($property)
+ {
+ if (property_exists($this, $property)) {
+ return $this->$property;
+ }
+
+ return $this->whereSlug($property)->first();
+ }
}
diff --git a/src/Item.php b/src/Item.php
index e7db856..09e593e 100755
--- a/src/Item.php
+++ b/src/Item.php
@@ -5,404 +5,404 @@
class Item
{
- /**
- * @var \Caffeinated\Menus\Builder
- */
- protected $builder;
-
- /**
- * @var int
- */
- public $id;
-
- /**
- * @var string
- */
- public $title;
-
- /**
- * @var string
- */
- public $slug;
-
- /**
- * @var array
- */
- public $divider = array();
-
- /**
- * @var int
- */
- public $parent;
-
- /**
- * @var array
- */
- protected $data = array();
-
- /**
- * @var array
- */
- public $attributes = array();
-
- /**
- * Constructor.
- *
- * @param \Caffeinated\Menus\Builder $builder
- * @param int $id
- * @param string $title
- * @param array|string $options
- */
- public function __construct($builder, $id, $title, $options)
- {
- $this->builder = $builder;
- $this->id = $id;
- $this->title = $title;
- $this->slug = camel_case(str_slug($title, ' '));
- $this->attributes = $this->builder->extractAttributes($options);
- $this->parent = (is_array($options) and isset($options['parent'])) ? $options['parent'] : null;
-
- $this->configureLink($options);
- }
-
- public function builder()
- {
- return $this->builder;
- }
-
- /**
- * Configures the link for the menu item.
- *
- * @param array|string $options
- * @return null
- */
- public function configureLink($options)
- {
- if (! is_array($options)) {
- $path = ['url' => $options];
- } elseif (isset($options['raw']) and $options['raw'] == true) {
- $path = null;
- } else {
- $path = array_only($options, ['url', 'route', 'action', 'secure']);
- }
-
- if (! is_null($path)) {
- $path['prefix'] = $this->builder->getLastGroupPrefix();
- }
-
- $this->link = isset($path) ? new Link($path) : null;
-
- $this->checkActiveStatus();
- }
-
- /**
- * Adds a sub item to the menu.
- *
- * @param string $title
- * @param array|string $options
- * @return \Caffeinated\Menus\Item
- */
- public function add($title, $options = '')
- {
- if (! is_array($options)) {
- $url = $options;
- $options = array();
- $options['url'] = $url;
- }
-
- $options['parent'] = $this->id;
-
- return $this->builder->add($title, $options);
- }
-
- /**
- * Fetch the formatted attributes for the item in HTML.
- *
- * @return string
- */
- public function attributes()
- {
- return $this->builder->attributes($this->attributes);
- }
-
- /**
- * Get all attributes.
- *
- * @return array
- */
- public function getAttributes()
- {
- return $this->attributes;
- }
-
- /**
- * Assign or fetch the desired attribute.
- *
- * @param array|string $attribute
- * @param string $value
- * @return mixed
- */
- public function attribute($attribute, $value = null)
- {
- if (isset($attribute) and is_array($attribute)) {
- if (array_key_exists('class', $attribute)) {
- $this->attributes['class'] = $this->builder->formatGroupClass(['class' => $attribute['class']], $this->attributes);
- unset ($attribute['class']);
- }
-
- $this->attributes = array_merge($this->attributes, $attribute);
-
- return $this;
- } elseif (isset($attribute) and isset($value)) {
- if ($attribute == 'class') {
- $this->attributes['class'] = $this->builder->formatGroupClass(['class' => $value], $this->attributes);
- } else {
- $this->attributes[$attribute] = $value;
- }
-
- return $this;
- }
-
- return isset($this->attributes[$attribute]) ? $this->attributes[$attribute] : null;
- }
-
- /**
- * Generates a valid URL for the menu item.
- *
- * @return string
- */
- public function url()
- {
- if (! is_null($this->link)) {
- if ($this->link->href) {
- return $this->link->href;
- }
-
- return $this->builder->dispatch($this->link->path);
- }
- }
-
- /**
- * Prepends HTML to the item.
- *
- * @param string $html
- * @return \Caffeinated\Menus\Item
- */
- public function prepend($html)
- {
- $this->title = $html.' '.$this->title;
-
- return $this;
- }
-
- /**
- * Appends HTML to the item.
- *
- * @param string $html
- * @return \Caffeinated\Menus\Item
- */
- public function append($html)
- {
- $this->title = $this->title.' '.$html;
-
- return $this;
- }
-
- /**
- * Appends the specified icon to the item.
- *
- * @param string $icon
- * @param string $type Can be either "fontawesome" or "glyphicon"
- * @return \Caffeinated\Menus\Item
- */
- public function icon($icon, $type = 'fontawesome')
- {
- switch ($type) {
- case 'fontawesome':
- $html = '';
- break;
-
- case 'glyphicon':
- $html = '';
- break;
-
- case 'entypo':
- $html = '';
- break;
-
- default:
- $html = '';
- break;
- }
-
- return $this->data('icon', $html);
- }
-
- /**
- * Return the title with the icon prepended automatically.
- *
- * @return string
- */
- public function prependIcon()
- {
- return $this->prepend($this->data('icon'));
- }
-
- /**
- * Return the title with the icon appended automatically.
- *
- * @return string
- */
- public function appendIcon()
- {
- return $this->append($this->data('icon'));
- }
-
- /**
- * Insert a divider after the item.
- *
- * @param array $attributes
- * @return void
- */
- public function divide($attributes = array())
- {
- $attributes['class'] = $this->builder->formatGroupClass($attributes, ['class' => 'divider']);
-
- $this->divider = $attributes;
-
- return $this;
- }
-
- /**
- * Determines if the menu item has children.
- *
- * @return bool
- */
- public function hasChildren()
- {
- return count($this->builder->whereParent($this->id)) or false;
- }
-
- /**
- * Returns all children underneath the menu item.
- *
- * @return \Caffeinated\Menus\Collection
- */
- public function children()
- {
- return $this->builder->whereParent($this->id);
- }
-
- /**
- * Set or get an item's metadata.
- *
- * @param mixed
- * @return string|\Caffeinated\Menus\Item
- */
- public function data()
- {
- $args = func_get_args();
-
- if (isset($args[0]) and is_array($args[0])) {
- $this->data = array_merge($this->data, array_change_key_case($args[0]));
-
- return $this;
- } elseif (isset($args[0]) and isset($args[1])) {
- $this->data[strtolower($args[0])] = $args[1];
-
- return $this;
- } elseif (isset($args[0])) {
- return isset($this->data[$args[0]]) ? $this->data[$args[0]] : null;
- }
-
- return $this->data;
- }
-
- /**
- * Decide if the item should be active.
- *
- * @return null
- */
- public function checkActiveStatus()
- {
- $path = ltrim(parse_url($this->url(), PHP_URL_PATH), '/');
- $requestPath = Request::path();
-
- if ($this->builder->config['rest_base']) {
- $base = (is_array($this->builder->config['rest_base'])) ? implode('|', $this->builder->config['rest_base']) : $this->builder->conf['rest_base'];
-
- list($path, $requestPath) = preg_replace('@^('.$base.')/@', '', [$path, $requestPath], 1);
- }
-
- if ($this->url() == Request::url() || $this->url() == \URL::secure(Request::path())) {
- $this->activate();
- }
- }
-
- public function activate(Item $item = null)
- {
- $item = (is_null($item)) ? $this : $item;
-
- $item->active();
-
- $item->data('active', true);
-
- if ($item->parent) {
+ /**
+ * @var \Caffeinated\Menus\Builder
+ */
+ protected $builder;
+
+ /**
+ * @var int
+ */
+ public $id;
+
+ /**
+ * @var string
+ */
+ public $title;
+
+ /**
+ * @var string
+ */
+ public $slug;
+
+ /**
+ * @var array
+ */
+ public $divider = array();
+
+ /**
+ * @var int
+ */
+ public $parent;
+
+ /**
+ * @var array
+ */
+ protected $data = array();
+
+ /**
+ * @var array
+ */
+ public $attributes = array();
+
+ /**
+ * Constructor.
+ *
+ * @param \Caffeinated\Menus\Builder $builder
+ * @param int $id
+ * @param string $title
+ * @param array|string $options
+ */
+ public function __construct($builder, $id, $title, $options)
+ {
+ $this->builder = $builder;
+ $this->id = $id;
+ $this->title = $title;
+ $this->slug = camel_case(str_slug($title, ' '));
+ $this->attributes = $this->builder->extractAttributes($options);
+ $this->parent = (is_array($options) and isset($options['parent'])) ? $options['parent'] : null;
+
+ $this->configureLink($options);
+ }
+
+ public function builder()
+ {
+ return $this->builder;
+ }
+
+ /**
+ * Configures the link for the menu item.
+ *
+ * @param array|string $options
+ * @return null
+ */
+ public function configureLink($options)
+ {
+ if (! is_array($options)) {
+ $path = ['url' => $options];
+ } elseif (isset($options['raw']) and $options['raw'] == true) {
+ $path = null;
+ } else {
+ $path = array_only($options, ['url', 'route', 'action', 'secure']);
+ }
+
+ if (! is_null($path)) {
+ $path['prefix'] = $this->builder->getLastGroupPrefix();
+ }
+
+ $this->link = isset($path) ? new Link($path) : null;
+
+ $this->checkActiveStatus();
+ }
+
+ /**
+ * Adds a sub item to the menu.
+ *
+ * @param string $title
+ * @param array|string $options
+ * @return \Caffeinated\Menus\Item
+ */
+ public function add($title, $options = '')
+ {
+ if (! is_array($options)) {
+ $url = $options;
+ $options = array();
+ $options['url'] = $url;
+ }
+
+ $options['parent'] = $this->id;
+
+ return $this->builder->add($title, $options);
+ }
+
+ /**
+ * Fetch the formatted attributes for the item in HTML.
+ *
+ * @return string
+ */
+ public function attributes()
+ {
+ return $this->builder->attributes($this->attributes);
+ }
+
+ /**
+ * Get all attributes.
+ *
+ * @return array
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Assign or fetch the desired attribute.
+ *
+ * @param array|string $attribute
+ * @param string $value
+ * @return mixed
+ */
+ public function attribute($attribute, $value = null)
+ {
+ if (isset($attribute) and is_array($attribute)) {
+ if (array_key_exists('class', $attribute)) {
+ $this->attributes['class'] = $this->builder->formatGroupClass(['class' => $attribute['class']], $this->attributes);
+ unset($attribute['class']);
+ }
+
+ $this->attributes = array_merge($this->attributes, $attribute);
+
+ return $this;
+ } elseif (isset($attribute) and isset($value)) {
+ if ($attribute == 'class') {
+ $this->attributes['class'] = $this->builder->formatGroupClass(['class' => $value], $this->attributes);
+ } else {
+ $this->attributes[$attribute] = $value;
+ }
+
+ return $this;
+ }
+
+ return isset($this->attributes[$attribute]) ? $this->attributes[$attribute] : null;
+ }
+
+ /**
+ * Generates a valid URL for the menu item.
+ *
+ * @return string
+ */
+ public function url()
+ {
+ if (! is_null($this->link)) {
+ if ($this->link->href) {
+ return $this->link->href;
+ }
+
+ return $this->builder->dispatch($this->link->path['url']);
+ }
+ }
+
+ /**
+ * Prepends HTML to the item.
+ *
+ * @param string $html
+ * @return \Caffeinated\Menus\Item
+ */
+ public function prepend($html)
+ {
+ $this->title = $html.' '.$this->title;
+
+ return $this;
+ }
+
+ /**
+ * Appends HTML to the item.
+ *
+ * @param string $html
+ * @return \Caffeinated\Menus\Item
+ */
+ public function append($html)
+ {
+ $this->title = $this->title.' '.$html;
+
+ return $this;
+ }
+
+ /**
+ * Appends the specified icon to the item.
+ *
+ * @param string $icon
+ * @param string $type Can be either "fontawesome" or "glyphicon"
+ * @return \Caffeinated\Menus\Item
+ */
+ public function icon($icon, $type = 'fontawesome')
+ {
+ switch ($type) {
+ case 'fontawesome':
+ $html = '';
+ break;
+
+ case 'glyphicon':
+ $html = '';
+ break;
+
+ case 'entypo':
+ $html = '';
+ break;
+
+ default:
+ $html = '';
+ break;
+ }
+
+ return $this->data('icon', $html);
+ }
+
+ /**
+ * Return the title with the icon prepended automatically.
+ *
+ * @return string
+ */
+ public function prependIcon()
+ {
+ return $this->prepend($this->data('icon'));
+ }
+
+ /**
+ * Return the title with the icon appended automatically.
+ *
+ * @return string
+ */
+ public function appendIcon()
+ {
+ return $this->append($this->data('icon'));
+ }
+
+ /**
+ * Insert a divider after the item.
+ *
+ * @param array $attributes
+ * @return void
+ */
+ public function divide($attributes = array())
+ {
+ $attributes['class'] = $this->builder->formatGroupClass($attributes, ['class' => 'divider']);
+
+ $this->divider = $attributes;
+
+ return $this;
+ }
+
+ /**
+ * Determines if the menu item has children.
+ *
+ * @return bool
+ */
+ public function hasChildren()
+ {
+ return count($this->builder->whereParent($this->id)) or false;
+ }
+
+ /**
+ * Returns all children underneath the menu item.
+ *
+ * @return \Caffeinated\Menus\Collection
+ */
+ public function children()
+ {
+ return $this->builder->whereParent($this->id);
+ }
+
+ /**
+ * Set or get an item's metadata.
+ *
+ * @param mixed
+ * @return string|\Caffeinated\Menus\Item
+ */
+ public function data()
+ {
+ $args = func_get_args();
+
+ if (isset($args[0]) and is_array($args[0])) {
+ $this->data = array_merge($this->data, array_change_key_case($args[0]));
+
+ return $this;
+ } elseif (isset($args[0]) and isset($args[1])) {
+ $this->data[strtolower($args[0])] = $args[1];
+
+ return $this;
+ } elseif (isset($args[0])) {
+ return isset($this->data[$args[0]]) ? $this->data[$args[0]] : null;
+ }
+
+ return $this->data;
+ }
+
+ /**
+ * Decide if the item should be active.
+ *
+ * @return null
+ */
+ public function checkActiveStatus()
+ {
+ $path = ltrim(parse_url($this->url(), PHP_URL_PATH), '/');
+ $requestPath = Request::path();
+
+ if ($this->builder->config['rest_base']) {
+ $base = (is_array($this->builder->config['rest_base'])) ? implode('|', $this->builder->config['rest_base']) : $this->builder->conf['rest_base'];
+
+ list($path, $requestPath) = preg_replace('@^('.$base.')/@', '', [$path, $requestPath], 1);
+ }
+
+ if ($this->url() == Request::url() || $this->url() == \URL::secure(Request::path())) {
+ $this->activate();
+ }
+ }
+
+ public function activate(Item $item = null)
+ {
+ $item = (is_null($item)) ? $this : $item;
+
+ $item->active();
+
+ $item->data('active', true);
+
+ if ($item->parent) {
$parent = $this->builder->whereId($item->parent)->first();
$parent->attributes['class'] = $parent->builder->formatGroupClass(['class' => 'opened'], $parent->attributes);
- $this->activate($parent);
- }
- }
-
- public function active($pattern = null)
- {
- if (! is_null($pattern)) {
- $pattern = ltrim(preg_replace('/\/\*/', '(/.*)?', $pattern), '/');
-
- if (preg_match("@{$pattern}\z@", Request::path())) {
- $this->activate();
- }
-
- return $this;
- }
-
- $this->attributes['class'] = $this->builder->formatGroupClass(['class' => 'active'], $this->attributes);
-
- return $this;
- }
-
- /**
- * Returns bool value if item is active or not.
- *
- * @return bool
- */
- public function isActive()
- {
- return $this->data('active');
- }
-
- public function can($permissions)
- {
- return $this->data('can', $permissions);
- }
-
- public function canAtLeast($permissions)
- {
- return $this->data('canatleast', $permissions);
- }
-
- /**
- * Return either a property or attribute item value.
- *
- * @param string $property
- * @return string
- */
- public function __get($property)
- {
- if (property_exists($this, $property)) {
- return $this->$property;
- }
-
- return $this->data($property);
- }
+ $this->activate($parent);
+ }
+ }
+
+ public function active($pattern = null)
+ {
+ if (! is_null($pattern)) {
+ $pattern = ltrim(preg_replace('/\/\*/', '(/.*)?', $pattern), '/');
+
+ if (preg_match("@{$pattern}\z@", Request::path())) {
+ $this->activate();
+ }
+
+ return $this;
+ }
+
+ $this->attributes['class'] = $this->builder->formatGroupClass(['class' => 'active'], $this->attributes);
+
+ return $this;
+ }
+
+ /**
+ * Returns bool value if item is active or not.
+ *
+ * @return bool
+ */
+ public function isActive()
+ {
+ return $this->data('active');
+ }
+
+ public function can($permissions)
+ {
+ return $this->data('can', $permissions);
+ }
+
+ public function canAtLeast($permissions)
+ {
+ return $this->data('canatleast', $permissions);
+ }
+
+ /**
+ * Return either a property or attribute item value.
+ *
+ * @param string $property
+ * @return string
+ */
+ public function __get($property)
+ {
+ if (property_exists($this, $property)) {
+ return $this->$property;
+ }
+
+ return $this->data($property);
+ }
}