xref: /plugin/recommend/action.php (revision 45cf09e9f24b61e62adc94b9340cf0dd23815487)
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
14    public function handle(Doku_Event $event) {
15        if ($event->data !=='recommend') {
16            return;
17        }
18
19        $event->preventDefault();
20
21        if ($event->name === 'ACTION_ACT_PREPROCESS') {
22            return;
23        }
24
25        $event->stopPropagation();
26
27        if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
28            isset($_POST['sectok']) &&
29            !($err = $this->_handle_post())) {
30            if ($event->name === 'AJAX_CALL_UNKNOWN') {
31                /* To signal success to AJAX. */
32                header('HTTP/1.1 204 No Content');
33                return;
34            }
35            echo 'Thanks for recommending our site.';
36            return;
37        }
38        /* To display msgs even via AJAX. */
39        echo ' ';
40        if (isset($err)) {
41            msg($err, -1);
42        }
43        echo $this->getForm();
44    }
45
46    public function handleMenu(Doku_Event $event)
47    {
48        if ($event->data['view'] !== 'page') return;
49
50        array_splice($event->data['items'], -1, 0, [new \dokuwiki\plugin\recommend\MenuItem()]);
51    }
52    /**
53     * Returns rendered form
54     *
55     * @return string
56     */
57    protected function getForm()
58    {
59        global $INPUT;
60
61        $id = getID(); // we may run in AJAX context
62        if ($id === '') throw new \RuntimeException('No ID given');
63
64        $form = new \dokuwiki\Form\Form([
65            'action' => wl($id, ['do' => 'recommend'], false, '&'),
66            'id' => 'recommend__plugin',
67        ]);
68        $form->setHiddenField('id', $id); // we need it for the ajax call
69
70        if ($INPUT->server->has('REMOTE_USER')) {
71            global $USERINFO;
72            $form->setHiddenField('s_name', $USERINFO['name']);
73            $form->setHiddenField('s_email', $USERINFO['mail']);
74        } else {
75            $form->addTextInput('s_name', $this->getLang('yourname'))->addClass('edit');
76            $form->addTextInput('s_email', $this->getLang('youremailaddress'))->addClass('edit');
77        }
78
79        $form->addTextInput('r_email', $this->getLang('recipients'))->addClass('edit');
80        $form->addTextInput('subject', $this->getLang('subject'))->addClass('edit');
81        $form->addTextarea('comment', $this->getLang('message'))->attr('rows', '8')->attr('cols', '10')->addClass('edit');
82
83        /** @var helper_plugin_captcha $captcha */
84        $captcha = plugin_load('helper', 'captcha');
85        if ($captcha) $form->addHTML($captcha->getHTML());
86
87        $form->addTagOpen('div')->addClass('buttons');
88        $form->addButton('submit', $this->getLang('send'))->attr('type', 'submit');
89        $form->addButton('reset', $this->getLang('cancel'))->attr('type', 'reset');
90        $form->addTagClose('div');
91
92        return $form->toHTML();
93    }
94
95    /**
96     * Handles form submission and returns error state: error message or else false.
97     *
98     * @return string|false
99     * @throws Exception
100     */
101    protected function _handle_post()
102    {
103        if (!checkSecurityToken()) {
104            throw new \Exception('Security token did not match');
105        }
106
107        global $INPUT;
108
109        $helper = null;
110        if (@is_dir(DOKU_PLUGIN.'captcha')) $helper = plugin_load('helper','captcha');
111        if (!is_null($helper) && $helper->isEnabled() && !$helper->check()) {
112            return 'Wrong captcha';
113        }
114
115        /* Validate input. */
116        $recipient = $INPUT->str('r_email');
117        if (!$recipient || !mail_isvalid($recipient)) {
118            return 'Invalid recipient email address submitted';
119        }
120
121        if (!isset($_POST['s_email']) || !mail_isvalid($_POST['s_email'])) {
122            return 'Invalid sender email address submitted';
123        }
124        if (!isset($_POST['s_name']) || trim($_POST['s_name']) === '') {
125            return 'Invalid sender name submitted';
126        }
127        $s_name = $_POST['s_name'];
128        $sender = $s_name . ' <' . $_POST['s_email'] . '>';
129
130        $id = $INPUT->filter('cleanID')->str('id');
131        if ($id === '' || !page_exists($id)) throw new \Exception($this->getLang('err_page'));
132
133        $comment = $INPUT->str('comment');
134
135        /* Prepare mail text. */
136        $mailtext = file_get_contents(dirname(__FILE__).'/template.txt');
137
138        global $conf;
139        foreach (array('NAME' => $recipient,
140                       'PAGE' => $id,
141                       'SITE' => $conf['title'],
142                       'URL'  => wl($id, '', true),
143                       'COMMENT' => $comment,
144                       'AUTHOR' => $s_name) as $var => $val) {
145            $mailtext = str_replace('@' . $var . '@', $val, $mailtext);
146        }
147        /* Limit to two empty lines. */
148        $mailtext = preg_replace('/\n{4,}/', "\n\n\n", $mailtext);
149
150        /* Perform stuff. */
151        $this->sendMail($recipient, $mailtext, $sender);
152        /** @var helper_plugin_recommend_log $log */
153        $log = new helper_plugin_recommend_log(date('Y-m'));
154        $log->writeEntry($id, $sender, $recipient, $comment);
155
156        return false;
157    }
158
159    /**
160     * @param string $recipient
161     * @param string $mailtext
162     * @param string $sender
163     * @return void
164     */
165    protected function sendMail($recipient, $mailtext, $sender)
166    {
167        global $INPUT;
168
169        $mailer = new Mailer();
170        $mailer->bcc($recipient);
171        $mailer->from($sender);
172
173        $subject = $INPUT->str('subject');
174        $mailer->subject($subject);
175        $mailer->setBody($mailtext);
176        $mailer->send();
177    }
178}
179