|
| 1 | +<?php |
| 2 | +// 2012-06-10 DB: cleaned up PHP4 references |
| 3 | +/** |
| 4 | + * Text_CAPTCHA - creates a CAPTCHA for Turing tests |
| 5 | + * |
| 6 | + * Class to create a Turing test for websites by |
| 7 | + * creating an image, ASCII art or something else |
| 8 | + * with some (obfuscated) characters |
| 9 | + * |
| 10 | + * |
| 11 | + * @package Text_CAPTCHA |
| 12 | + * @license BSD License |
| 13 | + * @author Christian Wenz <wenz@php.net> |
| 14 | + * @category Text |
| 15 | + */ |
| 16 | + |
| 17 | + |
| 18 | +/** |
| 19 | + * |
| 20 | + * Require PEAR class for error handling. |
| 21 | + * |
| 22 | + */ |
| 23 | +require_once MOD_SIMPLEEMAILFORM_DIR . DIRECTORY_SEPARATOR . 'PEAR.php'; |
| 24 | + |
| 25 | +/** |
| 26 | + * |
| 27 | + * Require Text_Password class for generating the phrase. |
| 28 | + * |
| 29 | + */ |
| 30 | +require_once MOD_SIMPLEEMAILFORM_DIR . DIRECTORY_SEPARATOR . 'Password.php'; |
| 31 | + |
| 32 | +/** |
| 33 | + * Text_CAPTCHA - creates a CAPTCHA for Turing tests |
| 34 | + * |
| 35 | + * Class to create a Turing test for websites by |
| 36 | + * creating an image, ASCII art or something else |
| 37 | + * with some (obfuscated) characters |
| 38 | + * |
| 39 | + * @package Text_CAPTCHA |
| 40 | + */ |
| 41 | + |
| 42 | +/* |
| 43 | + // This is a simple example script |
| 44 | +
|
| 45 | + <?php |
| 46 | + if (!function_exists('file_put_contents')) { |
| 47 | + public function file_put_contents($filename, $content) { |
| 48 | + if (!($file = fopen($filename, 'w'))) { |
| 49 | + return false; |
| 50 | + } |
| 51 | + $n = fwrite($file, $content); |
| 52 | + fclose($file); |
| 53 | + return $n ? $n : false; |
| 54 | + } |
| 55 | + } |
| 56 | +
|
| 57 | + // Start PHP session support |
| 58 | + session_start(); |
| 59 | +
|
| 60 | + $ok = false; |
| 61 | +
|
| 62 | + $msg = 'Please enter the text in the image in the field below!'; |
| 63 | +
|
| 64 | + if ($_SERVER['REQUEST_METHOD'] == 'POST') { |
| 65 | +
|
| 66 | + if (isset($_POST['phrase']) && is_string($_SESSION['phrase']) && isset($_SESSION['phrase']) && |
| 67 | + strlen($_POST['phrase']) > 0 && strlen($_SESSION['phrase']) > 0 && |
| 68 | + $_POST['phrase'] == $_SESSION['phrase']) { |
| 69 | + $msg = 'OK!'; |
| 70 | + $ok = true; |
| 71 | + unset($_SESSION['phrase']); |
| 72 | + } else { |
| 73 | + $msg = 'Please try again!'; |
| 74 | + } |
| 75 | +
|
| 76 | + unlink(sha1(session_id()) . '.png'); |
| 77 | +
|
| 78 | + } |
| 79 | +
|
| 80 | + print "<p>$msg</p>"; |
| 81 | +
|
| 82 | + if (!$ok) { |
| 83 | + |
| 84 | + require_once 'Text/CAPTCHA.php'; |
| 85 | + |
| 86 | + // Set CAPTCHA image options (font must exist!) |
| 87 | + $imageOptions = array( |
| 88 | + 'font_size' => 24, |
| 89 | + 'font_path' => './', |
| 90 | + 'font_file' => 'COUR.TTF', |
| 91 | + 'text_color' => '#DDFF99', |
| 92 | + 'lines_color' => '#CCEEDD', |
| 93 | + 'background_color' => '#555555' |
| 94 | + ); |
| 95 | +
|
| 96 | + // Set CAPTCHA options |
| 97 | + $options = array( |
| 98 | + 'width' => 200, |
| 99 | + 'height' => 80, |
| 100 | + 'output' => 'png', |
| 101 | + 'imageOptions' => $imageOptions |
| 102 | + ); |
| 103 | +
|
| 104 | + // Generate a new Text_CAPTCHA object, Image driver |
| 105 | + $c = Text_CAPTCHA::factory('Image'); |
| 106 | + $retval = $c->init($options); |
| 107 | + if (PEAR::isError($retval)) { |
| 108 | + printf('Error initializing CAPTCHA: %s!', |
| 109 | + $retval->getMessage()); |
| 110 | + exit; |
| 111 | + } |
| 112 | + |
| 113 | + // Get CAPTCHA secret passphrase |
| 114 | + $_SESSION['phrase'] = $c->getPhrase(); |
| 115 | + |
| 116 | + // Get CAPTCHA image (as PNG) |
| 117 | + $png = $c->getCAPTCHA(); |
| 118 | + if (PEAR::isError($png)) { |
| 119 | + printf('Error generating CAPTCHA: %s!', |
| 120 | + $png->getMessage()); |
| 121 | + exit; |
| 122 | + } |
| 123 | + file_put_contents(sha1(session_id()) . '.png', $png); |
| 124 | + |
| 125 | + echo '<form method="post">' . |
| 126 | + '<img src="' . sha1(session_id()) . '.png?' . time() . '" />' . |
| 127 | + '<input type="text" name="phrase" />' . |
| 128 | + '<input type="submit" /></form>'; |
| 129 | + } |
| 130 | + ?> |
| 131 | +*/ |
| 132 | + |
| 133 | +class Text_CAPTCHA { |
| 134 | + |
| 135 | + /** |
| 136 | + * Version number |
| 137 | + * |
| 138 | + * @access private |
| 139 | + * @var string |
| 140 | + */ |
| 141 | + public $_version = '0.4.0'; |
| 142 | + |
| 143 | + /** |
| 144 | + * Phrase |
| 145 | + * |
| 146 | + * @access private |
| 147 | + * @var string |
| 148 | + */ |
| 149 | + public $_phrase; |
| 150 | + |
| 151 | + /** |
| 152 | + * Create a new Text_CAPTCHA object |
| 153 | + * |
| 154 | + * @param string $driver name of driver class to initialize |
| 155 | + * |
| 156 | + * @return mixed a newly created Text_CAPTCHA object, or a PEAR |
| 157 | + * error object on error |
| 158 | + * |
| 159 | + * @see PEAR::isError() |
| 160 | + */ |
| 161 | + public static function factory($driver) |
| 162 | + { |
| 163 | + if ($driver == '') { |
| 164 | + return PEAR::raiseError('No CAPTCHA type specified ... aborting. You must call ::factory() with one parameter, the CAPTCHA type.', true); |
| 165 | + } |
| 166 | + $driver = basename($driver); |
| 167 | + include_once "$driver.php"; |
| 168 | + |
| 169 | + $classname = "Text_CAPTCHA_Driver_$driver"; |
| 170 | + $obj = new $classname; |
| 171 | + return $obj; |
| 172 | + } |
| 173 | + |
| 174 | + /** |
| 175 | + * Create random CAPTCHA phrase |
| 176 | + * |
| 177 | + * This method creates a random phrase, 8 characters long |
| 178 | + * |
| 179 | + * @access private |
| 180 | + */ |
| 181 | + public function _createPhrase($options = array()) |
| 182 | + { |
| 183 | + $len = 8; |
| 184 | + if (!is_array($options) || count($options) === 0) { |
| 185 | + $this->_phrase = Text_Password::create($len); |
| 186 | + } else { |
| 187 | + if (count($options) === 1) { |
| 188 | + $this->_phrase = Text_Password::create($len, $options[0]); |
| 189 | + } else { |
| 190 | + $this->_phrase = Text_Password::create($len, $options[0], $options[1]); |
| 191 | + } |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + /** |
| 196 | + * Return secret CAPTCHA phrase |
| 197 | + * |
| 198 | + * This method returns the CAPTCHA phrase |
| 199 | + * |
| 200 | + * @access public |
| 201 | + * @return phrase secret phrase |
| 202 | + */ |
| 203 | + public function getPhrase() |
| 204 | + { |
| 205 | + return $this->_phrase; |
| 206 | + } |
| 207 | + |
| 208 | + /** |
| 209 | + * Sets secret CAPTCHA phrase |
| 210 | + * |
| 211 | + * This method sets the CAPTCHA phrase |
| 212 | + * (use null for a random phrase) |
| 213 | + * |
| 214 | + * @access public |
| 215 | + * @param string $phrase the (new) phrase |
| 216 | + * @void |
| 217 | + */ |
| 218 | + public function setPhrase($phrase = null) |
| 219 | + { |
| 220 | + if (!empty($phrase)) { |
| 221 | + $this->_phrase = $phrase; |
| 222 | + } else { |
| 223 | + $this->_createPhrase(); |
| 224 | + } |
| 225 | + } |
| 226 | + |
| 227 | + /** |
| 228 | + * Place holder for the real init() method |
| 229 | + * used by extended classes to initialize CAPTCHA |
| 230 | + * |
| 231 | + * @access private |
| 232 | + * @return PEAR_Error |
| 233 | + */ |
| 234 | + public function init() { |
| 235 | + return PEAR::raiseError('CAPTCHA type not selected', true); |
| 236 | + } |
| 237 | + |
| 238 | + /** |
| 239 | + * Place holder for the real _createCAPTCHA() method |
| 240 | + * used by extended classes to generate CAPTCHA from phrase |
| 241 | + * |
| 242 | + * @access private |
| 243 | + * @return PEAR_Error |
| 244 | + */ |
| 245 | + public function _createCAPTCHA() { |
| 246 | + return PEAR::raiseError('CAPTCHA type not selected', true); |
| 247 | + } |
| 248 | + |
| 249 | + /** |
| 250 | + * Place holder for the real getCAPTCHA() method |
| 251 | + * used by extended classes to return the generated CAPTCHA |
| 252 | + * (as an image resource, as an ASCII text, ...) |
| 253 | + * |
| 254 | + * @access private |
| 255 | + * @return PEAR_Error |
| 256 | + */ |
| 257 | + public function getCAPTCHA() { |
| 258 | + return PEAR::raiseError('CAPTCHA type not selected', true); |
| 259 | + } |
| 260 | + |
| 261 | +} |
| 262 | +?> |
0 commit comments