xref: /plugin/captcha/action.php (revision c2695b4064acf71a0be53fa2784565975ea97dd2)
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 Gohr
1242a27035SAndreas Gohrif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
1342a27035SAndreas Gohrrequire_once(DOKU_PLUGIN.'action.php');
1442a27035SAndreas Gohr
1542a27035SAndreas Gohrclass action_plugin_captcha extends DokuWiki_Action_Plugin {
1642a27035SAndreas Gohr
1742a27035SAndreas Gohr    /**
1842a27035SAndreas Gohr     * register the eventhandlers
1942a27035SAndreas Gohr     */
2042a27035SAndreas Gohr    function register(&$controller) {
21*c2695b40SAndreas Gohr        $controller->register_hook(
22*c2695b40SAndreas Gohr            'ACTION_ACT_PREPROCESS',
2342a27035SAndreas Gohr            'BEFORE',
2442a27035SAndreas Gohr            $this,
2542a27035SAndreas Gohr            'handle_act_preprocess',
26*c2695b40SAndreas Gohr            array()
27*c2695b40SAndreas Gohr        );
2842a27035SAndreas Gohr
2947afabe6SAndreas Gohr        // old hook
30*c2695b40SAndreas Gohr        $controller->register_hook(
31*c2695b40SAndreas Gohr            'HTML_EDITFORM_INJECTION',
3242a27035SAndreas Gohr            'BEFORE',
3342a27035SAndreas Gohr            $this,
3447afabe6SAndreas Gohr            'handle_editform_output',
35*c2695b40SAndreas Gohr            array('editform' => true, 'oldhook' => true)
36*c2695b40SAndreas Gohr        );
3747afabe6SAndreas Gohr
3847afabe6SAndreas Gohr        // new hook
39*c2695b40SAndreas Gohr        $controller->register_hook(
40*c2695b40SAndreas Gohr            'HTML_EDITFORM_OUTPUT',
4147afabe6SAndreas Gohr            'BEFORE',
4247afabe6SAndreas Gohr            $this,
4347afabe6SAndreas Gohr            'handle_editform_output',
44*c2695b40SAndreas Gohr            array('editform' => true, 'oldhook' => false)
45*c2695b40SAndreas Gohr        );
4642a27035SAndreas Gohr
4742a27035SAndreas Gohr        if($this->getConf('regprotect')) {
4847afabe6SAndreas Gohr            // old hook
49*c2695b40SAndreas Gohr            $controller->register_hook(
50*c2695b40SAndreas Gohr                'HTML_REGISTERFORM_INJECTION',
5142a27035SAndreas Gohr                'BEFORE',
5242a27035SAndreas Gohr                $this,
5347afabe6SAndreas Gohr                'handle_editform_output',
54*c2695b40SAndreas Gohr                array('editform' => false, 'oldhook' => true)
55*c2695b40SAndreas Gohr            );
5647afabe6SAndreas Gohr
5747afabe6SAndreas Gohr            // new hook
58*c2695b40SAndreas Gohr            $controller->register_hook(
59*c2695b40SAndreas Gohr                'HTML_REGISTERFORM_OUTPUT',
6047afabe6SAndreas Gohr                'BEFORE',
6147afabe6SAndreas Gohr                $this,
6247afabe6SAndreas Gohr                'handle_editform_output',
63*c2695b40SAndreas Gohr                array('editform' => false, 'oldhook' => false)
64*c2695b40SAndreas Gohr            );
6542a27035SAndreas Gohr        }
6642a27035SAndreas Gohr    }
6742a27035SAndreas Gohr
6842a27035SAndreas Gohr    /**
6942a27035SAndreas Gohr     * Will intercept the 'save' action and check for CAPTCHA first.
7042a27035SAndreas Gohr     */
7142a27035SAndreas Gohr    function handle_act_preprocess(&$event, $param) {
7293f66506SAndreas Gohr        $act = $this->_act_clean($event->data);
7393f66506SAndreas Gohr        if(!('save' == $act || ($this->getConf('regprotect') &&
7493f66506SAndreas Gohr                'register' == $act &&
75*c2695b40SAndreas Gohr                $_POST['save']))
76*c2695b40SAndreas Gohr        ) {
7793f66506SAndreas Gohr            return; // nothing to do for us
7893f66506SAndreas Gohr        }
7993f66506SAndreas Gohr
8042a27035SAndreas Gohr        // do nothing if logged in user and no CAPTCHA required
8142a27035SAndreas Gohr        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']) {
8242a27035SAndreas Gohr            return;
8342a27035SAndreas Gohr        }
8442a27035SAndreas Gohr
8577e00bf9SAndreas Gohr        // check captcha
8677e00bf9SAndreas Gohr        $helper = plugin_load('helper', 'captcha');
8777e00bf9SAndreas Gohr        if(!$helper->check()) {
8893f66506SAndreas Gohr            if($act == 'save') {
8993f66506SAndreas Gohr                // stay in preview mode
9042a27035SAndreas Gohr                $event->data = 'preview';
9193f66506SAndreas Gohr            } else {
9293f66506SAndreas Gohr                // stay in register mode, but disable the save parameter
9393f66506SAndreas Gohr                $_POST['save'] = false;
9442a27035SAndreas Gohr            }
9542a27035SAndreas Gohr        }
9642a27035SAndreas Gohr    }
9742a27035SAndreas Gohr
9842a27035SAndreas Gohr    /**
9942a27035SAndreas Gohr     * Create the additional fields for the edit form
10042a27035SAndreas Gohr     */
10147afabe6SAndreas Gohr    function handle_editform_output(&$event, $param) {
10247afabe6SAndreas Gohr        // check if source view -> no captcha needed
10347afabe6SAndreas Gohr        if(!$param['oldhook']) {
10447afabe6SAndreas Gohr            // get position of submit button
10547afabe6SAndreas Gohr            $pos = $event->data->findElementByAttribute('type', 'submit');
10647afabe6SAndreas Gohr            if(!$pos) return; // no button -> source view mode
10747afabe6SAndreas Gohr        } elseif($param['editform'] && !$event->data['writable']) {
10842a27035SAndreas Gohr            if($param['editform'] && !$event->data['writable']) return;
10947afabe6SAndreas Gohr        }
11047afabe6SAndreas Gohr
11142a27035SAndreas Gohr        // do nothing if logged in user and no CAPTCHA required
11242a27035SAndreas Gohr        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']) {
11342a27035SAndreas Gohr            return;
11442a27035SAndreas Gohr        }
11542a27035SAndreas Gohr
11677e00bf9SAndreas Gohr        // get the CAPTCHA
11777e00bf9SAndreas Gohr        $helper = plugin_load('helper', 'captcha');
11877e00bf9SAndreas Gohr        $out    = $helper->getHTML();
11947afabe6SAndreas Gohr
12047afabe6SAndreas Gohr        if($param['oldhook']) {
12147afabe6SAndreas Gohr            // old wiki - just print
12247afabe6SAndreas Gohr            echo $out;
12347afabe6SAndreas Gohr        } else {
12447afabe6SAndreas Gohr            // new wiki - insert at correct position
12547afabe6SAndreas Gohr            $event->data->insertElement($pos++, $out);
12647afabe6SAndreas Gohr        }
12742a27035SAndreas Gohr    }
12842a27035SAndreas Gohr
12942a27035SAndreas Gohr    /**
13042a27035SAndreas Gohr     * Pre-Sanitize the action command
13142a27035SAndreas Gohr     *
13242a27035SAndreas Gohr     * Similar to act_clean in action.php but simplified and without
13342a27035SAndreas Gohr     * error messages
13442a27035SAndreas Gohr     */
13542a27035SAndreas Gohr    function _act_clean($act) {
13642a27035SAndreas Gohr        // check if the action was given as array key
13742a27035SAndreas Gohr        if(is_array($act)) {
13842a27035SAndreas Gohr            list($act) = array_keys($act);
13942a27035SAndreas Gohr        }
14042a27035SAndreas Gohr
14142a27035SAndreas Gohr        //remove all bad chars
14242a27035SAndreas Gohr        $act = strtolower($act);
14342a27035SAndreas Gohr        $act = preg_replace('/[^a-z_]+/', '', $act);
14442a27035SAndreas Gohr
14542a27035SAndreas Gohr        return $act;
14642a27035SAndreas Gohr    }
14742a27035SAndreas Gohr
14842a27035SAndreas Gohr}
14942a27035SAndreas Gohr
150