xref: /plugin/captcha/action.php (revision 77e00bf9777c569c0942655691c32ae8fd03dbb5)
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     * return some info
1942a27035SAndreas Gohr     */
2042a27035SAndreas Gohr    function getInfo(){
21*77e00bf9SAndreas Gohr        return confToHash(dirname(__FILE__).'/info.txt');
2242a27035SAndreas Gohr    }
2342a27035SAndreas Gohr
2442a27035SAndreas Gohr    /**
2542a27035SAndreas Gohr     * register the eventhandlers
2642a27035SAndreas Gohr     */
2742a27035SAndreas Gohr    function register(&$controller){
2842a27035SAndreas Gohr        $controller->register_hook('ACTION_ACT_PREPROCESS',
2942a27035SAndreas Gohr                                   'BEFORE',
3042a27035SAndreas Gohr                                   $this,
3142a27035SAndreas Gohr                                   'handle_act_preprocess',
3242a27035SAndreas Gohr                                   array());
3342a27035SAndreas Gohr
3447afabe6SAndreas Gohr        // old hook
3542a27035SAndreas Gohr        $controller->register_hook('HTML_EDITFORM_INJECTION',
3642a27035SAndreas Gohr                                   'BEFORE',
3742a27035SAndreas Gohr                                   $this,
3847afabe6SAndreas Gohr                                   'handle_editform_output',
3947afabe6SAndreas Gohr                                   array('editform' => true, 'oldhook' => true));
4047afabe6SAndreas Gohr
4147afabe6SAndreas Gohr        // new hook
4247afabe6SAndreas Gohr        $controller->register_hook('HTML_EDITFORM_OUTPUT',
4347afabe6SAndreas Gohr                                   'BEFORE',
4447afabe6SAndreas Gohr                                   $this,
4547afabe6SAndreas Gohr                                   'handle_editform_output',
4647afabe6SAndreas Gohr                                   array('editform' => true, 'oldhook' => false));
4742a27035SAndreas Gohr
4842a27035SAndreas Gohr        if($this->getConf('regprotect')){
4947afabe6SAndreas Gohr            // old hook
5042a27035SAndreas Gohr            $controller->register_hook('HTML_REGISTERFORM_INJECTION',
5142a27035SAndreas Gohr                                       'BEFORE',
5242a27035SAndreas Gohr                                       $this,
5347afabe6SAndreas Gohr                                       'handle_editform_output',
5447afabe6SAndreas Gohr                                       array('editform' => false, 'oldhook' => true));
5547afabe6SAndreas Gohr
5647afabe6SAndreas Gohr            // new hook
5747afabe6SAndreas Gohr            $controller->register_hook('HTML_REGISTERFORM_OUTPUT',
5847afabe6SAndreas Gohr                                       'BEFORE',
5947afabe6SAndreas Gohr                                       $this,
6047afabe6SAndreas Gohr                                       'handle_editform_output',
6147afabe6SAndreas Gohr                                       array('editform' => false, 'oldhook' => false));
6242a27035SAndreas Gohr        }
6342a27035SAndreas Gohr    }
6442a27035SAndreas Gohr
6542a27035SAndreas Gohr    /**
6642a27035SAndreas Gohr     * Will intercept the 'save' action and check for CAPTCHA first.
6742a27035SAndreas Gohr     */
6842a27035SAndreas Gohr    function handle_act_preprocess(&$event, $param){
6993f66506SAndreas Gohr        $act = $this->_act_clean($event->data);
7093f66506SAndreas Gohr        if(!('save' == $act || ($this->getConf('regprotect') &&
7193f66506SAndreas Gohr                                'register' == $act &&
7293f66506SAndreas Gohr                                $_POST['save']))){
7393f66506SAndreas Gohr            return; // nothing to do for us
7493f66506SAndreas Gohr        }
7593f66506SAndreas Gohr
7642a27035SAndreas Gohr        // do nothing if logged in user and no CAPTCHA required
7742a27035SAndreas Gohr        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']){
7842a27035SAndreas Gohr            return;
7942a27035SAndreas Gohr        }
8042a27035SAndreas Gohr
81*77e00bf9SAndreas Gohr        // check captcha
82*77e00bf9SAndreas Gohr        $helper = plugin_load('helper','captcha');
83*77e00bf9SAndreas Gohr        if(!$helper->check()){
8493f66506SAndreas Gohr                if($act == 'save'){
8593f66506SAndreas Gohr                    // stay in preview mode
8642a27035SAndreas Gohr                    $event->data = 'preview';
8793f66506SAndreas Gohr                }else{
8893f66506SAndreas Gohr                    // stay in register mode, but disable the save parameter
8993f66506SAndreas Gohr                    $_POST['save'] = false;
9042a27035SAndreas Gohr                }
9142a27035SAndreas Gohr        }
9242a27035SAndreas Gohr    }
9342a27035SAndreas Gohr
9442a27035SAndreas Gohr    /**
9542a27035SAndreas Gohr     * Create the additional fields for the edit form
9642a27035SAndreas Gohr     */
9747afabe6SAndreas Gohr    function handle_editform_output(&$event, $param){
9847afabe6SAndreas Gohr        // check if source view -> no captcha needed
9947afabe6SAndreas Gohr        if(!$param['oldhook']){
10047afabe6SAndreas Gohr            // get position of submit button
10147afabe6SAndreas Gohr            $pos = $event->data->findElementByAttribute('type','submit');
10247afabe6SAndreas Gohr            if(!$pos) return; // no button -> source view mode
10347afabe6SAndreas Gohr        }elseif($param['editform'] && !$event->data['writable']){
10442a27035SAndreas Gohr            if($param['editform'] && !$event->data['writable']) return;
10547afabe6SAndreas Gohr        }
10647afabe6SAndreas Gohr
10742a27035SAndreas Gohr        // do nothing if logged in user and no CAPTCHA required
10842a27035SAndreas Gohr        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']){
10942a27035SAndreas Gohr            return;
11042a27035SAndreas Gohr        }
11142a27035SAndreas Gohr
112*77e00bf9SAndreas Gohr        // get the CAPTCHA
113*77e00bf9SAndreas Gohr        $helper = plugin_load('helper','captcha');
114*77e00bf9SAndreas Gohr        $out = $helper->getHTML();
11547afabe6SAndreas Gohr
11647afabe6SAndreas Gohr        if($param['oldhook']){
11747afabe6SAndreas Gohr            // old wiki - just print
11847afabe6SAndreas Gohr            echo $out;
11947afabe6SAndreas Gohr        }else{
12047afabe6SAndreas Gohr            // new wiki - insert at correct position
12147afabe6SAndreas Gohr            $event->data->insertElement($pos++,$out);
12247afabe6SAndreas Gohr        }
12342a27035SAndreas Gohr    }
12442a27035SAndreas Gohr
12542a27035SAndreas Gohr    /**
12642a27035SAndreas Gohr     * Pre-Sanitize the action command
12742a27035SAndreas Gohr     *
12842a27035SAndreas Gohr     * Similar to act_clean in action.php but simplified and without
12942a27035SAndreas Gohr     * error messages
13042a27035SAndreas Gohr     */
13142a27035SAndreas Gohr    function _act_clean($act){
13242a27035SAndreas Gohr         // check if the action was given as array key
13342a27035SAndreas Gohr         if(is_array($act)){
13442a27035SAndreas Gohr           list($act) = array_keys($act);
13542a27035SAndreas Gohr         }
13642a27035SAndreas Gohr
13742a27035SAndreas Gohr         //remove all bad chars
13842a27035SAndreas Gohr         $act = strtolower($act);
13942a27035SAndreas Gohr         $act = preg_replace('/[^a-z_]+/','',$act);
14042a27035SAndreas Gohr
14142a27035SAndreas Gohr         return $act;
14242a27035SAndreas Gohr     }
14342a27035SAndreas Gohr
14442a27035SAndreas Gohr}
14542a27035SAndreas Gohr
146