xref: /plugin/acknowledge/action.php (revision 524b6abe238d0240b517cb59e5dbb10153e29791)
14d6d17d0SAndreas Gohr<?php
23b76424dSannda
34d6d17d0SAndreas Gohr/**
44d6d17d0SAndreas Gohr * DokuWiki Plugin acknowledge (Action Component)
54d6d17d0SAndreas Gohr *
64d6d17d0SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
74d6d17d0SAndreas Gohr * @author  Andreas Gohr, Anna Dabrowska <dokuwiki@cosmocode.de>
84d6d17d0SAndreas Gohr */
94d6d17d0SAndreas Gohr
103b76424dSanndause dokuwiki\Extension\ActionPlugin;
113b76424dSanndause dokuwiki\Extension\EventHandler;
123b76424dSanndause dokuwiki\Extension\Event;
135773dd37SAnna Dabrowskause dokuwiki\Form\Form;
144d6d17d0SAndreas Gohr
153b76424dSanndaclass action_plugin_acknowledge extends ActionPlugin
164d6d17d0SAndreas Gohr{
17ef3ab392SAndreas Gohr    /** @inheritDoc */
183b76424dSannda    public function register(EventHandler $controller)
194d6d17d0SAndreas Gohr    {
20ef3ab392SAndreas Gohr        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'handlePageSave');
21c92ac04cSAnna Dabrowska        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxAcknowledge');
2245240794SAnna Dabrowska        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxAutocomplete');
23f09444ffSAndreas Gohr        $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'AFTER', $this, 'handleUpgrade');
244d6d17d0SAndreas Gohr    }
254d6d17d0SAndreas Gohr
264d6d17d0SAndreas Gohr    /**
27ef3ab392SAndreas Gohr     * Manage page meta data
284d6d17d0SAndreas Gohr     *
29ef3ab392SAndreas Gohr     * Store page last modified date
30ef3ab392SAndreas Gohr     * Handle page deletions
31f09444ffSAndreas Gohr     * Handle page creations
324d6d17d0SAndreas Gohr     *
333b76424dSannda     * @param Event $event
34ef3ab392SAndreas Gohr     * @param $param
354d6d17d0SAndreas Gohr     */
363b76424dSannda    public function handlePageSave(Event $event, $param)
374d6d17d0SAndreas Gohr    {
38ef3ab392SAndreas Gohr        /** @var helper_plugin_acknowledge $helper */
39ef3ab392SAndreas Gohr        $helper = plugin_load('helper', 'acknowledge');
40ef3ab392SAndreas Gohr
41ef3ab392SAndreas Gohr        if ($event->data['changeType'] === DOKU_CHANGE_TYPE_DELETE) {
42f09444ffSAndreas Gohr            $helper->removePage($event->data['id']); // this cascades to assignments
43ef3ab392SAndreas Gohr        } elseif ($event->data['changeType'] !== DOKU_CHANGE_TYPE_MINOR_EDIT) {
445dee13f7SAnna Dabrowska            $helper->storePageDate($event->data['id'], $event->data['newRevision'], $event->data['newContent']);
454d6d17d0SAndreas Gohr        }
464d6d17d0SAndreas Gohr
47f09444ffSAndreas Gohr        // Remove page assignees here because the syntax might have been removed
48f09444ffSAndreas Gohr        // they are readded on metadata rendering if still there
49f09444ffSAndreas Gohr        $helper->clearPageAssignments($event->data['id']);
50f09444ffSAndreas Gohr
51f09444ffSAndreas Gohr        if ($event->data['changeType'] === DOKU_CHANGE_TYPE_CREATE) {
52f09444ffSAndreas Gohr            // new pages need to have their auto assignments updated based on the existing patterns
53f09444ffSAndreas Gohr            $helper->setAutoAssignees($event->data['id']);
54f09444ffSAndreas Gohr        }
55ef3ab392SAndreas Gohr    }
56ef3ab392SAndreas Gohr
57ef3ab392SAndreas Gohr    /**
583b76424dSannda     * @param Event $event
59ef3ab392SAndreas Gohr     * @param $param
60ef3ab392SAndreas Gohr     */
61c92ac04cSAnna Dabrowska    public function handleAjaxAcknowledge(Event $event, $param)
62ef3ab392SAndreas Gohr    {
63c92ac04cSAnna Dabrowska        if ($event->data === 'plugin_acknowledge_acknowledge') {
64ef3ab392SAndreas Gohr            $event->stopPropagation();
65ef3ab392SAndreas Gohr            $event->preventDefault();
66cfdacc6aSAnna Dabrowska
67cfdacc6aSAnna Dabrowska            global $INPUT;
68cfdacc6aSAnna Dabrowska            $id = $INPUT->str('id');
69cfdacc6aSAnna Dabrowska
70cfdacc6aSAnna Dabrowska            if (page_exists($id)) {
71cfdacc6aSAnna Dabrowska                echo $this->html();
72cfdacc6aSAnna Dabrowska            }
73ef3ab392SAndreas Gohr        }
74ef3ab392SAndreas Gohr    }
75ef3ab392SAndreas Gohr
76ef3ab392SAndreas Gohr    /**
7745240794SAnna Dabrowska     * @param Event $event
7845240794SAnna Dabrowska     * @return void
7945240794SAnna Dabrowska     */
8045240794SAnna Dabrowska    public function handleAjaxAutocomplete(Event $event)
8145240794SAnna Dabrowska    {
8245240794SAnna Dabrowska        if ($event->data === 'plugin_acknowledge_autocomplete') {
8345240794SAnna Dabrowska            if (!checkSecurityToken()) return;
8445240794SAnna Dabrowska
8545240794SAnna Dabrowska            global $INPUT;
8645240794SAnna Dabrowska
8745240794SAnna Dabrowska            $event->stopPropagation();
8845240794SAnna Dabrowska            $event->preventDefault();
8945240794SAnna Dabrowska
9045240794SAnna Dabrowska            /** @var helper_plugin_acknowledge $hlp */
9145240794SAnna Dabrowska            $hlp = $this->loadHelper('acknowledge');
9245240794SAnna Dabrowska
93*524b6abeSAnna Dabrowska            $found = [];
9445240794SAnna Dabrowska
95*524b6abeSAnna Dabrowska            if ($INPUT->has('user')) {
9645240794SAnna Dabrowska                $search = $INPUT->str('user');
97*524b6abeSAnna Dabrowska                $knownUsers = $hlp->getUsers();
9845240794SAnna Dabrowska                $found = array_filter($knownUsers, function ($user) use ($search) {
9945240794SAnna Dabrowska                    return (strstr(strtolower($user['label']), strtolower($search))) !== false ? $user : null;
10045240794SAnna Dabrowska                });
101*524b6abeSAnna Dabrowska            }
102*524b6abeSAnna Dabrowska
103*524b6abeSAnna Dabrowska            if ($INPUT->has('pg')) {
104*524b6abeSAnna Dabrowska                $search = $INPUT->str('pg');
105*524b6abeSAnna Dabrowska                $pages = ft_pageLookup($search);
106*524b6abeSAnna Dabrowska                $found = array_map(function ($id, $title) {
107*524b6abeSAnna Dabrowska                    return ['value' => $id, 'label' => $title ?? $id];
108*524b6abeSAnna Dabrowska                }, array_keys($pages), array_values($pages));
109*524b6abeSAnna Dabrowska            }
11045240794SAnna Dabrowska
11145240794SAnna Dabrowska            header('Content-Type: application/json');
11245240794SAnna Dabrowska
11345240794SAnna Dabrowska            echo json_encode($found);
11445240794SAnna Dabrowska        }
11545240794SAnna Dabrowska    }
11645240794SAnna Dabrowska
11745240794SAnna Dabrowska    /**
118f09444ffSAndreas Gohr     * Handle Migration events
119f09444ffSAndreas Gohr     *
1203b76424dSannda     * @param Event $event
121f09444ffSAndreas Gohr     * @param $param
122f09444ffSAndreas Gohr     * @return void
123f09444ffSAndreas Gohr     */
1243b76424dSannda    public function handleUpgrade(Event $event, $param)
125f09444ffSAndreas Gohr    {
126f09444ffSAndreas Gohr        if ($event->data['sqlite']->getAdapter()->getDbname() !== 'acknowledgement') {
127f09444ffSAndreas Gohr            return;
128f09444ffSAndreas Gohr        }
129f09444ffSAndreas Gohr        $to = $event->data['to'];
130f09444ffSAndreas Gohr        if ($to !== 3) return; // only handle upgrade to version 3
131f09444ffSAndreas Gohr
132f09444ffSAndreas Gohr        /** @var helper_plugin_acknowledge $helper */
133f09444ffSAndreas Gohr        $helper = plugin_load('helper', 'acknowledge');
134f09444ffSAndreas Gohr        $helper->updatePageIndex();
135f09444ffSAndreas Gohr    }
136f09444ffSAndreas Gohr
137f09444ffSAndreas Gohr    /**
138ef3ab392SAndreas Gohr     * Returns the acknowledgment form/confirmation
139ef3ab392SAndreas Gohr     *
140ef3ab392SAndreas Gohr     * @return string The HTML to display
141ef3ab392SAndreas Gohr     */
142ef3ab392SAndreas Gohr    protected function html()
143ef3ab392SAndreas Gohr    {
144ef3ab392SAndreas Gohr        global $INPUT;
145ef3ab392SAndreas Gohr        global $USERINFO;
146ef3ab392SAndreas Gohr        $id = $INPUT->str('id');
1472d63bbe3SAnna Dabrowska        $ackSubmitted = $INPUT->bool('ack');
148ef3ab392SAndreas Gohr        $user = $INPUT->server->str('REMOTE_USER');
149ef3ab392SAndreas Gohr        if ($id === '' || $user === '') return '';
150ef3ab392SAndreas Gohr
151ef3ab392SAndreas Gohr        /** @var helper_plugin_acknowledge $helper */
152ef3ab392SAndreas Gohr        $helper = plugin_load('helper', 'acknowledge');
153ef3ab392SAndreas Gohr
15435bc8beaSAndreas Gohr        // only display for users assigned to the page
15535bc8beaSAndreas Gohr        if (!$helper->isUserAssigned($id, $user, $USERINFO['grps'])) {
15635bc8beaSAndreas Gohr            return '';
15735bc8beaSAndreas Gohr        }
15835bc8beaSAndreas Gohr
1595773dd37SAnna Dabrowska        if ($ackSubmitted) {
1605773dd37SAnna Dabrowska            $helper->saveAcknowledgement($id, $user);
1615773dd37SAnna Dabrowska        }
1625773dd37SAnna Dabrowska
163ef3ab392SAndreas Gohr        $ack = $helper->hasUserAcknowledged($id, $user);
164209df5deSAndreas Gohr
165209df5deSAndreas Gohr        $html = '<div class="' . ($ack ? 'ack' : 'noack') . '">';
166209df5deSAndreas Gohr        $html .= inlineSVG(__DIR__ . '/admin.svg');
167209df5deSAndreas Gohr        $html .= '</div>';
168209df5deSAndreas Gohr
169ef3ab392SAndreas Gohr        if ($ack) {
170ef3ab392SAndreas Gohr            $html .= '<div>';
171209df5deSAndreas Gohr            $html .= '<h4>';
172209df5deSAndreas Gohr            $html .= $this->getLang('ackOk');
173209df5deSAndreas Gohr            $html .= '</h4>';
174209df5deSAndreas Gohr            $html .= sprintf($this->getLang('ackGranted'), dformat($ack));
175ef3ab392SAndreas Gohr            $html .= '</div>';
17635bc8beaSAndreas Gohr        } else {
177ef3ab392SAndreas Gohr            $html .= '<div>';
178209df5deSAndreas Gohr            $html .= '<h4>' . $this->getLang('ackRequired') . '</h4>';
179d9a8334dSAnna Dabrowska            $latest = $helper->getLatestUserAcknowledgement($id, $user);
180d9a8334dSAnna Dabrowska            if ($latest) {
181d9a8334dSAnna Dabrowska                $html .= '<a href="'
182d9a8334dSAnna Dabrowska                    . wl($id, ['do' => 'diff', 'at' => $latest], false, '&') . '">'
183d9a8334dSAnna Dabrowska                    . sprintf($this->getLang('ackDiff'), dformat($latest))
184d9a8334dSAnna Dabrowska                    . '</a><br>';
185d9a8334dSAnna Dabrowska            }
186d9a8334dSAnna Dabrowska
187209df5deSAndreas Gohr            $form = new Form(['id' => 'ackForm']);
188209df5deSAndreas Gohr            $form->addCheckbox('ack', $this->getLang('ackText'))->attr('required', 'required');
189ba917e33SAnna Dabrowska            $form->addHTML(
190ba917e33SAnna Dabrowska                '<br><button type="submit" name="acksubmit" id="ack-submit">'
191ba917e33SAnna Dabrowska                . $this->getLang('ackButton')
192ba917e33SAnna Dabrowska                . '</button>'
193ba917e33SAnna Dabrowska            );
194209df5deSAndreas Gohr
1955773dd37SAnna Dabrowska            $html .= $form->toHTML();
196ef3ab392SAndreas Gohr            $html .= '</div>';
197ef3ab392SAndreas Gohr        }
198ef3ab392SAndreas Gohr
199ef3ab392SAndreas Gohr        return $html;
200ef3ab392SAndreas Gohr    }
2014d6d17d0SAndreas Gohr}
202