'basic', 'width' => 150, 'height' => 50, 'complexity' => 4, 'background' => '', 'fontpath' => '', 'fonts' => array(), 'promote' => FALSE, ); public static function instance() { empty(Captcha::$instance) and new Captcha; return Captcha::$instance; } public static function factory($group = NULL) { return new Captcha($group); } public function __construct($group = NULL) { empty(Captcha::$instance) and Captcha::$instance = $this; if ( ! is_string($group)) { $group = 'default'; } if ( ! is_array($config = Kohana::config('captcha.'.$group))) throw new Kohana_Exception('captcha.undefined_group', $group); if ($group !== 'default') { if ( ! is_array($default = Kohana::config('captcha.default'))) throw new Kohana_Exception('captcha.undefined_group', 'default'); $config += $default; } foreach ($config as $key => $value) { if (array_key_exists($key, Captcha::$config)) { Captcha::$config[$key] = $value; } } Captcha::$config['group'] = $group; if ( ! empty($config['background'])) { Captcha::$config['background'] = str_replace('\\', '/', realpath($config['background'])); if ( ! is_file(Captcha::$config['background'])) throw new Kohana_Exception('captcha.file_not_found', Captcha::$config['background']); } if ( ! empty($config['fonts'])) { Captcha::$config['fontpath'] = str_replace('\\', '/', realpath($config['fontpath'])).'/'; foreach ($config['fonts'] as $font) { if ( ! is_file(Captcha::$config['fontpath'].$font)) throw new Kohana_Exception('captcha.file_not_found', Captcha::$config['fontpath'].$font); } } $driver = 'Captcha_'.ucfirst($config['style']).'_Driver'; if ( ! Kohana::auto_load($driver)) throw new Kohana_Exception('core.driver_not_found', $config['style'], get_class($this)); $this->driver = new $driver; if ( ! ($this->driver instanceof Captcha_Driver)) throw new Kohana_Exception('core.driver_implements', $config['style'], get_class($this), 'Captcha_Driver'); Kohana::log('debug', 'Captcha Library initialized'); } public static function valid($response) { static $counted; if (Captcha::instance()->promoted()) return TRUE; $result = (bool) Captcha::instance()->driver->valid($response); if ($counted !== TRUE) { $counted = TRUE; if ($result === TRUE) { Captcha::instance()->valid_count(Session::instance()->get('captcha_valid_count') + 1); } else { Captcha::instance()->invalid_count(Session::instance()->get('captcha_invalid_count') + 1); } } return $result; } public function valid_count($new_count = NULL, $invalid = FALSE) { $session = ($invalid === TRUE) ? 'captcha_invalid_count' : 'captcha_valid_count'; if ($new_count !== NULL) { $new_count = (int) $new_count; if ($new_count < 1) { Session::instance()->delete($session); } else { Session::instance()->set($session, (int) $new_count); } return (int) $new_count; } return (int) Session::instance()->get($session); } public function invalid_count($new_count = NULL) { return $this->valid_count($new_count, TRUE); } public function reset_count() { $this->valid_count(0); $this->valid_count(0, TRUE); } public function promoted($threshold = NULL) { if (Captcha::$config['promote'] === FALSE) return FALSE; if ($threshold === NULL) { $threshold = Captcha::$config['promote']; } return ($this->valid_count() >= $threshold); } public function render($html = TRUE) { return $this->driver->render($html); } public function __toString() { return $this->render(); } }