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