xref: /plugin/renderrevisions/action/revisions.php (revision 3e4faa7909287fd936f946fb2a5d1faecafacfb3)
1<?php
2
3use dokuwiki\Extension\ActionPlugin;
4use dokuwiki\Extension\Event;
5use dokuwiki\Extension\EventHandler;
6use dokuwiki\Form\HTMLElement;
7
8/**
9 * DokuWiki Plugin renderrevisions (Action Component)
10 *
11 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
12 * @author Andreas Gohr <dokuwiki@cosmocode.de>
13 */
14class action_plugin_renderrevisions_revisions extends ActionPlugin
15{
16    /** @inheritDoc */
17    public function register(EventHandler $controller)
18    {
19        if($this->getConf('store')) {
20            $controller->register_hook('FORM_REVISIONS_OUTPUT', 'BEFORE', $this, 'handleRevisions');
21            $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleActPreprocess');
22            $controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, 'handleActUnknown');
23        }
24    }
25
26    /**
27     * Event handler for FORM_REVISIONS_OUTPUT
28     *
29     * Link revisions to their rendered output when available
30     *
31     * @see https://www.dokuwiki.org/devel:events:FORM_REVISIONS_OUTPUT
32     * @param Event $event Event object
33     * @param mixed $param optional parameter passed when event was registered
34     * @return void
35     */
36    public function handleRevisions(Event $event, $param)
37    {
38        global $INFO;
39
40        /** @var dokuwiki\Form\Form $form */
41        $form = $event->data;
42
43        /** @var helper_plugin_renderrevisions_storage $storage */
44        $storage = plugin_load('helper', 'renderrevisions_storage');
45
46        $id = $INFO['id'];
47        $elementCount = $form->elementCount();
48
49        for ($i = 0; $i < $elementCount; $i++) {
50            $element = $form->getElementAt($i);
51            if (!$element instanceof HTMLElement) continue;
52            if (!preg_match('/[;&?]rev=(\d+)/', $element->val(), $match)) continue;
53            $rev = (int)$match[1];
54            if (!$rev) continue;
55            if (!$storage->hasRevision($id, $rev)) continue;
56
57            $html = $element->val();
58            $html = preg_replace('/([;&?]rev=\d+)/', '\\1&amp;do=renderrevisions', $html);
59            $html = preg_replace('/class="wikilink1"/', 'class="wikilink1 renderrevisions"', $html);
60            $element->val($html);
61        }
62    }
63
64    /**
65     * Event handler for ACTION_ACT_PREPROCESS
66     *
67     * @see https://www.dokuwiki.org/devel:event:ACTION_ACT_PREPROCESS
68     * @param Event $event Event object
69     * @param mixed $param optional parameter passed when event was registered
70     * @return void
71     */
72    public function handleActPreprocess(Event $event, $param)
73    {
74        global $REV;
75        global $INFO;
76
77        // not our circus?
78        if ($event->data !== 'renderrevisions') return;
79
80        // no revision? show the page. id should always be set, but just in case
81        if (!$REV || !$INFO['id']) {
82            $event->data = 'show';
83            return;
84        }
85
86        // check permissions
87        if(auth_quickaclcheck($INFO['id']) < AUTH_READ) {
88            $event->data = 'denied';
89            return;
90        }
91
92        // no stored revision? show the page
93        /** @var helper_plugin_renderrevisions_storage $storage */
94        $storage = plugin_load('helper', 'renderrevisions_storage');
95        if (!$storage->hasRevision($INFO['id'], (int)$REV)) {
96            $event->data = 'show';
97            return;
98        }
99
100        // we can handle it!
101        $event->preventDefault();
102        $event->stopPropagation();
103    }
104
105
106    /**
107     * Event handler for TPL_ACT_UNKNOWN
108     *
109     * @see https://www.dokuwiki.org/devel:event:TPL_ACT_UNKNOWN
110     * @param Event $event Event object
111     * @param mixed $param optional parameter passed when event was registered
112     * @return void
113     */
114    public function handleActUnknown(Event $event, $param)
115    {
116        global $REV;
117        global $INFO;
118        global $ACT;
119
120        if ($event->data !== 'renderrevisions') return;
121        $event->preventDefault();
122        $event->stopPropagation();
123
124        /** @var helper_plugin_renderrevisions_storage $storage */
125        $storage = plugin_load('helper', 'renderrevisions_storage');
126        $content = $storage->getRevision($INFO['id'], (int)$REV);
127        $intro = sprintf(
128            $this->getLang('intro'),
129            dformat($REV),
130            '<a href="' . wl($INFO['id'], ['rev' => $REV]) . '">' . $this->getLang('rerender') . '</a>'
131        );
132
133        echo '<div class="renderrevisions">';
134        echo $intro;
135        echo '</div>';
136        echo $content;
137    }
138}
139