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