[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nvendor\ndata\n"
  },
  {
    "path": ".travis.yml",
    "content": "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",
    "content": "# Menu\n\n[![Build Status](https://secure.travis-ci.org/vespakoen/menu.png?branch=master)](http://travis-ci.org/vespakoen/menu)\n[![Total Downloads](https://poser.pugx.org/vespakoen/menu/d/total.svg)](https://packagist.org/packages/vespakoen/menu)\n[![Latest Stable Version](https://poser.pugx.org/vespakoen/menu/v/stable.svg)](https://packagist.org/packages/vespakoen/menu)\n[![Latest Unstable Version](https://poser.pugx.org/vespakoen/menu/v/unstable.svg)](https://packagist.org/packages/vespakoen/menu)\n[![License](https://poser.pugx.org/vespakoen/menu/license.svg)](https://packagist.org/packages/vespakoen/menu)\n\n[API Docs](http://vespakoen.github.io/menu/)\n\nAre 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!\n\n# Quick overview example\n\n```php\n$menu = Menu::handler('mailbox'); \n\n// items\n$menu\n    ->add('contacts', 'Contacts')\n    ->add('inbox', 'Inbox')\n    ->raw(null, null, ['class' => 'divider'])\n    ->add('folders', 'Folders', Menu::items() \n        ->prefixParents() \n        ->add('urgent', 'Urgent') // with prefix: /folders/urgent\n        ->add('sent', 'Sent')\n        ->add('deleted', 'Deleted')\n    );\n\n// styling\n$menu\n    ->addClass('nav navbar-nav')\n    ->getItemsByContentType(Menu\\Items\\Contents\\Link::class)\n    ->map(function($item) {\n        if ( $item->isActive() )  {\n            $item->addClass('active');\n        }\n    });\n```\n\n`{!! $menu !!}` will output:\n\n```html\n<ul class=\"nav navbar-nav\">\n  <li class=\"active\"> <!-- current element in laravel, detected by library -->\n    <a href=\"http://myapp.com/contacts\">Contacts</a>\n  </li>\n  <li>\n    <a href=\"http://myapp.com/inbox\">Inbox</a>\n  </li>\n  <li class=\"divider\"></li>\n  <li>\n    <a href=\"http://myapp.com/folders\">Folders</a>\n    <ul>\n      <li>\n        <a href=\"http://myapp.com/folders/urgent\">Urgent</a>\n      </li>\n      <li>\n        <a href=\"http://myapp.com/folders/sent\">Sent</a>\n      </li>\n      <li>\n        <a href=\"http://myapp.com/folders/deleted\">Deleted</a>\n      </li>\n    </ul>\n  </li>\n</ul>\n```\n\n# Key concepts\n\n## Item lists\nAn item list is what a menu is all about and it should be pretty self explanatory because it simply stores a list of items.\nthere are some configurations available for an item list.\nYou 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.\n\n## Menu handlers\nMenu handlers allow us to create and interact with item lists and act as a place to store and retrieve our menus.\nBecause we are able to interact with multiple item lists at the same time some interesting possibilities become available to us.\n\n## Items\nThe Menu package has 2 types of items available out of the box.\n\n- Link\n  For creating links to other pages\n- Raw\n  Be free to add anything you like in the item.\n  This type is usually used for dividers, titles etc.\n\nThe HTML element and attributes for the item can also be changed, more on this topic later.\n\n# Installing\n\n## Laravel 3\n\nInstall Menu via the artisan command line tool. Open the terminal and navigate to your Laravel project's root.\nNow type the following command :\n\n```shell\nphp artisan bundle:install menu\n```\n\nTo let Laravel know the Laravel Menu package should be started, open up `application/packages.php` and add the following lines to the packages array.\n\n```php\n'menu' => array('auto' => true),\n```\n\n## Laravel 4\n\nAdd this to your `composer.json` file's `\"require\"` :\n\n```json\n\"vespakoen/menu\": \"2.*\"\n```\n\nAnd add the following to your `app/config/app.php` file :\n\n- In the Service Providers array : `'Menu\\MenuServiceProvider',`\n- In the aliases array : `'Menu' => 'Menu\\Menu',`\n\n## Laravel 5\n\nAdd this to your `composer.json` file's `\"require\"` :\n\n```json\n\"vespakoen/menu\": \"3.*\"\n```\n\nAnd add the following to your `config/app.php` file :\n\n- In the Service Providers array : `'Menu\\MenuServiceProvider',`\n- In the aliases array : `'Menu' => 'Menu\\Menu',`\n\nLastly, run the following from your project's root dir:\n\n```\nphp artisan vendor:publish\n```\n\n# Basic usage\n\nFirst, let's load some pages into the menu.\nWe will do this by utilising the `hydrate` method.\n\n\n```php\nMenu::handler('main')->hydrate(function()\n  {\n    return Page::with('translation')\n      ->where('group', '=', 'main')\n      ->get();\n  },\n  function($children, $item)\n  {\n    $children->add($item->translation->slug, $item->translation->name, Menu::items($item->as));\n  });\n\n/* the hydrate method takes these arguments\n  $resolver       Closure     A callback to resolve results\n  $decorator      Closure     A callback that gets called for every result fetched from the resolver with the corresponding ItemList and result as the arguments\n  $idField        integer (default = 'id')           the property on the result that contains the id\n  $parentIdField  integer (default = 'parent_id')    the property on the result that contains the parent id\n  $parentId       integer (default = 0)              the parentId to start hydrating from\n*/\n```\n\nNow 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.\n\nFind a node by it's name and add a subitem.\n```php\nMenu::find('users')\n  ->add('users/create', 'Create new user');\n```\n\nAdd some properties to the root node\n```php\nMenu::handler('main')\n  ->addClass('nav navbar-nav');\n```\n\nGet all `ItemList`s at a certain depth and add a class\n```php\nMenu::handler('main')\n  ->getItemListsAtDepth(0)\n  ->addClass('level-1');\n```\n\nGet all `ItemList`s at a depth range and change the element\n```php\nMenu::handler('main')\n  ->getItemListsAtDepthRange(0,2)\n  ->setElement('div');\n```\n\nGet all `Item`s at a certain depth and add a class\n```php\nMenu::handler('main')\n  ->getItemsAtDepth(0)\n  ->addClass('level-1');\n```\n\nGet `Item`s by it's content type and use the map function to walk over the results and perform actions based on gathered information\n```php\nMenu::handler('main')\n  ->getItemsByContentType('Menu\\Items\\Contents\\Link')\n  ->map(function($item)\n  {\n    if($item->isActive() && $item->hasChildren())\n    {\n      $item->addClass('is-active-link-with-children');\n    }\n\n    if($item->getContent()->getUrl() == 'home')\n    {\n      $item->addClass('is-home');\n    }\n  });\n```\n\nGet all `ItemList`s and add a class to them if they have children\n```php\nMenu::handler('main')\n  ->getAllItemLists()\n  ->map(function($itemList)\n  {\n    if($itemList->hasChildren())\n    {\n      $itemList->addClass('has-children');\n    }\n  });\n```\n\n# Breadcrumbs\n\nBreadcrumb hell is a thing of the past.\n\nBootstrap ready breadcrums are as easy as this\n```php\nMenu::handler('main')\n    ->breadcrumbs()\n    ->setElement('ol')\n    ->addClass('breadcrumb');\n```\n\nThe breadcrumbs method searches all handlers and returns a plain old ItemList, that you can manipulate.\nIf 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.\nHowever, 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.\n\nAnd example is shown below:\n```php\nMenu::breadcrumbs(function($itemLists)\n    {\n      return $itemLists[0]; // returns first match\n    })\n    ->setElement('ol')\n    ->addClass('breadcrumb');\n```\n\n# Diving deeper\n\nThe Laravel Menu packages consists of a couple of classes, but you can interact with all of them via the _Menu_ class.\nLet'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.\nIf an itemlist we asked for didn't exist yet, it will create it for us.\nAfter 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.\n\n```php\n// Get a MenuHandler instance that handles an ItemList named \"main\"\nMenu::handler('main');\n```\n\nWhen we call a method on this menu handler, it will simply forward the call to all the item lists that it handles.\nIn 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.\n\nThe _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_.\n\n```php\nMenu::handler('main')->add('home', 'Homepage');\n\n/* The add method takes these arguments\n  $url  string  The URL to another page\n  $title  string  The visible string on the link\n  $children (default = null)  ItemList  (optional) The children of this page\n  $link_attributes (default = array())  array (optional) HTML attributes for the <a> element\n  $item_attributes (default = array())  array (optional) HTML attributes for the list element (usually <li>)\n  $item_element (default = 'li')  string  (optional) The type of the list element\n*/\n```\n\nLet's take a look at the **raw** method, for adding \"anything\" to the list.\n\n```php\nMenu::handler('main')->raw('<img src=\"img/seperator.gif\">');\n\n/* The raw method takes these arguments\n  $html string  The contents of the item\n  $children (default = null)  ItemList  (optional) The children of this item\n  $item_attributes (default = array())  array (optional) HTML attributes for the list element (usually <li>)\n  $item_element (default = 'li')  string  (optional) The type of the list element\n*/\n```\n\nGreat! 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.\nEvery 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.\nSo what do we use? the **items** method returns a fresh _ItemList_ object. Let's have a look.\n\n```php\nMenu::handler('main')\n    ->add('home', 'Homepage', Menu::items()\n        ->add('sub-of-home', 'Sub of homepage'));\n\n/* The items method takes these arguments\n  $name (default = null)  string  (optional) The name (=identifier) of this ItemList\n  $attributes (default = array()) array (optional) HTML attributes for the ItemList element (usually <ul>)\n  $element (default = 'ul') string  (optional) The type of the ItemList element\n*/\n```\n\nSo now we know how to build menus, add items and items with children.\nLet's find out how to display the menus.\nThe MenuHandler and _ItemList_ classes implement the \"__toString\" method, that calls the **render** method.\nThis means you can simply echo the MenuHandler or _ItemList_ object.\nHere is an example to make things more clear.\n\n```php\necho Menu::handler('main');\n\n// Is the same as\n\necho Menu::handler('main')->render();\n```\n\nNow that we have the basics under control, we are going to explore some other cool features this package provides.\n\n# Class diagram\n\n[![Class diagram](http://rawgithub.com/vespakoen/menu/master/menu-class-diagram.svg)](http://rawgithub.com/vespakoen/menu/master/menu-class-diagram.svg)\n\n# Some last words\n\nThanks for following along and using this package.\nSpecial thanks to @Anahkiasen for refactoring this package and boosting new life into it!\n"
  },
  {
    "path": "composer.json",
    "content": "{\n\t\"name\": \"vespakoen/menu\",\n\t\"description\": \"Managing menus the easy way.\",\n\t\"keywords\": [\"menu\", \"laravel\", \"laravel 5\"],\n\t\"license\": \"MIT\",\n\t\"authors\": [\n\t\t{\n\t\t\t\"name\": \"Koen Schmeets\",\n\t\t\t\"email\": \"hello@koenschmeets.nl\"\n\t\t}\n\t],\n\t\"require\": {\n\t\t\"php\": \">=5.4.0\",\n\t\t\"anahkiasen/underscore-php\": \"^2.0\",\n\t\t\"anahkiasen/html-object\": \"~1.4\",\n\t\t\"illuminate/http\": \"6.*|^7\",\n\t\t\"illuminate/config\": \"6.*|^7\",\n\t\t\"illuminate/container\": \"6.*|^7\"\n\t},\n\t\"require-dev\": {\n\t\t\"phpunit/phpunit\": \"4.0\",\n\t\t\"orchestra/testbench\": \"3.0.*\"\n\t},\n\t\"autoload\": {\n\t\t\"psr-0\": {\n\t\t\t\"Menu\": \"src\"\n\t\t}\n\t},\n\t\"minimum-stability\": \"stable\"\n}\n"
  },
  {
    "path": "phpdoc.dist.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<phpdoc>\n  <parser>\n    <target>data/output</target>\n  </parser>\n  <transformer>\n    <target>data/output</target>\n  </transformer>\n  <files>\n    <directory>src</directory>\n    <directory>vendor/anahkiasen/html-object/src</directory>\n    <directory>vendor/anahkiasen/underscore-php/src</directory>\n  </files>\n</phpdoc>\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit backupGlobals=\"false\"\n  backupStaticAttributes=\"false\"\n  bootstrap=\"vendor/autoload.php\"\n  colors=\"true\"\n  convertErrorsToExceptions=\"true\"\n  convertNoticesToExceptions=\"true\"\n  convertWarningsToExceptions=\"true\"\n  processIsolation=\"false\"\n  stopOnFailure=\"true\"\n  syntaxCheck=\"false\">\n\n  <testsuites>\n    <testsuite name=\"Menu Test Suite\">\n      <directory>tests</directory>\n    </testsuite>\n  </testsuites>\n\n  <filter>\n    <blacklist>\n      <directory>vendor</directory>\n    </blacklist>\n  </filter>\n</phpunit>"
  },
  {
    "path": "src/Menu/Items/Contents/Link.php",
    "content": "<?php\nnamespace Menu\\Items\\Contents;\n\nuse HtmlObject\\Traits\\Helpers;\nuse HtmlObject\\Link as HtmlLink;\nuse Menu\\Menu;\nuse Menu\\Traits\\Content;\nuse Underscore\\Methods\\StringsMethods;\n\n/**\n * A Link in an Item\n */\nclass Link extends HtmlLink\n{\n  /**\n   * URL segments that you want to hide from the\n   * generated URL when using ->prefixParents()\n   *\n   * @var array\n   */\n  private $hidden = array(\n    '#',\n    'javascript:',\n  );\n\n  /**\n   * The link's URL\n   *\n   * @var string\n   */\n  protected $href;\n\n  /**\n   * An array of properties to be injected as attributes\n   *\n   * @var array\n   */\n  protected $injectedProperties = array('href');\n\n  /**\n   * Build a new Link\n   *\n   * @param string $url        Its URL\n   * @param string $value      Its text\n   * @param array  $attributes Facultative attributes\n   */\n  public function __construct($url, $value = null, $attributes = array())\n  {\n    $this->attributes = $attributes;\n    $this->value      = $value;\n    $this->href       = $url;\n  }\n\n  /**\n   * Change the Link's URL\n   *\n   * @param string $href An URL\n   *\n   * @return Link\n   */\n  public function href($href)\n  {\n    $this->href = $href;\n\n    return $this;\n  }\n\n  /**\n   * Get the link's href\n   *\n   * @return string the href\n   */\n  public function getUrl()\n  {\n    return $this->href;\n  }\n\n  /**\n   * Break off a chain\n   *\n   * @return Item\n   */\n  public function stop()\n  {\n    return $this->getParent(1);\n  }\n\n  /**\n   * Render the Link\n   *\n   * @return string\n   */\n  public function render()\n  {\n    $this->href = $this->getEvaluatedUrl();\n\n    // Don't compote URL if special URL\n    if (!$this->isSpecialUrl()) {\n      $this->href = Menu::getContainer()->bound('url')\n        ? Menu::getContainer('url')->to($this->href)\n        : $this->href;\n    }\n\n    return parent::render();\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ////////////////////////////// HELPERS /////////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Get the content type\n   *\n   * @return boolean\n   */\n  public function isLink()\n  {\n    return true;\n  }\n\n  /**\n   * Whether the link is special or not\n   *\n   * @return boolean\n   */\n  public function isSpecialUrl()\n  {\n    foreach ($this->hidden as $hidden) {\n      if (StringsMethods::startsWith($this->href, $hidden)) return true;\n    }\n\n    return false;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  /////////////////////// PREFIXES AND SEGMENTS //////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Get the evaluated URL based on the prefix settings\n   *\n   * @return string\n   */\n  public function getEvaluatedUrl()\n  {\n    $segments = array();\n\n    // If the URL is just an hash, don't do shit\n    if (!$this->getParent() or $this->isSpecialUrl()) {\n      return $this->href;\n    }\n\n    // Prepend list prefix\n    $listPrefix = $this->getParent(1)->getOption('item_list.prefix');\n    if (!is_null($listPrefix)) {\n      $segments[] = $listPrefix;\n    }\n\n    // Prepend parent item prefix\n    $prefixParents = $this->getParent(1)->getOption('item_list.prefix_parents');\n    if ($prefixParents) {\n      $segments += $this->getParentItemsUrls();\n    }\n\n    // Prepend handler prefix\n    $prefixHandler = $this->getParent(1)->getOption('item_list.prefix_handler');\n    if ($prefixHandler) {\n      $segments[] = $this->getHandlerSegment();\n    }\n\n    $segments[] = $this->href;\n\n    return implode('/', $segments);\n  }\n\n  /**\n   * Get all the parent Items\n   *\n   * @return array An array of Items\n   */\n  protected function getParentItems()\n  {\n    $parents = array();\n\n    $list = $this->getParent(1);\n\n    while ($list->getParent()) {\n      $parents[] = $list->getParent();\n\n      $parent = $list->getParent(1);\n      $list = $parent ? $list->getParent(1) : null;\n    }\n\n    return array_reverse($parents);\n  }\n\n  /**\n   * Get all the parent Lists\n   *\n   * @return array An array of Lists\n   */\n  protected function getParentLists()\n  {\n    $parents = array();\n\n    $list   = $this->getParent(1);\n    $parent = $list->getParent() ?: null;\n    $parents[] = $list;\n\n    while ($list and $parent) {\n      $parents[] = $parent;\n      $list = $parent ?: null;\n    }\n\n    return array_reverse($parents);\n  }\n\n  /**\n   * Get the handler of the Menu containing this link\n   *\n   * @return string\n   */\n  protected function getHandlerSegment()\n  {\n    $parentLists = $this->getParentLists();\n    $handler = array_pop($parentLists);\n\n    return $handler->name;\n  }\n\n  /**\n   * Get the URL of the parent Items\n   *\n   * @return array\n   */\n  protected function getParentItemsUrls()\n  {\n    $urls = array();\n\n    foreach ($this->getParentItems() as $item) {\n      if (!is_object($item)) continue;\n\n      if (\n        $item->value->isLink() and\n        !$item->value->isSpecialUrl() and\n        !is_null($item->value->href)) {\n          $urls[] = $item->value->href;\n      }\n    }\n\n    return $urls;\n  }\n}\n"
  },
  {
    "path": "src/Menu/Items/Contents/Raw.php",
    "content": "<?php\nnamespace Menu\\Items\\Contents;\n\nuse Menu\\Traits\\Content;\n\n/**\n * Raw content in an Item\n */\nclass Raw extends Content {}\n"
  },
  {
    "path": "src/Menu/Items/Item.php",
    "content": "<?php\nnamespace Menu\\Items;\n\nuse HtmlObject\\Element;\nuse HtmlObject\\Traits\\Tag;\n\nuse Menu\\Menu;\nuse Menu\\Traits\\Content;\nuse Menu\\Traits\\MenuObject;\nuse Menu\\MenuHandler;\n\nuse Underscore\\Methods\\ArraysMethods;\n\n/**\n * An Item in a list\n */\nclass Item extends MenuObject\n{\n  /**\n   * Array of patterns to match the active state\n   *\n   * @var array\n   */\n  protected $patterns = array();\n\n  /**\n   * Create a new item instance\n   *\n   * @param ItemList $parent   The parent\n   * @param Tag      $value    The content\n   * @param array    $children Facultative children ItemLists\n   * @param array    $element  The Item element\n   * @param string   $beforeContent  String to add before the content\n   * @param string   $afterContent   String to add after the content\n   */\n  public function __construct(ItemList $parent, Tag $value, $children = null, $element = null, $beforeContent = null, $afterContent = null)\n  {\n    $this->parent   = $parent;\n    $this->children = is_null($children) ? new ItemList() : $children;\n    $this->element = $element;\n    $this->beforeContent = $beforeContent;\n    $this->afterContent = $afterContent;\n\n    // Create content\n    $this->value = $value->setParent($this);\n  }\n\n  /**\n   * Add an pattern to $patterns array\n   *\n   * @param string|array  $pattern The pattern\n   * @param string        $name  Its name\n   *\n   */\n  public function setActivePatterns($pattern, $name = null)\n  {\n    if (!$name) $name = sizeof($this->patterns);\n    $this->patterns[$name] = $pattern;\n  }\n\n  /**\n   * Break off a chain\n   *\n   * @return ItemList\n   */\n  public function stop()\n  {\n    return $this->getParent();\n  }\n\n  /**\n   * Get the Item's content\n   *\n   * @return Content\n   */\n  public function getContent()\n  {\n    return $this->value;\n  }\n\n  /**\n   * Set the value to be inserted before the item's content\n   *\n   * @param string $value The value to insert\n   */\n  public function setBeforeContent($value)\n  {\n    $this->beforeContent = $value;\n    return $this;\n  }\n\n  /**\n   * Set the value to be inserted after the item's content\n   *\n   * @param string $value The value to insert\n   */\n  public function setAfterContent($value)\n  {\n    $this->beforeContent = $value;\n    return $this;\n  }\n\n  /**\n   * Set the Item's element\n   *\n   * @param string $element\n   */\n  public function setElement($element = null)\n  {\n    $this->setOption('item.element', $element);\n\n    return $this;\n  }\n\n  /**\n   * Get the Item's element\n   *\n   * @return string\n   */\n  public function getElement()\n  {\n    if(is_null($this->element))\n    {\n      return $this->getOption('item.element');\n    }\n\n    return $this->element;\n  }\n\n  /**\n   * Render the item\n   *\n   * @param array\n   *\n   * @return string\n   */\n  public function render($depth = 0)\n  {\n    // Add the active classes\n    $value = is_null($this->beforeContent) ? '' : $this->beforeContent;\n    $value .= $this->value->render();\n    $value .= is_null($this->afterContent) ? '' : $this->afterContent;\n\n    $this->addActiveClasses();\n\n    // Render children if any\n    if ($this->hasChildren()) {\n      $value .= $this->children->render($depth);\n    }\n\n    // Facultatively render an element around the item\n    $element = $this->getElement();\n    if ($element) $value = Element::create($element, $value, $this->attributes)->render();\n    return html_entity_decode($value, ENT_QUOTES, 'UTF-8');\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ///////////////////////// PUBLIC INTERFACE /////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Check if this item is active\n   *\n   * @return boolean\n   */\n  public function isActive()\n  {\n    if( ! $this->value->isLink()) {\n      return false;\n    }\n\n    return\n      trim($this->getUrl(), '/') == trim($this->getRequest()->getPathInfo(), '/') or\n      $this->getUrl() == $this->getRequest()->fullUrl() or\n      $this->getUrl() == $this->getRequest()->url() or\n      $this->hasActivePatterns();\n  }\n\n  public function hasChildren()\n  {\n    return count($this->children->getChildren()) > 0;\n  }\n\n  /**\n   * Check if this item has an active pattern\n   *\n   * @return boolean\n   */\n  protected function hasActivePatterns()\n  {\n    foreach ($this->patterns as $pattern) {\n      $path = $this->getRequest()->getPathInfo();\n\n      if (is_array($pattern)) {\n        foreach ($pattern as $p)\n          $isActive = preg_match('/'.$p.'/i', $path);\n      } else {\n        $isActive = preg_match('/'.$pattern.'/i', $path);\n      }\n\n      if($isActive) return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Check if this item has an active child\n   *\n   * @return boolean\n   */\n  public function hasActiveChild()\n  {\n    if (!$this->hasChildren()) {\n      return false;\n    }\n\n    foreach ($this->children->getChildren() as $child) {\n      if ($child->isActive()) {\n        return true;\n      }\n\n      if ($child->hasChildren()) {\n        return $child->hasActiveChild();\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * Get the url of the Item's content\n   *\n   * @return string\n   */\n  protected function getUrl()\n  {\n    return $this->value->isLink() ? $this->value->getEvaluatedUrl() : null;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ////////////////////////////// HELPERS /////////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Add the various active classes to an array of attributes\n   */\n  private function addActiveClasses()\n  {\n    if ($this->isActive()) {\n      $this->addClass($this->getOption('item.active_class'));\n    }\n\n    if ($this->hasActiveChild()) {\n      $this->addClass($this->getOption('item.active_child_class'));\n    }\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  //////////////////////////// DEPENDENCIES //////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Get the Request instance\n   *\n   * @return Request\n   */\n  public function getRequest()\n  {\n    return Menu::getContainer('request');\n  }\n\n}\n"
  },
  {
    "path": "src/Menu/Items/ItemList.php",
    "content": "<?php\nnamespace Menu\\Items;\n\nuse Exception;\n\nuse HtmlObject\\Element;\n\nuse Menu\\Menu;\nuse Menu\\MenuHandler;\nuse Menu\\Items\\Contents\\Link;\nuse Menu\\Items\\Contents\\Raw;\nuse Menu\\Traits\\MenuObject;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Str;\n\nuse Underscore\\Methods\\ArraysMethods;\n\n/**\n * A container for Items\n */\nclass ItemList extends MenuObject\n{\n  /**\n   * The name of this ItemList\n   *\n   * @var string\n   */\n  public $name;\n\n  /**\n   * Create a new Item List instance\n   *\n   * @param string  $name        The ItemList's name\n   * @param array   $attributes  Attributes for the ItemList's HMTL element\n   * @param string  $element     The HTML element for the ItemList\n   *\n   * @return void\n   */\n  public function __construct($items = array(), $name = null, $attributes = array(), $element = null)\n  {\n    $this->children   = $items;\n    $this->name       = $name;\n    $this->attributes = $attributes;\n    $this->element  = $element;\n  }\n\n  /**\n   * Get the last Item\n   *\n   * @return Item\n   */\n  public function onItem()\n  {\n    return $this->children[sizeof($this->children) - 1];\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ///////////////////////// PUBLIC INTERFACE /////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Set a particular option in the array\n   *\n   * @param string $option The option\n   * @param mixed  $value  Its new value\n   *\n   * @return MenuObject\n   */\n  public function setOption($option, $value)\n  {\n    // forward item config values to the items\n    if(Str::startsWith($option, 'item.')) {\n      foreach($this->children as $child) {\n        $child->setOption($option, $value);\n      }\n    }\n    elseif(Str::startsWith($option, 'item_list.')) {\n      $this->options = ArraysMethods::set($this->options, $option, $value);\n    }\n    else\n    {\n      Menu::setOption($option, $value);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Add a link item to the ItemList instance.\n   *\n   * <code>\n   *    // Add a item to the default menu\n   *    Menu::add('home', 'Homepage');\n   *\n   *    // Add a item with a subitem to the default menu\n   *    Menu::add('home', 'Homepage', Menu::items()->add('home/sub', 'Subitem'));\n   *\n   *    // Add a item with attributes for the item's HTML element\n   *    Menu::add('home', 'Homepage', null, array('class' => 'fancy'));\n   * </code>\n   *\n   * @param string   $url             Url of the link\n   * @param string   $value           (H)T(ML) inside of the link\n   * @param ItemList $children        Children\n   * @param array    $linkAttributes  Attributes for the link\n   * @param array    $itemAttributes  Attributes for the item\n   * @param string   $itemElement     The element for the item\n   * @param string   $beforeContent   String to add before the link\n   * @param string   $afterContent    String to add after the link\n   *\n   * @return ItemList\n   */\n  public function add($url, $value, $children = null, $linkAttributes = array(), $itemAttributes = array(), $itemElement = null, $beforeContent = null, $afterContent = null)\n  {\n    $content = new Link($url, $value, $linkAttributes);\n    $item = $this->addContent($content, $children, $itemAttributes, $itemElement, $beforeContent, $afterContent);\n\n    return $this;\n  }\n\n  /**\n   * Add a raw html item to the ItemList instance.\n   *\n   * <code>\n   *    // Add a raw item to the default main menu\n   *    Menu::raw('<img src=\"img/seperator.gif\">');\n   * </code>\n   *\n   * @param string   $raw            The raw content\n   * @param ItemList $children       Children\n   * @param array    $itemAttributes The item attributes\n   * @param string   $itemElement    The item element\n   * @param string   $beforeContent  String to add before the raw content\n   * @param string   $afterContent   String to add after the raw content\n   *\n   * @return ItemList\n   */\n  public function raw($raw, $children = null, $itemAttributes = array(), $itemElement = null, $beforeContent = null, $afterContent = null)\n  {\n    $content = new Raw($raw);\n    $item = $this->addContent($content, $children, $itemAttributes, $itemElement, $beforeContent, $afterContent);\n\n    return $this;\n  }\n\n  /**\n   * Add content to the ItemList\n   *\n   * @param Content   $content        Content object\n   * @param ItemList  $children       Children\n   * @param array     $itemAttributes Attributes for the item (li)\n   * @param string    $itemElement    Element for the item (li is default)\n   * @param string    $beforeContent  String to add before the content\n   * @param string    $afterContent   String to add after the content\n   */\n  public function addContent($content, $children = null, $itemAttributes = array(), $itemElement = null, $beforeContent = null, $afterContent = null)\n  {\n    $item = new Item($this, $content, $children, $itemElement, $beforeContent, $afterContent);\n    $item->setAttributes($itemAttributes);\n\n    // Set Item as parent of its children\n    if (!is_null($children)) {\n      $children->setParent($item);\n    }\n\n    $this->setChild($item);\n\n    return $item;\n  }\n\n  /**\n   * Add an active pattern to the ItemList instance.\n   *\n   * <code>\n   *    // Add a item to the default menu and set an active class for /user/5/edit\n   *    Menu::add('user', 'Users')->activePattern('\\/user\\/\\d\\/edit');\n   * </code>\n   *\n   * @param string   $pattern\n   *\n   * @return ItemList\n   */\n  public function activePattern($pattern)\n  {\n    $pattern = (array) $pattern;\n    $item = end($this->children);\n    $item->setActivePatterns($pattern);\n\n    return $this;\n  }\n\n  /**\n   * Add menu items to another ItemList.\n   *\n   * <code>\n   *    // Attach menu items to the default MenuHandler\n   *    Menu::attach(Menu::items()->add('home', 'Homepage'));\n   * </code>\n   *\n   * @param  ItemList $itemList\n   *\n   * @return ItemList\n   */\n  public function attach(ItemList $itemList)\n  {\n    $this->nestChildren($itemList->getChildren());\n\n    return $this;\n  }\n\n  /**\n   * Set the name for this ItemList\n   *\n   * @param string  $name\n   *\n   * @return ItemList\n   */\n  public function name($name)\n  {\n    $this->name = $name;\n\n    return $this;\n  }\n\n  /**\n   * Get the name of the ItemList\n   *\n   * @return string Name of the ItemList\n   */\n  public function getName()\n  {\n    return $this->name;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ///////////////////////////// PREFIXES /////////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Prefix this ItemList with a string\n   *\n   * @param string $prefix\n   *\n   * @return ItemList\n   */\n  public function prefix($prefix)\n  {\n    $this->setOption('item_list.prefix', $prefix);\n\n    return $this;\n  }\n\n  /**\n   * Prefix this ItemList with the parent ItemList(s) name(s)\n   *\n   * @param boolean $prefixParents\n   *\n   * @return ItemList\n   */\n  public function prefixParents($prefixParents = true)\n  {\n    $this->setOption('item_list.prefix_parents', $prefixParents);\n\n    return $this;\n  }\n\n  /**\n   * Prefix this ItemList with the name of the ItemList at the very top of the tree\n   *\n   * @param boolean $prefixMenuHandler\n   *\n   * @return ItemList\n   */\n  public function prefixMenuHandler($prefixMenuHandler = true)\n  {\n    $this->setOption('item_list.prefix_handler', $prefixMenuHandler);\n\n    return $this;\n  }\n\n  /**\n   * Set the Item's element\n   *\n   * @param string $element\n   */\n  public function setElement($element = null)\n  {\n    $this->element = $element;\n    return $this;\n  }\n\n  /**\n   * Get the Item's element\n   *\n   * @return string\n   */\n  public function getElement()\n  {\n    if (is_null($this->element)) {\n      return $this->getOption('item_list.element');\n    }\n\n    return $this->element;\n  }\n\n  /**\n   * Get all items with the depth as key\n   *\n   * @return array\n   */\n  public function getItemsWithDepth()\n  {\n    return $this->getItemsRecursivelyWithDepth($this->getChildren());\n  }\n\n  /**\n   * Get all items for an array of items recursively for a specific depth\n   *\n   * @return array\n   */\n  protected function getItemsRecursivelyWithDepth($items, $depth = 0)\n  {\n    $results = array();\n    foreach($items as $item)\n    {\n      $results[$depth][] = $item;\n\n      $subItems = $item->getChildren()\n        ->getChildren();\n      foreach($this->getItemsRecursivelyWithDepth($subItems, $depth + 1) as $childrenDepth => $children)\n      {\n        foreach($children as $child)\n        {\n          $results[$childrenDepth][] = $child;\n        }\n      }\n    }\n\n    return $results;\n  }\n\n  /**\n   * Get all itemlists with the depth as key\n   *\n   * @return array\n   */\n  public function getItemListsWithDepth()\n  {\n    return $this->getItemListsRecursivelyWithDepth($this);\n  }\n\n  /**\n   * Get all itemlists for an itemlsit recursively for a specific depth\n   *\n   * @return array\n   */\n  protected function getItemListsRecursivelyWithDepth($itemList, $depth = 0)\n  {\n    $results = array();\n\n    $results[$depth][] = $itemList;\n\n    $items = $itemList->getChildren();\n    foreach($items as $item)\n    {\n      foreach($this->getItemListsRecursivelyWithDepth($item->getChildren(), $depth + 1) as $childrenDepth => $children)\n      {\n        foreach($children as $child)\n        {\n          $results[$childrenDepth][] = $child;\n        }\n      }\n    }\n\n    return $results;\n  }\n\n  /**\n   * Get all items\n   *\n   * @return \\Vespakoen\\Menu\\MenuHandler\n   */\n  public function getAllItems()\n  {\n    $results = array();\n\n    foreach($this->getItemsWithDepth() as $depth => $items)\n    {\n      foreach($items as $item)\n      {\n        $results[] = $item;\n      }\n    }\n\n    return new MenuHandler($results);\n  }\n\n  /**\n   * Get items by their content type\n   *\n   * @param  string $contentType The full object name\n   *\n   * @return \\VEspakoen\\Menu\\MenuHandler\n   */\n  public function getItemsByContentType($contentType)\n  {\n    $results = array();\n\n    $itemList = $this->getAllItems();\n    foreach($itemList->getMenuObjects() as $item)\n    {\n      $content = $item->getContent();\n      if(get_class($content) == $contentType)\n      {\n        $results[] = $item;\n      }\n    }\n\n    return new MenuHandler($results);\n  }\n\n  /**\n   * Get all itemlists\n   *\n   * @return \\Vespakoen\\Menu\\MenuHandler\n   */\n  public function getAllItemLists()\n  {\n    $results = array();\n\n    foreach($this->getItemListsWithDepth() as $depth => $items)\n    {\n      foreach($items as $item)\n      {\n        $results[] = $item;\n      }\n    }\n\n    return new MenuHandler($results);\n  }\n\n  /**\n   * Get all itemslists including this one\n   *\n   * @return \\Vespakoen\\Menu\\MenuHandler\n   */\n  public function getAllItemListsIncludingThisOne()\n  {\n    return $this->getAllItemLists()\n      ->addMenuObject($this);\n  }\n\n  /**\n   * Get itemlists at a certain depth\n   *\n   * @return \\Vespakoen\\Menu\\MenuHandler\n   */\n  public function getItemListsAtDepth($depth)\n  {\n    $itemListsWithDepth = $this->getItemListsWithDepth();\n    if (array_key_exists($depth, $itemListsWithDepth)) {\n      return new MenuHandler($itemListsWithDepth[$depth]);  \n    }\n    return new MenuHandler(array());\n  }\n\n  /**\n   * Get itemlists in a range of depths\n   *\n   * @return \\Vespakoen\\Menu\\MenuHandler\n   */\n  public function getItemListsAtDepthRange($from, $to)\n  {\n    $itemListsWithDepth = $this->getItemListsWithDepth();\n\n    $results = array();\n    foreach($itemListsWithDepth as $depth => $itemLists)\n    {\n      if($depth >= $from && $depth <= $to)\n      {\n        foreach($itemLists as $itemList)\n        {\n          $results[] = $itemList;\n        }\n      }\n    }\n\n    return new MenuHandler($results);\n  }\n\n  /**\n   * Get all items at a certain depth\n   *\n   * @return \\Vespakoen\\Menu\\MenuHandler\n   */\n  public function getItemsAtDepth($depth)\n  {\n    $itemsWithDepth = $this->getItemsWithDepth();\n    if (array_key_exists($depth, $itemsWithDepth)) {\n      return new MenuHandler($itemsWithDepth[$depth]);  \n    }\n    return new MenuHandler(array());\n  }\n\n  /**\n   * Get items in a range of depths\n   *\n   * @return \\Vespakoen\\Menu\\MenuHandler\n   */\n  public function getItemsAtDepthRange($from, $to)\n  {\n    $itemsWithDepth = $this->getItemsWithDepth();\n\n    $results = array();\n    foreach($itemsWithDepth as $depth => $items)\n    {\n      if($depth >= $from && $depth <= $to)\n      {\n        foreach($items as $item)\n        {\n          $results[] = $item;\n        }\n      }\n    }\n\n    return new MenuHandler($results);\n  }\n\n  public function reverse()\n  {\n    $this->children = array_reverse($this->children);\n\n    return $this;\n  }\n\n  public function findActiveItem()\n  {\n    $items = $this->getAllItems()\n      ->getMenuObjects();\n\n    // Find the active one\n    foreach($items as $item) {\n      if($item->isActive()) {\n        return $item;\n      }\n    }\n\n    return null;\n  }\n\n  public function getSubmenu()\n  {\n    if($activeItem = $this->findActiveItem())\n    {\n      return $activeItem->getChildren();\n    }\n\n    return new ItemList;\n  }\n\n  public function breadcrumbs()\n  {\n    // Collect all items\n    $activeItem = $this->findActiveItem();\n\n    $separator  = $this->getOption('item_list.breadcrumb_separator');\n\n    // Make the breadcrumbs\n    $itemList = new ItemList(array(), 'breadcrumbs');\n\n    // Fill her up if we found the active link\n    if( ! is_null($activeItem)) {\n      // Add the found item\n      $itemList->addContent($activeItem->getContent());\n      // Loop throught the parents until we hit the root\n      while($nextItem = $activeItem->getParent()) {\n        if(is_null($nextItem->getParent())) break;\n\n        // Add a separator and the link\n        if ( ! empty($separator))\n        {\n          $itemList->raw($separator);\n        }\n\n        $itemList->addContent($nextItem->getParent()->getContent());\n\n        // Set the activeItem for the next iteration\n        $activeItem = $nextItem->getParent();\n      }\n    }\n\n    // Correct order\n    $itemList->reverse();\n\n    return $itemList;\n  }\n\n  public function map($callback)\n  {\n    array_map($callback, $this->children);\n\n    return $this;\n  }\n\n  /**\n   * Find an itemlist by it's name\n   *\n   * @return \\Vespakoen\\Menu\\Items\\ItemLists|false\n   */\n  public function findItemListByName($name)\n  {\n    $itemLists = $this->getAllItemListsIncludingThisOne()\n      ->getMenuObjects();\n    foreach($itemLists as $itemList)\n    {\n      if($itemList->getName() == $name)\n      {\n        return $itemList;\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * Find an itemlist by it's name\n   *\n   * alias for findItemListByName\n   *\n   * @return \\Vespakoen\\Menu\\Items\\ItemLists|false\n   */\n  public function findByName($name)\n  {\n    return $this->findItemListByName($name);\n  }\n\n  /**\n   * Find an itemlist by it's name\n   *\n   * alias for findItemListByName\n   *\n   * @return \\Vespakoen\\Menu\\Items\\ItemLists|false\n   */\n  public function find($name)\n  {\n    return $this->findItemListByName($name);\n  }\n\n  /**\n   * Find an item by an attribute\n   *\n   * @return \\Vespakoen\\Menu\\Items\\Item|false\n   */\n  public function findItemByAttribute($key, $value)\n  {\n    $itemLists = $this->getAllItemListsIncludingThisOne()\n      ->getMenuObjects();\n\n    foreach($itemLists as $itemList)\n    {\n      if($itemList->getAttibute($key) == $value)\n      {\n        return $itemList;\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * Find an item by it's link's URL\n   *\n   * @return \\Vespakoen\\Menu\\Items\\Item|false\n   */\n  public function findItemByUrl($url)\n  {\n    $itemList = $this->getItemsByContentType('Menu\\Items\\Contents\\Link');\n    foreach($itemList->getChildren() as $item)\n    {\n      $content = $item->getContent();\n      if($content->getUrl() == $url)\n      {\n        return $item;\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * Easily create items while looping over DB results\n   * that have a reference to the parent (usually via parentId)\n   *\n   * <code>\n   *     Menu::hydrate(function($parentId)\n   *       {\n   *         return Page::where('parent_id', $parentId)\n   *           ->get();\n   *       },\n   *       function($children, $page)\n   *       {\n   *         $children->add($page->slug, $page->name);\n   *       });\n   * </code>\n   *\n   * @param Closure $resolver   the callback to resolve results for a given parentId\n   * @param Closure $decorator  the callback that modifies the ItemList for the given node\n   * @param integer $idField    the id column that matches with the parentId\n   * @param integer $parentId   the parentId to start hydrating from\n   *\n   * @return ItemList the\n   */\n  public function hydrate($resolver, $decorator, $idField = 'id', $parentIdField = 'parent_id', $parentId = 0)\n  {\n    $items = is_callable($resolver) ? $resolver() : $resolver;\n\n    if($items instanceof Collection)\n    {\n      $items = $items->all();\n    }\n\n    $itemsForThisLevel = array_filter($items, function($item) use ($parentId, $parentIdField)\n    {\n      return $parentId == (is_object($item) ? (isset($item->$parentIdField) ? $item->$parentIdField : 0) : (isset($item[$parentIdField]) ? $item[$parentIdField] : 0));\n    });\n\n    foreach($itemsForThisLevel as $item)\n    {\n      // Let the decorator add the item(s) (and maybe set some attributes)\n      $decorator($this, $item);\n\n      // Grab the newest item\n      $newestItem = end($this->children);\n\n      // If there is an item, add hydrate it\n      if($newestItem)\n      {\n        // Grab the newest itemlist\n        $newestItemList = $newestItem->getChildren();\n\n        // Get the id of the item\n        $parentId = is_object($item) ? $item->$idField : $item[$idField];\n\n        // Hydrate the children\n        $newestItemList->hydrate($items, $decorator, $idField, $parentIdField, $parentId);\n      }\n    }\n\n    return $this;\n  }\n\n  /**\n   * Get the evaluated string content of the ItemList.\n   *\n   * @param  integer $depth The depth at which the ItemList should be rendered\n   *\n   * @return string\n   */\n  public function render($depth = 0)\n  {\n    if( ! is_int($depth))\n    {\n      throw new Exception(\"The render method doesn't take any arguments anymore, you can now configure your menu via the config file.\");\n    }\n\n    // Check for maximal depth\n    $maxDepth = $this->getOption('max_depth');\n    if ($maxDepth !== -1 and $depth > $maxDepth) return false;\n\n    // Render contained items\n    $contents = null;\n    if(count($this->children) == 0)\n    {\n      return \"\";\n    }\n\n    foreach ($this->children as $item) {\n      $contents .= $item->render($depth + 1);\n    }\n\n    $element = $this->getElement();\n    if ($element) $contents = Element::create($element, $contents, $this->attributes)->render();\n    return $contents;\n  }\n}\n"
  },
  {
    "path": "src/Menu/Menu.php",
    "content": "<?php\nnamespace Menu;\n\nuse Illuminate\\Config\\FileLoader;\nuse Illuminate\\Config\\Repository;\nuse Illuminate\\Container\\Container;\nuse Illuminate\\Http\\Request;\nuse Menu\\Items\\ItemList;\n\n/**\n * Basic interface to different components within the package\n */\nclass Menu\n{\n\n  /**\n   * The current IoC container\n   * @var Container\n   */\n  protected static $container;\n\n  /**\n   * All the registered names and the associated ItemLists\n   *\n   * @var array\n   */\n  protected static $itemLists = array();\n\n  /**\n   * Get a MenuHandler.\n   *\n   * This method will retrieve ItemLists by name,\n   * If an ItemList doesn't already exist, it will\n   * be registered and added to the handler.\n   *\n   * <code>\n   *    // Get the menu handler that handles the default name\n   *    $handler = Menu::handler();\n   *\n   *    // Get a named menu handler for a single name\n   *    $handler = Menu::handler('backend');\n   *\n   *    // Get a menu handler that handles multiple names\n   *    $handler = Menu::handler(array('admin', 'sales'));\n   * </code>\n   *\n   * @param string|array $names      The name this handler should respond to\n   * @param array        $attributes Its attributes\n   * @param string       $element    Its element\n   *\n   * @return MenuHandler\n   */\n  public static function handler($names = '', $attributes = array(), $element = 'ul')\n  {\n    $names = (array) $names;\n\n    $itemLists = array();\n    // Create a new ItemList instance for the names that don't exist yet\n    foreach ($names as $name) {\n      if (!array_key_exists($name, static::$itemLists)) {\n        $itemList = new ItemList(array(), $name, $attributes, $element);\n        static::setItemList($name, $itemList);\n      }\n      else {\n        $itemList = static::getItemList($name);\n      }\n\n      $itemLists[] = $itemList;\n    }\n\n    // Return a Handler for the item lists\n    return new MenuHandler($itemLists);\n  }\n\n  /**\n   * Get a MenuHandler for all registered ItemLists\n   *\n   * @return MenuHandler\n   */\n  public static function allHandlers()\n  {\n    return new MenuHandler(static::$itemLists);\n  }\n\n  /**\n   * Erase all menus in memory\n   */\n  public static function reset()\n  {\n    static::$itemLists = array();\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  //////////////////////// ITEM LISTS MANAGING ///////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Create a new ItemList\n   *\n   * @param string $name       The name of the ItemList\n   * @param array  $attributes The HTML attributes for the list element\n   * @param string $element    The HTML element for the list (ul or dd)\n   *\n   * @return ItemList\n   */\n  public static function items($name = null, $attributes = array(), $element = 'ul')\n  {\n    return new ItemList(array(), $name, $attributes, $element);\n  }\n\n  /**\n   * Store an ItemList in memory\n   *\n   * @param  string   $name     The handle to store it to\n   * @param  ItemList $itemList\n   *\n   * @return ItemList\n   */\n  public static function setItemList($name, $itemList)\n  {\n    static::$itemLists[$name] = $itemList;\n\n    return $itemList;\n  }\n\n  /**\n   * Get an ItemList from the memory\n   *\n   * @param string $name The ItemList handle\n   *\n   * @return ItemList\n   */\n  public static function getItemList($name = null)\n  {\n    if (is_null($name)) return static::$itemLists;\n    return static::$itemLists[$name];\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  /////////////////////////// MAGIC METHODS //////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Magic Method for calling methods on the default handler.\n   *\n   * <code>\n   *    // Call the \"render\" method on the default handler\n   *    echo Menu::render();\n   *\n   *    // Call the \"add\" method on the default handler\n   *    Menu::add('home', 'Home');\n   * </code>\n   *\n   * @param string $method\n   * @param array  $parameters\n   *\n   * @return mixed\n   */\n  public static function __callStatic($method, $parameters = array())\n  {\n    return call_user_func_array(array(static::handler(), $method), $parameters);\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  /////////////////////// DEPENDENCY INJECTIONS //////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Get the current dependencies\n   *\n   * @param string $dependency A dependency to make on the fly\n   *\n   * @return Container\n   */\n  public static function getContainer($dependency = null)\n  {\n    if (!static::$container) {\n      $container = new Container;\n\n      // Create HTML\n      $container->bindIf('html', 'LaravelBook\\Laravel4Powerpack\\HTML');\n\n      // Create basic Request instance to use\n      $container->alias('Symfony\\Component\\HttpFoundation\\Request', 'request');\n      $container->bindIf('Symfony\\Component\\HttpFoundation\\Request', function() {\n        return Request::createFromGlobals();\n      });\n\n      static::setContainer($container);\n    }\n\n    // Shortcut for getting a dependency\n    if ($dependency) {\n      return static::$container->make($dependency);\n    }\n\n    return static::$container;\n  }\n\n  /**\n   * Set the Container to use\n   *\n   * @param Container $container\n   */\n  public static function setContainer($container)\n  {\n    static::$container = $container;\n  }\n\n  /**\n   * Get an option from the options array\n   *\n   * @param string $option The option key\n   *\n   * @return mixed Its value\n   */\n  public static function getOption($option = null)\n  {\n      if ($option == null) {\n\n        return static::getContainer('config')->get('menu');\n      }\n\n      return static::getContainer('config')->get('menu.'.$option);\n  }\n\n  /**\n   * Set a global option\n   *\n   * @param key   $option The option\n   * @param mixed $value  Its value\n   */\n  public static function setOption($option, $value)\n  {\n      if ($option == null) {\n          $option = 'config';\n      }\n      static::getContainer('config')->set('menu.'.$option, $value);\n  }\n\n}\n"
  },
  {
    "path": "src/Menu/MenuHandler.php",
    "content": "<?php\nnamespace Menu;\n\nuse Menu\\Items\\ItemList;\nuse Illuminate\\Support\\Str;\nuse Exception;\n\n/**\n * Handles various instances of ItemList at once\n */\nclass MenuHandler\n{\n\n  /**\n   * The ItemList or Item instances this handler acts on\n   *\n   * @var array\n   */\n  protected $menuObjects = array();\n\n  public static $override = array(\n    'add',\n    'set',\n    'wrap'\n  );\n\n  public static $responses = array(\n    'getHandlerFromResults' => array(\n      'getAllItems',\n      'getItemsAtDepth',\n      'getItemsAtDepthRange',\n      'getItemsByContentType',\n      'getAllItemLists',\n      'getSubmenu',\n      'getItemListsAtDepth',\n      'getItemListsAtDepthRange',\n      'onItem',\n      'getContent',\n      'stop',\n      'filter'\n    ),\n    'getMatchFromResults' => array(\n      'findItemListByName',\n      'findActiveItem',\n      'findByName',\n      'findItemByUrl',\n      'find'\n    ),\n    'getCombinedResults' => array(\n      'lists'\n    ),\n    'getCombindedResultsByKey' => array(\n      'getItemsWithDepth',\n      'getItemListsWithDepth'\n    ),\n    'getImplodedResults' => array(\n      'render'\n    )\n  );\n\n  /**\n   * Set the menuobjects on which this menu should act\n   *\n   * @param array $menuObjects The menuobjects\n   *\n   * @return void\n   */\n  public function __construct($menuObjects = array())\n  {\n    $this->menuObjects = $menuObjects;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ////////////////////////// PUBLIC INTERFACE ////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  public function setMenuObjects($menuObjects)\n  {\n    $this->menuObjects = $menuObjects;\n\n    return $this;\n  }\n\n  public function getMenuObjects()\n  {\n    return $this->menuObjects;\n  }\n\n  public function addMenuObject($menuObject)\n  {\n    $this->menuObjects[] = $menuObject;\n\n    return $this;\n  }\n\n  public function map($callback)\n  {\n    array_map($callback, $this->getMenuObjects());\n  }\n\n  public function breadcrumbs($choosePath = null)\n  {\n    if(is_null($choosePath)) {\n      $choosePath = function($itemLists) {\n        return $itemLists[0];\n      };\n    }\n\n    $menuObjects = array();\n    foreach (Menu::allHandlers()->getMenuObjects() as $itemList) {\n      $breadcrumbs = $itemList->breadcrumbs();\n      if($breadcrumbs->hasChildren()) {\n        $menuObjects[] = $breadcrumbs;\n      }\n    }\n\n    if(count($menuObjects) > 1)\n    {\n      return $choosePath($menuObjects);\n    }\n\n    return isset($menuObjects[0]) ? $menuObjects[0] : new MenuHandler;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  //////////////////////////// RESPONDERS ////////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  protected function getHandlerFromResults($menuHandlers)\n  {\n    if(is_array($menuHandlers) && count($menuHandlers) > 0 && ! $menuHandlers[0] instanceof MenuHandler) {\n      foreach ($menuHandlers as &$menuHandler) {\n        $menuHandler = new MenuHandler(array($menuHandler));\n      }\n    }\n\n    $menuObjects = $this->getMenuObjectsFromHandlers($menuHandlers);\n\n    return new MenuHandler($menuObjects);\n  }\n\n  protected function getMatchFromResults($results)\n  {\n    foreach($results as $result)\n    {\n      if($result !== false)\n      {\n        return $result;\n      }\n    }\n\n    return false;\n  }\n\n  protected function getCombinedResults($results)\n  {\n    return call_user_func_array('array_merge', $results);\n  }\n\n  protected function getCombindedResultsByKey($results)\n  {\n    $combinedResults = array();\n    foreach ($results as $result)\n    {\n      foreach($result as $key => $items)\n      {\n        foreach($items as $item)\n        {\n          $combinedResults[$key][] = $item;\n        }\n      }\n    }\n\n    return $combinedResults;\n  }\n\n  protected function getImplodedResults($results)\n  {\n    return implode('', $results);\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ///////////////////////// RESULT EXTRACTORS ////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  protected function getMenuObjectsFromHandlers($menuHandlers)\n  {\n    $results = array();\n    foreach($menuHandlers as $menuHandler)\n    {\n      foreach($menuHandler->getMenuObjects() as $item)\n      {\n        $results[] = $item;\n      }\n    }\n\n    return $results;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  /////////////////////////// MAGIC METHODS //////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Magic method that will pass the incoming calls to\n   * all of the ItemLists this handler acts on\n   *\n   * @param string  $method\n   * @param array   $parameters\n   *\n   * @return MenuHandler\n   */\n  public function __call($method, $parameters = array())\n  {\n    $results = array();\n    foreach ($this->menuObjects as &$menuObject) {\n      $result = call_user_func_array(array($menuObject, $method), $parameters);\n\n      if (Str::startsWith($method, static::$override)) {\n        $menuObject = $result;\n      }\n\n      $results[] = $result;\n    }\n\n    foreach (static::$responses as $responseMethod => $methods) {\n      if(in_array($method, $methods)) {\n        return $this->$responseMethod($results);\n      }\n    }\n\n    return $this;\n  }\n\n  /**\n   * Render the MenuHandler\n   *\n   * @return string\n   */\n  public function __toString()\n  {\n    return $this->render();\n  }\n\n}\n"
  },
  {
    "path": "src/Menu/MenuServiceProvider.php",
    "content": "<?php\nnamespace Menu;\n\nuse Illuminate\\Support\\ServiceProvider;\n\n/**\n * The \"start\" file for laravel\n */\nclass MenuServiceProvider extends ServiceProvider\n{\n\n  /**\n   * Indicates if loading of the provider is deferred.\n   *\n   * @var bool\n   */\n  protected $defer = false;\n\n  /**\n   * Register the service provider.\n   *\n   * @return void\n   */\n  public function register()\n  {\n    $configPath = __DIR__ . '/../config/config.php';\n    $this->mergeConfigFrom($configPath, 'menu');\n\n    $container = Menu::getContainer();\n    $container['url'] = $this->app['url'];\n    $container['config'] = $this->app['config'];\n    Menu::setContainer($container);\n  }\n\n  /**\n   * Get the services provided by the provider.\n   *\n   * @return array\n   */\n  public function provides()\n  {\n    return array('menu');\n  }\n\n  /**\n   * Declare publishable assets\n   *\n   * @return void\n   */\n  public function boot()\n  {\n        $configPath = __DIR__ . '/../config/config.php';\n        $this->publishes([$configPath => config_path('menu.php')], 'config');\n  }\n}\n"
  },
  {
    "path": "src/Menu/Traits/Content.php",
    "content": "<?php\nnamespace Menu\\Traits;\n\nuse HtmlObject\\Text;\n\n/**\n * The base class around the different content types\n */\nclass Content extends Text\n{\n  /**\n   * Whether the content is a link or not\n   *\n   * @return boolean\n   */\n  public function isLink()\n  {\n    return false;\n  }\n\n  /**\n   * Break off a chain\n   *\n   * @return Item\n   */\n  public function stop()\n  {\n    return $this->getParent(1);\n  }\n}\n"
  },
  {
    "path": "src/Menu/Traits/MenuObject.php",
    "content": "<?php\nnamespace Menu\\Traits;\n\nuse HtmlObject\\Traits\\Tag;\nuse Menu\\Menu;\nuse Underscore\\Methods\\ArraysMethods;\n\n/**\n * Allows dynamic setting and getting of attributes\n * on the various parts of a menu (items, ItemLists, etc)\n */\nabstract class MenuObject extends Tag\n{\n\n  /**\n   * Per-element configuration\n   *\n   * @var array\n   */\n  public $options = array();\n\n  ////////////////////////////////////////////////////////////////////\n  /////////////////////////// CONFIGURATION //////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Replace an array of options\n   *\n   * @param array $options The new options\n   *\n   * @return MenuObject\n   */\n  public function replaceOptions($options)\n  {\n    $this->options = array();\n\n    foreach($options as $key => $value) {\n      $this->setOption($key, $value);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set a particular option in the array\n   *\n   * @param string $option The option\n   * @param mixed  $value  Its new value\n   *\n   * @return MenuObject\n   */\n  public function setOption($option, $value)\n  {\n    $this->options = ArraysMethods::set($this->options, $option, $value);\n\n    return $this;\n  }\n\n  /**\n   * Get a particular option in the array\n   *\n   * @param string $option An option\n   *\n   * @return mixed Its value\n   */\n  public function getOption($option = null)\n  {\n    $globalOptions = Menu::getOption();\n    $combinedOptions = array_replace_recursive($globalOptions, $this->options);\n    if (!$option) return $combinedOptions;\n    return ArraysMethods::get($combinedOptions, $option);\n  }\n}\n"
  },
  {
    "path": "src/config/config.php",
    "content": "<?php return array(\n\n  // Global options ------------------------------------------------ /\n\n  // The maximum depth a list can be generated\n  // -1 means no limit\n  'max_depth' => -1,\n\n  // Items --------------------------------------------------------- /\n\n  // Various options related to Items\n  'item' => array(\n\n    // The default Item element\n    'element' => 'li',\n\n    // Various classes to mark active items or children\n    'active_class'       => 'active',\n    'active_child_class' => 'active-child',\n  ),\n\n  // ItemLists ----------------------------------------------------- /\n\n  'item_list' => array(\n\n    // The default ItemList element\n    'element' => 'ul',\n\n    // The default breadcrumb separator, set to '' to not output any separators for\n    // use with bootstrap.\n    'breadcrumb_separator' => '/',\n\n    // A prefix to prepend the links URLs with\n    'prefix'         => null,\n\n    // Whether links should inherit their parent/handler's prefix\n    'prefix_parents' => false,\n    'prefix_handler' => false,\n  ),\n);\n"
  },
  {
    "path": "start.php",
    "content": "<?php\nrequire 'vendor/autoload.php';"
  },
  {
    "path": "tests/ItemListTest.php",
    "content": "<?php\ninclude '_start.php';\n\nuse Menu\\Menu;\nuse Menu\\Items\\Item;\nuse Menu\\Items\\ItemList;\n\nclass ItemListTest extends MenuTests\n{\n  public function testEmptyItemListRendersNothing()\n  {\n    $this->assertTrue('' == static::$itemList->render());\n  }\n\n  public function testCanCreateListsOfADifferentElement()\n  {\n    $list = static::$itemList->add('some', 'item');\n    $list->setElement('ol');\n\n    $this->assertHTML($this->matchList('ol'), $list->render());\n  }\n\n  public function testCanPrefixItems()\n  {\n    $list = static::$itemList;\n    $list->prefixParents()->prefix('foo');\n    $list->add('bar', 'foo');\n\n    $matcher = $this->matchListWithItem();\n    $matcher['child']['child'] = $this->matchLink(URL::to('foo/bar'));\n\n    $this->assertHTML($matcher, $list->render());\n  }\n\n  public function testCanSetClassOnLists()\n  {\n    $list = static::$itemList;\n    $list->addClass('foo')->data_foo('bar');\n    $list->add('some', 'item');\n    $matcher = $this->matchList();\n    $matcher['attributes']['class'] = 'foo';\n    $matcher['attributes']['data-foo'] = 'bar';\n\n    $this->assertHTML($matcher, $list);\n  }\n\n  public function testCanSetClassOnItems()\n  {\n    $list = static::$itemList;\n    $list->add('#', 'foo')->onItem()->addClass('foo')\n        ->getContent()->href('#lol');\n\n    $matcher = $this->matchListWithItem('ul', 'li');\n    $matcher['child']['attributes']['class'] = 'foo';\n    $matcher['child']['child']['attributes']['href'] = '#lol';\n\n    $this->assertHTML($matcher, $list);\n  }\n\n  public function testChainingMethods()\n  {\n    $menu = static::$itemList\n      ->add('#', 'foo')->onItem()->data_foo('bar')->addClass('active')\n        ->getContent()->href('lol')->stop()\n      ->add('#', 'bar');\n\n    $this->assertEquals(\n      '<ul>'.\n        '<li data-foo=\"bar\" class=\"active\">'.\n          '<a href=\"'.URL::to('lol').'\">foo</a>'.\n        '</li>'.\n        '<li>'.\n          '<a href=\"#\">bar</a>'.\n        '</li>'.\n      '</ul>', $menu->render());\n  }\n\n  public function testCanAttachMenus()\n  {\n    $list = static::$itemList;\n    $list->add('#', 'foo');\n    $list->attach(Menu::items()->add('#', 'bar'));\n\n    $this->assertHTML($this->matchListWithItem(), $list);\n    $this->assertHTML($this->matchLink('#', 'bar'), $list);\n  }\n}\n"
  },
  {
    "path": "tests/ItemTest.php",
    "content": "<?php\nuse Menu\\Items\\Item;\nuse Menu\\Items\\ItemList;\n\nclass ItemTest extends MenuTests\n{\n  public function testCanCreateAnItem()\n  {\n    $this->assertHTML($this->matchItem(), static::$item->render());\n  }\n\n  public function testCanCreateItemOfADifferentElement()\n  {\n    $item = static::$item;\n    $item->setElement('dl');\n\n    $this->assertHTML($this->matchItem('dl'), $item->render());\n  }\n\n  public function testCanCreateRawItem()\n  {\n    $item = new Item(static::$itemList, static::$raw);\n    $matcher = array('tag' => 'li', 'content' => 'foo');\n\n    $this->assertHTML($matcher, $item->render());\n  }\n\n  public function testCanCreateItemWithSublist()\n  {\n    $sublist = static::$itemList;\n    $sublist->add('#', 'foo');\n    $item = new Item(static::$itemList, static::$link, $sublist);\n\n    $matchSublist = array(\n      'tag' => 'li',\n      'child' => array(\n        'tag' => 'ul',\n        'child' => $this->matchItem(),\n      ),\n    );\n\n    $this->assertHTML($this->matchItem(), $item->render());\n    $this->assertHTML($matchSublist, $item->render());\n  }\n\n  public function testCanCreateElementlessItems()\n  {\n    $item = new Item(static::$itemList, static::$link);\n    $item->setElement(null);\n\n    $this->assertHTML($this->matchLink(), $item->render());\n  }\n}"
  },
  {
    "path": "tests/LinkTest.php",
    "content": "<?php\nuse Menu\\Items\\Contents\\Link;\n\nclass LinkTest extends MenuTests\n{\n  public function testCanCreateRawContent()\n  {\n    $this->assertHTML($this->matchLink(), static::$link->render());\n  }\n\n  public function testLinksAreLinks()\n  {\n    $this->assertTrue(static::$link->isLink());\n  }\n\n  public function testDoesntAlterSpecialUrls()\n  {\n    $link = new Link('javascript:void(0);', 'foo');\n    $matcher = $this->matchLink('javascript:void(0);');\n\n    $this->assertHTML($matcher, $link);\n  }\n\n  public function testCanSetAttributesOnLinks()\n  {\n    $link = static::$link;\n    $link->class('foobar');\n\n    $matcher = $this->matchLink();\n    $matcher['attributes']['class'] = 'foobar';\n\n    $this->assertHTML($matcher, $link->render());\n  }\n}"
  },
  {
    "path": "tests/MenuHandlerTest.php",
    "content": "<?php\nuse Menu\\Menu;\n\nclass MenuHandlerTest extends MenuTests\n{\n  public function testCanHandle()\n  {\n    $handles = array('foo', 'bar');\n    $menu = Menu::handler($handles);\n\n    $this->assertEquals(array_values(Menu::getItemList()), $menu->getMenuObjects());\n  }\n}\n"
  },
  {
    "path": "tests/MenuTest.php",
    "content": "<?php\nuse Menu\\Menu;\nuse Menu\\Items\\ItemList;\n\nclass MenuTest extends MenuTests\n{\n  public function testCanReturnAMenuHandler()\n  {\n    $menu = Menu::handler('foo');\n\n    $this->assertInstanceOf('Menu\\MenuHandler', $menu);\n  }\n\n  public function testCanGetAMenuThatHandlesEverything()\n  {\n    Menu::handler('foo');\n    Menu::handler('bar');\n    $allHandlers = Menu::allHandlers();\n\n    $this->assertEquals(array('foo', 'bar'), array_keys($allHandlers->getMenuObjects()));\n  }\n\n  public function testCanResetAllHandles()\n  {\n    Menu::handler('foo');\n    Menu::reset();\n\n    $this->assertEquals(array(), Menu::getItemList());\n  }\n\n  public function testCanReturnItemLists()\n  {\n    $itemList = Menu::items('foo');\n\n    $this->assertInstanceOf('Menu\\Items\\ItemList', $itemList);\n  }\n\n  public function testCanSetItemLists()\n  {\n    $itemList = Menu::items('foo');\n    Menu::setItemList('foo', $itemList);\n\n    $this->assertArrayHasKey('foo', Menu::getItemList());\n  }\n\n  public function testCanRenderManuallyBindedItemLists()\n  {\n    $menu = Menu::handler('categories')\n      ->add('algorithms', 'Algorithms', Menu::items()->prefixParents()\n        ->add('cryptography', 'Cryptography')\n        ->add('data-structures', 'Data Structures')\n        ->add('digital-image-processing', 'Digital Image Processing')\n        ->add('memory-management', 'Memory Management'))\n      ->add('graphics-and-multimedia', 'Graphics & Multimedia', Menu::items()->prefixParents()\n        ->add('directx', 'DirectX')\n        ->add('flash', 'Flash')\n        ->add('opengl', 'OpenGL'));\n\n    $matcher =\n    '<ul>'.\n      '<li>'.\n        '<a href=\"'.URL::to('algorithms').'\">Algorithms</a>'.\n        '<ul>'.\n          '<li><a href=\"'.URL::to('algorithms/cryptography').'\">Cryptography</a></li>'.\n          '<li><a href=\"'.URL::to('algorithms/data-structures').'\">Data Structures</a></li>'.\n          '<li><a href=\"'.URL::to('algorithms/digital-image-processing').'\">Digital Image Processing</a></li>'.\n          '<li><a href=\"'.URL::to('algorithms/memory-management').'\">Memory Management</a></li>'.\n        '</ul>'.\n      '</li>'.\n      '<li>'.\n        '<a href=\"'.URL::to('graphics-and-multimedia').'\">Graphics & Multimedia</a>'.\n        '<ul>'.\n          '<li><a href=\"'.URL::to('graphics-and-multimedia/directx').'\">DirectX</a></li>'.\n          '<li><a href=\"'.URL::to('graphics-and-multimedia/flash').'\">Flash</a></li>'.\n          '<li><a href=\"'.URL::to('graphics-and-multimedia/opengl').'\">OpenGL</a></li>'.\n        '</ul>'.\n      '</li>'.\n    '</ul>';\n\n    $this->assertEquals($matcher, $menu->render());\n  }\n\n  public function testCanGetItemLists()\n  {\n    $itemList = Menu::items('foo');\n    Menu::setItemList('foo', $itemList);\n\n    $this->assertEquals($itemList, Menu::getItemList('foo'));\n  }\n\n  public function testCanGetValueFromConfig()\n  {\n    $config = Menu::getOption('max_depth');\n    $this->assertEquals(-1, $config);\n\n    $config = Menu::getOption();\n    $this->assertInternalType('array', $config);\n  }\n\n  public function testClassesPassTheirConfigurationToChildren()\n  {\n    $list = static::$itemList;\n    $list->add('#', 'foo');\n    $list->setOption('item.element', 'dl');\n\n    $this->assertHTML($this->matchListWithItem('ul', 'dl'), $list->render());\n    $this->assertHTML($this->matchLink(), $list->render());\n  }\n\n  public function testMenuCanSetGlobalOptions()\n  {\n    Menu::setOption('item.element', 'dl');\n\n    $list = new ItemList;\n    $list->add('#', 'foo');\n\n    $this->assertHTML($this->matchListWithItem('ul', 'dl'), $list->render());\n    $this->assertHTML($this->matchLink(), $list->render());\n  }\n\n  public function testChainingMethods()\n  {\n    $menu = Menu::handler('foo')\n      ->add('#', 'foo')->onItem()->data_foo('bar')->addClass('active')\n        ->getContent()->href('lol')->stop()\n      ->add('#', 'bar');\n\n    $this->assertEquals(\n      '<ul>'.\n        '<li data-foo=\"bar\" class=\"active\">'.\n          '<a href=\"http://localhost/lol\">foo</a>'.\n        '</li>'.\n        '<li>'.\n          '<a href=\"#\">bar</a>'.\n        '</li>'.\n      '</ul>', $menu->render());\n  }\n}\n"
  },
  {
    "path": "tests/RawTest.php",
    "content": "<?php\nuse Menu\\Items\\Contents\\Raw;\n\nclass RawTest extends MenuTests\n{\n  public function testCanCreateRawContent()\n  {\n    $raw = new Raw('foobar');\n\n    $this->assertEquals('foobar', $raw->render());\n  }\n}"
  },
  {
    "path": "tests/_start.php",
    "content": "<?php\nuse Menu\\Items\\Contents\\Link;\nuse Menu\\Items\\Contents\\Raw;\nuse Menu\\Items\\Item;\nuse Menu\\Items\\ItemList;\nuse Menu\\Menu;\nuse PHPUnit\\Util\\XML;\nuse PHPUnit\\DOMNode;\n\nabstract class MenuTests extends \\Orchestra\\Testbench\\TestCase\n{\n  protected static $link;\n  protected static $raw;\n  protected static $itemList;\n  protected static $item;\n\n  public function setUp()\n  {\n    parent::setUp();\n    // Reset all menus\n    Menu::reset();\n    $this->refreshApplication();\n\n    // Precreate somme Dummy data\n    static::$link     = new Link('#', 'foo');\n    static::$raw      = new Raw('foo');\n    static::$itemList = new ItemList;\n    static::$item     = new Item(static::$itemList, static::$link);\n  }\n\n\n  protected function getPackageProviders($app = null)\n  {\n    return array(\n      'Menu\\MenuServiceProvider',\n    );\n  }\n\n  protected function getPackageAliases($app = null)\n  {\n    return array(\n      'Menu' => 'Menu\\Menu',\n    );\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ////////////////////////////// MATCHERS ////////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Basic matcher for an ItemList\n   *\n   * @param string $element\n   *\n   * @return array\n   */\n  protected function matchList($element = 'ul')\n  {\n    return array(\n      'tag' => $element,\n    );\n  }\n\n  /**\n   * Matcher for an ItemList with an Item\n   *\n   * @return array\n   */\n  protected function matchListWithItem($list = 'ul', $item = 'li')\n  {\n    $list = $this->matchList($list);\n    $list['child'] = $this->matchItem($item);\n\n    return $list;\n  }\n\n  /**\n   * Basic matcher for an Item\n   *\n   * @param string $element\n   *\n   * @return array\n   */\n  protected function matchItem($element = 'li')\n  {\n    return array(\n      'tag'   => $element,\n      'child' => $this->matchLink(),\n    );\n  }\n\n  /**\n   * Basic matcher for a Link\n   *\n   * @return array\n   */\n  protected function matchLink($link = '#', $content = 'foo')\n  {\n    return array(\n      'tag' => 'a',\n      'content' => $content,\n      'attributes' => array(\n        'href' => $link,\n      ),\n    );\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  ////////////////////////////// HELPERS /////////////////////////////\n  ////////////////////////////////////////////////////////////////////\n\n  /**\n   * Asserts some HTML is, once stripped, equals to a matcher\n   *\n   * @param string $matcher The matcher\n   * @param string $html    The HTML\n   */\n  protected function assertStripedEquals($matcher, $html)\n  {\n    $html = preg_replace(\"/[\\n\\r\\t]/\", null, $html);\n\n    return $this->assertEquals($matcher, $html);\n  }\n\n  /**\n   * Enhanced version of assertTag\n   *\n   * @param array  $matcher The tag matcher\n   * @param string $html    The HTML\n   */\n  protected function assertHTML($matcher, $html)\n  {\n    return $this->assertTag(\n      $matcher,\n      $html,\n      \"Failed asserting that the HTML matches the provided format :\\n\\t\"\n        .$html.\"\\n\\t\"\n        .json_encode($matcher));\n  }\n}\n"
  }
]