xref: /dokuwiki/inc/Menu/AbstractMenu.php (revision 33792c0e7da35449c4591cfbb2b77377e2f465b1)
193b8c351SAndreas Gohr<?php
293b8c351SAndreas Gohr
393b8c351SAndreas Gohrnamespace dokuwiki\Menu;
493b8c351SAndreas Gohr
5cbb44eabSAndreas Gohruse dokuwiki\Extension\Event;
693b8c351SAndreas Gohruse dokuwiki\Menu\Item\AbstractItem;
793b8c351SAndreas Gohr
8368ce258SAndreas Gohr/**
9368ce258SAndreas Gohr * Class AbstractMenu
10368ce258SAndreas Gohr *
11368ce258SAndreas Gohr * Basic menu functionality. A menu defines a list of AbstractItem that shall be shown.
12368ce258SAndreas Gohr * It contains convenience functions to display the menu in HTML, but template authors can also
13368ce258SAndreas Gohr * just accesst the items via getItems() and create the HTML as however they see fit.
14368ce258SAndreas Gohr */
1533b91513SAndreas Gohrabstract class AbstractMenu implements MenuInterface
1633b91513SAndreas Gohr{
1793b8c351SAndreas Gohr    /** @var string[] list of Item classes to load */
1833b91513SAndreas Gohr    protected $types = [];
1993b8c351SAndreas Gohr
2093b8c351SAndreas Gohr    /** @var int the context this menu is used in */
2193b8c351SAndreas Gohr    protected $context = AbstractItem::CTX_DESKTOP;
2293b8c351SAndreas Gohr
2393b8c351SAndreas Gohr    /** @var string view identifier to be set in the event */
2493b8c351SAndreas Gohr    protected $view = '';
2593b8c351SAndreas Gohr
2693b8c351SAndreas Gohr    /**
2793b8c351SAndreas Gohr     * AbstractMenu constructor.
2893b8c351SAndreas Gohr     *
2993b8c351SAndreas Gohr     * @param int $context the context this menu is used in
3093b8c351SAndreas Gohr     */
3133b91513SAndreas Gohr    public function __construct($context = AbstractItem::CTX_DESKTOP)
3233b91513SAndreas Gohr    {
3393b8c351SAndreas Gohr        $this->context = $context;
3493b8c351SAndreas Gohr    }
3593b8c351SAndreas Gohr
3693b8c351SAndreas Gohr    /**
3793b8c351SAndreas Gohr     * Get the list of action items in this menu
3893b8c351SAndreas Gohr     *
3993b8c351SAndreas Gohr     * @return AbstractItem[]
4093b8c351SAndreas Gohr     * @triggers MENU_ITEMS_ASSEMBLY
4193b8c351SAndreas Gohr     */
4233b91513SAndreas Gohr    public function getItems()
4333b91513SAndreas Gohr    {
4433b91513SAndreas Gohr        $data = ['view' => $this->view, 'items' => []];
4533b91513SAndreas Gohr        Event::createAndTrigger('MENU_ITEMS_ASSEMBLY', $data, [$this, 'loadItems']);
46*33792c0eSAndreas Gohr
47*33792c0eSAndreas Gohr        $data['items'] = array_filter(
48*33792c0eSAndreas Gohr            $data['items'],
49*33792c0eSAndreas Gohr            fn($item) => $item instanceof AbstractItem && $item->visibleInContext($this->context)
50*33792c0eSAndreas Gohr        );
51*33792c0eSAndreas Gohr
5293b8c351SAndreas Gohr        return $data['items'];
5393b8c351SAndreas Gohr    }
5493b8c351SAndreas Gohr
5593b8c351SAndreas Gohr    /**
5693b8c351SAndreas Gohr     * Default action for the MENU_ITEMS_ASSEMBLY event
5793b8c351SAndreas Gohr     *
5893b8c351SAndreas Gohr     * @param array $data The plugin data
5933b91513SAndreas Gohr     * @see getItems()
6093b8c351SAndreas Gohr     */
6133b91513SAndreas Gohr    public function loadItems(&$data)
6233b91513SAndreas Gohr    {
6393b8c351SAndreas Gohr        foreach ($this->types as $class) {
6493b8c351SAndreas Gohr            try {
6593b8c351SAndreas Gohr                $class = "\\dokuwiki\\Menu\\Item\\$class";
6693b8c351SAndreas Gohr                /** @var AbstractItem $item */
6793b8c351SAndreas Gohr                $item = new $class();
68e6bd4c92SAndreas Gohr                $data['items'][] = $item;
6993b8c351SAndreas Gohr            } catch (\RuntimeException $ignored) {
7093b8c351SAndreas Gohr                // item not available
7193b8c351SAndreas Gohr            }
7293b8c351SAndreas Gohr        }
7393b8c351SAndreas Gohr    }
7493b8c351SAndreas Gohr
7593b8c351SAndreas Gohr    /**
7693b8c351SAndreas Gohr     * Generate HTML list items for this menu
7793b8c351SAndreas Gohr     *
7893b8c351SAndreas Gohr     * This is a convenience method for template authors. If you need more fine control over the
7993b8c351SAndreas Gohr     * output, use getItems() and build the HTML yourself
8093b8c351SAndreas Gohr     *
8193b8c351SAndreas Gohr     * @param string|false $classprefix create a class from type with this prefix, false for no class
822f7a5efdSAndreas Gohr     * @param bool $svg add the SVG link
83c2b9771aSAndreas Gohr     * @return string
8493b8c351SAndreas Gohr     */
8533b91513SAndreas Gohr    public function getListItems($classprefix = '', $svg = true)
8633b91513SAndreas Gohr    {
8793b8c351SAndreas Gohr        $html = '';
8893b8c351SAndreas Gohr        foreach ($this->getItems() as $item) {
8993b8c351SAndreas Gohr            if ($classprefix !== false) {
9093b8c351SAndreas Gohr                $class = ' class="' . $classprefix . $item->getType() . '"';
9193b8c351SAndreas Gohr            } else {
9293b8c351SAndreas Gohr                $class = '';
9393b8c351SAndreas Gohr            }
9493b8c351SAndreas Gohr
9593b8c351SAndreas Gohr            $html .= "<li$class>";
962f7a5efdSAndreas Gohr            $html .= $item->asHtmlLink(false, $svg);
9793b8c351SAndreas Gohr            $html .= '</li>';
9893b8c351SAndreas Gohr        }
99c2b9771aSAndreas Gohr        return $html;
10093b8c351SAndreas Gohr    }
10193b8c351SAndreas Gohr}
102