xref: /plugin/acknowledge/action/ajax.php (revision b55c1d2d1a0da3f1d0a253b758a162b4c0c2a0a0)
1c38b6ca8SAnna Dabrowska<?php
2c38b6ca8SAnna Dabrowska
3c38b6ca8SAnna Dabrowska/**
4c38b6ca8SAnna Dabrowska * DokuWiki Plugin acknowledge (AJAX Action Component)
5c38b6ca8SAnna Dabrowska *
6c38b6ca8SAnna Dabrowska * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7c38b6ca8SAnna Dabrowska * @author  Andreas Gohr, Anna Dabrowska <dokuwiki@cosmocode.de>
8c38b6ca8SAnna Dabrowska */
9c38b6ca8SAnna Dabrowska
10c38b6ca8SAnna Dabrowskause dokuwiki\Extension\ActionPlugin;
11c38b6ca8SAnna Dabrowskause dokuwiki\Extension\EventHandler;
12c38b6ca8SAnna Dabrowskause dokuwiki\Extension\Event;
13c38b6ca8SAnna Dabrowskause dokuwiki\Form\Form;
14c38b6ca8SAnna Dabrowska
15c38b6ca8SAnna Dabrowskaclass action_plugin_acknowledge_ajax extends ActionPlugin
16c38b6ca8SAnna Dabrowska{
17c38b6ca8SAnna Dabrowska    /** @inheritDoc */
18c38b6ca8SAnna Dabrowska    public function register(EventHandler $controller)
19c38b6ca8SAnna Dabrowska    {
20c38b6ca8SAnna Dabrowska        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxAcknowledge');
21c38b6ca8SAnna Dabrowska        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxAutocomplete');
22c38b6ca8SAnna Dabrowska    }
23c38b6ca8SAnna Dabrowska
24c38b6ca8SAnna Dabrowska    /**
25c38b6ca8SAnna Dabrowska     * @param Event $event
26c38b6ca8SAnna Dabrowska     * @param $param
27c38b6ca8SAnna Dabrowska     */
28c38b6ca8SAnna Dabrowska    public function handleAjaxAcknowledge(Event $event, $param)
29c38b6ca8SAnna Dabrowska    {
30c38b6ca8SAnna Dabrowska        if ($event->data === 'plugin_acknowledge_acknowledge') {
31c38b6ca8SAnna Dabrowska            $event->stopPropagation();
32c38b6ca8SAnna Dabrowska            $event->preventDefault();
33c38b6ca8SAnna Dabrowska
34c38b6ca8SAnna Dabrowska            global $INPUT;
35c38b6ca8SAnna Dabrowska            $id = $INPUT->str('id');
36c38b6ca8SAnna Dabrowska
37c38b6ca8SAnna Dabrowska            if (page_exists($id)) {
38c38b6ca8SAnna Dabrowska                echo $this->html();
39c38b6ca8SAnna Dabrowska            }
40c38b6ca8SAnna Dabrowska        }
41c38b6ca8SAnna Dabrowska    }
42c38b6ca8SAnna Dabrowska
43c38b6ca8SAnna Dabrowska    /**
44c38b6ca8SAnna Dabrowska     * @param Event $event
45c38b6ca8SAnna Dabrowska     * @return void
46c38b6ca8SAnna Dabrowska     */
47c38b6ca8SAnna Dabrowska    public function handleAjaxAutocomplete(Event $event)
48c38b6ca8SAnna Dabrowska    {
49c38b6ca8SAnna Dabrowska        if ($event->data === 'plugin_acknowledge_autocomplete') {
50c38b6ca8SAnna Dabrowska            if (!checkSecurityToken()) return;
51c38b6ca8SAnna Dabrowska
52c38b6ca8SAnna Dabrowska            global $INPUT;
53c38b6ca8SAnna Dabrowska
54c38b6ca8SAnna Dabrowska            $event->stopPropagation();
55c38b6ca8SAnna Dabrowska            $event->preventDefault();
56c38b6ca8SAnna Dabrowska
57c38b6ca8SAnna Dabrowska            /** @var helper_plugin_acknowledge $hlp */
58c38b6ca8SAnna Dabrowska            $hlp = $this->loadHelper('acknowledge');
59c38b6ca8SAnna Dabrowska
60c38b6ca8SAnna Dabrowska            $found = [];
61c38b6ca8SAnna Dabrowska
62c38b6ca8SAnna Dabrowska            if ($INPUT->has('user')) {
63c38b6ca8SAnna Dabrowska                $search = $INPUT->str('user');
64c38b6ca8SAnna Dabrowska                $knownUsers = $hlp->getUsers();
65c38b6ca8SAnna Dabrowska                $found = array_filter($knownUsers, function ($user) use ($search) {
66c38b6ca8SAnna Dabrowska                    return (strstr(strtolower($user['label']), strtolower($search))) !== false ? $user : null;
67c38b6ca8SAnna Dabrowska                });
68c38b6ca8SAnna Dabrowska            }
69c38b6ca8SAnna Dabrowska
70c38b6ca8SAnna Dabrowska            if ($INPUT->has('pg')) {
71c38b6ca8SAnna Dabrowska                $search = $INPUT->str('pg');
72c38b6ca8SAnna Dabrowska                $pages = ft_pageLookup($search, true);
73c38b6ca8SAnna Dabrowska                $found = array_map(function ($id, $title) {
74c38b6ca8SAnna Dabrowska                    return ['value' => $id, 'label' => $title ?? $id];
75c38b6ca8SAnna Dabrowska                }, array_keys($pages), array_values($pages));
76c38b6ca8SAnna Dabrowska            }
77c38b6ca8SAnna Dabrowska
78c38b6ca8SAnna Dabrowska            header('Content-Type: application/json');
79c38b6ca8SAnna Dabrowska
80c38b6ca8SAnna Dabrowska            echo json_encode($found);
81c38b6ca8SAnna Dabrowska        }
82c38b6ca8SAnna Dabrowska    }
83c38b6ca8SAnna Dabrowska
84c38b6ca8SAnna Dabrowska    /**
85*b55c1d2dSAnna Dabrowska     * Returns the acknowledgment form/confirmation and optionally management report
86c38b6ca8SAnna Dabrowska     *
87c38b6ca8SAnna Dabrowska     * @return string The HTML to display
88c38b6ca8SAnna Dabrowska     */
89c38b6ca8SAnna Dabrowska    protected function html()
90c38b6ca8SAnna Dabrowska    {
91c38b6ca8SAnna Dabrowska        global $INPUT;
92c38b6ca8SAnna Dabrowska        $id = $INPUT->str('id');
93c38b6ca8SAnna Dabrowska        $user = $INPUT->server->str('REMOTE_USER');
94c38b6ca8SAnna Dabrowska        if ($id === '' || $user === '') return '';
95c38b6ca8SAnna Dabrowska
96c38b6ca8SAnna Dabrowska        /** @var helper_plugin_acknowledge $helper */
97c38b6ca8SAnna Dabrowska        $helper = plugin_load('helper', 'acknowledge');
98c38b6ca8SAnna Dabrowska
99*b55c1d2dSAnna Dabrowska        return $this->bannerHtml($id, $user, $helper) . $this->reportHtml($id, $helper);
100*b55c1d2dSAnna Dabrowska    }
101*b55c1d2dSAnna Dabrowska
102*b55c1d2dSAnna Dabrowska    /**
103*b55c1d2dSAnna Dabrowska     * Returns the personal acknowledgement banner
104*b55c1d2dSAnna Dabrowska     *
105*b55c1d2dSAnna Dabrowska     * @param string $id
106*b55c1d2dSAnna Dabrowska     * @param string $user
107*b55c1d2dSAnna Dabrowska     * @param helper_plugin_acknowledge $helper
108*b55c1d2dSAnna Dabrowska     * @return string
109*b55c1d2dSAnna Dabrowska     */
110*b55c1d2dSAnna Dabrowska    protected function bannerHtml($id, $user, helper_plugin_acknowledge $helper)
111*b55c1d2dSAnna Dabrowska    {
112*b55c1d2dSAnna Dabrowska        global $INPUT;
113*b55c1d2dSAnna Dabrowska        global $USERINFO;
114*b55c1d2dSAnna Dabrowska
115c38b6ca8SAnna Dabrowska        // only display for users assigned to the page
116c38b6ca8SAnna Dabrowska        if (!$helper->isUserAssigned($id, $user, $USERINFO['grps'])) {
117c38b6ca8SAnna Dabrowska            return '';
118c38b6ca8SAnna Dabrowska        }
119c38b6ca8SAnna Dabrowska
120a8303a15SAnna Dabrowska        // if the approve plugin is active, only show if the page is approved
121a8303a15SAnna Dabrowska        if ($helper->isBlockedByApprove($id)) {
122a8303a15SAnna Dabrowska            return '';
123a8303a15SAnna Dabrowska        }
124a8303a15SAnna Dabrowska
125*b55c1d2dSAnna Dabrowska        if ($INPUT->bool('ack')) {
126c38b6ca8SAnna Dabrowska            $helper->saveAcknowledgement($id, $user);
127c38b6ca8SAnna Dabrowska        }
128c38b6ca8SAnna Dabrowska
129c38b6ca8SAnna Dabrowska        $ack = $helper->hasUserAcknowledged($id, $user);
130c38b6ca8SAnna Dabrowska
131*b55c1d2dSAnna Dabrowska        $html = '<div class="plugin-acknowledge-box ack' . ($ack ? ' done' : '') . '">';
132*b55c1d2dSAnna Dabrowska        $html .= '<div class="ack-icon">';
133c38b6ca8SAnna Dabrowska        $html .= inlineSVG(__DIR__ . '/../admin.svg');
134c38b6ca8SAnna Dabrowska        $html .= '</div>';
135c38b6ca8SAnna Dabrowska
136*b55c1d2dSAnna Dabrowska        $html .= '<div class="content">';
137c38b6ca8SAnna Dabrowska        if ($ack) {
138c38b6ca8SAnna Dabrowska            $html .= '<h4>';
139c38b6ca8SAnna Dabrowska            $html .= $this->getLang('ackOk');
140c38b6ca8SAnna Dabrowska            $html .= '</h4>';
141c38b6ca8SAnna Dabrowska            $html .= sprintf($this->getLang('ackGranted'), dformat($ack));
142c38b6ca8SAnna Dabrowska        } else {
143c38b6ca8SAnna Dabrowska            $html .= '<h4>' . $this->getLang('ackRequired') . '</h4>';
144c38b6ca8SAnna Dabrowska            $latest = $helper->getLatestUserAcknowledgement($id, $user);
145c38b6ca8SAnna Dabrowska            if ($latest) {
146c38b6ca8SAnna Dabrowska                $html .= '<a href="'
147c38b6ca8SAnna Dabrowska                    . wl($id, ['do' => 'diff', 'at' => $latest], false, '&') . '">'
148c38b6ca8SAnna Dabrowska                    . sprintf($this->getLang('ackDiff'), dformat($latest))
149c38b6ca8SAnna Dabrowska                    . '</a><br>';
150c38b6ca8SAnna Dabrowska            }
151c38b6ca8SAnna Dabrowska
152c38b6ca8SAnna Dabrowska            $form = new Form(['id' => 'ackForm']);
153c38b6ca8SAnna Dabrowska            $form->addCheckbox('ack', $this->getLang('ackText'))->attr('required', 'required');
154c38b6ca8SAnna Dabrowska            $form->addHTML(
155c38b6ca8SAnna Dabrowska                '<br><button type="submit" name="acksubmit" id="ack-submit">'
156c38b6ca8SAnna Dabrowska                . $this->getLang('ackButton')
157c38b6ca8SAnna Dabrowska                . '</button>'
158c38b6ca8SAnna Dabrowska            );
159c38b6ca8SAnna Dabrowska
160c38b6ca8SAnna Dabrowska            $html .= $form->toHTML();
161c38b6ca8SAnna Dabrowska        }
162*b55c1d2dSAnna Dabrowska        $html .= '</div>'; // content
163*b55c1d2dSAnna Dabrowska        $html .= '</div>'; // box
164*b55c1d2dSAnna Dabrowska
165*b55c1d2dSAnna Dabrowska        return $html;
166*b55c1d2dSAnna Dabrowska    }
167*b55c1d2dSAnna Dabrowska
168*b55c1d2dSAnna Dabrowska    /**
169*b55c1d2dSAnna Dabrowska     * Returns the manager/admin report box
170*b55c1d2dSAnna Dabrowska     *
171*b55c1d2dSAnna Dabrowska     * @param string $id
172*b55c1d2dSAnna Dabrowska     * @param helper_plugin_acknowledge $helper
173*b55c1d2dSAnna Dabrowska     * @return string
174*b55c1d2dSAnna Dabrowska     */
175*b55c1d2dSAnna Dabrowska    protected function reportHtml($id, helper_plugin_acknowledge $helper)
176*b55c1d2dSAnna Dabrowska    {
177*b55c1d2dSAnna Dabrowska        $mode = $this->getConf('onpage_report');
178*b55c1d2dSAnna Dabrowska        if ($mode === 'off') return '';
179*b55c1d2dSAnna Dabrowska
180*b55c1d2dSAnna Dabrowska        if (!auth_ismanager()) return '';
181*b55c1d2dSAnna Dabrowska
182*b55c1d2dSAnna Dabrowska        if (!$helper->getPageAssignees($id)) return '';
183*b55c1d2dSAnna Dabrowska
184*b55c1d2dSAnna Dabrowska        $html = '<div class="plugin-acknowledge-box report">';
185*b55c1d2dSAnna Dabrowska
186*b55c1d2dSAnna Dabrowska        $html .= '<div class="ack-icon">';
187*b55c1d2dSAnna Dabrowska        $html .= inlineSVG(__DIR__ . '/../admin.svg');
188*b55c1d2dSAnna Dabrowska        $html .= '</div>';
189*b55c1d2dSAnna Dabrowska
190*b55c1d2dSAnna Dabrowska        $html .= '<div class="content">';
191*b55c1d2dSAnna Dabrowska        $html .= '<h3>' . $this->getLang('reportTitle') . '</h3>';
192*b55c1d2dSAnna Dabrowska
193*b55c1d2dSAnna Dabrowska        if ($mode === 'acknowledged' || $mode === 'both') {
194*b55c1d2dSAnna Dabrowska            $acked = $helper->getPageAcknowledgements($id, '', 'current');
195*b55c1d2dSAnna Dabrowska            $html .= '<h4>' . $this->getLang('reportAcknowledgedTitle') . '</h4>';
196*b55c1d2dSAnna Dabrowska            $html .= $this->userListHtml($acked);
197*b55c1d2dSAnna Dabrowska        }
198*b55c1d2dSAnna Dabrowska
199*b55c1d2dSAnna Dabrowska        if ($mode === 'pending' || $mode === 'both') {
200*b55c1d2dSAnna Dabrowska            $pending = $helper->getPageAcknowledgements($id, '', 'due');
201*b55c1d2dSAnna Dabrowska            $html .= '<h4>' . $this->getLang('reportPendingTitle') . '</h4>';
202*b55c1d2dSAnna Dabrowska            $html .= $this->userListHtml($pending);
203*b55c1d2dSAnna Dabrowska        }
204*b55c1d2dSAnna Dabrowska
205*b55c1d2dSAnna Dabrowska        $html .= '</div>'; // content
206*b55c1d2dSAnna Dabrowska        $html .= '</div>'; // box
207*b55c1d2dSAnna Dabrowska
208*b55c1d2dSAnna Dabrowska        return $html;
209*b55c1d2dSAnna Dabrowska    }
210*b55c1d2dSAnna Dabrowska
211*b55c1d2dSAnna Dabrowska    /**
212*b55c1d2dSAnna Dabrowska     * Renders a list of users from acknowledgement records.
213*b55c1d2dSAnna Dabrowska     *
214*b55c1d2dSAnna Dabrowska     * @param array $rows
215*b55c1d2dSAnna Dabrowska     * @return string
216*b55c1d2dSAnna Dabrowska     */
217*b55c1d2dSAnna Dabrowska    protected function userListHtml($rows)
218*b55c1d2dSAnna Dabrowska    {
219*b55c1d2dSAnna Dabrowska        if (!$rows) {
220*b55c1d2dSAnna Dabrowska            return '<p>' . $this->getLang('reportNobody') . '</p>';
221*b55c1d2dSAnna Dabrowska        }
222*b55c1d2dSAnna Dabrowska
223*b55c1d2dSAnna Dabrowska        $html = '<ul>';
224*b55c1d2dSAnna Dabrowska        foreach ($rows as $row) {
225*b55c1d2dSAnna Dabrowska            $html .= '<li>';
226*b55c1d2dSAnna Dabrowska            $html .= userlink($row['user']);
227*b55c1d2dSAnna Dabrowska
228*b55c1d2dSAnna Dabrowska            if (!empty($row['ack'])) {
229*b55c1d2dSAnna Dabrowska                $html .= ' ' . $this->getLang('reportAckedOn') . ' ' . hsc(dformat($row['ack']));
230*b55c1d2dSAnna Dabrowska            }
231*b55c1d2dSAnna Dabrowska            $html .= '</li>';
232*b55c1d2dSAnna Dabrowska        }
233*b55c1d2dSAnna Dabrowska        $html .= '</ul>';
234c38b6ca8SAnna Dabrowska
235c38b6ca8SAnna Dabrowska        return $html;
236c38b6ca8SAnna Dabrowska    }
237c38b6ca8SAnna Dabrowska}
238