Code syncronized with shipsimu code base
[mailer.git] / inc / classes / main / helper / captcha / web / class_GraphicalCodeCaptcha.php
diff --git a/inc/classes/main/helper/captcha/web/class_GraphicalCodeCaptcha.php b/inc/classes/main/helper/captcha/web/class_GraphicalCodeCaptcha.php
new file mode 100644 (file)
index 0000000..37a206c
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+/**
+ * A solveable graphical code CAPTCHA
+ *
+ * @author             Roland Haeder <webmaster@ship-simu.org>
+ * @version            0.0.0
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, this is free software
+ * @license            GNU GPL 3.0 or any newer version
+ * @link               http://www.ship-simu.org
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+class GraphicalCodeCaptcha extends BaseCaptcha implements SolveableCaptcha {
+       /**
+        * Hash of the CAPTCHA string
+        */
+       private $hashedString = "";
+
+       /**
+        * Encrypted string
+        */
+       private $encryptedString = "";
+
+       /**
+        * Protected constructor
+        *
+        * @return      void
+        */
+       protected function __construct () {
+               // Call parent constructor
+               parent::__construct(__CLASS__);
+       }
+
+       /**
+        * Creates an instance of this captcha class
+        *
+        * @param       $helperInstance         An instance of a helper class
+        * @param       $extraInstance          An extra instance, just for better hash data
+        * @return      $captchaInstance        An instance of this captcha class
+        */
+       public final static function createGraphicalCodeCaptcha (HelpableTemplate $helperInstance, FrameworkInterface $extraInstance = null) {
+               // Get a new instance
+               $captchaInstance = new GraphicalCodeCaptcha();
+
+               // Set template instance
+               $captchaInstance->setHelperInstance($helperInstance);
+
+               // Initialize the RNG
+               $captchaInstance->initializeRandomNumberGenerator($extraInstance);
+
+               // Return the instance
+               return $captchaInstance;
+       }
+
+       /**
+        * Initiates the CAPTCHA
+        *
+        * @return      void
+        */
+       public function initiateCaptcha () {
+               // Get total length
+               $captchaLength = $this->getConfigInstance()->readConfig('captcha_string_length');
+
+               // Get max string length
+               $strLength = $this->getConfigInstance()->readConfig('random_string_length');
+
+               // Calculate starting position based on random place
+               $start = $this->getRngInstance()->randomNumber(0, ($strLength - $captchaLength));
+
+               // Test it
+               assert($start >= 0);
+
+               // Generate a random string for confirmation
+               $randomString = $this->getRngInstance()->randomString($strLength);
+
+               // Encode the string with BASE64
+               $base64String = base64_encode($randomString);
+
+               // Make this string a bit more readable for humans
+               $captchaString = substr($base64String, $start, $captchaLength);
+
+               // Get all characters we want to replace
+               $searchChars = $this->getConfigInstance()->readConfig('captcha_search_chars');
+
+               // Get fixed salt and use it as "replacement characters"
+               $replaceChars = $this->getRngInstance()->getExtraSalt();
+
+               // Remove any plus, equals or slashes
+               for ($searchIdx = 0; $searchIdx < strlen($searchChars); $searchIdx++) {
+                       // Get search character
+                       $search = substr($searchChars, $searchIdx, 1);
+
+                       // Random array index
+                       $charIdx = $this->getRngInstance()->randomNumber(0, (strlen($replaceChars) - 1));
+
+                       // Get replacement
+                       $replace = substr($replaceChars, $charIdx, 1);
+
+                       // Replace character
+                       $captchaString = str_replace($search, $replace, $captchaString, $captchaLength);
+               } // END - foreach
+
+               // Get crypto instance
+               $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class');
+
+               // Hash the CAPTCHA code for later comparison
+               $this->hashedString = $cryptoInstance->hashString($captchaString);
+
+               // Encrypt the string for later usage
+               $this->encryptedString = $cryptoInstance->encryptString($captchaString);
+       }
+
+       /**
+        * Render the CAPTCHA code
+        *
+        * @return      void
+        */
+       public function renderCode () {
+               // Get helper instance
+               $helperInstance = $this->getHelperInstance();
+
+               // Get template instance
+               $templateInstance = $helperInstance->getTemplateInstance();
+
+               // Load a template for this CAPTCHA
+               $templateInstance->loadCodeTemplate('captch_graphic_code');
+
+               // Rename variable
+               $templateInstance->renameVariable('captcha_code', $helperInstance->getFormName().'_captcha');
+               $templateInstance->renameVariable('captcha_hash', $helperInstance->getFormName().'_hash');
+               $templateInstance->renameVariable('encrypted_code', $helperInstance->getFormName().'_encrypt');
+
+               // Assign variables
+               $templateInstance->assignVariable($helperInstance->getFormName().'_encrypt', urlencode(base64_encode($this->encryptedString)));
+               $templateInstance->assignVariable($helperInstance->getFormName().'_hash', $this->hashedString);
+
+               // Compile the template
+               $templateInstance->compileTemplate();
+
+               // Get the content back
+               $this->addContent($templateInstance->getRawTemplateData());
+       }
+}
+
+// [EOF]
+?>