xref: /plugin/captcha/action.php (revision 77e00bf9777c569c0942655691c32ae8fd03dbb5)
1<?php
2/**
3 * CAPTCHA antispam plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <gohr@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
13require_once(DOKU_PLUGIN.'action.php');
14
15class action_plugin_captcha extends DokuWiki_Action_Plugin {
16
17    /**
18     * return some info
19     */
20    function getInfo(){
21        return confToHash(dirname(__FILE__).'/info.txt');
22    }
23
24    /**
25     * register the eventhandlers
26     */
27    function register(&$controller){
28        $controller->register_hook('ACTION_ACT_PREPROCESS',
29                                   'BEFORE',
30                                   $this,
31                                   'handle_act_preprocess',
32                                   array());
33
34        // old hook
35        $controller->register_hook('HTML_EDITFORM_INJECTION',
36                                   'BEFORE',
37                                   $this,
38                                   'handle_editform_output',
39                                   array('editform' => true, 'oldhook' => true));
40
41        // new hook
42        $controller->register_hook('HTML_EDITFORM_OUTPUT',
43                                   'BEFORE',
44                                   $this,
45                                   'handle_editform_output',
46                                   array('editform' => true, 'oldhook' => false));
47
48        if($this->getConf('regprotect')){
49            // old hook
50            $controller->register_hook('HTML_REGISTERFORM_INJECTION',
51                                       'BEFORE',
52                                       $this,
53                                       'handle_editform_output',
54                                       array('editform' => false, 'oldhook' => true));
55
56            // new hook
57            $controller->register_hook('HTML_REGISTERFORM_OUTPUT',
58                                       'BEFORE',
59                                       $this,
60                                       'handle_editform_output',
61                                       array('editform' => false, 'oldhook' => false));
62        }
63    }
64
65    /**
66     * Will intercept the 'save' action and check for CAPTCHA first.
67     */
68    function handle_act_preprocess(&$event, $param){
69        $act = $this->_act_clean($event->data);
70        if(!('save' == $act || ($this->getConf('regprotect') &&
71                                'register' == $act &&
72                                $_POST['save']))){
73            return; // nothing to do for us
74        }
75
76        // do nothing if logged in user and no CAPTCHA required
77        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']){
78            return;
79        }
80
81        // check captcha
82        $helper = plugin_load('helper','captcha');
83        if(!$helper->check()){
84                if($act == 'save'){
85                    // stay in preview mode
86                    $event->data = 'preview';
87                }else{
88                    // stay in register mode, but disable the save parameter
89                    $_POST['save'] = false;
90                }
91        }
92    }
93
94    /**
95     * Create the additional fields for the edit form
96     */
97    function handle_editform_output(&$event, $param){
98        // check if source view -> no captcha needed
99        if(!$param['oldhook']){
100            // get position of submit button
101            $pos = $event->data->findElementByAttribute('type','submit');
102            if(!$pos) return; // no button -> source view mode
103        }elseif($param['editform'] && !$event->data['writable']){
104            if($param['editform'] && !$event->data['writable']) return;
105        }
106
107        // do nothing if logged in user and no CAPTCHA required
108        if(!$this->getConf('forusers') && $_SERVER['REMOTE_USER']){
109            return;
110        }
111
112        // get the CAPTCHA
113        $helper = plugin_load('helper','captcha');
114        $out = $helper->getHTML();
115
116        if($param['oldhook']){
117            // old wiki - just print
118            echo $out;
119        }else{
120            // new wiki - insert at correct position
121            $event->data->insertElement($pos++,$out);
122        }
123    }
124
125    /**
126     * Pre-Sanitize the action command
127     *
128     * Similar to act_clean in action.php but simplified and without
129     * error messages
130     */
131    function _act_clean($act){
132         // check if the action was given as array key
133         if(is_array($act)){
134           list($act) = array_keys($act);
135         }
136
137         //remove all bad chars
138         $act = strtolower($act);
139         $act = preg_replace('/[^a-z_]+/','',$act);
140
141         return $act;
142     }
143
144}
145
146