auth = false; if (empty($parameter['table'])) { $parameter['table'] = WBClass::create('WBDatasource_Table', $parameter); } $this->table = $parameter['table']; // set default namespace $this->namespace = self::NAMESPACE_GLOBAL; $config = WBClass::create('WBConfig'); $c = array(); if ($config->load('captcha', true)) { $c = $config->get('mode/auto', array()); } if (isset($c[self::NAMESPACE_GLOBAL])) { $c[self::NAMESPACE_GLOBAL] = array_merge(array('limit' => 10, 'timeout' => 600), $c[self::NAMESPACE_GLOBAL]); } $this->config = $c; } /** * Set Current Authentication Status * * @param bool * @return WBUte_Captcha */ public function setAuth($auth = true) { $this->auth = $auth; return $this; } /** * Set Current Namespace * * @param bool * @return WBUte_Captcha */ public function setNamespace($namespace = null) { if (empty($namespace)) { $namespace = self::NAMESPACE_GLOBAL; } $this->namespace = $namespace; return $this; } /** * Add Request * * @return WBUte_Captcha */ public function addRequest() { if (1 == rand(1, 1000)) { $this->flushOldRequests(); } $save = array( 'created' => date('Y-m-d H:i:s'), 'namespace' => $this->namespace, 'authenticated' => intval($this->auth) ); $this->table->save(self::TABLE_CAPTCHAREQUEST, '__new', $save); } /** * Delete Old Captcha-Requests * * Remove all stored requests for current namespace, that are older than 5 times the timeout */ private function flushOldRequests() { // find timeout of configured namespace if (isset($this->config[$this->namespace]) && isset($this->config[$this->namespace]['timeout'])) { $timeout = $this->config[$this->namespace]['timeout']; } else { $timeout = $this->config[self::NAMESPACE_GLOBAL]['timeout']; } // 5 times the timout $until = time() - 5 * $timeout; $clause = array(); $clause[] = array( 'field' => 'created', 'relation' => 'lt', 'value' => date('Y-m-d H:i:s', $until) ); $clause[] = array( 'field' => 'namespace', 'value' => $this->namespace ); $this->table->delete(self::TABLE_CAPTCHAREQUEST, null, null, $clause); } /** * See if CAPTCHA is required * * Return true if CAPTCHA is required * * @return bool */ public function isRequired($mode) { switch (strtolower($mode)) { case 'auto': break; // CAPTCHA is not required case 'none': case '0': return false; break; // default: CAPTCHA is required default: case '1'; return true; break; } if ($this->auth) { return false; } // don't count if (1 > $this->config[$this->namespace]['limit']) { return true; } $min = date('Y-m-d H:i:s', time() - $this->config[$this->namespace]['timeout']); $clause = array(); $clause[] = array( 'field' => 'created', 'relation' => 'ge', 'value' => $min ); $clause[] = array( 'field' => 'namespace', 'value' => $this->namespace ); $cnt = $this->table->count(self::TABLE_CAPTCHAREQUEST, null, null, $clause); if ($cnt > $this->config[$this->namespace]['limit']) { return true; } return false; // session if (empty($this->config[$this->namespace]['sessiontimeout'])) { return false; } $this->sess = WBClass::create('patSession'); $sto = $this->sess->get('wb.captcha.timeout'); if (empty($sto) || time() > $sto) { $this->sess->set('wb.captcha.timeout', time() + $this->config[$this->namespace]['sessiontimeout']); $this->sess->set('wb.captcha.limit', $this->config[$this->namespace]['sessionlimit']); return true; } $sli = $this->sess->get('wb.captcha.limit'); --$sli; if (1 > $sli) { $this->sess->set('wb.captcha.limit', $this->config[$this->namespace]['sessionlimit']); return true; } $this->sess->set('wb.captcha.limit', $sli); return false; } }