xref: /plugin/captcha/action.php (revision bd26d35b7b32407ed0189c28198eae135056a68b)
142a27035SAndreas Gohr<?php
242a27035SAndreas Gohr/**
342a27035SAndreas Gohr * CAPTCHA antispam plugin
442a27035SAndreas Gohr *
542a27035SAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
642a27035SAndreas Gohr * @author     Andreas Gohr <gohr@cosmocode.de>
742a27035SAndreas Gohr */
842a27035SAndreas Gohr
942a27035SAndreas Gohr// must be run within Dokuwiki
1042a27035SAndreas Gohrif(!defined('DOKU_INC')) die();
1142a27035SAndreas Gohrif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
127218f96cSAndreas Gohr
1342a27035SAndreas Gohrclass action_plugin_captcha extends DokuWiki_Action_Plugin {
1442a27035SAndreas Gohr
1542a27035SAndreas Gohr    /**
1642a27035SAndreas Gohr     * register the eventhandlers
1742a27035SAndreas Gohr     */
187218f96cSAndreas Gohr    public function register(Doku_Event_Handler $controller) {
197218f96cSAndreas Gohr        // check CAPTCHA success
20c2695b40SAndreas Gohr        $controller->register_hook(
21c2695b40SAndreas Gohr            'ACTION_ACT_PREPROCESS',
2242a27035SAndreas Gohr            'BEFORE',
2342a27035SAndreas Gohr            $this,
247218f96cSAndreas Gohr            'handle_captcha_input',
25c2695b40SAndreas Gohr            array()
26c2695b40SAndreas Gohr        );
2742a27035SAndreas Gohr
287218f96cSAndreas Gohr        // inject in edit form
29c2695b40SAndreas Gohr        $controller->register_hook(
30c2695b40SAndreas Gohr            'HTML_EDITFORM_OUTPUT',
3147afabe6SAndreas Gohr            'BEFORE',
3247afabe6SAndreas Gohr            $this,
337218f96cSAndreas Gohr            'handle_form_output',
347218f96cSAndreas Gohr            array()
35c2695b40SAndreas Gohr        );
3642a27035SAndreas Gohr
377218f96cSAndreas Gohr        // inject in user registration
38c2695b40SAndreas Gohr        $controller->register_hook(
39c2695b40SAndreas Gohr            'HTML_REGISTERFORM_OUTPUT',
4047afabe6SAndreas Gohr            'BEFORE',
4147afabe6SAndreas Gohr            $this,
427218f96cSAndreas Gohr            'handle_form_output',
437218f96cSAndreas Gohr            array()
44c2695b40SAndreas Gohr        );
4542a27035SAndreas Gohr    }
4642a27035SAndreas Gohr
4742a27035SAndreas Gohr    /**
48*bd26d35bSAndreas Gohr     * Check if the current mode should be handled by CAPTCHA
49*bd26d35bSAndreas Gohr     *
50*bd26d35bSAndreas Gohr     * @param string $act cleaned action mode
51*bd26d35bSAndreas Gohr     * @return bool
52*bd26d35bSAndreas Gohr     */
53*bd26d35bSAndreas Gohr    protected function is_protected($act) {
54*bd26d35bSAndreas Gohr        global $INPUT;
55*bd26d35bSAndreas Gohr
56*bd26d35bSAndreas Gohr        switch($act) {
57*bd26d35bSAndreas Gohr            case 'save':
58*bd26d35bSAndreas Gohr                return true;
59*bd26d35bSAndreas Gohr            case 'register':
60*bd26d35bSAndreas Gohr                return $INPUT->bool('save');
61*bd26d35bSAndreas Gohr            default:
62*bd26d35bSAndreas Gohr                return false;
63*bd26d35bSAndreas Gohr        }
64*bd26d35bSAndreas Gohr    }
65*bd26d35bSAndreas Gohr
66*bd26d35bSAndreas Gohr    /**
67*bd26d35bSAndreas Gohr     * Aborts the given mode
68*bd26d35bSAndreas Gohr     *
69*bd26d35bSAndreas Gohr     * Aborting depends on the mode. It might unset certain input parameters or simply switch
70*bd26d35bSAndreas Gohr     * the mode to something else (giving as return which needs to be passed back to the
71*bd26d35bSAndreas Gohr     * ACTION_ACT_PREPROCESS event)
72*bd26d35bSAndreas Gohr     *
73*bd26d35bSAndreas Gohr     * @param string $act cleaned action mode
74*bd26d35bSAndreas Gohr     * @return string the new mode to use
75*bd26d35bSAndreas Gohr     */
76*bd26d35bSAndreas Gohr    protected function abort_action($act) {
77*bd26d35bSAndreas Gohr        global $INPUT;
78*bd26d35bSAndreas Gohr
79*bd26d35bSAndreas Gohr        switch($act) {
80*bd26d35bSAndreas Gohr            case 'save':
81*bd26d35bSAndreas Gohr                return 'preview';
82*bd26d35bSAndreas Gohr            case 'register':
83*bd26d35bSAndreas Gohr                $INPUT->post->set('save', false);
84*bd26d35bSAndreas Gohr                return 'register';
85*bd26d35bSAndreas Gohr            default:
86*bd26d35bSAndreas Gohr                return $act;
87*bd26d35bSAndreas Gohr        }
88*bd26d35bSAndreas Gohr    }
89*bd26d35bSAndreas Gohr
90*bd26d35bSAndreas Gohr    /**
9142a27035SAndreas Gohr     * Will intercept the 'save' action and check for CAPTCHA first.
9242a27035SAndreas Gohr     */
937218f96cSAndreas Gohr    public function handle_captcha_input(Doku_Event $event, $param) {
947218f96cSAndreas Gohr        $act = act_clean($event->data);
95*bd26d35bSAndreas Gohr        if(!$this->is_protected($act)) return;
9693f66506SAndreas Gohr
9742a27035SAndreas Gohr        // do nothing if logged in user and no CAPTCHA required
9842a27035SAndreas Gohr        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']) {
9942a27035SAndreas Gohr            return;
10042a27035SAndreas Gohr        }
10142a27035SAndreas Gohr
10277e00bf9SAndreas Gohr        // check captcha
1037218f96cSAndreas Gohr        /** @var helper_plugin_captcha $helper */
10477e00bf9SAndreas Gohr        $helper = plugin_load('helper', 'captcha');
10577e00bf9SAndreas Gohr        if(!$helper->check()) {
106*bd26d35bSAndreas Gohr            $event->data = $this->abort_action($act);
10742a27035SAndreas Gohr        }
10842a27035SAndreas Gohr    }
10942a27035SAndreas Gohr
11042a27035SAndreas Gohr    /**
1117218f96cSAndreas Gohr     * Inject the CAPTCHA in a DokuForm
11242a27035SAndreas Gohr     */
1137218f96cSAndreas Gohr    public function handle_form_output(Doku_Event $event, $param) {
11447afabe6SAndreas Gohr        // get position of submit button
11547afabe6SAndreas Gohr        $pos = $event->data->findElementByAttribute('type', 'submit');
11647afabe6SAndreas Gohr        if(!$pos) return; // no button -> source view mode
11747afabe6SAndreas Gohr
11842a27035SAndreas Gohr        // do nothing if logged in user and no CAPTCHA required
11942a27035SAndreas Gohr        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']) {
12042a27035SAndreas Gohr            return;
12142a27035SAndreas Gohr        }
12242a27035SAndreas Gohr
12377e00bf9SAndreas Gohr        // get the CAPTCHA
1247218f96cSAndreas Gohr        /** @var helper_plugin_captcha $helper */
12577e00bf9SAndreas Gohr        $helper = plugin_load('helper', 'captcha');
12677e00bf9SAndreas Gohr        $out = $helper->getHTML();
12747afabe6SAndreas Gohr
1287218f96cSAndreas Gohr        // new wiki - insert after the submit button
1297218f96cSAndreas Gohr        $event->data->insertElement($pos + 1, $out);
13042a27035SAndreas Gohr    }
13142a27035SAndreas Gohr
13242a27035SAndreas Gohr}
13342a27035SAndreas Gohr
134