xref: /plugin/recommend/action.php (revision c6f9d3d590f898165ce791277f4554ff3ef97548)
14654e4deSAdrian Lang<?php
24654e4deSAdrian Lang
3*c6f9d3d5SAnna Dabrowskause dokuwiki\Extension\ActionPlugin;
4*c6f9d3d5SAnna Dabrowskause dokuwiki\Extension\EventHandler;
5*c6f9d3d5SAnna Dabrowskause dokuwiki\Extension\Event;
6*c6f9d3d5SAnna Dabrowskause dokuwiki\plugin\recommend\MenuItem;
7*c6f9d3d5SAnna Dabrowskause dokuwiki\Form\Form;
8*c6f9d3d5SAnna Dabrowskause dokuwiki\Utf8\PhpString;
94654e4deSAdrian Lang
10*c6f9d3d5SAnna Dabrowskaclass action_plugin_recommend extends ActionPlugin
11*c6f9d3d5SAnna Dabrowska{
12*c6f9d3d5SAnna Dabrowska    public function register(EventHandler $controller)
13*c6f9d3d5SAnna Dabrowska    {
14*c6f9d3d5SAnna Dabrowska        foreach (['ACTION_ACT_PREPROCESS', 'AJAX_CALL_UNKNOWN', 'TPL_ACT_UNKNOWN'] as $event) {
152937e9a5SAnna Dabrowska            $controller->register_hook($event, 'BEFORE', $this, 'handle');
164654e4deSAdrian Lang        }
1745cf09e9SAnna Dabrowska        $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'handleMenu');
189121cb07SAnna Dabrowska        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'autocomplete');
194654e4deSAdrian Lang    }
204654e4deSAdrian Lang
219121cb07SAnna Dabrowska    /**
229121cb07SAnna Dabrowska     * Main processing
239121cb07SAnna Dabrowska     *
24*c6f9d3d5SAnna Dabrowska     * @param Event $event
259121cb07SAnna Dabrowska     * @return void
269121cb07SAnna Dabrowska     */
27*c6f9d3d5SAnna Dabrowska    public function handle(Event $event)
28*c6f9d3d5SAnna Dabrowska    {
292937e9a5SAnna Dabrowska        if ($event->data !== 'recommend') {
304654e4deSAdrian Lang            return;
314654e4deSAdrian Lang        }
324654e4deSAdrian Lang
334654e4deSAdrian Lang        $event->preventDefault();
344654e4deSAdrian Lang
354654e4deSAdrian Lang        if ($event->name === 'ACTION_ACT_PREPROCESS') {
364654e4deSAdrian Lang            return;
374654e4deSAdrian Lang        }
384654e4deSAdrian Lang
394654e4deSAdrian Lang        $event->stopPropagation();
404654e4deSAdrian Lang
41945a672eSAnna Dabrowska        global $INPUT;
42945a672eSAnna Dabrowska
43945a672eSAnna Dabrowska        // early output to trigger display msgs even via AJAX.
4470f4a435SAdrian Lang        echo ' ';
45945a672eSAnna Dabrowska        tpl_flush();
46945a672eSAnna Dabrowska        if ($INPUT->server->str('REQUEST_METHOD') === 'POST') {
47945a672eSAnna Dabrowska            try {
48945a672eSAnna Dabrowska                $this->handlePost();
49945a672eSAnna Dabrowska                if ($event->name === 'AJAX_CALL_UNKNOWN') {
50945a672eSAnna Dabrowska                    $this->ajaxSuccess(); // To signal success to AJAX.
51945a672eSAnna Dabrowska                } else {
52945a672eSAnna Dabrowska                    msg($this->getLang('thanks'), 1);
5370f4a435SAdrian Lang                }
54945a672eSAnna Dabrowska                return; // we're done here
55945a672eSAnna Dabrowska            } catch (\Exception $e) {
56945a672eSAnna Dabrowska                msg($e->getMessage(), -1);
57945a672eSAnna Dabrowska            }
58945a672eSAnna Dabrowska        }
59945a672eSAnna Dabrowska
602937e9a5SAnna Dabrowska        echo $this->getForm();
614654e4deSAdrian Lang    }
624654e4deSAdrian Lang
635187ba70SAnna Dabrowska    /**
645187ba70SAnna Dabrowska     * Page menu item
655187ba70SAnna Dabrowska     *
66*c6f9d3d5SAnna Dabrowska     * @param Event $event
675187ba70SAnna Dabrowska     * @return void
685187ba70SAnna Dabrowska     */
69*c6f9d3d5SAnna Dabrowska    public function handleMenu(Event $event)
7045cf09e9SAnna Dabrowska    {
7145cf09e9SAnna Dabrowska        if ($event->data['view'] !== 'page') return;
729fd061b7SAnna Dabrowska        // menu item is only for logged in users
739fd061b7SAnna Dabrowska        if (empty($_SERVER['REMOTE_USER'])) return;
7445cf09e9SAnna Dabrowska
75*c6f9d3d5SAnna Dabrowska        array_splice($event->data['items'], -1, 0, [new MenuItem()]);
7645cf09e9SAnna Dabrowska    }
775187ba70SAnna Dabrowska
782937e9a5SAnna Dabrowska    /**
799121cb07SAnna Dabrowska     * Autocomplete
80*c6f9d3d5SAnna Dabrowska     * @param Event $event
819121cb07SAnna Dabrowska     * @throws Exception
829121cb07SAnna Dabrowska     * @author Andreas Gohr
839121cb07SAnna Dabrowska     */
84*c6f9d3d5SAnna Dabrowska    public function autocomplete(Event $event)
859121cb07SAnna Dabrowska    {
869121cb07SAnna Dabrowska
879121cb07SAnna Dabrowska        if ($event->data !== 'plugin_recommend_ac') {
889121cb07SAnna Dabrowska            return;
899121cb07SAnna Dabrowska        }
909121cb07SAnna Dabrowska
919121cb07SAnna Dabrowska        $event->preventDefault();
929121cb07SAnna Dabrowska        $event->stopPropagation();
939121cb07SAnna Dabrowska
949121cb07SAnna Dabrowska        /** @var \DokuWiki_Auth_Plugin $auth */
959121cb07SAnna Dabrowska        global $auth;
969121cb07SAnna Dabrowska        global $INPUT;
979121cb07SAnna Dabrowska
989121cb07SAnna Dabrowska        if (!$auth->canDo('getUsers')) {
999121cb07SAnna Dabrowska            throw new Exception('The user backend can not search for users');
1009121cb07SAnna Dabrowska        }
1019121cb07SAnna Dabrowska
1029121cb07SAnna Dabrowska        header('Content-Type: application/json');
1039121cb07SAnna Dabrowska
1049121cb07SAnna Dabrowska        // check minimum length
1059121cb07SAnna Dabrowska        $lookup = trim($INPUT->str('search'));
106*c6f9d3d5SAnna Dabrowska        if (PhpString::strlen($lookup) < 3) {
1079121cb07SAnna Dabrowska            echo json_encode([]);
1089121cb07SAnna Dabrowska            return;
1099121cb07SAnna Dabrowska        }
1109121cb07SAnna Dabrowska
1119121cb07SAnna Dabrowska        // find users by login and name
1129121cb07SAnna Dabrowska        $logins = $auth->retrieveUsers(0, 10, ['user' => $lookup]);
1139121cb07SAnna Dabrowska        if (count($logins) < 10) {
1149121cb07SAnna Dabrowska            $logins = array_merge($logins, $auth->retrieveUsers(0, 10, ['name' => $lookup]));
1159121cb07SAnna Dabrowska        }
1169121cb07SAnna Dabrowska
1179121cb07SAnna Dabrowska        // reformat result for jQuery UI Autocomplete
1189121cb07SAnna Dabrowska        $users = [];
1199121cb07SAnna Dabrowska        foreach ($logins as $login => $info) {
1209121cb07SAnna Dabrowska            $users[] = [
1219121cb07SAnna Dabrowska                'label' => $info['name'] . ' [' . $login . ']',
1229121cb07SAnna Dabrowska                'value' => $login
1239121cb07SAnna Dabrowska            ];
1249121cb07SAnna Dabrowska        }
1259121cb07SAnna Dabrowska
1269121cb07SAnna Dabrowska        echo json_encode($users);
1279121cb07SAnna Dabrowska    }
1289121cb07SAnna Dabrowska
1299121cb07SAnna Dabrowska    /**
1302937e9a5SAnna Dabrowska     * Returns rendered form
1312937e9a5SAnna Dabrowska     *
1322937e9a5SAnna Dabrowska     * @return string
1332937e9a5SAnna Dabrowska     */
1342937e9a5SAnna Dabrowska    protected function getForm()
1352937e9a5SAnna Dabrowska    {
1362937e9a5SAnna Dabrowska        global $INPUT;
1372937e9a5SAnna Dabrowska
1382937e9a5SAnna Dabrowska        $id = getID(); // we may run in AJAX context
1392937e9a5SAnna Dabrowska        if ($id === '') throw new \RuntimeException('No ID given');
1402937e9a5SAnna Dabrowska
141*c6f9d3d5SAnna Dabrowska        $form = new Form([
1422937e9a5SAnna Dabrowska            'action' => wl($id, ['do' => 'recommend'], false, '&'),
143945a672eSAnna Dabrowska            'id' => 'plugin__recommend',
1442937e9a5SAnna Dabrowska        ]);
1452937e9a5SAnna Dabrowska        $form->setHiddenField('id', $id); // we need it for the ajax call
1462937e9a5SAnna Dabrowska
147b8b86b6cSAnna Dabrowska        /** @var helper_plugin_recommend_assignment $helper */
148b8b86b6cSAnna Dabrowska        $helper = plugin_load('helper', 'recommend_assignment');
149b8b86b6cSAnna Dabrowska        $template = $helper->loadMatchingTemplate();
150b8b86b6cSAnna Dabrowska
1512937e9a5SAnna Dabrowska        if ($INPUT->server->has('REMOTE_USER')) {
152e596e22bSAdrian Lang            global $USERINFO;
1532937e9a5SAnna Dabrowska            $form->setHiddenField('s_name', $USERINFO['name']);
1542937e9a5SAnna Dabrowska            $form->setHiddenField('s_email', $USERINFO['mail']);
155e596e22bSAdrian Lang        } else {
1562937e9a5SAnna Dabrowska            $form->addTextInput('s_name', $this->getLang('yourname'))->addClass('edit');
1572937e9a5SAnna Dabrowska            $form->addTextInput('s_email', $this->getLang('youremailaddress'))->addClass('edit');
158e596e22bSAdrian Lang        }
159e596e22bSAdrian Lang
160d0dae647SAnna Dabrowska        $form->addTextInput('r_email', $this->getLang('recipients'))
161d0dae647SAnna Dabrowska            ->addClass('edit')
162d0dae647SAnna Dabrowska            ->val($template['user'] ?? '');
163d0dae647SAnna Dabrowska        $form->addTextInput('subject', $this->getLang('subject'))
164d0dae647SAnna Dabrowska            ->addClass('edit')
165d0dae647SAnna Dabrowska            ->val($template['subject'] ?? '');
166b8b86b6cSAnna Dabrowska        $form->addTextarea('comment', $this->getLang('message'))
167b8b86b6cSAnna Dabrowska            ->attr('rows', '8')
168b8b86b6cSAnna Dabrowska            ->attr('cols', '40')
169b8b86b6cSAnna Dabrowska            ->addClass('edit')
170d0dae647SAnna Dabrowska            ->val($template['message'] ?? '');
1712937e9a5SAnna Dabrowska
1722937e9a5SAnna Dabrowska        /** @var helper_plugin_captcha $captcha */
1732937e9a5SAnna Dabrowska        $captcha = plugin_load('helper', 'captcha');
1742937e9a5SAnna Dabrowska        if ($captcha) $form->addHTML($captcha->getHTML());
1752937e9a5SAnna Dabrowska
1762937e9a5SAnna Dabrowska        $form->addTagOpen('div')->addClass('buttons');
1772937e9a5SAnna Dabrowska        $form->addButton('submit', $this->getLang('send'))->attr('type', 'submit');
1782937e9a5SAnna Dabrowska        $form->addTagClose('div');
1792937e9a5SAnna Dabrowska
1802937e9a5SAnna Dabrowska        return $form->toHTML();
1814654e4deSAdrian Lang    }
1824654e4deSAdrian Lang
1832937e9a5SAnna Dabrowska    /**
184945a672eSAnna Dabrowska     * Handles form submission
1852937e9a5SAnna Dabrowska     *
1862937e9a5SAnna Dabrowska     * @throws Exception
1872937e9a5SAnna Dabrowska     */
188945a672eSAnna Dabrowska    protected function handlePost()
1892937e9a5SAnna Dabrowska    {
190945a672eSAnna Dabrowska        global $INPUT;
191945a672eSAnna Dabrowska
1922937e9a5SAnna Dabrowska        if (!checkSecurityToken()) {
1932937e9a5SAnna Dabrowska            throw new \Exception('Security token did not match');
1942937e9a5SAnna Dabrowska        }
1952937e9a5SAnna Dabrowska
1965187ba70SAnna Dabrowska        /** @var helper_plugin_recommend_mail $mailHelper */
1975187ba70SAnna Dabrowska        $mailHelper = plugin_load('helper', 'recommend_mail');
1985187ba70SAnna Dabrowska
199945a672eSAnna Dabrowska        // Captcha plugin
2005187ba70SAnna Dabrowska        $captcha = null;
2015187ba70SAnna Dabrowska        if (@is_dir(DOKU_PLUGIN . 'captcha')) $captcha = plugin_load('helper', 'captcha');
2025187ba70SAnna Dabrowska        if (!is_null($captcha) && $captcha->isEnabled() && !$captcha->check()) {
203945a672eSAnna Dabrowska            throw new \Exception($this->getLang('err_captcha'));
204e596e22bSAdrian Lang        }
205e596e22bSAdrian Lang
2065187ba70SAnna Dabrowska        /* Validate input */
2075187ba70SAnna Dabrowska        $recipients = $INPUT->str('r_email');
2085187ba70SAnna Dabrowska
2095187ba70SAnna Dabrowska        if (empty($recipients)) {
210945a672eSAnna Dabrowska            throw new \Exception($this->getLang('err_recipient'));
2114654e4deSAdrian Lang        }
212e596e22bSAdrian Lang
2135187ba70SAnna Dabrowska        $recipients = $mailHelper->resolveRecipients($recipients);
2145187ba70SAnna Dabrowska        $recipients = implode(',', $recipients);
2155187ba70SAnna Dabrowska
216e596e22bSAdrian Lang        if (!isset($_POST['s_email']) || !mail_isvalid($_POST['s_email'])) {
217945a672eSAnna Dabrowska            throw new \Exception($this->getLang('err_sendermail'));
218e596e22bSAdrian Lang        }
219c18a4184SAdrian Lang        if (!isset($_POST['s_name']) || trim($_POST['s_name']) === '') {
220945a672eSAnna Dabrowska            throw new \Exception($this->getLang('err_sendername'));
221c18a4184SAdrian Lang        }
222c18a4184SAdrian Lang        $s_name = $_POST['s_name'];
223c18a4184SAdrian Lang        $sender = $s_name . ' <' . $_POST['s_email'] . '>';
2244654e4deSAdrian Lang
2252937e9a5SAnna Dabrowska        $id = $INPUT->filter('cleanID')->str('id');
2262937e9a5SAnna Dabrowska        if ($id === '' || !page_exists($id)) throw new \Exception($this->getLang('err_page'));
2274654e4deSAdrian Lang
2282937e9a5SAnna Dabrowska        $comment = $INPUT->str('comment');
2294654e4deSAdrian Lang
2304654e4deSAdrian Lang        global $conf;
231f1a0181dSAnna Dabrowska        $replacements = [
232f1a0181dSAnna Dabrowska            'PAGE' => $id,
2334654e4deSAdrian Lang            'SITE' => $conf['title'],
2342937e9a5SAnna Dabrowska            'URL'  => wl($id, '', true),
2354654e4deSAdrian Lang            'COMMENT' => $comment,
236f1a0181dSAnna Dabrowska            'AUTHOR' => $s_name
237f1a0181dSAnna Dabrowska        ];
2384654e4deSAdrian Lang
239f1a0181dSAnna Dabrowska        $mailHelper->sendMail($recipients, $sender, $replacements);
240945a672eSAnna Dabrowska
2412937e9a5SAnna Dabrowska        /** @var helper_plugin_recommend_log $log */
2422937e9a5SAnna Dabrowska        $log = new helper_plugin_recommend_log(date('Y-m'));
2435187ba70SAnna Dabrowska        $log->writeEntry($id, $sender, $recipients, $comment);
2442937e9a5SAnna Dabrowska    }
245945a672eSAnna Dabrowska
246945a672eSAnna Dabrowska    /**
247945a672eSAnna Dabrowska     * show success message in ajax mode
248945a672eSAnna Dabrowska     */
249945a672eSAnna Dabrowska    protected function ajaxSuccess()
250945a672eSAnna Dabrowska    {
251945a672eSAnna Dabrowska        echo '<form id="plugin__recommend" accept-charset="utf-8" method="post" action="?do=recommend">';
252945a672eSAnna Dabrowska        echo '<div class="no">';
253945a672eSAnna Dabrowska        echo '<span class="ui-icon ui-icon-circle-check" style="float: left; margin: 0 7px 50px 0;"></span>';
254945a672eSAnna Dabrowska        echo '<p>' . $this->getLang('done') . '</p>';
255945a672eSAnna Dabrowska        echo '<button type="reset" class="button">' . $this->getLang('close') . '</button>';
256945a672eSAnna Dabrowska        echo '</div>';
257945a672eSAnna Dabrowska        echo '</form>';
258945a672eSAnna Dabrowska    }
2594654e4deSAdrian Lang}
260