1<?php
2/**
3 * DokuWiki Plugin menuext (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <andi@splitbrain.org>
7 */
8
9// must be run within Dokuwiki
10use dokuwiki\plugin\menuext\MenuExtItem;
11
12if (!defined('DOKU_INC')) {
13    die();
14}
15
16class action_plugin_menuext extends DokuWiki_Action_Plugin
17{
18    protected $menuconf = [];
19
20    /**
21     * action_plugin_menuext constructor.
22     */
23    public function __construct()
24    {
25        $cf = DOKU_CONF . 'menuext.json';
26        if (file_exists($cf)) {
27            $config = @json_decode(file_get_contents($cf), true);
28            if (!is_array($config)) {
29                msg('Failed to parse config for MenuExt plugin in conf/menuext.json', -1, '', '', MSG_ADMINS_ONLY);
30            }
31        } else {
32            msg('No config for MenuExt plugin found in conf/menuext.json', -1, '', '', MSG_ADMINS_ONLY);
33        }
34        $this->menuconf = $config;
35    }
36
37    /**
38     * Registers a callback function for a given event
39     *
40     * @param Doku_Event_Handler $controller DokuWiki's event controller object
41     *
42     * @return void
43     */
44    public function register(Doku_Event_Handler $controller)
45    {
46        $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'handle_menu_items_assembly', [], 999);
47
48    }
49
50    /**
51     * [Custom event handler which performs action]
52     *
53     * Called for event:
54     *
55     * @param Doku_Event $event event object by reference
56     * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
57     *                           handler was registered]
58     *
59     * @return void
60     */
61    public function handle_menu_items_assembly(Doku_Event $event, $param)
62    {
63        $view = $event->data['view'];
64        if (!isset($this->menuconf[$view])) return;
65
66        foreach ($this->menuconf[$view] as $data) {
67            $order = isset($data['order']) ? (int) $data['order'] : count($event->data['items']);
68
69            // default action or custom one?
70            if (isset($data['action'])) {
71                $action = ucfirst(strtolower($data['action']));
72
73                $class = "\\dokuwiki\\Menu\\Item\\$action";
74                if (!class_exists($class)) {
75                    msg('No menu item for action ' . hsc($action), -1, '', '', MSG_ADMINS_ONLY);
76                    continue;
77                }
78                $item = new $class();
79            } else if (isset($data['classname'])) {
80                $class = $data['classname'];
81                if (!class_exists($class)) {
82                    msg('Item class ' . hsc($class) . ' does not exist', -1, '', '', MSG_ADMINS_ONLY);
83                    continue;
84                }
85                $item = new $class();
86                if (!is_a($item, 'dokuwiki\Menu\Item\AbstractItem')) {
87                    msg('Not a menu item: ' . hsc($class), -1, '', '', MSG_ADMINS_ONLY);
88                    unset($item);
89                    continue;
90                }
91            } else {
92                $item = new MenuExtItem($data);
93            }
94
95            array_splice($event->data['items'], $order, 0, [$item]);
96        }
97    }
98}
99
100