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