Repository: vespakoen/menu
Branch: master
Commit: a3922c07c5ae
Files: 24
Total size: 68.7 KB
Directory structure:
gitextract_dkc3rpkb/
├── .gitignore
├── .travis.yml
├── README.md
├── composer.json
├── phpdoc.dist.xml
├── phpunit.xml.dist
├── src/
│ ├── Menu/
│ │ ├── Items/
│ │ │ ├── Contents/
│ │ │ │ ├── Link.php
│ │ │ │ └── Raw.php
│ │ │ ├── Item.php
│ │ │ └── ItemList.php
│ │ ├── Menu.php
│ │ ├── MenuHandler.php
│ │ ├── MenuServiceProvider.php
│ │ └── Traits/
│ │ ├── Content.php
│ │ └── MenuObject.php
│ └── config/
│ └── config.php
├── start.php
└── tests/
├── ItemListTest.php
├── ItemTest.php
├── LinkTest.php
├── MenuHandlerTest.php
├── MenuTest.php
├── RawTest.php
└── _start.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
vendor
data
================================================
FILE: .travis.yml
================================================
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
sudo: false
before_script:
- composer update
================================================
FILE: README.md
================================================
# Menu
[](http://travis-ci.org/vespakoen/menu)
[](https://packagist.org/packages/vespakoen/menu)
[](https://packagist.org/packages/vespakoen/menu)
[](https://packagist.org/packages/vespakoen/menu)
[](https://packagist.org/packages/vespakoen/menu)
[API Docs](http://vespakoen.github.io/menu/)
Are you the type of person that writes menus by hand in view files or do you find yourself looking for the best place to store links to pages on your website? then Menu is for you!
# Quick overview example
```php
$menu = Menu::handler('mailbox');
// items
$menu
->add('contacts', 'Contacts')
->add('inbox', 'Inbox')
->raw(null, null, ['class' => 'divider'])
->add('folders', 'Folders', Menu::items()
->prefixParents()
->add('urgent', 'Urgent') // with prefix: /folders/urgent
->add('sent', 'Sent')
->add('deleted', 'Deleted')
);
// styling
$menu
->addClass('nav navbar-nav')
->getItemsByContentType(Menu\Items\Contents\Link::class)
->map(function($item) {
if ( $item->isActive() ) {
$item->addClass('active');
}
});
```
`{!! $menu !!}` will output:
```html
<ul class="nav navbar-nav">
<li class="active"> <!-- current element in laravel, detected by library -->
<a href="http://myapp.com/contacts">Contacts</a>
</li>
<li>
<a href="http://myapp.com/inbox">Inbox</a>
</li>
<li class="divider"></li>
<li>
<a href="http://myapp.com/folders">Folders</a>
<ul>
<li>
<a href="http://myapp.com/folders/urgent">Urgent</a>
</li>
<li>
<a href="http://myapp.com/folders/sent">Sent</a>
</li>
<li>
<a href="http://myapp.com/folders/deleted">Deleted</a>
</li>
</ul>
</li>
</ul>
```
# Key concepts
## Item lists
An item list is what a menu is all about and it should be pretty self explanatory because it simply stores a list of items.
there are some configurations available for an item list.
You can, for example set the HMTL element that will be used to render the list, prefix every item in the list with all the parent's url segments, and a lot more. We will explore these options later.
## Menu handlers
Menu handlers allow us to create and interact with item lists and act as a place to store and retrieve our menus.
Because we are able to interact with multiple item lists at the same time some interesting possibilities become available to us.
## Items
The Menu package has 2 types of items available out of the box.
- Link
For creating links to other pages
- Raw
Be free to add anything you like in the item.
This type is usually used for dividers, titles etc.
The HTML element and attributes for the item can also be changed, more on this topic later.
# Installing
## Laravel 3
Install Menu via the artisan command line tool. Open the terminal and navigate to your Laravel project's root.
Now type the following command :
```shell
php artisan bundle:install menu
```
To let Laravel know the Laravel Menu package should be started, open up `application/packages.php` and add the following lines to the packages array.
```php
'menu' => array('auto' => true),
```
## Laravel 4
Add this to your `composer.json` file's `"require"` :
```json
"vespakoen/menu": "2.*"
```
And add the following to your `app/config/app.php` file :
- In the Service Providers array : `'Menu\MenuServiceProvider',`
- In the aliases array : `'Menu' => 'Menu\Menu',`
## Laravel 5
Add this to your `composer.json` file's `"require"` :
```json
"vespakoen/menu": "3.*"
```
And add the following to your `config/app.php` file :
- In the Service Providers array : `'Menu\MenuServiceProvider',`
- In the aliases array : `'Menu' => 'Menu\Menu',`
Lastly, run the following from your project's root dir:
```
php artisan vendor:publish
```
# Basic usage
First, let's load some pages into the menu.
We will do this by utilising the `hydrate` method.
```php
Menu::handler('main')->hydrate(function()
{
return Page::with('translation')
->where('group', '=', 'main')
->get();
},
function($children, $item)
{
$children->add($item->translation->slug, $item->translation->name, Menu::items($item->as));
});
/* the hydrate method takes these arguments
$resolver Closure A callback to resolve results
$decorator Closure A callback that gets called for every result fetched from the resolver with the corresponding ItemList and result as the arguments
$idField integer (default = 'id') the property on the result that contains the id
$parentIdField integer (default = 'parent_id') the property on the result that contains the parent id
$parentId integer (default = 0) the parentId to start hydrating from
*/
```
Now that we have loaded our pages into the menu, and even identified every menu item with a name (via `Menu::items($item->as)`) a lot of options are available to us.
Find a node by it's name and add a subitem.
```php
Menu::find('users')
->add('users/create', 'Create new user');
```
Add some properties to the root node
```php
Menu::handler('main')
->addClass('nav navbar-nav');
```
Get all `ItemList`s at a certain depth and add a class
```php
Menu::handler('main')
->getItemListsAtDepth(0)
->addClass('level-1');
```
Get all `ItemList`s at a depth range and change the element
```php
Menu::handler('main')
->getItemListsAtDepthRange(0,2)
->setElement('div');
```
Get all `Item`s at a certain depth and add a class
```php
Menu::handler('main')
->getItemsAtDepth(0)
->addClass('level-1');
```
Get `Item`s by it's content type and use the map function to walk over the results and perform actions based on gathered information
```php
Menu::handler('main')
->getItemsByContentType('Menu\Items\Contents\Link')
->map(function($item)
{
if($item->isActive() && $item->hasChildren())
{
$item->addClass('is-active-link-with-children');
}
if($item->getContent()->getUrl() == 'home')
{
$item->addClass('is-home');
}
});
```
Get all `ItemList`s and add a class to them if they have children
```php
Menu::handler('main')
->getAllItemLists()
->map(function($itemList)
{
if($itemList->hasChildren())
{
$itemList->addClass('has-children');
}
});
```
# Breadcrumbs
Breadcrumb hell is a thing of the past.
Bootstrap ready breadcrums are as easy as this
```php
Menu::handler('main')
->breadcrumbs()
->setElement('ol')
->addClass('breadcrumb');
```
The breadcrumbs method searches all handlers and returns a plain old ItemList, that you can manipulate.
If you call the breadcrumbs method directly on the Menu class, it will search all your handlers for breadcrumbs, and by default will return the first match.
However, there might be cases where you want to choose the breadcrumbs out of the ones it found, for this you can provide a callback method as the first argument.
And example is shown below:
```php
Menu::breadcrumbs(function($itemLists)
{
return $itemLists[0]; // returns first match
})
->setElement('ol')
->addClass('breadcrumb');
```
# Diving deeper
The Laravel Menu packages consists of a couple of classes, but you can interact with all of them via the _Menu_ class.
Let's take a look at the **handler** method. it takes a string or an array as the only argument, the string(s) given are the names for the item lists we want to retrieve.
If an itemlist we asked for didn't exist yet, it will create it for us.
After the menu class has found and created the item lists we want, it will hand back a menuhandler that handles the item lists we asked for.
```php
// Get a MenuHandler instance that handles an ItemList named "main"
Menu::handler('main');
```
When we call a method on this menu handler, it will simply forward the call to all the item lists that it handles.
In order to find out what we can do now that we have a handler, we need to take a look at the methods on the ItemList class.
The _ItemList_ class has a method called **add** that you are probably going to use a lot. It adds an _Item_ of type "link" to the _ItemList_.
```php
Menu::handler('main')->add('home', 'Homepage');
/* The add method takes these arguments
$url string The URL to another page
$title string The visible string on the link
$children (default = null) ItemList (optional) The children of this page
$link_attributes (default = array()) array (optional) HTML attributes for the <a> element
$item_attributes (default = array()) array (optional) HTML attributes for the list element (usually <li>)
$item_element (default = 'li') string (optional) The type of the list element
*/
```
Let's take a look at the **raw** method, for adding "anything" to the list.
```php
Menu::handler('main')->raw('<img src="img/seperator.gif">');
/* The raw method takes these arguments
$html string The contents of the item
$children (default = null) ItemList (optional) The children of this item
$item_attributes (default = array()) array (optional) HTML attributes for the list element (usually <li>)
$item_element (default = 'li') string (optional) The type of the list element
*/
```
Great! Now that we have learned how to add items to an item list, let's have a look at how we add children to a item.
Every item can have children, the children object is just another _ItemList_. As we have seen before, we can create item lists via the **handler** method, but this method returns a _MenuHandler_, making it unusable for item children.
So what do we use? the **items** method returns a fresh _ItemList_ object. Let's have a look.
```php
Menu::handler('main')
->add('home', 'Homepage', Menu::items()
->add('sub-of-home', 'Sub of homepage'));
/* The items method takes these arguments
$name (default = null) string (optional) The name (=identifier) of this ItemList
$attributes (default = array()) array (optional) HTML attributes for the ItemList element (usually <ul>)
$element (default = 'ul') string (optional) The type of the ItemList element
*/
```
So now we know how to build menus, add items and items with children.
Let's find out how to display the menus.
The MenuHandler and _ItemList_ classes implement the "__toString" method, that calls the **render** method.
This means you can simply echo the MenuHandler or _ItemList_ object.
Here is an example to make things more clear.
```php
echo Menu::handler('main');
// Is the same as
echo Menu::handler('main')->render();
```
Now that we have the basics under control, we are going to explore some other cool features this package provides.
# Class diagram
[](http://rawgithub.com/vespakoen/menu/master/menu-class-diagram.svg)
# Some last words
Thanks for following along and using this package.
Special thanks to @Anahkiasen for refactoring this package and boosting new life into it!
================================================
FILE: composer.json
================================================
{
"name": "vespakoen/menu",
"description": "Managing menus the easy way.",
"keywords": ["menu", "laravel", "laravel 5"],
"license": "MIT",
"authors": [
{
"name": "Koen Schmeets",
"email": "hello@koenschmeets.nl"
}
],
"require": {
"php": ">=5.4.0",
"anahkiasen/underscore-php": "^2.0",
"anahkiasen/html-object": "~1.4",
"illuminate/http": "6.*|^7",
"illuminate/config": "6.*|^7",
"illuminate/container": "6.*|^7"
},
"require-dev": {
"phpunit/phpunit": "4.0",
"orchestra/testbench": "3.0.*"
},
"autoload": {
"psr-0": {
"Menu": "src"
}
},
"minimum-stability": "stable"
}
================================================
FILE: phpdoc.dist.xml
================================================
<?xml version="1.0" encoding="UTF-8" ?>
<phpdoc>
<parser>
<target>data/output</target>
</parser>
<transformer>
<target>data/output</target>
</transformer>
<files>
<directory>src</directory>
<directory>vendor/anahkiasen/html-object/src</directory>
<directory>vendor/anahkiasen/underscore-php/src</directory>
</files>
</phpdoc>
================================================
FILE: phpunit.xml.dist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="true"
syntaxCheck="false">
<testsuites>
<testsuite name="Menu Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory>vendor</directory>
</blacklist>
</filter>
</phpunit>
================================================
FILE: src/Menu/Items/Contents/Link.php
================================================
<?php
namespace Menu\Items\Contents;
use HtmlObject\Traits\Helpers;
use HtmlObject\Link as HtmlLink;
use Menu\Menu;
use Menu\Traits\Content;
use Underscore\Methods\StringsMethods;
/**
* A Link in an Item
*/
class Link extends HtmlLink
{
/**
* URL segments that you want to hide from the
* generated URL when using ->prefixParents()
*
* @var array
*/
private $hidden = array(
'#',
'javascript:',
);
/**
* The link's URL
*
* @var string
*/
protected $href;
/**
* An array of properties to be injected as attributes
*
* @var array
*/
protected $injectedProperties = array('href');
/**
* Build a new Link
*
* @param string $url Its URL
* @param string $value Its text
* @param array $attributes Facultative attributes
*/
public function __construct($url, $value = null, $attributes = array())
{
$this->attributes = $attributes;
$this->value = $value;
$this->href = $url;
}
/**
* Change the Link's URL
*
* @param string $href An URL
*
* @return Link
*/
public function href($href)
{
$this->href = $href;
return $this;
}
/**
* Get the link's href
*
* @return string the href
*/
public function getUrl()
{
return $this->href;
}
/**
* Break off a chain
*
* @return Item
*/
public function stop()
{
return $this->getParent(1);
}
/**
* Render the Link
*
* @return string
*/
public function render()
{
$this->href = $this->getEvaluatedUrl();
// Don't compote URL if special URL
if (!$this->isSpecialUrl()) {
$this->href = Menu::getContainer()->bound('url')
? Menu::getContainer('url')->to($this->href)
: $this->href;
}
return parent::render();
}
////////////////////////////////////////////////////////////////////
////////////////////////////// HELPERS /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get the content type
*
* @return boolean
*/
public function isLink()
{
return true;
}
/**
* Whether the link is special or not
*
* @return boolean
*/
public function isSpecialUrl()
{
foreach ($this->hidden as $hidden) {
if (StringsMethods::startsWith($this->href, $hidden)) return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
/////////////////////// PREFIXES AND SEGMENTS //////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get the evaluated URL based on the prefix settings
*
* @return string
*/
public function getEvaluatedUrl()
{
$segments = array();
// If the URL is just an hash, don't do shit
if (!$this->getParent() or $this->isSpecialUrl()) {
return $this->href;
}
// Prepend list prefix
$listPrefix = $this->getParent(1)->getOption('item_list.prefix');
if (!is_null($listPrefix)) {
$segments[] = $listPrefix;
}
// Prepend parent item prefix
$prefixParents = $this->getParent(1)->getOption('item_list.prefix_parents');
if ($prefixParents) {
$segments += $this->getParentItemsUrls();
}
// Prepend handler prefix
$prefixHandler = $this->getParent(1)->getOption('item_list.prefix_handler');
if ($prefixHandler) {
$segments[] = $this->getHandlerSegment();
}
$segments[] = $this->href;
return implode('/', $segments);
}
/**
* Get all the parent Items
*
* @return array An array of Items
*/
protected function getParentItems()
{
$parents = array();
$list = $this->getParent(1);
while ($list->getParent()) {
$parents[] = $list->getParent();
$parent = $list->getParent(1);
$list = $parent ? $list->getParent(1) : null;
}
return array_reverse($parents);
}
/**
* Get all the parent Lists
*
* @return array An array of Lists
*/
protected function getParentLists()
{
$parents = array();
$list = $this->getParent(1);
$parent = $list->getParent() ?: null;
$parents[] = $list;
while ($list and $parent) {
$parents[] = $parent;
$list = $parent ?: null;
}
return array_reverse($parents);
}
/**
* Get the handler of the Menu containing this link
*
* @return string
*/
protected function getHandlerSegment()
{
$parentLists = $this->getParentLists();
$handler = array_pop($parentLists);
return $handler->name;
}
/**
* Get the URL of the parent Items
*
* @return array
*/
protected function getParentItemsUrls()
{
$urls = array();
foreach ($this->getParentItems() as $item) {
if (!is_object($item)) continue;
if (
$item->value->isLink() and
!$item->value->isSpecialUrl() and
!is_null($item->value->href)) {
$urls[] = $item->value->href;
}
}
return $urls;
}
}
================================================
FILE: src/Menu/Items/Contents/Raw.php
================================================
<?php
namespace Menu\Items\Contents;
use Menu\Traits\Content;
/**
* Raw content in an Item
*/
class Raw extends Content {}
================================================
FILE: src/Menu/Items/Item.php
================================================
<?php
namespace Menu\Items;
use HtmlObject\Element;
use HtmlObject\Traits\Tag;
use Menu\Menu;
use Menu\Traits\Content;
use Menu\Traits\MenuObject;
use Menu\MenuHandler;
use Underscore\Methods\ArraysMethods;
/**
* An Item in a list
*/
class Item extends MenuObject
{
/**
* Array of patterns to match the active state
*
* @var array
*/
protected $patterns = array();
/**
* Create a new item instance
*
* @param ItemList $parent The parent
* @param Tag $value The content
* @param array $children Facultative children ItemLists
* @param array $element The Item element
* @param string $beforeContent String to add before the content
* @param string $afterContent String to add after the content
*/
public function __construct(ItemList $parent, Tag $value, $children = null, $element = null, $beforeContent = null, $afterContent = null)
{
$this->parent = $parent;
$this->children = is_null($children) ? new ItemList() : $children;
$this->element = $element;
$this->beforeContent = $beforeContent;
$this->afterContent = $afterContent;
// Create content
$this->value = $value->setParent($this);
}
/**
* Add an pattern to $patterns array
*
* @param string|array $pattern The pattern
* @param string $name Its name
*
*/
public function setActivePatterns($pattern, $name = null)
{
if (!$name) $name = sizeof($this->patterns);
$this->patterns[$name] = $pattern;
}
/**
* Break off a chain
*
* @return ItemList
*/
public function stop()
{
return $this->getParent();
}
/**
* Get the Item's content
*
* @return Content
*/
public function getContent()
{
return $this->value;
}
/**
* Set the value to be inserted before the item's content
*
* @param string $value The value to insert
*/
public function setBeforeContent($value)
{
$this->beforeContent = $value;
return $this;
}
/**
* Set the value to be inserted after the item's content
*
* @param string $value The value to insert
*/
public function setAfterContent($value)
{
$this->beforeContent = $value;
return $this;
}
/**
* Set the Item's element
*
* @param string $element
*/
public function setElement($element = null)
{
$this->setOption('item.element', $element);
return $this;
}
/**
* Get the Item's element
*
* @return string
*/
public function getElement()
{
if(is_null($this->element))
{
return $this->getOption('item.element');
}
return $this->element;
}
/**
* Render the item
*
* @param array
*
* @return string
*/
public function render($depth = 0)
{
// Add the active classes
$value = is_null($this->beforeContent) ? '' : $this->beforeContent;
$value .= $this->value->render();
$value .= is_null($this->afterContent) ? '' : $this->afterContent;
$this->addActiveClasses();
// Render children if any
if ($this->hasChildren()) {
$value .= $this->children->render($depth);
}
// Facultatively render an element around the item
$element = $this->getElement();
if ($element) $value = Element::create($element, $value, $this->attributes)->render();
return html_entity_decode($value, ENT_QUOTES, 'UTF-8');
}
////////////////////////////////////////////////////////////////////
///////////////////////// PUBLIC INTERFACE /////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Check if this item is active
*
* @return boolean
*/
public function isActive()
{
if( ! $this->value->isLink()) {
return false;
}
return
trim($this->getUrl(), '/') == trim($this->getRequest()->getPathInfo(), '/') or
$this->getUrl() == $this->getRequest()->fullUrl() or
$this->getUrl() == $this->getRequest()->url() or
$this->hasActivePatterns();
}
public function hasChildren()
{
return count($this->children->getChildren()) > 0;
}
/**
* Check if this item has an active pattern
*
* @return boolean
*/
protected function hasActivePatterns()
{
foreach ($this->patterns as $pattern) {
$path = $this->getRequest()->getPathInfo();
if (is_array($pattern)) {
foreach ($pattern as $p)
$isActive = preg_match('/'.$p.'/i', $path);
} else {
$isActive = preg_match('/'.$pattern.'/i', $path);
}
if($isActive) return true;
}
return false;
}
/**
* Check if this item has an active child
*
* @return boolean
*/
public function hasActiveChild()
{
if (!$this->hasChildren()) {
return false;
}
foreach ($this->children->getChildren() as $child) {
if ($child->isActive()) {
return true;
}
if ($child->hasChildren()) {
return $child->hasActiveChild();
}
}
return false;
}
/**
* Get the url of the Item's content
*
* @return string
*/
protected function getUrl()
{
return $this->value->isLink() ? $this->value->getEvaluatedUrl() : null;
}
////////////////////////////////////////////////////////////////////
////////////////////////////// HELPERS /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Add the various active classes to an array of attributes
*/
private function addActiveClasses()
{
if ($this->isActive()) {
$this->addClass($this->getOption('item.active_class'));
}
if ($this->hasActiveChild()) {
$this->addClass($this->getOption('item.active_child_class'));
}
}
////////////////////////////////////////////////////////////////////
//////////////////////////// DEPENDENCIES //////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get the Request instance
*
* @return Request
*/
public function getRequest()
{
return Menu::getContainer('request');
}
}
================================================
FILE: src/Menu/Items/ItemList.php
================================================
<?php
namespace Menu\Items;
use Exception;
use HtmlObject\Element;
use Menu\Menu;
use Menu\MenuHandler;
use Menu\Items\Contents\Link;
use Menu\Items\Contents\Raw;
use Menu\Traits\MenuObject;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Underscore\Methods\ArraysMethods;
/**
* A container for Items
*/
class ItemList extends MenuObject
{
/**
* The name of this ItemList
*
* @var string
*/
public $name;
/**
* Create a new Item List instance
*
* @param string $name The ItemList's name
* @param array $attributes Attributes for the ItemList's HMTL element
* @param string $element The HTML element for the ItemList
*
* @return void
*/
public function __construct($items = array(), $name = null, $attributes = array(), $element = null)
{
$this->children = $items;
$this->name = $name;
$this->attributes = $attributes;
$this->element = $element;
}
/**
* Get the last Item
*
* @return Item
*/
public function onItem()
{
return $this->children[sizeof($this->children) - 1];
}
////////////////////////////////////////////////////////////////////
///////////////////////// PUBLIC INTERFACE /////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Set a particular option in the array
*
* @param string $option The option
* @param mixed $value Its new value
*
* @return MenuObject
*/
public function setOption($option, $value)
{
// forward item config values to the items
if(Str::startsWith($option, 'item.')) {
foreach($this->children as $child) {
$child->setOption($option, $value);
}
}
elseif(Str::startsWith($option, 'item_list.')) {
$this->options = ArraysMethods::set($this->options, $option, $value);
}
else
{
Menu::setOption($option, $value);
}
return $this;
}
/**
* Add a link item to the ItemList instance.
*
* <code>
* // Add a item to the default menu
* Menu::add('home', 'Homepage');
*
* // Add a item with a subitem to the default menu
* Menu::add('home', 'Homepage', Menu::items()->add('home/sub', 'Subitem'));
*
* // Add a item with attributes for the item's HTML element
* Menu::add('home', 'Homepage', null, array('class' => 'fancy'));
* </code>
*
* @param string $url Url of the link
* @param string $value (H)T(ML) inside of the link
* @param ItemList $children Children
* @param array $linkAttributes Attributes for the link
* @param array $itemAttributes Attributes for the item
* @param string $itemElement The element for the item
* @param string $beforeContent String to add before the link
* @param string $afterContent String to add after the link
*
* @return ItemList
*/
public function add($url, $value, $children = null, $linkAttributes = array(), $itemAttributes = array(), $itemElement = null, $beforeContent = null, $afterContent = null)
{
$content = new Link($url, $value, $linkAttributes);
$item = $this->addContent($content, $children, $itemAttributes, $itemElement, $beforeContent, $afterContent);
return $this;
}
/**
* Add a raw html item to the ItemList instance.
*
* <code>
* // Add a raw item to the default main menu
* Menu::raw('<img src="img/seperator.gif">');
* </code>
*
* @param string $raw The raw content
* @param ItemList $children Children
* @param array $itemAttributes The item attributes
* @param string $itemElement The item element
* @param string $beforeContent String to add before the raw content
* @param string $afterContent String to add after the raw content
*
* @return ItemList
*/
public function raw($raw, $children = null, $itemAttributes = array(), $itemElement = null, $beforeContent = null, $afterContent = null)
{
$content = new Raw($raw);
$item = $this->addContent($content, $children, $itemAttributes, $itemElement, $beforeContent, $afterContent);
return $this;
}
/**
* Add content to the ItemList
*
* @param Content $content Content object
* @param ItemList $children Children
* @param array $itemAttributes Attributes for the item (li)
* @param string $itemElement Element for the item (li is default)
* @param string $beforeContent String to add before the content
* @param string $afterContent String to add after the content
*/
public function addContent($content, $children = null, $itemAttributes = array(), $itemElement = null, $beforeContent = null, $afterContent = null)
{
$item = new Item($this, $content, $children, $itemElement, $beforeContent, $afterContent);
$item->setAttributes($itemAttributes);
// Set Item as parent of its children
if (!is_null($children)) {
$children->setParent($item);
}
$this->setChild($item);
return $item;
}
/**
* Add an active pattern to the ItemList instance.
*
* <code>
* // Add a item to the default menu and set an active class for /user/5/edit
* Menu::add('user', 'Users')->activePattern('\/user\/\d\/edit');
* </code>
*
* @param string $pattern
*
* @return ItemList
*/
public function activePattern($pattern)
{
$pattern = (array) $pattern;
$item = end($this->children);
$item->setActivePatterns($pattern);
return $this;
}
/**
* Add menu items to another ItemList.
*
* <code>
* // Attach menu items to the default MenuHandler
* Menu::attach(Menu::items()->add('home', 'Homepage'));
* </code>
*
* @param ItemList $itemList
*
* @return ItemList
*/
public function attach(ItemList $itemList)
{
$this->nestChildren($itemList->getChildren());
return $this;
}
/**
* Set the name for this ItemList
*
* @param string $name
*
* @return ItemList
*/
public function name($name)
{
$this->name = $name;
return $this;
}
/**
* Get the name of the ItemList
*
* @return string Name of the ItemList
*/
public function getName()
{
return $this->name;
}
////////////////////////////////////////////////////////////////////
///////////////////////////// PREFIXES /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Prefix this ItemList with a string
*
* @param string $prefix
*
* @return ItemList
*/
public function prefix($prefix)
{
$this->setOption('item_list.prefix', $prefix);
return $this;
}
/**
* Prefix this ItemList with the parent ItemList(s) name(s)
*
* @param boolean $prefixParents
*
* @return ItemList
*/
public function prefixParents($prefixParents = true)
{
$this->setOption('item_list.prefix_parents', $prefixParents);
return $this;
}
/**
* Prefix this ItemList with the name of the ItemList at the very top of the tree
*
* @param boolean $prefixMenuHandler
*
* @return ItemList
*/
public function prefixMenuHandler($prefixMenuHandler = true)
{
$this->setOption('item_list.prefix_handler', $prefixMenuHandler);
return $this;
}
/**
* Set the Item's element
*
* @param string $element
*/
public function setElement($element = null)
{
$this->element = $element;
return $this;
}
/**
* Get the Item's element
*
* @return string
*/
public function getElement()
{
if (is_null($this->element)) {
return $this->getOption('item_list.element');
}
return $this->element;
}
/**
* Get all items with the depth as key
*
* @return array
*/
public function getItemsWithDepth()
{
return $this->getItemsRecursivelyWithDepth($this->getChildren());
}
/**
* Get all items for an array of items recursively for a specific depth
*
* @return array
*/
protected function getItemsRecursivelyWithDepth($items, $depth = 0)
{
$results = array();
foreach($items as $item)
{
$results[$depth][] = $item;
$subItems = $item->getChildren()
->getChildren();
foreach($this->getItemsRecursivelyWithDepth($subItems, $depth + 1) as $childrenDepth => $children)
{
foreach($children as $child)
{
$results[$childrenDepth][] = $child;
}
}
}
return $results;
}
/**
* Get all itemlists with the depth as key
*
* @return array
*/
public function getItemListsWithDepth()
{
return $this->getItemListsRecursivelyWithDepth($this);
}
/**
* Get all itemlists for an itemlsit recursively for a specific depth
*
* @return array
*/
protected function getItemListsRecursivelyWithDepth($itemList, $depth = 0)
{
$results = array();
$results[$depth][] = $itemList;
$items = $itemList->getChildren();
foreach($items as $item)
{
foreach($this->getItemListsRecursivelyWithDepth($item->getChildren(), $depth + 1) as $childrenDepth => $children)
{
foreach($children as $child)
{
$results[$childrenDepth][] = $child;
}
}
}
return $results;
}
/**
* Get all items
*
* @return \Vespakoen\Menu\MenuHandler
*/
public function getAllItems()
{
$results = array();
foreach($this->getItemsWithDepth() as $depth => $items)
{
foreach($items as $item)
{
$results[] = $item;
}
}
return new MenuHandler($results);
}
/**
* Get items by their content type
*
* @param string $contentType The full object name
*
* @return \VEspakoen\Menu\MenuHandler
*/
public function getItemsByContentType($contentType)
{
$results = array();
$itemList = $this->getAllItems();
foreach($itemList->getMenuObjects() as $item)
{
$content = $item->getContent();
if(get_class($content) == $contentType)
{
$results[] = $item;
}
}
return new MenuHandler($results);
}
/**
* Get all itemlists
*
* @return \Vespakoen\Menu\MenuHandler
*/
public function getAllItemLists()
{
$results = array();
foreach($this->getItemListsWithDepth() as $depth => $items)
{
foreach($items as $item)
{
$results[] = $item;
}
}
return new MenuHandler($results);
}
/**
* Get all itemslists including this one
*
* @return \Vespakoen\Menu\MenuHandler
*/
public function getAllItemListsIncludingThisOne()
{
return $this->getAllItemLists()
->addMenuObject($this);
}
/**
* Get itemlists at a certain depth
*
* @return \Vespakoen\Menu\MenuHandler
*/
public function getItemListsAtDepth($depth)
{
$itemListsWithDepth = $this->getItemListsWithDepth();
if (array_key_exists($depth, $itemListsWithDepth)) {
return new MenuHandler($itemListsWithDepth[$depth]);
}
return new MenuHandler(array());
}
/**
* Get itemlists in a range of depths
*
* @return \Vespakoen\Menu\MenuHandler
*/
public function getItemListsAtDepthRange($from, $to)
{
$itemListsWithDepth = $this->getItemListsWithDepth();
$results = array();
foreach($itemListsWithDepth as $depth => $itemLists)
{
if($depth >= $from && $depth <= $to)
{
foreach($itemLists as $itemList)
{
$results[] = $itemList;
}
}
}
return new MenuHandler($results);
}
/**
* Get all items at a certain depth
*
* @return \Vespakoen\Menu\MenuHandler
*/
public function getItemsAtDepth($depth)
{
$itemsWithDepth = $this->getItemsWithDepth();
if (array_key_exists($depth, $itemsWithDepth)) {
return new MenuHandler($itemsWithDepth[$depth]);
}
return new MenuHandler(array());
}
/**
* Get items in a range of depths
*
* @return \Vespakoen\Menu\MenuHandler
*/
public function getItemsAtDepthRange($from, $to)
{
$itemsWithDepth = $this->getItemsWithDepth();
$results = array();
foreach($itemsWithDepth as $depth => $items)
{
if($depth >= $from && $depth <= $to)
{
foreach($items as $item)
{
$results[] = $item;
}
}
}
return new MenuHandler($results);
}
public function reverse()
{
$this->children = array_reverse($this->children);
return $this;
}
public function findActiveItem()
{
$items = $this->getAllItems()
->getMenuObjects();
// Find the active one
foreach($items as $item) {
if($item->isActive()) {
return $item;
}
}
return null;
}
public function getSubmenu()
{
if($activeItem = $this->findActiveItem())
{
return $activeItem->getChildren();
}
return new ItemList;
}
public function breadcrumbs()
{
// Collect all items
$activeItem = $this->findActiveItem();
$separator = $this->getOption('item_list.breadcrumb_separator');
// Make the breadcrumbs
$itemList = new ItemList(array(), 'breadcrumbs');
// Fill her up if we found the active link
if( ! is_null($activeItem)) {
// Add the found item
$itemList->addContent($activeItem->getContent());
// Loop throught the parents until we hit the root
while($nextItem = $activeItem->getParent()) {
if(is_null($nextItem->getParent())) break;
// Add a separator and the link
if ( ! empty($separator))
{
$itemList->raw($separator);
}
$itemList->addContent($nextItem->getParent()->getContent());
// Set the activeItem for the next iteration
$activeItem = $nextItem->getParent();
}
}
// Correct order
$itemList->reverse();
return $itemList;
}
public function map($callback)
{
array_map($callback, $this->children);
return $this;
}
/**
* Find an itemlist by it's name
*
* @return \Vespakoen\Menu\Items\ItemLists|false
*/
public function findItemListByName($name)
{
$itemLists = $this->getAllItemListsIncludingThisOne()
->getMenuObjects();
foreach($itemLists as $itemList)
{
if($itemList->getName() == $name)
{
return $itemList;
}
}
return false;
}
/**
* Find an itemlist by it's name
*
* alias for findItemListByName
*
* @return \Vespakoen\Menu\Items\ItemLists|false
*/
public function findByName($name)
{
return $this->findItemListByName($name);
}
/**
* Find an itemlist by it's name
*
* alias for findItemListByName
*
* @return \Vespakoen\Menu\Items\ItemLists|false
*/
public function find($name)
{
return $this->findItemListByName($name);
}
/**
* Find an item by an attribute
*
* @return \Vespakoen\Menu\Items\Item|false
*/
public function findItemByAttribute($key, $value)
{
$itemLists = $this->getAllItemListsIncludingThisOne()
->getMenuObjects();
foreach($itemLists as $itemList)
{
if($itemList->getAttibute($key) == $value)
{
return $itemList;
}
}
return false;
}
/**
* Find an item by it's link's URL
*
* @return \Vespakoen\Menu\Items\Item|false
*/
public function findItemByUrl($url)
{
$itemList = $this->getItemsByContentType('Menu\Items\Contents\Link');
foreach($itemList->getChildren() as $item)
{
$content = $item->getContent();
if($content->getUrl() == $url)
{
return $item;
}
}
return false;
}
/**
* Easily create items while looping over DB results
* that have a reference to the parent (usually via parentId)
*
* <code>
* Menu::hydrate(function($parentId)
* {
* return Page::where('parent_id', $parentId)
* ->get();
* },
* function($children, $page)
* {
* $children->add($page->slug, $page->name);
* });
* </code>
*
* @param Closure $resolver the callback to resolve results for a given parentId
* @param Closure $decorator the callback that modifies the ItemList for the given node
* @param integer $idField the id column that matches with the parentId
* @param integer $parentId the parentId to start hydrating from
*
* @return ItemList the
*/
public function hydrate($resolver, $decorator, $idField = 'id', $parentIdField = 'parent_id', $parentId = 0)
{
$items = is_callable($resolver) ? $resolver() : $resolver;
if($items instanceof Collection)
{
$items = $items->all();
}
$itemsForThisLevel = array_filter($items, function($item) use ($parentId, $parentIdField)
{
return $parentId == (is_object($item) ? (isset($item->$parentIdField) ? $item->$parentIdField : 0) : (isset($item[$parentIdField]) ? $item[$parentIdField] : 0));
});
foreach($itemsForThisLevel as $item)
{
// Let the decorator add the item(s) (and maybe set some attributes)
$decorator($this, $item);
// Grab the newest item
$newestItem = end($this->children);
// If there is an item, add hydrate it
if($newestItem)
{
// Grab the newest itemlist
$newestItemList = $newestItem->getChildren();
// Get the id of the item
$parentId = is_object($item) ? $item->$idField : $item[$idField];
// Hydrate the children
$newestItemList->hydrate($items, $decorator, $idField, $parentIdField, $parentId);
}
}
return $this;
}
/**
* Get the evaluated string content of the ItemList.
*
* @param integer $depth The depth at which the ItemList should be rendered
*
* @return string
*/
public function render($depth = 0)
{
if( ! is_int($depth))
{
throw new Exception("The render method doesn't take any arguments anymore, you can now configure your menu via the config file.");
}
// Check for maximal depth
$maxDepth = $this->getOption('max_depth');
if ($maxDepth !== -1 and $depth > $maxDepth) return false;
// Render contained items
$contents = null;
if(count($this->children) == 0)
{
return "";
}
foreach ($this->children as $item) {
$contents .= $item->render($depth + 1);
}
$element = $this->getElement();
if ($element) $contents = Element::create($element, $contents, $this->attributes)->render();
return $contents;
}
}
================================================
FILE: src/Menu/Menu.php
================================================
<?php
namespace Menu;
use Illuminate\Config\FileLoader;
use Illuminate\Config\Repository;
use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Menu\Items\ItemList;
/**
* Basic interface to different components within the package
*/
class Menu
{
/**
* The current IoC container
* @var Container
*/
protected static $container;
/**
* All the registered names and the associated ItemLists
*
* @var array
*/
protected static $itemLists = array();
/**
* Get a MenuHandler.
*
* This method will retrieve ItemLists by name,
* If an ItemList doesn't already exist, it will
* be registered and added to the handler.
*
* <code>
* // Get the menu handler that handles the default name
* $handler = Menu::handler();
*
* // Get a named menu handler for a single name
* $handler = Menu::handler('backend');
*
* // Get a menu handler that handles multiple names
* $handler = Menu::handler(array('admin', 'sales'));
* </code>
*
* @param string|array $names The name this handler should respond to
* @param array $attributes Its attributes
* @param string $element Its element
*
* @return MenuHandler
*/
public static function handler($names = '', $attributes = array(), $element = 'ul')
{
$names = (array) $names;
$itemLists = array();
// Create a new ItemList instance for the names that don't exist yet
foreach ($names as $name) {
if (!array_key_exists($name, static::$itemLists)) {
$itemList = new ItemList(array(), $name, $attributes, $element);
static::setItemList($name, $itemList);
}
else {
$itemList = static::getItemList($name);
}
$itemLists[] = $itemList;
}
// Return a Handler for the item lists
return new MenuHandler($itemLists);
}
/**
* Get a MenuHandler for all registered ItemLists
*
* @return MenuHandler
*/
public static function allHandlers()
{
return new MenuHandler(static::$itemLists);
}
/**
* Erase all menus in memory
*/
public static function reset()
{
static::$itemLists = array();
}
////////////////////////////////////////////////////////////////////
//////////////////////// ITEM LISTS MANAGING ///////////////////////
////////////////////////////////////////////////////////////////////
/**
* Create a new ItemList
*
* @param string $name The name of the ItemList
* @param array $attributes The HTML attributes for the list element
* @param string $element The HTML element for the list (ul or dd)
*
* @return ItemList
*/
public static function items($name = null, $attributes = array(), $element = 'ul')
{
return new ItemList(array(), $name, $attributes, $element);
}
/**
* Store an ItemList in memory
*
* @param string $name The handle to store it to
* @param ItemList $itemList
*
* @return ItemList
*/
public static function setItemList($name, $itemList)
{
static::$itemLists[$name] = $itemList;
return $itemList;
}
/**
* Get an ItemList from the memory
*
* @param string $name The ItemList handle
*
* @return ItemList
*/
public static function getItemList($name = null)
{
if (is_null($name)) return static::$itemLists;
return static::$itemLists[$name];
}
////////////////////////////////////////////////////////////////////
/////////////////////////// MAGIC METHODS //////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Magic Method for calling methods on the default handler.
*
* <code>
* // Call the "render" method on the default handler
* echo Menu::render();
*
* // Call the "add" method on the default handler
* Menu::add('home', 'Home');
* </code>
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public static function __callStatic($method, $parameters = array())
{
return call_user_func_array(array(static::handler(), $method), $parameters);
}
////////////////////////////////////////////////////////////////////
/////////////////////// DEPENDENCY INJECTIONS //////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get the current dependencies
*
* @param string $dependency A dependency to make on the fly
*
* @return Container
*/
public static function getContainer($dependency = null)
{
if (!static::$container) {
$container = new Container;
// Create HTML
$container->bindIf('html', 'LaravelBook\Laravel4Powerpack\HTML');
// Create basic Request instance to use
$container->alias('Symfony\Component\HttpFoundation\Request', 'request');
$container->bindIf('Symfony\Component\HttpFoundation\Request', function() {
return Request::createFromGlobals();
});
static::setContainer($container);
}
// Shortcut for getting a dependency
if ($dependency) {
return static::$container->make($dependency);
}
return static::$container;
}
/**
* Set the Container to use
*
* @param Container $container
*/
public static function setContainer($container)
{
static::$container = $container;
}
/**
* Get an option from the options array
*
* @param string $option The option key
*
* @return mixed Its value
*/
public static function getOption($option = null)
{
if ($option == null) {
return static::getContainer('config')->get('menu');
}
return static::getContainer('config')->get('menu.'.$option);
}
/**
* Set a global option
*
* @param key $option The option
* @param mixed $value Its value
*/
public static function setOption($option, $value)
{
if ($option == null) {
$option = 'config';
}
static::getContainer('config')->set('menu.'.$option, $value);
}
}
================================================
FILE: src/Menu/MenuHandler.php
================================================
<?php
namespace Menu;
use Menu\Items\ItemList;
use Illuminate\Support\Str;
use Exception;
/**
* Handles various instances of ItemList at once
*/
class MenuHandler
{
/**
* The ItemList or Item instances this handler acts on
*
* @var array
*/
protected $menuObjects = array();
public static $override = array(
'add',
'set',
'wrap'
);
public static $responses = array(
'getHandlerFromResults' => array(
'getAllItems',
'getItemsAtDepth',
'getItemsAtDepthRange',
'getItemsByContentType',
'getAllItemLists',
'getSubmenu',
'getItemListsAtDepth',
'getItemListsAtDepthRange',
'onItem',
'getContent',
'stop',
'filter'
),
'getMatchFromResults' => array(
'findItemListByName',
'findActiveItem',
'findByName',
'findItemByUrl',
'find'
),
'getCombinedResults' => array(
'lists'
),
'getCombindedResultsByKey' => array(
'getItemsWithDepth',
'getItemListsWithDepth'
),
'getImplodedResults' => array(
'render'
)
);
/**
* Set the menuobjects on which this menu should act
*
* @param array $menuObjects The menuobjects
*
* @return void
*/
public function __construct($menuObjects = array())
{
$this->menuObjects = $menuObjects;
}
////////////////////////////////////////////////////////////////////
////////////////////////// PUBLIC INTERFACE ////////////////////////
////////////////////////////////////////////////////////////////////
public function setMenuObjects($menuObjects)
{
$this->menuObjects = $menuObjects;
return $this;
}
public function getMenuObjects()
{
return $this->menuObjects;
}
public function addMenuObject($menuObject)
{
$this->menuObjects[] = $menuObject;
return $this;
}
public function map($callback)
{
array_map($callback, $this->getMenuObjects());
}
public function breadcrumbs($choosePath = null)
{
if(is_null($choosePath)) {
$choosePath = function($itemLists) {
return $itemLists[0];
};
}
$menuObjects = array();
foreach (Menu::allHandlers()->getMenuObjects() as $itemList) {
$breadcrumbs = $itemList->breadcrumbs();
if($breadcrumbs->hasChildren()) {
$menuObjects[] = $breadcrumbs;
}
}
if(count($menuObjects) > 1)
{
return $choosePath($menuObjects);
}
return isset($menuObjects[0]) ? $menuObjects[0] : new MenuHandler;
}
////////////////////////////////////////////////////////////////////
//////////////////////////// RESPONDERS ////////////////////////////
////////////////////////////////////////////////////////////////////
protected function getHandlerFromResults($menuHandlers)
{
if(is_array($menuHandlers) && count($menuHandlers) > 0 && ! $menuHandlers[0] instanceof MenuHandler) {
foreach ($menuHandlers as &$menuHandler) {
$menuHandler = new MenuHandler(array($menuHandler));
}
}
$menuObjects = $this->getMenuObjectsFromHandlers($menuHandlers);
return new MenuHandler($menuObjects);
}
protected function getMatchFromResults($results)
{
foreach($results as $result)
{
if($result !== false)
{
return $result;
}
}
return false;
}
protected function getCombinedResults($results)
{
return call_user_func_array('array_merge', $results);
}
protected function getCombindedResultsByKey($results)
{
$combinedResults = array();
foreach ($results as $result)
{
foreach($result as $key => $items)
{
foreach($items as $item)
{
$combinedResults[$key][] = $item;
}
}
}
return $combinedResults;
}
protected function getImplodedResults($results)
{
return implode('', $results);
}
////////////////////////////////////////////////////////////////////
///////////////////////// RESULT EXTRACTORS ////////////////////////
////////////////////////////////////////////////////////////////////
protected function getMenuObjectsFromHandlers($menuHandlers)
{
$results = array();
foreach($menuHandlers as $menuHandler)
{
foreach($menuHandler->getMenuObjects() as $item)
{
$results[] = $item;
}
}
return $results;
}
////////////////////////////////////////////////////////////////////
/////////////////////////// MAGIC METHODS //////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Magic method that will pass the incoming calls to
* all of the ItemLists this handler acts on
*
* @param string $method
* @param array $parameters
*
* @return MenuHandler
*/
public function __call($method, $parameters = array())
{
$results = array();
foreach ($this->menuObjects as &$menuObject) {
$result = call_user_func_array(array($menuObject, $method), $parameters);
if (Str::startsWith($method, static::$override)) {
$menuObject = $result;
}
$results[] = $result;
}
foreach (static::$responses as $responseMethod => $methods) {
if(in_array($method, $methods)) {
return $this->$responseMethod($results);
}
}
return $this;
}
/**
* Render the MenuHandler
*
* @return string
*/
public function __toString()
{
return $this->render();
}
}
================================================
FILE: src/Menu/MenuServiceProvider.php
================================================
<?php
namespace Menu;
use Illuminate\Support\ServiceProvider;
/**
* The "start" file for laravel
*/
class MenuServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$configPath = __DIR__ . '/../config/config.php';
$this->mergeConfigFrom($configPath, 'menu');
$container = Menu::getContainer();
$container['url'] = $this->app['url'];
$container['config'] = $this->app['config'];
Menu::setContainer($container);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('menu');
}
/**
* Declare publishable assets
*
* @return void
*/
public function boot()
{
$configPath = __DIR__ . '/../config/config.php';
$this->publishes([$configPath => config_path('menu.php')], 'config');
}
}
================================================
FILE: src/Menu/Traits/Content.php
================================================
<?php
namespace Menu\Traits;
use HtmlObject\Text;
/**
* The base class around the different content types
*/
class Content extends Text
{
/**
* Whether the content is a link or not
*
* @return boolean
*/
public function isLink()
{
return false;
}
/**
* Break off a chain
*
* @return Item
*/
public function stop()
{
return $this->getParent(1);
}
}
================================================
FILE: src/Menu/Traits/MenuObject.php
================================================
<?php
namespace Menu\Traits;
use HtmlObject\Traits\Tag;
use Menu\Menu;
use Underscore\Methods\ArraysMethods;
/**
* Allows dynamic setting and getting of attributes
* on the various parts of a menu (items, ItemLists, etc)
*/
abstract class MenuObject extends Tag
{
/**
* Per-element configuration
*
* @var array
*/
public $options = array();
////////////////////////////////////////////////////////////////////
/////////////////////////// CONFIGURATION //////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Replace an array of options
*
* @param array $options The new options
*
* @return MenuObject
*/
public function replaceOptions($options)
{
$this->options = array();
foreach($options as $key => $value) {
$this->setOption($key, $value);
}
return $this;
}
/**
* Set a particular option in the array
*
* @param string $option The option
* @param mixed $value Its new value
*
* @return MenuObject
*/
public function setOption($option, $value)
{
$this->options = ArraysMethods::set($this->options, $option, $value);
return $this;
}
/**
* Get a particular option in the array
*
* @param string $option An option
*
* @return mixed Its value
*/
public function getOption($option = null)
{
$globalOptions = Menu::getOption();
$combinedOptions = array_replace_recursive($globalOptions, $this->options);
if (!$option) return $combinedOptions;
return ArraysMethods::get($combinedOptions, $option);
}
}
================================================
FILE: src/config/config.php
================================================
<?php return array(
// Global options ------------------------------------------------ /
// The maximum depth a list can be generated
// -1 means no limit
'max_depth' => -1,
// Items --------------------------------------------------------- /
// Various options related to Items
'item' => array(
// The default Item element
'element' => 'li',
// Various classes to mark active items or children
'active_class' => 'active',
'active_child_class' => 'active-child',
),
// ItemLists ----------------------------------------------------- /
'item_list' => array(
// The default ItemList element
'element' => 'ul',
// The default breadcrumb separator, set to '' to not output any separators for
// use with bootstrap.
'breadcrumb_separator' => '/',
// A prefix to prepend the links URLs with
'prefix' => null,
// Whether links should inherit their parent/handler's prefix
'prefix_parents' => false,
'prefix_handler' => false,
),
);
================================================
FILE: start.php
================================================
<?php
require 'vendor/autoload.php';
================================================
FILE: tests/ItemListTest.php
================================================
<?php
include '_start.php';
use Menu\Menu;
use Menu\Items\Item;
use Menu\Items\ItemList;
class ItemListTest extends MenuTests
{
public function testEmptyItemListRendersNothing()
{
$this->assertTrue('' == static::$itemList->render());
}
public function testCanCreateListsOfADifferentElement()
{
$list = static::$itemList->add('some', 'item');
$list->setElement('ol');
$this->assertHTML($this->matchList('ol'), $list->render());
}
public function testCanPrefixItems()
{
$list = static::$itemList;
$list->prefixParents()->prefix('foo');
$list->add('bar', 'foo');
$matcher = $this->matchListWithItem();
$matcher['child']['child'] = $this->matchLink(URL::to('foo/bar'));
$this->assertHTML($matcher, $list->render());
}
public function testCanSetClassOnLists()
{
$list = static::$itemList;
$list->addClass('foo')->data_foo('bar');
$list->add('some', 'item');
$matcher = $this->matchList();
$matcher['attributes']['class'] = 'foo';
$matcher['attributes']['data-foo'] = 'bar';
$this->assertHTML($matcher, $list);
}
public function testCanSetClassOnItems()
{
$list = static::$itemList;
$list->add('#', 'foo')->onItem()->addClass('foo')
->getContent()->href('#lol');
$matcher = $this->matchListWithItem('ul', 'li');
$matcher['child']['attributes']['class'] = 'foo';
$matcher['child']['child']['attributes']['href'] = '#lol';
$this->assertHTML($matcher, $list);
}
public function testChainingMethods()
{
$menu = static::$itemList
->add('#', 'foo')->onItem()->data_foo('bar')->addClass('active')
->getContent()->href('lol')->stop()
->add('#', 'bar');
$this->assertEquals(
'<ul>'.
'<li data-foo="bar" class="active">'.
'<a href="'.URL::to('lol').'">foo</a>'.
'</li>'.
'<li>'.
'<a href="#">bar</a>'.
'</li>'.
'</ul>', $menu->render());
}
public function testCanAttachMenus()
{
$list = static::$itemList;
$list->add('#', 'foo');
$list->attach(Menu::items()->add('#', 'bar'));
$this->assertHTML($this->matchListWithItem(), $list);
$this->assertHTML($this->matchLink('#', 'bar'), $list);
}
}
================================================
FILE: tests/ItemTest.php
================================================
<?php
use Menu\Items\Item;
use Menu\Items\ItemList;
class ItemTest extends MenuTests
{
public function testCanCreateAnItem()
{
$this->assertHTML($this->matchItem(), static::$item->render());
}
public function testCanCreateItemOfADifferentElement()
{
$item = static::$item;
$item->setElement('dl');
$this->assertHTML($this->matchItem('dl'), $item->render());
}
public function testCanCreateRawItem()
{
$item = new Item(static::$itemList, static::$raw);
$matcher = array('tag' => 'li', 'content' => 'foo');
$this->assertHTML($matcher, $item->render());
}
public function testCanCreateItemWithSublist()
{
$sublist = static::$itemList;
$sublist->add('#', 'foo');
$item = new Item(static::$itemList, static::$link, $sublist);
$matchSublist = array(
'tag' => 'li',
'child' => array(
'tag' => 'ul',
'child' => $this->matchItem(),
),
);
$this->assertHTML($this->matchItem(), $item->render());
$this->assertHTML($matchSublist, $item->render());
}
public function testCanCreateElementlessItems()
{
$item = new Item(static::$itemList, static::$link);
$item->setElement(null);
$this->assertHTML($this->matchLink(), $item->render());
}
}
================================================
FILE: tests/LinkTest.php
================================================
<?php
use Menu\Items\Contents\Link;
class LinkTest extends MenuTests
{
public function testCanCreateRawContent()
{
$this->assertHTML($this->matchLink(), static::$link->render());
}
public function testLinksAreLinks()
{
$this->assertTrue(static::$link->isLink());
}
public function testDoesntAlterSpecialUrls()
{
$link = new Link('javascript:void(0);', 'foo');
$matcher = $this->matchLink('javascript:void(0);');
$this->assertHTML($matcher, $link);
}
public function testCanSetAttributesOnLinks()
{
$link = static::$link;
$link->class('foobar');
$matcher = $this->matchLink();
$matcher['attributes']['class'] = 'foobar';
$this->assertHTML($matcher, $link->render());
}
}
================================================
FILE: tests/MenuHandlerTest.php
================================================
<?php
use Menu\Menu;
class MenuHandlerTest extends MenuTests
{
public function testCanHandle()
{
$handles = array('foo', 'bar');
$menu = Menu::handler($handles);
$this->assertEquals(array_values(Menu::getItemList()), $menu->getMenuObjects());
}
}
================================================
FILE: tests/MenuTest.php
================================================
<?php
use Menu\Menu;
use Menu\Items\ItemList;
class MenuTest extends MenuTests
{
public function testCanReturnAMenuHandler()
{
$menu = Menu::handler('foo');
$this->assertInstanceOf('Menu\MenuHandler', $menu);
}
public function testCanGetAMenuThatHandlesEverything()
{
Menu::handler('foo');
Menu::handler('bar');
$allHandlers = Menu::allHandlers();
$this->assertEquals(array('foo', 'bar'), array_keys($allHandlers->getMenuObjects()));
}
public function testCanResetAllHandles()
{
Menu::handler('foo');
Menu::reset();
$this->assertEquals(array(), Menu::getItemList());
}
public function testCanReturnItemLists()
{
$itemList = Menu::items('foo');
$this->assertInstanceOf('Menu\Items\ItemList', $itemList);
}
public function testCanSetItemLists()
{
$itemList = Menu::items('foo');
Menu::setItemList('foo', $itemList);
$this->assertArrayHasKey('foo', Menu::getItemList());
}
public function testCanRenderManuallyBindedItemLists()
{
$menu = Menu::handler('categories')
->add('algorithms', 'Algorithms', Menu::items()->prefixParents()
->add('cryptography', 'Cryptography')
->add('data-structures', 'Data Structures')
->add('digital-image-processing', 'Digital Image Processing')
->add('memory-management', 'Memory Management'))
->add('graphics-and-multimedia', 'Graphics & Multimedia', Menu::items()->prefixParents()
->add('directx', 'DirectX')
->add('flash', 'Flash')
->add('opengl', 'OpenGL'));
$matcher =
'<ul>'.
'<li>'.
'<a href="'.URL::to('algorithms').'">Algorithms</a>'.
'<ul>'.
'<li><a href="'.URL::to('algorithms/cryptography').'">Cryptography</a></li>'.
'<li><a href="'.URL::to('algorithms/data-structures').'">Data Structures</a></li>'.
'<li><a href="'.URL::to('algorithms/digital-image-processing').'">Digital Image Processing</a></li>'.
'<li><a href="'.URL::to('algorithms/memory-management').'">Memory Management</a></li>'.
'</ul>'.
'</li>'.
'<li>'.
'<a href="'.URL::to('graphics-and-multimedia').'">Graphics & Multimedia</a>'.
'<ul>'.
'<li><a href="'.URL::to('graphics-and-multimedia/directx').'">DirectX</a></li>'.
'<li><a href="'.URL::to('graphics-and-multimedia/flash').'">Flash</a></li>'.
'<li><a href="'.URL::to('graphics-and-multimedia/opengl').'">OpenGL</a></li>'.
'</ul>'.
'</li>'.
'</ul>';
$this->assertEquals($matcher, $menu->render());
}
public function testCanGetItemLists()
{
$itemList = Menu::items('foo');
Menu::setItemList('foo', $itemList);
$this->assertEquals($itemList, Menu::getItemList('foo'));
}
public function testCanGetValueFromConfig()
{
$config = Menu::getOption('max_depth');
$this->assertEquals(-1, $config);
$config = Menu::getOption();
$this->assertInternalType('array', $config);
}
public function testClassesPassTheirConfigurationToChildren()
{
$list = static::$itemList;
$list->add('#', 'foo');
$list->setOption('item.element', 'dl');
$this->assertHTML($this->matchListWithItem('ul', 'dl'), $list->render());
$this->assertHTML($this->matchLink(), $list->render());
}
public function testMenuCanSetGlobalOptions()
{
Menu::setOption('item.element', 'dl');
$list = new ItemList;
$list->add('#', 'foo');
$this->assertHTML($this->matchListWithItem('ul', 'dl'), $list->render());
$this->assertHTML($this->matchLink(), $list->render());
}
public function testChainingMethods()
{
$menu = Menu::handler('foo')
->add('#', 'foo')->onItem()->data_foo('bar')->addClass('active')
->getContent()->href('lol')->stop()
->add('#', 'bar');
$this->assertEquals(
'<ul>'.
'<li data-foo="bar" class="active">'.
'<a href="http://localhost/lol">foo</a>'.
'</li>'.
'<li>'.
'<a href="#">bar</a>'.
'</li>'.
'</ul>', $menu->render());
}
}
================================================
FILE: tests/RawTest.php
================================================
<?php
use Menu\Items\Contents\Raw;
class RawTest extends MenuTests
{
public function testCanCreateRawContent()
{
$raw = new Raw('foobar');
$this->assertEquals('foobar', $raw->render());
}
}
================================================
FILE: tests/_start.php
================================================
<?php
use Menu\Items\Contents\Link;
use Menu\Items\Contents\Raw;
use Menu\Items\Item;
use Menu\Items\ItemList;
use Menu\Menu;
use PHPUnit\Util\XML;
use PHPUnit\DOMNode;
abstract class MenuTests extends \Orchestra\Testbench\TestCase
{
protected static $link;
protected static $raw;
protected static $itemList;
protected static $item;
public function setUp()
{
parent::setUp();
// Reset all menus
Menu::reset();
$this->refreshApplication();
// Precreate somme Dummy data
static::$link = new Link('#', 'foo');
static::$raw = new Raw('foo');
static::$itemList = new ItemList;
static::$item = new Item(static::$itemList, static::$link);
}
protected function getPackageProviders($app = null)
{
return array(
'Menu\MenuServiceProvider',
);
}
protected function getPackageAliases($app = null)
{
return array(
'Menu' => 'Menu\Menu',
);
}
////////////////////////////////////////////////////////////////////
////////////////////////////// MATCHERS ////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Basic matcher for an ItemList
*
* @param string $element
*
* @return array
*/
protected function matchList($element = 'ul')
{
return array(
'tag' => $element,
);
}
/**
* Matcher for an ItemList with an Item
*
* @return array
*/
protected function matchListWithItem($list = 'ul', $item = 'li')
{
$list = $this->matchList($list);
$list['child'] = $this->matchItem($item);
return $list;
}
/**
* Basic matcher for an Item
*
* @param string $element
*
* @return array
*/
protected function matchItem($element = 'li')
{
return array(
'tag' => $element,
'child' => $this->matchLink(),
);
}
/**
* Basic matcher for a Link
*
* @return array
*/
protected function matchLink($link = '#', $content = 'foo')
{
return array(
'tag' => 'a',
'content' => $content,
'attributes' => array(
'href' => $link,
),
);
}
////////////////////////////////////////////////////////////////////
////////////////////////////// HELPERS /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Asserts some HTML is, once stripped, equals to a matcher
*
* @param string $matcher The matcher
* @param string $html The HTML
*/
protected function assertStripedEquals($matcher, $html)
{
$html = preg_replace("/[\n\r\t]/", null, $html);
return $this->assertEquals($matcher, $html);
}
/**
* Enhanced version of assertTag
*
* @param array $matcher The tag matcher
* @param string $html The HTML
*/
protected function assertHTML($matcher, $html)
{
return $this->assertTag(
$matcher,
$html,
"Failed asserting that the HTML matches the provided format :\n\t"
.$html."\n\t"
.json_encode($matcher));
}
}
gitextract_dkc3rpkb/
├── .gitignore
├── .travis.yml
├── README.md
├── composer.json
├── phpdoc.dist.xml
├── phpunit.xml.dist
├── src/
│ ├── Menu/
│ │ ├── Items/
│ │ │ ├── Contents/
│ │ │ │ ├── Link.php
│ │ │ │ └── Raw.php
│ │ │ ├── Item.php
│ │ │ └── ItemList.php
│ │ ├── Menu.php
│ │ ├── MenuHandler.php
│ │ ├── MenuServiceProvider.php
│ │ └── Traits/
│ │ ├── Content.php
│ │ └── MenuObject.php
│ └── config/
│ └── config.php
├── start.php
└── tests/
├── ItemListTest.php
├── ItemTest.php
├── LinkTest.php
├── MenuHandlerTest.php
├── MenuTest.php
├── RawTest.php
└── _start.php
SYMBOL INDEX (154 symbols across 16 files)
FILE: src/Menu/Items/Contents/Link.php
class Link (line 13) | class Link extends HtmlLink
method __construct (line 47) | public function __construct($url, $value = null, $attributes = array())
method href (line 61) | public function href($href)
method getUrl (line 73) | public function getUrl()
method stop (line 83) | public function stop()
method render (line 93) | public function render()
method isLink (line 116) | public function isLink()
method isSpecialUrl (line 126) | public function isSpecialUrl()
method getEvaluatedUrl (line 144) | public function getEvaluatedUrl()
method getParentItems (line 181) | protected function getParentItems()
method getParentLists (line 202) | protected function getParentLists()
method getHandlerSegment (line 223) | protected function getHandlerSegment()
method getParentItemsUrls (line 236) | protected function getParentItemsUrls()
FILE: src/Menu/Items/Contents/Raw.php
class Raw (line 9) | class Raw extends Content {}
FILE: src/Menu/Items/Item.php
class Item (line 17) | class Item extends MenuObject
method __construct (line 36) | public function __construct(ItemList $parent, Tag $value, $children = ...
method setActivePatterns (line 55) | public function setActivePatterns($pattern, $name = null)
method stop (line 66) | public function stop()
method getContent (line 76) | public function getContent()
method setBeforeContent (line 86) | public function setBeforeContent($value)
method setAfterContent (line 97) | public function setAfterContent($value)
method setElement (line 108) | public function setElement($element = null)
method getElement (line 120) | public function getElement()
method render (line 137) | public function render($depth = 0)
method isActive (line 166) | public function isActive()
method hasChildren (line 179) | public function hasChildren()
method hasActivePatterns (line 189) | protected function hasActivePatterns()
method hasActiveChild (line 212) | public function hasActiveChild()
method getUrl (line 236) | protected function getUrl()
method addActiveClasses (line 248) | private function addActiveClasses()
method getRequest (line 268) | public function getRequest()
FILE: src/Menu/Items/ItemList.php
class ItemList (line 22) | class ItemList extends MenuObject
method __construct (line 40) | public function __construct($items = array(), $name = null, $attribute...
method onItem (line 53) | public function onItem()
method setOption (line 70) | public function setOption($option, $value)
method add (line 114) | public function add($url, $value, $children = null, $linkAttributes = ...
method raw (line 139) | public function raw($raw, $children = null, $itemAttributes = array(),...
method addContent (line 157) | public function addContent($content, $children = null, $itemAttributes...
method activePattern (line 184) | public function activePattern($pattern)
method attach (line 205) | public function attach(ItemList $itemList)
method name (line 219) | public function name($name)
method getName (line 231) | public function getName()
method prefix (line 247) | public function prefix($prefix)
method prefixParents (line 261) | public function prefixParents($prefixParents = true)
method prefixMenuHandler (line 275) | public function prefixMenuHandler($prefixMenuHandler = true)
method setElement (line 287) | public function setElement($element = null)
method getElement (line 298) | public function getElement()
method getItemsWithDepth (line 312) | public function getItemsWithDepth()
method getItemsRecursivelyWithDepth (line 322) | protected function getItemsRecursivelyWithDepth($items, $depth = 0)
method getItemListsWithDepth (line 348) | public function getItemListsWithDepth()
method getItemListsRecursivelyWithDepth (line 358) | protected function getItemListsRecursivelyWithDepth($itemList, $depth ...
method getAllItems (line 384) | public function getAllItems()
method getItemsByContentType (line 406) | public function getItemsByContentType($contentType)
method getAllItemLists (line 428) | public function getAllItemLists()
method getAllItemListsIncludingThisOne (line 448) | public function getAllItemListsIncludingThisOne()
method getItemListsAtDepth (line 459) | public function getItemListsAtDepth($depth)
method getItemListsAtDepthRange (line 473) | public function getItemListsAtDepthRange($from, $to)
method getItemsAtDepth (line 497) | public function getItemsAtDepth($depth)
method getItemsAtDepthRange (line 511) | public function getItemsAtDepthRange($from, $to)
method reverse (line 530) | public function reverse()
method findActiveItem (line 537) | public function findActiveItem()
method getSubmenu (line 552) | public function getSubmenu()
method breadcrumbs (line 562) | public function breadcrumbs()
method map (line 599) | public function map($callback)
method findItemListByName (line 611) | public function findItemListByName($name)
method findByName (line 633) | public function findByName($name)
method find (line 645) | public function find($name)
method findItemByAttribute (line 655) | public function findItemByAttribute($key, $value)
method findItemByUrl (line 676) | public function findItemByUrl($url)
method hydrate (line 714) | public function hydrate($resolver, $decorator, $idField = 'id', $paren...
method render (line 760) | public function render($depth = 0)
FILE: src/Menu/Menu.php
class Menu (line 13) | class Menu
method handler (line 53) | public static function handler($names = '', $attributes = array(), $el...
method allHandlers (line 80) | public static function allHandlers()
method reset (line 88) | public static function reset()
method items (line 106) | public static function items($name = null, $attributes = array(), $ele...
method setItemList (line 119) | public static function setItemList($name, $itemList)
method getItemList (line 133) | public static function getItemList($name = null)
method __callStatic (line 159) | public static function __callStatic($method, $parameters = array())
method getContainer (line 175) | public static function getContainer($dependency = null)
method setContainer (line 205) | public static function setContainer($container)
method getOption (line 217) | public static function getOption($option = null)
method setOption (line 233) | public static function setOption($option, $value)
FILE: src/Menu/MenuHandler.php
class MenuHandler (line 11) | class MenuHandler
method __construct (line 68) | public function __construct($menuObjects = array())
method setMenuObjects (line 77) | public function setMenuObjects($menuObjects)
method getMenuObjects (line 84) | public function getMenuObjects()
method addMenuObject (line 89) | public function addMenuObject($menuObject)
method map (line 96) | public function map($callback)
method breadcrumbs (line 101) | public function breadcrumbs($choosePath = null)
method getHandlerFromResults (line 129) | protected function getHandlerFromResults($menuHandlers)
method getMatchFromResults (line 142) | protected function getMatchFromResults($results)
method getCombinedResults (line 155) | protected function getCombinedResults($results)
method getCombindedResultsByKey (line 160) | protected function getCombindedResultsByKey($results)
method getImplodedResults (line 177) | protected function getImplodedResults($results)
method getMenuObjectsFromHandlers (line 186) | protected function getMenuObjectsFromHandlers($menuHandlers)
method __call (line 213) | public function __call($method, $parameters = array())
method __toString (line 240) | public function __toString()
FILE: src/Menu/MenuServiceProvider.php
class MenuServiceProvider (line 9) | class MenuServiceProvider extends ServiceProvider
method register (line 24) | public function register()
method provides (line 40) | public function provides()
method boot (line 50) | public function boot()
FILE: src/Menu/Traits/Content.php
class Content (line 9) | class Content extends Text
method isLink (line 16) | public function isLink()
method stop (line 26) | public function stop()
FILE: src/Menu/Traits/MenuObject.php
class MenuObject (line 12) | abstract class MenuObject extends Tag
method replaceOptions (line 33) | public function replaceOptions($options)
method setOption (line 52) | public function setOption($option, $value)
method getOption (line 66) | public function getOption($option = null)
FILE: tests/ItemListTest.php
class ItemListTest (line 8) | class ItemListTest extends MenuTests
method testEmptyItemListRendersNothing (line 10) | public function testEmptyItemListRendersNothing()
method testCanCreateListsOfADifferentElement (line 15) | public function testCanCreateListsOfADifferentElement()
method testCanPrefixItems (line 23) | public function testCanPrefixItems()
method testCanSetClassOnLists (line 35) | public function testCanSetClassOnLists()
method testCanSetClassOnItems (line 47) | public function testCanSetClassOnItems()
method testChainingMethods (line 60) | public function testChainingMethods()
method testCanAttachMenus (line 78) | public function testCanAttachMenus()
FILE: tests/ItemTest.php
class ItemTest (line 5) | class ItemTest extends MenuTests
method testCanCreateAnItem (line 7) | public function testCanCreateAnItem()
method testCanCreateItemOfADifferentElement (line 12) | public function testCanCreateItemOfADifferentElement()
method testCanCreateRawItem (line 20) | public function testCanCreateRawItem()
method testCanCreateItemWithSublist (line 28) | public function testCanCreateItemWithSublist()
method testCanCreateElementlessItems (line 46) | public function testCanCreateElementlessItems()
FILE: tests/LinkTest.php
class LinkTest (line 4) | class LinkTest extends MenuTests
method testCanCreateRawContent (line 6) | public function testCanCreateRawContent()
method testLinksAreLinks (line 11) | public function testLinksAreLinks()
method testDoesntAlterSpecialUrls (line 16) | public function testDoesntAlterSpecialUrls()
method testCanSetAttributesOnLinks (line 24) | public function testCanSetAttributesOnLinks()
FILE: tests/MenuHandlerTest.php
class MenuHandlerTest (line 4) | class MenuHandlerTest extends MenuTests
method testCanHandle (line 6) | public function testCanHandle()
FILE: tests/MenuTest.php
class MenuTest (line 5) | class MenuTest extends MenuTests
method testCanReturnAMenuHandler (line 7) | public function testCanReturnAMenuHandler()
method testCanGetAMenuThatHandlesEverything (line 14) | public function testCanGetAMenuThatHandlesEverything()
method testCanResetAllHandles (line 23) | public function testCanResetAllHandles()
method testCanReturnItemLists (line 31) | public function testCanReturnItemLists()
method testCanSetItemLists (line 38) | public function testCanSetItemLists()
method testCanRenderManuallyBindedItemLists (line 46) | public function testCanRenderManuallyBindedItemLists()
method testCanGetItemLists (line 83) | public function testCanGetItemLists()
method testCanGetValueFromConfig (line 91) | public function testCanGetValueFromConfig()
method testClassesPassTheirConfigurationToChildren (line 100) | public function testClassesPassTheirConfigurationToChildren()
method testMenuCanSetGlobalOptions (line 110) | public function testMenuCanSetGlobalOptions()
method testChainingMethods (line 121) | public function testChainingMethods()
FILE: tests/RawTest.php
class RawTest (line 4) | class RawTest extends MenuTests
method testCanCreateRawContent (line 6) | public function testCanCreateRawContent()
FILE: tests/_start.php
class MenuTests (line 10) | abstract class MenuTests extends \Orchestra\Testbench\TestCase
method setUp (line 17) | public function setUp()
method getPackageProviders (line 32) | protected function getPackageProviders($app = null)
method getPackageAliases (line 39) | protected function getPackageAliases($app = null)
method matchList (line 57) | protected function matchList($element = 'ul')
method matchListWithItem (line 69) | protected function matchListWithItem($list = 'ul', $item = 'li')
method matchItem (line 84) | protected function matchItem($element = 'li')
method matchLink (line 97) | protected function matchLink($link = '#', $content = 'foo')
method assertStripedEquals (line 118) | protected function assertStripedEquals($matcher, $html)
method assertHTML (line 131) | protected function assertHTML($matcher, $html)
Condensed preview — 24 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (75K chars).
[
{
"path": ".gitignore",
"chars": 22,
"preview": ".DS_Store\nvendor\ndata\n"
},
{
"path": ".travis.yml",
"chars": 102,
"preview": "language: php\n\nphp:\n - 5.4\n - 5.5\n - 5.6\n - hhvm\n\nsudo: false\n\nbefore_script:\n - composer update\n"
},
{
"path": "README.md",
"chars": 11350,
"preview": "# Menu\n\n[](http://travis-ci.org/vespakoen/"
},
{
"path": "composer.json",
"chars": 614,
"preview": "{\n\t\"name\": \"vespakoen/menu\",\n\t\"description\": \"Managing menus the easy way.\",\n\t\"keywords\": [\"menu\", \"laravel\", \"laravel 5"
},
{
"path": "phpdoc.dist.xml",
"chars": 358,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<phpdoc>\n <parser>\n <target>data/output</target>\n </parser>\n <transformer>"
},
{
"path": "phpunit.xml.dist",
"chars": 560,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit backupGlobals=\"false\"\n backupStaticAttributes=\"false\"\n bootstrap=\"vend"
},
{
"path": "src/Menu/Items/Contents/Link.php",
"chars": 5026,
"preview": "<?php\nnamespace Menu\\Items\\Contents;\n\nuse HtmlObject\\Traits\\Helpers;\nuse HtmlObject\\Link as HtmlLink;\nuse Menu\\Menu;\nuse"
},
{
"path": "src/Menu/Items/Contents/Raw.php",
"chars": 127,
"preview": "<?php\nnamespace Menu\\Items\\Contents;\n\nuse Menu\\Traits\\Content;\n\n/**\n * Raw content in an Item\n */\nclass Raw extends Cont"
},
{
"path": "src/Menu/Items/Item.php",
"chars": 6101,
"preview": "<?php\nnamespace Menu\\Items;\n\nuse HtmlObject\\Element;\nuse HtmlObject\\Traits\\Tag;\n\nuse Menu\\Menu;\nuse Menu\\Traits\\Content;"
},
{
"path": "src/Menu/Items/ItemList.php",
"chars": 18626,
"preview": "<?php\nnamespace Menu\\Items;\n\nuse Exception;\n\nuse HtmlObject\\Element;\n\nuse Menu\\Menu;\nuse Menu\\MenuHandler;\nuse Menu\\Item"
},
{
"path": "src/Menu/Menu.php",
"chars": 6054,
"preview": "<?php\nnamespace Menu;\n\nuse Illuminate\\Config\\FileLoader;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Cont"
},
{
"path": "src/Menu/MenuHandler.php",
"chars": 5470,
"preview": "<?php\nnamespace Menu;\n\nuse Menu\\Items\\ItemList;\nuse Illuminate\\Support\\Str;\nuse Exception;\n\n/**\n * Handles various insta"
},
{
"path": "src/Menu/MenuServiceProvider.php",
"chars": 1037,
"preview": "<?php\nnamespace Menu;\n\nuse Illuminate\\Support\\ServiceProvider;\n\n/**\n * The \"start\" file for laravel\n */\nclass MenuServic"
},
{
"path": "src/Menu/Traits/Content.php",
"chars": 401,
"preview": "<?php\nnamespace Menu\\Traits;\n\nuse HtmlObject\\Text;\n\n/**\n * The base class around the different content types\n */\nclass C"
},
{
"path": "src/Menu/Traits/MenuObject.php",
"chars": 1607,
"preview": "<?php\nnamespace Menu\\Traits;\n\nuse HtmlObject\\Traits\\Tag;\nuse Menu\\Menu;\nuse Underscore\\Methods\\ArraysMethods;\n\n/**\n * Al"
},
{
"path": "src/config/config.php",
"chars": 1033,
"preview": "<?php return array(\n\n // Global options ------------------------------------------------ /\n\n // The maximum depth a li"
},
{
"path": "start.php",
"chars": 36,
"preview": "<?php\nrequire 'vendor/autoload.php';"
},
{
"path": "tests/ItemListTest.php",
"chars": 2245,
"preview": "<?php\ninclude '_start.php';\n\nuse Menu\\Menu;\nuse Menu\\Items\\Item;\nuse Menu\\Items\\ItemList;\n\nclass ItemListTest extends Me"
},
{
"path": "tests/ItemTest.php",
"chars": 1266,
"preview": "<?php\nuse Menu\\Items\\Item;\nuse Menu\\Items\\ItemList;\n\nclass ItemTest extends MenuTests\n{\n public function testCanCreateA"
},
{
"path": "tests/LinkTest.php",
"chars": 740,
"preview": "<?php\nuse Menu\\Items\\Contents\\Link;\n\nclass LinkTest extends MenuTests\n{\n public function testCanCreateRawContent()\n {\n"
},
{
"path": "tests/MenuHandlerTest.php",
"chars": 267,
"preview": "<?php\nuse Menu\\Menu;\n\nclass MenuHandlerTest extends MenuTests\n{\n public function testCanHandle()\n {\n $handles = arr"
},
{
"path": "tests/MenuTest.php",
"chars": 4088,
"preview": "<?php\nuse Menu\\Menu;\nuse Menu\\Items\\ItemList;\n\nclass MenuTest extends MenuTests\n{\n public function testCanReturnAMenuHa"
},
{
"path": "tests/RawTest.php",
"chars": 205,
"preview": "<?php\nuse Menu\\Items\\Contents\\Raw;\n\nclass RawTest extends MenuTests\n{\n public function testCanCreateRawContent()\n {\n "
},
{
"path": "tests/_start.php",
"chars": 3058,
"preview": "<?php\nuse Menu\\Items\\Contents\\Link;\nuse Menu\\Items\\Contents\\Raw;\nuse Menu\\Items\\Item;\nuse Menu\\Items\\ItemList;\nuse Menu\\"
}
]
About this extraction
This page contains the full source code of the vespakoen/menu GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 24 files (68.7 KB), approximately 18.8k tokens, and a symbol index with 154 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.