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