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