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