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'); 21*45240794SAnna Dabrowska $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxAssign'); 22*45240794SAnna 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 */ 61*45240794SAnna Dabrowska public function handleAjaxAssign(Event $event, $param) 62ef3ab392SAndreas Gohr { 635773dd37SAnna Dabrowska if ($event->data === 'plugin_acknowledge_assign') { 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 /** 77*45240794SAnna Dabrowska * @param Event $event 78*45240794SAnna Dabrowska * @return void 79*45240794SAnna Dabrowska */ 80*45240794SAnna Dabrowska public function handleAjaxAutocomplete(Event $event) 81*45240794SAnna Dabrowska { 82*45240794SAnna Dabrowska if ($event->data === 'plugin_acknowledge_autocomplete') { 83*45240794SAnna Dabrowska 84*45240794SAnna Dabrowska if (!checkSecurityToken()) return; 85*45240794SAnna Dabrowska 86*45240794SAnna Dabrowska global $INPUT; 87*45240794SAnna Dabrowska 88*45240794SAnna Dabrowska $event->stopPropagation(); 89*45240794SAnna Dabrowska $event->preventDefault(); 90*45240794SAnna Dabrowska 91*45240794SAnna Dabrowska /** @var helper_plugin_acknowledge $hlp */ 92*45240794SAnna Dabrowska $hlp = $this->loadHelper('acknowledge'); 93*45240794SAnna Dabrowska 94*45240794SAnna Dabrowska $knownUsers = $hlp->getUsers(); 95*45240794SAnna Dabrowska 96*45240794SAnna Dabrowska $search = $INPUT->str('user'); 97*45240794SAnna Dabrowska $found = array_filter($knownUsers, function ($user) use ($search) { 98*45240794SAnna Dabrowska return (strstr(strtolower($user['label']), strtolower($search))) !== false ? $user : null; 99*45240794SAnna Dabrowska }); 100*45240794SAnna Dabrowska 101*45240794SAnna Dabrowska header('Content-Type: application/json'); 102*45240794SAnna Dabrowska 103*45240794SAnna Dabrowska echo json_encode($found); 104*45240794SAnna Dabrowska } 105*45240794SAnna Dabrowska } 106*45240794SAnna Dabrowska 107*45240794SAnna Dabrowska /** 108f09444ffSAndreas Gohr * Handle Migration events 109f09444ffSAndreas Gohr * 1103b76424dSannda * @param Event $event 111f09444ffSAndreas Gohr * @param $param 112f09444ffSAndreas Gohr * @return void 113f09444ffSAndreas Gohr */ 1143b76424dSannda public function handleUpgrade(Event $event, $param) 115f09444ffSAndreas Gohr { 116f09444ffSAndreas Gohr if ($event->data['sqlite']->getAdapter()->getDbname() !== 'acknowledgement') { 117f09444ffSAndreas Gohr return; 118f09444ffSAndreas Gohr } 119f09444ffSAndreas Gohr $to = $event->data['to']; 120f09444ffSAndreas Gohr if ($to !== 3) return; // only handle upgrade to version 3 121f09444ffSAndreas Gohr 122f09444ffSAndreas Gohr /** @var helper_plugin_acknowledge $helper */ 123f09444ffSAndreas Gohr $helper = plugin_load('helper', 'acknowledge'); 124f09444ffSAndreas Gohr $helper->updatePageIndex(); 125f09444ffSAndreas Gohr } 126f09444ffSAndreas Gohr 127f09444ffSAndreas Gohr /** 128ef3ab392SAndreas Gohr * Returns the acknowledgment form/confirmation 129ef3ab392SAndreas Gohr * 130ef3ab392SAndreas Gohr * @return string The HTML to display 131ef3ab392SAndreas Gohr */ 132ef3ab392SAndreas Gohr protected function html() 133ef3ab392SAndreas Gohr { 134ef3ab392SAndreas Gohr global $INPUT; 135ef3ab392SAndreas Gohr global $USERINFO; 136ef3ab392SAndreas Gohr $id = $INPUT->str('id'); 1372d63bbe3SAnna Dabrowska $ackSubmitted = $INPUT->bool('ack'); 138ef3ab392SAndreas Gohr $user = $INPUT->server->str('REMOTE_USER'); 139ef3ab392SAndreas Gohr if ($id === '' || $user === '') return ''; 140ef3ab392SAndreas Gohr 141ef3ab392SAndreas Gohr /** @var helper_plugin_acknowledge $helper */ 142ef3ab392SAndreas Gohr $helper = plugin_load('helper', 'acknowledge'); 143ef3ab392SAndreas Gohr 14435bc8beaSAndreas Gohr // only display for users assigned to the page 14535bc8beaSAndreas Gohr if (!$helper->isUserAssigned($id, $user, $USERINFO['grps'])) { 14635bc8beaSAndreas Gohr return ''; 14735bc8beaSAndreas Gohr } 14835bc8beaSAndreas Gohr 1495773dd37SAnna Dabrowska if ($ackSubmitted) { 1505773dd37SAnna Dabrowska $helper->saveAcknowledgement($id, $user); 1515773dd37SAnna Dabrowska } 1525773dd37SAnna Dabrowska 153ef3ab392SAndreas Gohr $ack = $helper->hasUserAcknowledged($id, $user); 154209df5deSAndreas Gohr 155209df5deSAndreas Gohr $html = '<div class="' . ($ack ? 'ack' : 'noack') . '">'; 156209df5deSAndreas Gohr $html .= inlineSVG(__DIR__ . '/admin.svg'); 157209df5deSAndreas Gohr $html .= '</div>'; 158209df5deSAndreas Gohr 159ef3ab392SAndreas Gohr if ($ack) { 160ef3ab392SAndreas Gohr $html .= '<div>'; 161209df5deSAndreas Gohr $html .= '<h4>'; 162209df5deSAndreas Gohr $html .= $this->getLang('ackOk'); 163209df5deSAndreas Gohr $html .= '</h4>'; 164209df5deSAndreas Gohr $html .= sprintf($this->getLang('ackGranted'), dformat($ack)); 165ef3ab392SAndreas Gohr $html .= '</div>'; 16635bc8beaSAndreas Gohr } else { 167ef3ab392SAndreas Gohr $html .= '<div>'; 168209df5deSAndreas Gohr $html .= '<h4>' . $this->getLang('ackRequired') . '</h4>'; 169d9a8334dSAnna Dabrowska $latest = $helper->getLatestUserAcknowledgement($id, $user); 170d9a8334dSAnna Dabrowska if ($latest) { 171d9a8334dSAnna Dabrowska $html .= '<a href="' 172d9a8334dSAnna Dabrowska . wl($id, ['do' => 'diff', 'at' => $latest], false, '&') . '">' 173d9a8334dSAnna Dabrowska . sprintf($this->getLang('ackDiff'), dformat($latest)) 174d9a8334dSAnna Dabrowska . '</a><br>'; 175d9a8334dSAnna Dabrowska } 176d9a8334dSAnna Dabrowska 177209df5deSAndreas Gohr $form = new Form(['id' => 'ackForm']); 178209df5deSAndreas Gohr $form->addCheckbox('ack', $this->getLang('ackText'))->attr('required', 'required'); 179ba917e33SAnna Dabrowska $form->addHTML( 180ba917e33SAnna Dabrowska '<br><button type="submit" name="acksubmit" id="ack-submit">' 181ba917e33SAnna Dabrowska . $this->getLang('ackButton') 182ba917e33SAnna Dabrowska . '</button>' 183ba917e33SAnna Dabrowska ); 184209df5deSAndreas Gohr 1855773dd37SAnna Dabrowska $html .= $form->toHTML(); 186ef3ab392SAndreas Gohr $html .= '</div>'; 187ef3ab392SAndreas Gohr } 188ef3ab392SAndreas Gohr 189ef3ab392SAndreas Gohr return $html; 190ef3ab392SAndreas Gohr } 1914d6d17d0SAndreas Gohr} 192