Continued:
[core.git] / framework / main / classes / helper / captcha / web / class_GraphicalCodeCaptcha.php
1 <?php
2 // Own namespace
3 namespace Org\Mxchange\CoreFramework\Helper\Captcha;
4
5 // Import framework stuff
6 use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
7 use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
8 use Org\Mxchange\CoreFramework\Helper\Template\HelpableTemplate;
9
10 /**
11  * A solveable graphical code CAPTCHA
12  *
13  * @author              Roland Haeder <webmaster@shipsimu.org>
14  * @version             0.0.0
15  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2019 Core Developer Team
16  * @license             GNU GPL 3.0 or any newer version
17  * @link                http://www.shipsimu.org
18  *
19  * This program is free software: you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation, either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  */
32 class GraphicalCodeCaptcha extends BaseCaptcha implements SolveableCaptcha {
33         /**
34          * Hash of the CAPTCHA string
35          */
36         private $hashedString = '';
37
38         /**
39          * Encrypted string
40          */
41         private $encryptedString = '';
42
43         /**
44          * Protected constructor
45          *
46          * @return      void
47          */
48         protected function __construct () {
49                 // Call parent constructor
50                 parent::__construct(__CLASS__);
51         }
52
53         /**
54          * Creates an instance of this captcha class
55          *
56          * @param       $helperInstance         An instance of a helper class
57          * @param       $extraInstance          An extra instance, just for better hash data
58          * @return      $captchaInstance        An instance of this captcha class
59          */
60         public static final function createGraphicalCodeCaptcha (HelpableTemplate $helperInstance, FrameworkInterface $extraInstance = NULL) {
61                 // Get a new instance
62                 $captchaInstance = new GraphicalCodeCaptcha();
63
64                 // Set template instance
65                 $captchaInstance->setHelperInstance($helperInstance);
66
67                 // Initialize the RNG
68                 $captchaInstance->initializeRandomNumberGenerator($extraInstance);
69
70                 // Return the instance
71                 return $captchaInstance;
72         }
73
74         /**
75          * Initiates the CAPTCHA
76          *
77          * @return      void
78          */
79         public function initiateCaptcha () {
80                 // Get total length
81                 $captchaLength = $this->getConfigInstance()->getConfigEntry('captcha_string_length');
82
83                 // Get max string length
84                 $strLength = $this->getConfigInstance()->getConfigEntry('random_string_length');
85
86                 // Calculate starting position based on random place
87                 $start = $this->getRngInstance()->randomNumber(0, ($strLength - $captchaLength));
88
89                 // Test it
90                 assert($start >= 0);
91
92                 // Generate a random string for confirmation
93                 $randomString = $this->getRngInstance()->randomString($strLength);
94
95                 // Encode the string with BASE64
96                 $base64String = base64_encode($randomString);
97
98                 // Make this string a bit more readable for humans
99                 $captchaString = substr($base64String, $start, $captchaLength);
100
101                 // Get all characters we want to replace
102                 $searchChars = $this->getConfigInstance()->getConfigEntry('captcha_search_chars');
103
104                 // Get fixed salt and use it as "replacement characters"
105                 $replaceChars = $this->getRngInstance()->getExtraSalt();
106
107                 // Remove any plus, equals or slashes
108                 for ($searchIdx = 0; $searchIdx < strlen($searchChars); $searchIdx++) {
109                         // Get search character
110                         $search = substr($searchChars, $searchIdx, 1);
111
112                         // Random array index
113                         $charIdx = $this->getRngInstance()->randomNumber(0, (strlen($replaceChars) - 1));
114
115                         // Get replacement
116                         $replace = substr($replaceChars, $charIdx, 1);
117
118                         // Replace character
119                         $captchaString = str_replace($search, $replace, $captchaString, $captchaLength);
120                 } // END - foreach
121
122                 // Get crypto instance
123                 $cryptoInstance = ObjectFactory::createObjectByConfiguredName('crypto_class');
124
125                 // Hash the CAPTCHA code for later comparison
126                 $this->hashedString = $cryptoInstance->hashString($captchaString);
127
128                 // Encrypt the string for later usage
129                 $this->encryptedString = $cryptoInstance->encryptString($captchaString);
130         }
131
132         /**
133          * Render the CAPTCHA code
134          *
135          * @return      void
136          */
137         public function renderCode () {
138                 // Get helper instance
139                 $helperInstance = $this->getHelperInstance();
140
141                 // Get template instance
142                 $templateInstance = $helperInstance->getTemplateInstance();
143
144                 // Load a template for this CAPTCHA
145                 $templateInstance->loadCodeTemplate('captch_graphic_code');
146
147                 // Rename variable
148                 $templateInstance->renameVariable('captcha_code', $helperInstance->getFormName() . '_captcha');
149                 $templateInstance->renameVariable('captcha_hash', $helperInstance->getFormName() . '_hash');
150                 $templateInstance->renameVariable('encrypted_code', $helperInstance->getFormName() . '_encrypt');
151
152                 // Assign variables
153                 $templateInstance->assignVariable($helperInstance->getFormName() . '_encrypt', urlencode(base64_encode($this->encryptedString)));
154                 $templateInstance->assignVariable($helperInstance->getFormName() . '_hash', $this->hashedString);
155
156                 // Compile the template
157                 $templateInstance->compileTemplate();
158
159                 // Get the content back
160                 $this->addContent($templateInstance->getRawTemplateData());
161         }
162
163 }