/**
  * Builds a menu for displaying associated items to a model entry (i.e. /club/21/team).
  *
  * The menu will include:
  *  - An Add LinkMenuItem;
  *  - A SpacerMenuItem with the name of the associated model;
  *  - A ResourceMenuItem to hold entries of the associated model.
  *
  * @param String      $modelName       The name of the model (i.e. Club).
  * @param int         $modelId         The id of the model entry.
  * @param String      $associationName The name of the associated model (i.e. Team).
  * @param ModelConfig $config          (optional) The `ModelConfig` to use.
  *
  * @return Menu the Menu, which can be configured further.
  */
 public function create($modelName, $modelId, $associationName, ModelConfig $config = null)
 {
     $menu = new Menu();
     $addMenuItem = new LinkMenuItem();
     $addMenuItem->setText(Lang::trans('Add') . ' ' . Lang::trans($associationName));
     $addMenuItem->setIcon(Icons::ion_plus);
     $addMenuItem->setTarget(Url::route($this->aujaRouter->getCreateAssociationName($modelName, $associationName), $modelId));
     $menu->addMenuItem($addMenuItem);
     $headerMenuItem = new SpacerMenuItem();
     $headerMenuItem->setText(Lang::trans(str_plural($associationName)));
     $menu->addMenuItem($headerMenuItem);
     $resourceMenuItem = new ResourceMenuItem();
     $resourceMenuItem->setTarget(Url::route($this->aujaRouter->getAssociationName($modelName, $associationName), $modelId));
     $menu->addMenuItem($resourceMenuItem);
     return $menu;
 }
 /**
  * Builds a menu for a single model entry, where the model has multiple relationships with other models.
  *
  * The menu will include:
  *  - An Edit LinkMenuItem;
  *  - A SpacerMenuItem;
  *  - For each of the Relations, a LinkMenuItem for the associated model.
  *
  * @param String     $modelName the name of the model.
  * @param int        $modelId   the id of the model entry.
  * @param Relation[] $relations the Relations this model has with associated models.
  *
  * @return Menu the Menu, which can be configured further.
  */
 public function create($modelName, $modelId, array $relations, ModelConfig $config = null)
 {
     $menu = new Menu();
     $addMenuItem = new LinkMenuItem();
     $addMenuItem->setText(Lang::trans('Edit'));
     $addMenuItem->setTarget(URL::route($this->aujaRouter->getEditName($modelName), $modelId));
     $menu->addMenuItem($addMenuItem);
     $spacerMenuItem = new SpacerMenuItem();
     $spacerMenuItem->setText(Lang::trans('Properties'));
     $menu->addMenuItem($spacerMenuItem);
     foreach ($relations as $relation) {
         $otherModelName = $relation->getRight()->getName();
         $associationMenuItem = new LinkMenuItem();
         $associationMenuItem->setText(Lang::trans(str_plural($otherModelName)));
         $associationMenuItem->setTarget(URL::route($this->aujaRouter->getAssociationMenuName($modelName, $otherModelName), $modelId));
         $menu->addMenuItem($associationMenuItem);
     }
     return $menu;
 }
 /**
  * Builds a menu for a single model entry, where the model has exactly one relationship with another model.
  *
  * The menu will include:
  *  - An Edit LinkMenuItem to edit the model entry.
  *  - A SpacerMenuItem with the name of the associated model;
  *  - An Add LinkMenuItem to add an entry of the associated model;
  *  - A ResourceMenuItem to hold entries of the associated model.
  *
  * @param String      $modelName The name of the model.
  * @param int         $modelId   The id of the model entry.
  * @param Relation    $relation  The Relation this model has with the associated model.
  * @param ModelConfig $config    (optional) The `ModelConfig` to use.
  *
  * @return Menu The Menu, which can be configured further.
  */
 public function create($modelName, $modelId, Relation $relation, ModelConfig $config = null)
 {
     $otherModelName = $relation->getRight()->getName();
     $menu = new Menu();
     $editMenuItem = new LinkMenuItem();
     $editMenuItem->setText(Lang::trans('Edit'));
     $editMenuItem->setTarget(URL::route($this->aujaRouter->getEditName($modelName), $modelId));
     $menu->addMenuItem($editMenuItem);
     $headerMenuItem = new SpacerMenuItem();
     $headerMenuItem->setText(Lang::trans(str_plural($otherModelName)));
     $menu->addMenuItem($headerMenuItem);
     $addMenuItem = new LinkMenuItem();
     $addMenuItem->setText(sprintf('%s %s', Lang::trans('Add'), Lang::trans($otherModelName)));
     $addMenuItem->setIcon(Icons::ion_plus);
     $addMenuItem->setTarget(URL::route($this->aujaRouter->getCreateAssociationName($modelName, $otherModelName), $modelId));
     $menu->addMenuItem($addMenuItem);
     $resourceMenuItem = new ResourceMenuItem();
     $resourceMenuItem->setTarget(URL::route($this->aujaRouter->getAssociationName($modelName, $otherModelName), $modelId));
     $menu->addMenuItem($resourceMenuItem);
     return $menu;
 }
 /**
  * Builds a simple menu for given model, where typically this model should not have any relations to other models.
  *
  * The menu will include:
  *  - An Add LinkMenuItem;
  *  - A SpacerMenuItem with the model's name;
  *  - A ResourceMenuItem to hold entries of the model.
  *
  * @param String      $modelName The name of the model.
  * @param ModelConfig $config    (optional) The `ModelConfig` to use.
  *
  * @return Menu the Menu, which can be configured further.
  */
 public function create($modelName, ModelConfig $config = null)
 {
     $menu = new Menu();
     $addMenuItem = new LinkMenuItem();
     $addMenuItem->setText(Lang::trans('Add'));
     $addMenuItem->setIcon(Icons::ion_plus);
     $addMenuItem->setTarget(URL::route($this->aujaRouter->getCreateName($modelName)));
     $menu->addMenuItem($addMenuItem);
     $spacerMenuItem = new SpacerMenuItem();
     $spacerMenuItem->setText(Lang::trans($modelName));
     $menu->addMenuItem($spacerMenuItem);
     $resourceMenuItem = new ResourceMenuItem();
     $resourceMenuItem->setTarget(URL::route($this->aujaRouter->getIndexName($modelName)));
     $model = $this->aujaConfigurator->getModel($modelName);
     if ($this->aujaConfigurator->isSearchable($model, $config)) {
         $target = urldecode(URL::route($this->aujaRouter->getIndexName($modelName), ['q' => '%s']));
         /* urldecode because the '%' gets escaped. */
         $property = new Searchable($target);
         $resourceMenuItem->addProperty($property);
     }
     $menu->addMenuItem($resourceMenuItem);
     return $menu;
 }
 /**
  * Builds a Resource instance for given items.
  * This is typically used when a ResourceMenuItem triggers a call for items.
  *
  * This method also supports pagination, either manually or automatically.
  * To automatically use pagination, simply provide a Paginator as items.
  *
  * @param String          $modelName   the name of the model the items represent.
  * @param array|Paginator $items       an array of instances of the model to be shown, or a Paginator containing the instances.
  * @param String          $targetUrl   (optional) The target url for the items. Must contain '%d' in the place of the item id.
  * @param String          $nextPageUrl (optional) The url to the next page, if any.
  * @param int             $offset      (optional) The offset to start the order from.
  * @param ModelConfig     $config      (optional) The `ModelConfig` to use.
  *
  * @return Resource The built LinkMenuItems.
  */
 public function create($modelName, $items, $targetUrl = null, $nextPageUrl = null, $offset = -1, ModelConfig $config = null)
 {
     // TODO: create separate methods for pagination and no pagination?
     /* Extract items from Paginator if necessary */
     $paginator = null;
     if ($items instanceof Paginator) {
         $paginator = $items;
         $items = $paginator->getCollection();
         if ($offset == -1) {
             $offset = ($paginator->getCurrentPage() - 1) * $paginator->getPerPage();
         }
     }
     /* If the offset is not set, use no offset */
     if ($offset == -1) {
         $offset = 0;
     }
     /* No items. */
     if (count($items) == 0) {
         return new Resource();
     }
     /* If the items are not iterable */
     if (!$items instanceof \IteratorAggregate) {
         $items = new Collection([$items]);
     }
     $model = $this->aujaConfigurator->getModel($modelName);
     /* Find relations for this model, so we can know the target */
     $relations = $this->aujaConfigurator->getRelationsForModel($model);
     $associationRelations = array();
     foreach ($relations as $relation) {
         if ($relation->getType() == Relation::HAS_MANY || $relation->getType() == Relation::HAS_AND_BELONGS_TO) {
             $associationRelations[] = $relation;
         }
     }
     /* Build the actual items to return */
     $resourceItems = new Resource();
     $displayField = $this->aujaConfigurator->getDisplayField($model, $config);
     $icon = $this->aujaConfigurator->getIcon($model, $config);
     for ($i = 0; $i < count($items); $i++) {
         if ($targetUrl != null) {
             $target = sprintf($targetUrl, $items[$i]->id);
         } else {
             if (count($associationRelations) == 0) {
                 $target = URL::route($this->aujaRouter->getEditName($modelName), $items[$i]->id);
             } else {
                 $target = URL::route($this->aujaRouter->getShowMenuName($modelName), $items[$i]->id);
             }
         }
         $menuItem = new LinkMenuItem();
         $menuItem->setText($items[$i]->{$displayField});
         $menuItem->setTarget($target);
         $menuItem->setOrder($offset + $i);
         $menuItem->setIcon($icon);
         $resourceItems->addItem($menuItem);
     }
     /* Add pagination if necessary */
     if ($nextPageUrl != null) {
         $resourceItems->setNextPageUrl($nextPageUrl);
     } else {
         if ($paginator != null && $paginator->getCurrentPage() != $paginator->getLastPage()) {
             $target = route($this->aujaRouter->getIndexName($modelName), ['page' => $paginator->getCurrentPage() + 1]);
             $resourceItems->setNextPageUrl($target);
         }
     }
     return $resourceItems;
 }