Initial Kohana install
[speedfreak] / Server / system / libraries / Captcha.php
diff --git a/Server/system/libraries/Captcha.php b/Server/system/libraries/Captcha.php
new file mode 100644 (file)
index 0000000..f5f2b46
--- /dev/null
@@ -0,0 +1,279 @@
+<?php defined('SYSPATH') OR die('No direct access allowed.');
+/**
+ * Captcha library.
+ *
+ * $Id: Captcha.php 4072 2009-03-13 17:20:38Z jheathco $
+ *
+ * @package    Captcha
+ * @author     Kohana Team
+ * @copyright  (c) 2007-2008 Kohana Team
+ * @license    http://kohanaphp.com/license.html
+ */
+class Captcha_Core {
+
+       // Captcha singleton
+       protected static $instance;
+
+       // Style-dependent Captcha driver
+       protected $driver;
+
+       // Config values
+       public static $config = array
+       (
+               'style'      => 'basic',
+               'width'      => 150,
+               'height'     => 50,
+               'complexity' => 4,
+               'background' => '',
+               'fontpath'   => '',
+               'fonts'      => array(),
+               'promote'    => FALSE,
+       );
+
+       /**
+        * Singleton instance of Captcha.
+        *
+        * @return  object
+        */
+       public static function instance()
+       {
+               // Create the instance if it does not exist
+               empty(Captcha::$instance) and new Captcha;
+
+               return Captcha::$instance;
+       }
+
+       /**
+        * Constructs and returns a new Captcha object.
+        *
+        * @param   string  config group name
+        * @return  object
+        */
+       public static function factory($group = NULL)
+       {
+               return new Captcha($group);
+       }
+
+       /**
+        * Constructs a new Captcha object.
+        *
+        * @throws  Kohana_Exception
+        * @param   string  config group name
+        * @return  void
+        */
+       public function __construct($group = NULL)
+       {
+               // Create a singleton instance once
+               empty(Captcha::$instance) and Captcha::$instance = $this;
+
+               // No config group name given
+               if ( ! is_string($group))
+               {
+                       $group = 'default';
+               }
+
+               // Load and validate config group
+               if ( ! is_array($config = Kohana::config('captcha.'.$group)))
+                       throw new Kohana_Exception('captcha.undefined_group', $group);
+
+               // All captcha config groups inherit default config group
+               if ($group !== 'default')
+               {
+                       // Load and validate default config group
+                       if ( ! is_array($default = Kohana::config('captcha.default')))
+                               throw new Kohana_Exception('captcha.undefined_group', 'default');
+
+                       // Merge config group with default config group
+                       $config += $default;
+               }
+
+               // Assign config values to the object
+               foreach ($config as $key => $value)
+               {
+                       if (array_key_exists($key, Captcha::$config))
+                       {
+                               Captcha::$config[$key] = $value;
+                       }
+               }
+
+               // Store the config group name as well, so the drivers can access it
+               Captcha::$config['group'] = $group;
+
+               // If using a background image, check if it exists
+               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 using any fonts, check if they exist
+               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);
+                       }
+               }
+
+               // Set driver name
+               $driver = 'Captcha_'.ucfirst($config['style']).'_Driver';
+
+               // Load the driver
+               if ( ! Kohana::auto_load($driver))
+                       throw new Kohana_Exception('core.driver_not_found', $config['style'], get_class($this));
+
+               // Initialize the driver
+               $this->driver = new $driver;
+
+               // Validate the 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');
+       }
+
+       /**
+        * Validates a Captcha response and updates response counter.
+        *
+        * @param   string   captcha response
+        * @return  boolean
+        */
+       public static function valid($response)
+       {
+               // Maximum one count per page load
+               static $counted;
+
+               // User has been promoted, always TRUE and don't count anymore
+               if (Captcha::instance()->promoted())
+                       return TRUE;
+
+               // Challenge result
+               $result = (bool) Captcha::instance()->driver->valid($response);
+
+               // Increment response counter
+               if ($counted !== TRUE)
+               {
+                       $counted = TRUE;
+
+                       // Valid response
+                       if ($result === TRUE)
+                       {
+                               Captcha::instance()->valid_count(Session::instance()->get('captcha_valid_count') + 1);
+                       }
+                       // Invalid response
+                       else
+                       {
+                               Captcha::instance()->invalid_count(Session::instance()->get('captcha_invalid_count') + 1);
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
+        * Gets or sets the number of valid Captcha responses for this session.
+        *
+        * @param   integer  new counter value
+        * @param   boolean  trigger invalid counter (for internal use only)
+        * @return  integer  counter value
+        */
+       public function valid_count($new_count = NULL, $invalid = FALSE)
+       {
+               // Pick the right session to use
+               $session = ($invalid === TRUE) ? 'captcha_invalid_count' : 'captcha_valid_count';
+
+               // Update counter
+               if ($new_count !== NULL)
+               {
+                       $new_count = (int) $new_count;
+
+                       // Reset counter = delete session
+                       if ($new_count < 1)
+                       {
+                               Session::instance()->delete($session);
+                       }
+                       // Set counter to new value
+                       else
+                       {
+                               Session::instance()->set($session, (int) $new_count);
+                       }
+
+                       // Return new count
+                       return (int) $new_count;
+               }
+
+               // Return current count
+               return (int) Session::instance()->get($session);
+       }
+
+       /**
+        * Gets or sets the number of invalid Captcha responses for this session.
+        *
+        * @param   integer  new counter value
+        * @return  integer  counter value
+        */
+       public function invalid_count($new_count = NULL)
+       {
+               return $this->valid_count($new_count, TRUE);
+       }
+
+       /**
+        * Resets the Captcha response counters and removes the count sessions.
+        *
+        * @return  void
+        */
+       public function reset_count()
+       {
+               $this->valid_count(0);
+               $this->valid_count(0, TRUE);
+       }
+
+       /**
+        * Checks whether user has been promoted after having given enough valid responses.
+        *
+        * @param   integer  valid response count threshold
+        * @return  boolean
+        */
+       public function promoted($threshold = NULL)
+       {
+               // Promotion has been disabled
+               if (Captcha::$config['promote'] === FALSE)
+                       return FALSE;
+
+               // Use the config threshold
+               if ($threshold === NULL)
+               {
+                       $threshold = Captcha::$config['promote'];
+               }
+
+               // Compare the valid response count to the threshold
+               return ($this->valid_count() >= $threshold);
+       }
+
+       /**
+        * Returns or outputs the Captcha challenge.
+        *
+        * @param   boolean  TRUE to output html, e.g. <img src="#" />
+        * @return  mixed    html string or void
+        */
+       public function render($html = TRUE)
+       {
+               return $this->driver->render($html);
+       }
+
+       /**
+        * Magically outputs the Captcha challenge.
+        *
+        * @return  mixed
+        */
+       public function __toString()
+       {
+               return $this->render();
+       }
+
+} // End Captcha Class
\ No newline at end of file