xref: /plugin/recommend/action.php (revision b8b86b6cc38a68c8eb36a4b455118cdd5062ca1b)
1<?php
2
3class action_plugin_recommend extends DokuWiki_Action_Plugin {
4
5    public function register(Doku_Event_Handler $controller) {
6        foreach (array('ACTION_ACT_PREPROCESS', 'AJAX_CALL_UNKNOWN',
7                       'TPL_ACT_UNKNOWN') as $event) {
8            $controller->register_hook($event, 'BEFORE', $this, 'handle');
9        }
10        $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'handleMenu');
11    }
12
13    public function handle(Doku_Event $event) {
14        if ($event->data !=='recommend') {
15            return;
16        }
17
18        $event->preventDefault();
19
20        if ($event->name === 'ACTION_ACT_PREPROCESS') {
21            return;
22        }
23
24        $event->stopPropagation();
25
26        global $INPUT;
27
28        // early output to trigger display msgs even via AJAX.
29        echo ' ';
30        tpl_flush();
31        if ($INPUT->server->str('REQUEST_METHOD') === 'POST') {
32            try {
33                $this->handlePost();
34                if ($event->name === 'AJAX_CALL_UNKNOWN') {
35                    $this->ajaxSuccess(); // To signal success to AJAX.
36                } else {
37                    msg($this->getLang('thanks'), 1);
38                }
39                return; // we're done here
40            } catch (\Exception $e) {
41                msg($e->getMessage(), -1);
42            }
43        }
44
45        echo $this->getForm();
46    }
47
48    public function handleMenu(Doku_Event $event)
49    {
50        if ($event->data['view'] !== 'page') return;
51
52        array_splice($event->data['items'], -1, 0, [new \dokuwiki\plugin\recommend\MenuItem()]);
53    }
54    /**
55     * Returns rendered form
56     *
57     * @return string
58     */
59    protected function getForm()
60    {
61        global $INPUT;
62
63        $id = getID(); // we may run in AJAX context
64        if ($id === '') throw new \RuntimeException('No ID given');
65
66        $form = new \dokuwiki\Form\Form([
67            'action' => wl($id, ['do' => 'recommend'], false, '&'),
68            'id' => 'plugin__recommend',
69        ]);
70        $form->setHiddenField('id', $id); // we need it for the ajax call
71
72        /** @var helper_plugin_recommend_assignment $helper */
73        $helper = plugin_load('helper', 'recommend_assignment');
74        $template = $helper->loadMatchingTemplate();
75
76        if ($INPUT->server->has('REMOTE_USER')) {
77            global $USERINFO;
78            $form->setHiddenField('s_name', $USERINFO['name']);
79            $form->setHiddenField('s_email', $USERINFO['mail']);
80        } else {
81            $form->addTextInput('s_name', $this->getLang('yourname'))->addClass('edit');
82            $form->addTextInput('s_email', $this->getLang('youremailaddress'))->addClass('edit');
83        }
84
85        $recipientEmails = $template['user'] ?? '';
86        $message = $template['message'] ?? '';
87        $form->addTextInput('r_email', $this->getLang('recipients'))->addClass('edit')->val($recipientEmails);
88        $form->addTextInput('subject', $this->getLang('subject'))->addClass('edit');
89        $form->addTextarea('comment', $this->getLang('message'))
90            ->attr('rows', '8')
91            ->attr('cols', '40')
92            ->addClass('edit')
93            ->val($message);
94
95        /** @var helper_plugin_captcha $captcha */
96        $captcha = plugin_load('helper', 'captcha');
97        if ($captcha) $form->addHTML($captcha->getHTML());
98
99        $form->addTagOpen('div')->addClass('buttons');
100        $form->addButton('submit', $this->getLang('send'))->attr('type', 'submit');
101        $form->addTagClose('div');
102
103        return $form->toHTML();
104    }
105
106    /**
107     * Handles form submission
108     *
109     * @throws Exception
110     */
111    protected function handlePost()
112    {
113        global $INPUT;
114
115        if (!checkSecurityToken()) {
116            throw new \Exception('Security token did not match');
117        }
118
119        // Captcha plugin
120        $helper = null;
121        if (@is_dir(DOKU_PLUGIN . 'captcha')) $helper = plugin_load('helper','captcha');
122        if (!is_null($helper) && $helper->isEnabled() && !$helper->check()) {
123            throw new \Exception($this->getLang('err_captcha'));
124        }
125
126        /* Validate input. */
127        $recipient = $INPUT->str('r_email');
128        if (!$recipient || !mail_isvalid($recipient)) {
129            throw new \Exception($this->getLang('err_recipient'));
130        }
131
132        if (!isset($_POST['s_email']) || !mail_isvalid($_POST['s_email'])) {
133            throw new \Exception($this->getLang('err_sendermail'));
134        }
135        if (!isset($_POST['s_name']) || trim($_POST['s_name']) === '') {
136            throw new \Exception($this->getLang('err_sendername'));
137        }
138        $s_name = $_POST['s_name'];
139        $sender = $s_name . ' <' . $_POST['s_email'] . '>';
140
141        $id = $INPUT->filter('cleanID')->str('id');
142        if ($id === '' || !page_exists($id)) throw new \Exception($this->getLang('err_page'));
143
144        $comment = $INPUT->str('comment');
145
146        /* Prepare mail text. */
147        $mailtext = file_get_contents(dirname(__FILE__).'/template.txt');
148
149        global $conf;
150        foreach (array('NAME' => $recipient,
151                       'PAGE' => $id,
152                       'SITE' => $conf['title'],
153                       'URL'  => wl($id, '', true),
154                       'COMMENT' => $comment,
155                       'AUTHOR' => $s_name) as $var => $val) {
156            $mailtext = str_replace('@' . $var . '@', $val, $mailtext);
157        }
158        /* Limit to two empty lines. */
159        $mailtext = preg_replace('/\n{4,}/', "\n\n\n", $mailtext);
160
161        $this->sendMail($recipient, $mailtext, $sender);
162
163        /** @var helper_plugin_recommend_log $log */
164        $log = new helper_plugin_recommend_log(date('Y-m'));
165        $log->writeEntry($id, $sender, $recipient, $comment);
166    }
167
168    /**
169     * @param string $recipient
170     * @param string $mailtext
171     * @param string $sender
172     * @return void
173     */
174    protected function sendMail($recipient, $mailtext, $sender)
175    {
176        global $INPUT;
177
178        $mailer = new Mailer();
179        $mailer->bcc($recipient);
180        $mailer->from($sender);
181
182        $subject = $INPUT->str('subject');
183        $mailer->subject($subject);
184        $mailer->setBody($mailtext);
185        $mailer->send();
186    }
187
188    /**
189     * show success message in ajax mode
190     */
191    protected function ajaxSuccess()
192    {
193        echo '<form id="plugin__recommend" accept-charset="utf-8" method="post" action="?do=recommend">';
194        echo '<div class="no">';
195        echo '<span class="ui-icon ui-icon-circle-check" style="float: left; margin: 0 7px 50px 0;"></span>';
196        echo '<p>' . $this->getLang('done') . '</p>';
197        echo '<button type="reset" class="button">' . $this->getLang('close') . '</button>';
198        echo '</div>';
199        echo '</form>';
200    }
201}
202