parent
b8aaab9b72
commit
f817d5da57
@ -0,0 +1,267 @@ |
||||
<?php |
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
||||
|
||||
/** |
||||
* Common class for HTML_QuickForm elements to display a CAPTCHA |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA question (image, riddle, etc...) |
||||
* |
||||
* This package requires the use of a PHP session ($_SESSION). |
||||
* |
||||
* PHP versions 4 and 5 |
||||
* |
||||
* LICENSE: |
||||
* |
||||
* Copyright (c) 2006-2008, Philippe Jausions / 11abacus |
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* - Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* - Neither the name of 11abacus nor the names of its contributors may |
||||
* be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version CVS: $Id: CAPTCHA.php,v 1.1 2008/04/26 23:27:28 jausions Exp $ |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
*/ |
||||
|
||||
/** |
||||
* Required packages |
||||
*/ |
||||
require_once 'HTML/QuickForm/input.php'; |
||||
require_once 'Text/CAPTCHA.php'; |
||||
|
||||
/** |
||||
* Common class for HTML_QuickForm elements to display a CAPTCHA |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA question (image, riddle, etc...) |
||||
* |
||||
* This package requires the use of a PHP session ($_SESSION). |
||||
* |
||||
* Because the CAPTCHA element is serialized in the PHP session, |
||||
* you need to include the class declaration BEFORE the session starts. |
||||
* So BEWARE if you have php.ini session.auto_start enabled, you won't be |
||||
* able to use this element, unless you're also using PHP 5's __autoload() |
||||
* or php.ini's unserialize_callback_func setting |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version Release: 0.3.0 |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
* @abstract |
||||
*/ |
||||
class HTML_QuickForm_CAPTCHA extends HTML_QuickForm_input |
||||
{ |
||||
/** |
||||
* Default options |
||||
* |
||||
* @var array |
||||
* @access protected |
||||
*/ |
||||
var $_options = array( |
||||
'sessionVar' => '_HTML_QuickForm_CAPTCHA', |
||||
'phrase' => null, |
||||
); |
||||
|
||||
/** |
||||
* CAPTCHA driver |
||||
* |
||||
* @var string |
||||
* @access protected |
||||
*/ |
||||
var $_CAPTCHA_driver; |
||||
|
||||
/** |
||||
* Class constructor |
||||
* |
||||
* @param string $elementName Name |
||||
* @param mixed $elementLabel Label for the CAPTCHA |
||||
* @param array $options Options for the Text_CAPTCHA package |
||||
* <ul> |
||||
* <li>'sessionVar' (string) name of session variable containing |
||||
* the Text_CAPTCHA instance (defaults to |
||||
* _HTML_QuickForm_CAPTCHA.)</li> |
||||
* <li>Other options depend on the driver used</li> |
||||
* </ul> |
||||
* @param mixed $attributes HTML Attributes for the <a> tag surrounding |
||||
* the image. Can be a string or array. |
||||
* |
||||
* @access public |
||||
*/ |
||||
function HTML_QuickForm_CAPTCHA($elementName = null, $elementLabel = null, |
||||
$options = null, $attributes = null) |
||||
{ |
||||
HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, |
||||
$attributes); |
||||
$this->setType('CAPTCHA_'.$this->_CAPTCHA_driver); |
||||
|
||||
if (is_array($options)) { |
||||
$this->_options = array_merge($this->_options, $options); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Initializes the CAPTCHA instance (if needed) |
||||
* |
||||
* @return boolean TRUE or PEAR_Error on error |
||||
* @access protected |
||||
*/ |
||||
function _initCAPTCHA() |
||||
{ |
||||
$sessionVar = $this->_options['sessionVar']; |
||||
|
||||
if (empty($_SESSION[$sessionVar])) { |
||||
$_SESSION[$sessionVar] =& Text_CAPTCHA::factory($this->_CAPTCHA_driver); |
||||
if (PEAR::isError($_SESSION[$sessionVar])) { |
||||
return $_SESSION[$sessionVar]; |
||||
} |
||||
$result = $_SESSION[$sessionVar]->init($this->_options); |
||||
if (PEAR::isError($result)) { |
||||
return $result; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Returns the answer/phrase of the CAPTCHA |
||||
* |
||||
* @param mixed &$values Ignored by this element |
||||
* |
||||
* @return string |
||||
* @access private |
||||
*/ |
||||
function _findValue(&$values) |
||||
{ |
||||
return $this->getValue(); |
||||
} |
||||
|
||||
/** |
||||
* Returns the answer/phrase of the CAPTCHA |
||||
* |
||||
* @return string |
||||
* @access public |
||||
*/ |
||||
function getValue() |
||||
{ |
||||
$sessionVar = $this->_options['sessionVar']; |
||||
|
||||
return (!empty($_SESSION[$sessionVar])) |
||||
? $_SESSION[$sessionVar]->getPhrase() |
||||
: null; |
||||
} |
||||
|
||||
/** |
||||
* Returns the answer/phrase of the CAPTCHA |
||||
* |
||||
* @param mixed &$submitValues Ignored by this element |
||||
* @param boolean $assoc Whether to return an array |
||||
* |
||||
* @return string |
||||
* @access public |
||||
*/ |
||||
function exportValue(&$submitValues, $assoc = false) |
||||
{ |
||||
return ($assoc) |
||||
? array($this->getName() => $this->getValue()) |
||||
: $this->getValue(); |
||||
} |
||||
|
||||
/** |
||||
* Sets the CAPTCHA question/phrase |
||||
* |
||||
* Pass NULL or no argument for a random question/phrase to be generated |
||||
* |
||||
* @param string $phrase Value of the CAPTCHA to set |
||||
* |
||||
* @return void |
||||
* @access public |
||||
*/ |
||||
function setPhrase($phrase = null) |
||||
{ |
||||
$this->_options['phrase'] = $phrase; |
||||
|
||||
if (!empty($_SESSION[$this->_options['sessionVar']])) { |
||||
$_SESSION[$this->_options['sessionVar']]->setPhrase($phrase); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Destroys the CAPTCHA instance to prevent reuse |
||||
* |
||||
* @return void |
||||
* @access public |
||||
*/ |
||||
function destroy() |
||||
{ |
||||
unset($_SESSION[$this->_options['sessionVar']]); |
||||
} |
||||
|
||||
/** |
||||
* Returns the HTML for the CAPTCHA |
||||
* |
||||
* This can be overwritten by sub-classes for specific output behavior |
||||
* (for instance the Image CAPTCHA displays an image) |
||||
* |
||||
* @return string |
||||
* @access public |
||||
*/ |
||||
function toHtml() |
||||
{ |
||||
$result = $this->_initCAPTCHA(); |
||||
if (PEAR::isError($result)) { |
||||
return $result; |
||||
} |
||||
|
||||
$captcha = $_SESSION[$this->_options['sessionVar']]->getCAPTCHA(); |
||||
|
||||
$attr = $this->_attributes; |
||||
unset($attr['type']); |
||||
unset($attr['value']); |
||||
unset($attr['name']); |
||||
|
||||
$html = $this->_getTabs() |
||||
. '<span' . $this->_getAttrString($attr) . '>' |
||||
. htmlspecialchars($captcha) |
||||
. '</span>'; |
||||
return $html; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Register the rule with QuickForm |
||||
*/ |
||||
require_once 'HTML/QuickForm/Rule/CAPTCHA.php'; |
||||
|
||||
?> |
@ -0,0 +1,93 @@ |
||||
<?php |
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA equation |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA equation. |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* PHP versions 4 and 5 |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version CVS: $Id: Equation.php,v 1.1 2008/04/26 23:27:30 jausions Exp $ |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
*/ |
||||
|
||||
/** |
||||
* Required packages |
||||
*/ |
||||
require_once 'HTML/QuickForm/CAPTCHA.php'; |
||||
require_once 'Text/CAPTCHA/Driver/Equation.php'; |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA equation question |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA equation question. |
||||
* |
||||
* Options for the element |
||||
* <ul> |
||||
* <li>'min' (integer) Minimal number to use in an equation.</li> |
||||
* <li>'max' (integer) Maximal number to use in an equation.</li> |
||||
* <li>'severity' (integer) Complexity of the equation to resolve |
||||
* (1 = easy, 2 = harder)</li> |
||||
* <li>'numbersToText' (boolean) Whether to use the Numbers_Words |
||||
* package to convert numbers to text,</li> |
||||
* <li>'sessionVar' (string) name of session variable containing |
||||
* the Text_CAPTCHA instance (defaults to |
||||
* _HTML_QuickForm_CAPTCHA.)</li> |
||||
* </ul> |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version Release: 0.3.0 |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
* @see Text_CAPTCHA_Driver_Equation |
||||
*/ |
||||
class HTML_QuickForm_CAPTCHA_Equation extends HTML_QuickForm_CAPTCHA |
||||
{ |
||||
/** |
||||
* Default options |
||||
* |
||||
* @var array |
||||
* @access protected |
||||
*/ |
||||
var $_options = array( |
||||
'sessionVar' => '_HTML_QuickForm_CAPTCHA', |
||||
'severity' => 1, |
||||
'numbersToText' => false, |
||||
'phrase' => null, |
||||
); |
||||
|
||||
/** |
||||
* CAPTCHA driver |
||||
* |
||||
* @var string |
||||
* @access protected |
||||
*/ |
||||
var $_CAPTCHA_driver = 'Equation'; |
||||
} |
||||
|
||||
/** |
||||
* Registers the class with QuickForm |
||||
*/ |
||||
if (class_exists('HTML_QuickForm')) { |
||||
HTML_QuickForm::registerElementType('CAPTCHA_Equation', |
||||
'HTML/QuickForm/CAPTCHA/Equation.php', |
||||
'HTML_QuickForm_CAPTCHA_Equation'); |
||||
} |
||||
|
||||
?> |
@ -0,0 +1,126 @@ |
||||
<?php |
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA figlet |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA figlet. |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* PHP versions 4 and 5 |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version CVS: $Id: Figlet.php,v 1.1 2008/04/26 23:27:30 jausions Exp $ |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
*/ |
||||
|
||||
/** |
||||
* Required packages |
||||
*/ |
||||
require_once 'HTML/QuickForm/CAPTCHA.php'; |
||||
require_once 'Text/CAPTCHA/Driver/Figlet.php'; |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA figlet |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA figlet |
||||
* |
||||
* Options for the element |
||||
* <ul> |
||||
* <li>'width' (integer) Width of figlet (default is 200px)</li> |
||||
* <li>'output' (string) Output format: "html", "text" or |
||||
* "javascript" (default is "html").</li> |
||||
* <li>'length' (integer) number of letters in the figlet |
||||
* (default is 6)</li> |
||||
* <li>'options' (array) only index supported is "font_file", which |
||||
* should either be one figlet font file path, |
||||
* or an array of figlet font file paths |
||||
* (one we be picked randomly)</li> |
||||
* <li>'sessionVar' (string) name of session variable containing |
||||
* the Text_CAPTCHA instance (defaults to |
||||
* _HTML_QuickForm_CAPTCHA.)</li> |
||||
* </ul> |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version Release: 0.3.0 |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
* @see Text_CAPTCHA_Driver_Figlet |
||||
*/ |
||||
class HTML_QuickForm_CAPTCHA_Figlet extends HTML_QuickForm_CAPTCHA |
||||
{ |
||||
/** |
||||
* Default options |
||||
* |
||||
* @var array |
||||
* @access protected |
||||
*/ |
||||
var $_options = array( |
||||
'sessionVar' => '_HTML_QuickForm_CAPTCHA', |
||||
'output' => 'html', |
||||
'width' => 200, |
||||
'length' => 6, |
||||
'phrase' => null, |
||||
); |
||||
|
||||
/** |
||||
* CAPTCHA driver |
||||
* |
||||
* @var string |
||||
* @access protected |
||||
*/ |
||||
var $_CAPTCHA_driver = 'Figlet'; |
||||
|
||||
|
||||
/** |
||||
* Returns the HTML for the CAPTCHA |
||||
* |
||||
* This can be overwritten by sub-classes for specific output behavior |
||||
* (for instance the Image CAPTCHA displays an image) |
||||
* |
||||
* @access public |
||||
* @return string |
||||
*/ |
||||
function toHtml() |
||||
{ |
||||
$result = $this->_initCAPTCHA(); |
||||
if (PEAR::isError($result)) { |
||||
return $result; |
||||
} |
||||
|
||||
$attr = $this->_attributes; |
||||
unset($attr['type']); |
||||
unset($attr['value']); |
||||
unset($attr['name']); |
||||
|
||||
$html = $this->_getTabs() |
||||
. '<div' . $this->_getAttrString($attr) . '>' |
||||
. $_SESSION[$this->_options['sessionVar']]->getCAPTCHA() |
||||
. '</div>'; |
||||
return $html; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Registers the class with QuickForm |
||||
*/ |
||||
if (class_exists('HTML_QuickForm')) { |
||||
HTML_QuickForm::registerElementType('CAPTCHA_Figlet', |
||||
'HTML/QuickForm/CAPTCHA/Figlet.php', |
||||
'HTML_QuickForm_CAPTCHA_Figlet'); |
||||
} |
||||
|
||||
?> |
@ -0,0 +1,165 @@ |
||||
<?php |
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA image |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA image. |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* PHP versions 4 and 5 |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version CVS: $Id: Image.php,v 1.1 2008/04/26 23:27:30 jausions Exp $ |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
*/ |
||||
|
||||
/** |
||||
* Required packages |
||||
*/ |
||||
require_once 'HTML/QuickForm/CAPTCHA.php'; |
||||
require_once 'Text/CAPTCHA/Driver/Image.php'; |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA image |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA image. |
||||
* |
||||
* Options for the element |
||||
* <ul> |
||||
* <li>'width' (integer) width of the image,</li> |
||||
* <li>'height' (integer) height of the image,</li> |
||||
* <li>'imageOptions' (array) options passed to the Image_Text |
||||
* constructor,</li> |
||||
* <li>'callback' (string) URL of callback script that will generate |
||||
* and output the image itself,</li> |
||||
* <li>'alt' (string) the alt text for the image,</li> |
||||
* <li>'sessionVar' (string) name of session variable containing |
||||
* the Text_CAPTCHA instance (defaults to |
||||
* _HTML_QuickForm_CAPTCHA.)</li> |
||||
* </ul> |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version Release: 0.3.0 |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
* @see Text_CAPTCHA_Driver_Image |
||||
*/ |
||||
class HTML_QuickForm_CAPTCHA_Image extends HTML_QuickForm_CAPTCHA |
||||
{ |
||||
|
||||
/** |
||||
* Default options |
||||
* |
||||
* @var array |
||||
* @access protected |
||||
*/ |
||||
var $_options = array( |
||||
'sessionVar' => '_HTML_QuickForm_CAPTCHA', |
||||
'width' => '200', |
||||
'height' => '80', |
||||
'alt' => 'Click to view another image', |
||||
'callback' => '', |
||||
'imageOptions' => null, |
||||
'phrase' => null, |
||||
); |
||||
|
||||
/** |
||||
* CAPTCHA driver |
||||
* |
||||
* @var string |
||||
* @access protected |
||||
*/ |
||||
var $_CAPTCHA_driver = 'Image'; |
||||
|
||||
/** |
||||
* Returns the HTML for the CAPTCHA image |
||||
* |
||||
* @return string |
||||
* @access public |
||||
*/ |
||||
function toHtml() |
||||
{ |
||||
if ($this->_flagFrozen) { |
||||
return ''; |
||||
} |
||||
|
||||
$result = parent::_initCAPTCHA(); |
||||
if (PEAR::isError($result)) { |
||||
return $result; |
||||
} |
||||
|
||||
$html = ''; |
||||
$tabs = $this->_getTabs(); |
||||
$inputName = $this->getName(); |
||||
$imgName = 'QF_CAPTCHA_'.$inputName; |
||||
|
||||
if ($this->getComment() != '') { |
||||
$html .= $tabs.'<!-- '.$this->getComment().' // -->'; |
||||
} |
||||
|
||||
$attr = $this->_attributes; |
||||
unset($attr['type']); |
||||
unset($attr['value']); |
||||
unset($attr['name']); |
||||
|
||||
$html = $tabs.'<a href="'.$this->_options['callback'] |
||||
.'" target="_blank" ' |
||||
.$this->_getAttrString($attr) |
||||
.' onclick="var cancelClick = false; ' |
||||
.$this->getOnclickJs($imgName) |
||||
.' return !cancelClick;"><img src="' |
||||
.$this->_options['callback'].'" name="'.$imgName |
||||
.'" id="'.$imgName.'" width="'.$this->_options['width'] |
||||
.'" height="'.$this->_options['height'].'" title="' |
||||
.htmlspecialchars($this->_options['alt']).'" /></a>'; |
||||
|
||||
return $html; |
||||
} |
||||
|
||||
/** |
||||
* Creates the javascript for the onclick event which will |
||||
* reload a new CAPTCHA image |
||||
* |
||||
* @param string $imageName The image name/id |
||||
* |
||||
* @return string |
||||
* @access public |
||||
*/ |
||||
function getOnclickJs($imageName) |
||||
{ |
||||
$onclickJs = '' |
||||
.'if (document.images) {' |
||||
.' var img = new Image();' |
||||
.' var d = new Date();' |
||||
.' img.src = this.href + ((this.href.indexOf(\'?\') == -1) ' |
||||
.'? \'?\' : \'&\') + d.getTime();' |
||||
.' document.images[\''.addslashes($imageName).'\'].src = img.src;' |
||||
.' cancelClick = true;' |
||||
.'}'; |
||||
return $onclickJs; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Registers the class with QuickForm |
||||
*/ |
||||
if (class_exists('HTML_QuickForm')) { |
||||
HTML_QuickForm::registerElementType('CAPTCHA_Image', |
||||
'HTML/QuickForm/CAPTCHA/Image.php', 'HTML_QuickForm_CAPTCHA_Image'); |
||||
} |
||||
|
||||
?> |
@ -0,0 +1,90 @@ |
||||
<?php |
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4: */ |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA "Word" |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA "word". |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* PHP versions 4 and 5 |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version CVS: $Id: Word.php,v 1.1 2008/04/26 23:27:30 jausions Exp $ |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
*/ |
||||
|
||||
/** |
||||
* Required packages |
||||
*/ |
||||
require_once 'HTML/QuickForm/CAPTCHA.php'; |
||||
require_once 'Text/CAPTCHA/Driver/Word.php'; |
||||
|
||||
/** |
||||
* Element for HTML_QuickForm to display a CAPTCHA "word" question |
||||
* |
||||
* The HTML_QuickForm_CAPTCHA package adds an element to the |
||||
* HTML_QuickForm package to display a CAPTCHA "word" question. |
||||
* |
||||
* Options for the element |
||||
* <ul> |
||||
* <li>'length' (integer) the length of the Word.</li> |
||||
* <li>'mode' (string) 'single' for separated words.</li> |
||||
* <li>'locale' (string) locale for Numbers_Words package</li> |
||||
* <li>'sessionVar' (string) name of session variable containing |
||||
* the Text_CAPTCHA instance (defaults to |
||||
* _HTML_QuickForm_CAPTCHA.)</li> |
||||
* </ul> |
||||
* |
||||
* This package requires the use of a PHP session. |
||||
* |
||||
* @category HTML |
||||
* @package HTML_QuickForm_CAPTCHA |
||||
* @author Philippe Jausions <Philippe.Jausions@11abacus.com> |
||||
* @copyright 2006-2008 by Philippe Jausions / 11abacus |
||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD |
||||
* @version Release: 0.3.0 |
||||
* @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA |
||||
* @see Text_CAPTCHA_Driver_Equation |
||||
*/ |
||||
class HTML_QuickForm_CAPTCHA_Word extends HTML_QuickForm_CAPTCHA |
||||
{ |
||||
/** |
||||
* Default options |
||||
* |
||||
* @var array |
||||
* @access protected |
||||
*/ |
||||
var $_options = array( |
||||
'sessionVar' => '_HTML_QuickForm_CAPTCHA', |
||||
'length' => 4, |
||||
'mode' => 'single', |
||||
'locale' => 'en_US', |
||||
'phrase' => null, |
||||
); |
||||
|
||||
/** |
||||
* CAPTCHA driver |
||||
* |
||||
* @var string |
||||
* @access protected |
||||
*/ |
||||
var $_CAPTCHA_driver = 'Word'; |
||||
} |
||||
|
||||
/** |
||||
* Registers the class with QuickForm |
||||
*/ |
||||
if (class_exists('HTML_QuickForm')) { |
||||
HTML_QuickForm::registerElementType('CAPTCHA_Word', |
||||
'HTML/QuickForm/CAPTCHA/Word.php', 'HTML_QuickForm_CAPTCHA_Word'); |
||||
} |
||||
|
||||
?> |
@ -0,0 +1,152 @@ |
||||
<?php |
||||
/** |
||||
* Text_CAPTCHA - creates a CAPTCHA for Turing tests. |
||||
* Base class file for using Text_CAPTCHA. |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
/** |
||||
* Require Exception class for error handling. |
||||
*/ |
||||
require_once 'Text/CAPTCHA/Exception.php'; |
||||
/** |
||||
* Require Text_Password class for generating the phrase. |
||||
*/ |
||||
require_once 'Text/Password.php'; |
||||
|
||||
/** |
||||
* Text_CAPTCHA - creates a CAPTCHA for Turing tests. |
||||
* Class to create a Turing test for websites by creating an image, ASCII art or |
||||
* something else with some (obfuscated) characters. |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
class Text_CAPTCHA |
||||
{ |
||||
/** |
||||
* driver for Text_CAPTCHA |
||||
* |
||||
* @var Text_CAPTCHA_Driver_Base |
||||
*/ |
||||
private $_driver; |
||||
|
||||
/** |
||||
* check if an initial driver init was done. |
||||
* |
||||
* @var bool |
||||
*/ |
||||
private $_driverInitDone = false; |
||||
|
||||
/** |
||||
* Constructor for the TEXT_CAPTCHA object with the given driver. |
||||
* |
||||
* @param Text_CAPTCHA_Driver $driver driver |
||||
* |
||||
* @throws Text_CAPTCHA_Exception no driver given |
||||
*/ |
||||
function __construct($driver) |
||||
{ |
||||
if (is_null($driver)) { |
||||
throw new Text_CAPTCHA_Exception("No driver given"); |
||||
} |
||||
$this->_driver = $driver; |
||||
$this->_driverInitDone = false; |
||||
} |
||||
|
||||
/** |
||||
* Create a new Text_CAPTCHA object. |
||||
* |
||||
* @param string $driver name of driver class to initialize |
||||
* |
||||
* @return Text_CAPTCHA a newly created Text_CAPTCHA object |
||||
* @throws Text_CAPTCHA_Exception when driver could not be loaded |
||||
* |
||||
*/ |
||||
public static function factory($driver) |
||||
{ |
||||
$driver = basename($driver); |
||||
$class = 'Text_CAPTCHA_Driver_' . $driver; |
||||
$file = str_replace('_', '/', $class) . '.php'; |
||||
//check if it exists and can be loaded |
||||
if (!@fclose(@fopen($file, 'r', true))) { |
||||
throw new Text_CAPTCHA_Exception( |
||||
'Driver ' . $driver . ' cannot be loaded.' |
||||
); |
||||
} |
||||
//continue with including the driver |
||||
include_once $file; |
||||
|
||||
$driver = new $class; |
||||
|
||||
return new Text_CAPTCHA($driver); |
||||
} |
||||
|
||||
/** |
||||
* Create random CAPTCHA phrase |
||||
* |
||||
* @param boolean|string $newPhrase new Phrase to use or true to generate a new |
||||
* one |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception when driver is not initialized |
||||
*/ |
||||
public final function generate($newPhrase = false) |
||||
{ |
||||
if (!$this->_driverInitDone) { |
||||
throw new Text_CAPTCHA_Exception("Driver not initialized"); |
||||
} |
||||
if ($newPhrase === true || is_null($this->_driver->getPhrase())) { |
||||
$this->_driver->createPhrase(); |
||||
} else if (strlen($newPhrase) > 0) { |
||||
$this->_driver->setPhrase($newPhrase); |
||||
} |
||||
$this->_driver->createCAPTCHA(); |
||||
} |
||||
|
||||
/** |
||||
* Reinitialize the entire Text_CAPTCHA object. |
||||
* |
||||
* @param array $options Options to pass in. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public final function init($options = array()) |
||||
{ |
||||
$this->_driver->resetDriver(); |
||||
$this->_driver->initDriver($options); |
||||
$this->_driverInitDone = true; |
||||
$this->generate(); |
||||
} |
||||
|
||||
/** |
||||
* Place holder for the real getCAPTCHA() method used by extended classes to |
||||
* return the generated CAPTCHA (as an image resource, as an ASCII text, ...). |
||||
* |
||||
* @return string|object |
||||
*/ |
||||
public final function getCAPTCHA() |
||||
{ |
||||
return $this->_driver->getCAPTCHA(); |
||||
} |
||||
|
||||
/** |
||||
* Return secret CAPTCHA phrase. |
||||
* |
||||
* @return string secret phrase |
||||
*/ |
||||
public final function getPhrase() |
||||
{ |
||||
return $this->_driver->getPhrase(); |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
<?php |
||||
/** |
||||
* Interface for Drivers |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
/** |
||||
* Interface for Text_CAPTCHA drivers |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
interface Text_CAPTCHA_Driver |
||||
{ |
||||
/** |
||||
* Clear the internal state of the driver. |
||||
* |
||||
* @return void |
||||
*/ |
||||
function resetDriver(); |
||||
|
||||
/** |
||||
* Initialize the driver with the given options. |
||||
* |
||||
* @param array $options options for the driver as array |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception something went wrong during init |
||||
*/ |
||||
function initDriver($options); |
||||
|
||||
/** |
||||
* Generate the CAPTCHA. |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception something went wrong during creation of CAPTCHA |
||||
*/ |
||||
function createCAPTCHA(); |
||||
|
||||
/** |
||||
* Generate the phrase for the CAPTCHA. |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception something went wrong during creation of phrase |
||||
*/ |
||||
function createPhrase(); |
||||
} |
@ -0,0 +1,97 @@ |
||||
<?php |
||||
/** |
||||
* Base class file for all Text_CAPTCHA drivers. |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
require_once 'Text/CAPTCHA/Driver.php'; |
||||
/** |
||||
* Base class file for all Text_CAPTCHA drivers. |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
abstract class Text_CAPTCHA_Driver_Base implements Text_CAPTCHA_Driver |
||||
{ |
||||
/** |
||||
* Captcha |
||||
* |
||||
* @var object|string |
||||
*/ |
||||
private $_captcha; |
||||
|
||||
/** |
||||
* Phrase |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $_phrase; |
||||
|
||||
/** |
||||
* Sets secret CAPTCHA phrase. |
||||
* This method sets the CAPTCHA phrase (use null for a random phrase) |
||||
* |
||||
* @param string $phrase The (new) phrase |
||||
* |
||||
* @return void |
||||
*/ |
||||
public final function setPhrase($phrase) |
||||
{ |
||||
$this->_phrase = $phrase; |
||||
} |
||||
|
||||
/** |
||||
* Return secret CAPTCHA phrase |
||||
* This method returns the CAPTCHA phrase |
||||
* |
||||
* @return string secret phrase |
||||
*/ |
||||
public final function getPhrase() |
||||
{ |
||||
return $this->_phrase; |
||||
} |
||||
|
||||
/** |
||||
* Sets the generated captcha. |
||||
* |
||||
* @param object|string $captcha the generated captcha |
||||
* |
||||
* @return void |
||||
*/ |
||||
protected final function setCaptcha($captcha) |
||||
{ |
||||
$this->_captcha = $captcha; |
||||
} |
||||
|
||||
/** |
||||
* Place holder for the real getCAPTCHA() method |
||||
* used by extended classes to return the generated CAPTCHA |
||||
* (as an image resource, as an ASCII text, ...) |
||||
* |
||||
* @return string|object |
||||
*/ |
||||
public final function getCAPTCHA() |
||||
{ |
||||
return $this->_captcha; |
||||
} |
||||
|
||||
/** |
||||
* Reset the phrase and the CAPTCHA. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function resetDriver() |
||||
{ |
||||
$this->setPhrase(null); |
||||
$this->setCaptcha(null); |
||||
} |
||||
} |
@ -0,0 +1,215 @@ |
||||
<?php |
||||
/** |
||||
* Equation driver for Text_CAPTCHA. |
||||
* Returns simple equations as string, e.g. "9 - 2" |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Christian Weiske <cweiske@php.net> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
require_once 'Text/CAPTCHA/Driver/Base.php'; |
||||
/** |
||||
* Equation driver for Text_CAPTCHA. |
||||
* Returns simple equations as string, e.g. "9 - 2" |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Christian Weiske <cweiske@php.net> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
class Text_CAPTCHA_Driver_Equation extends Text_CAPTCHA_Driver_Base |
||||
{ |
||||
/** |
||||
* Operators that may be used in the equation. Two numbers have to be filled in, |
||||
* and %s is needed since number2text conversion may be applied and strings |
||||
* filled in. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $_operators = array( |
||||
'%s * %s', |
||||
'%s + %s', |
||||
'%s - %s', |
||||
'min(%s, %s)', |
||||
'max(%s, %s)' |
||||
); |
||||
|
||||
/** |
||||
* Minimal number to use in an equation. |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $_min = 1; |
||||
|
||||
/** |
||||
* Maximum number to use in an equation. |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $_max = 10; |
||||
|
||||
/** |
||||
* Whether numbers shall be converted to text. |
||||
* |
||||
* @var bool |
||||
*/ |
||||
private $_numbersToText = false; |
||||
|
||||
/** |
||||
* This variable holds the locale for Numbers_Words. |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $_locale = ''; |
||||
|
||||
/** |
||||
* Complexity of the generated equations.<br> |
||||
* 1 - simple ones such as "1 + 10"<br> |
||||
* 2 - harder ones such as "(3-2)*(min(5,6))" |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $_severity = 1; |
||||
|
||||
/** |
||||
* Initialize the driver. |
||||
* |
||||
* @param array $options CAPTCHA options with these keys:<br> |
||||
* min minimum numeric value |
||||
* max maximum numeric value |
||||
* numbersToText boolean for number to text conversion |
||||
* locale locale for number to text conversion |
||||
* severity number for complexity |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception when numbersToText is true, but Number_Words |
||||
* package is not available |
||||
*/ |
||||
public function initDriver($options = array()) |
||||
{ |
||||
if (isset($options['min'])) { |
||||
$this->_min = (int)$options['min']; |
||||
} else { |
||||
$this->_min = 1; |
||||
} |
||||
if (isset($options['max'])) { |
||||
$this->_max = (int)$options['max']; |
||||
} else { |
||||
$this->_max = 10; |
||||
} |
||||
if (isset($options['numbersToText'])) { |
||||
$this->_numbersToText = (bool)$options['numbersToText']; |
||||
} else { |
||||
$this->_numbersToText = false; |
||||
} |
||||
if (isset($options['locale'])) { |
||||
$this->_locale = (string)$options['locale']; |
||||
} else { |
||||
$this->_locale = ''; |
||||
} |
||||
if (isset($options['severity'])) { |
||||
$this->_severity = (int)$options['severity']; |
||||
} else { |
||||
$this->_severity = 1; |
||||
} |
||||
|
||||
if ($this->_numbersToText) { |
||||
include_once 'Numbers/Words.php'; |
||||
if (!class_exists('Numbers_Words')) { |
||||
throw new Text_CAPTCHA_Exception('Number_Words package required'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create random CAPTCHA equation. |
||||
* This method creates a random equation. |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception when invalid severity is specified |
||||
*/ |
||||
public function createCAPTCHA() |
||||
{ |
||||
switch ($this->_severity) { |
||||
case 1: |
||||
list($equation, $phrase) = $this->_createSimpleEquation(); |
||||
break; |
||||
case 2: |
||||
list($eq1, $sol1) = $this->_createSimpleEquation(); |
||||
list($eq2, $sol2) = $this->_createSimpleEquation(); |
||||
$op3 = $this->_operators[mt_rand(0, count($this->_operators) - 1)]; |
||||
list(, $phrase) = $this->_solveSimpleEquation($sol1, $sol2, $op3); |
||||
$equation = sprintf($op3, '(' . $eq1 . ')', '(' . $eq2 . ')'); |
||||
break; |
||||
default: |
||||
throw new Text_CAPTCHA_Exception( |
||||
'Equation complexity of ' . $this->_severity . ' not supported' |
||||
); |
||||
} |
||||
$this->setCaptcha($equation); |
||||
$this->setPhrase($phrase); |
||||
} |
||||
|
||||
/** |
||||
* Creates a simple equation of type (number operator number). |
||||
* |
||||
* @return array Array with equation and solution |
||||
*/ |
||||
private function _createSimpleEquation() |
||||
{ |
||||
$one = mt_rand($this->_min, $this->_max); |
||||
$two = mt_rand($this->_min, $this->_max); |
||||
$operator = $this->_operators[mt_rand(0, count($this->_operators) - 1)]; |
||||
|
||||
return $this->_solveSimpleEquation($one, $two, $operator); |
||||
} |
||||
|
||||
/** |
||||
* Solves a simple equation with two given numbers and one operator as defined |
||||
* in $this->_operators. |
||||
* Also converts the numbers to words if required. |
||||
* |
||||
* @param int $one First number |
||||
* @param int $two Second number |
||||
* @param string $operator Operator used with those two numbers |
||||
* |
||||
* @return array Array with equation and solution |
||||
*/ |
||||
private function _solveSimpleEquation($one, $two, $operator) |
||||
{ |
||||
$equation = sprintf($operator, $one, $two); |
||||
|
||||
$function = create_function('', 'return ' . $equation . ';'); |
||||
|
||||
if ($this->_numbersToText) { |
||||
$numberWords = new Numbers_Words(); |
||||
$equation = sprintf( |
||||
$operator, |
||||
$numberWords->toWords($one, $this->_locale), |
||||
$numberWords->toWords($two, $this->_locale) |
||||
); |
||||
} |
||||
return array($equation, $function()); |
||||
} |
||||
|
||||
/** |
||||
* Creates the captcha. This method is a placeholder, since the equation is |
||||
* created in createCAPTCHA() |
||||
* |
||||
* @return void |
||||
* @see createCAPTCHA() |
||||
*/ |
||||
public function createPhrase() |
||||
{ |
||||
$this->setPhrase(null); |
||||
} |
||||
} |
@ -0,0 +1,233 @@ |
||||
<?php |
||||
/** |
||||
* Require Figlet class for rendering the text. |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Aaron Wormus <wormus@php.net> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
require_once 'Text/CAPTCHA/Driver/Base.php'; |
||||
require_once 'Text/Figlet.php'; |
||||
/** |
||||
* Text_CAPTCHA_Driver_Figlet - Text_CAPTCHA driver Figlet based CAPTCHAs |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Aaron Wormus <wormus@php.net> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
* @todo define an obfuscation algorithm |
||||
*/ |
||||
class Text_CAPTCHA_Driver_Figlet extends Text_CAPTCHA_Driver_Base |
||||
{ |
||||
/** |
||||
* Text_Password options. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $_textPasswordOptions; |
||||
|
||||
/** |
||||
* Width of CAPTCHA |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $_width; |
||||
|
||||
/** |
||||
* Length of CAPTCHA |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $_length; |
||||
|
||||
/** |
||||
* Figlet font |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $_font; |
||||
|
||||
/** |
||||
* Figlet font |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $_style = array(); |
||||
|
||||
/** |
||||
* Output Format |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $_output; |
||||
|
||||
/** |
||||
* init function |
||||
* |
||||
* Initializes the new Text_CAPTCHA_Driver_Figlet object and creates a GD image |
||||
* |
||||
* @param array $options CAPTCHA options |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception when no options are given |
||||
*/ |
||||
public function initDriver($options = array()) |
||||
{ |
||||
if (!empty($options['output'])) { |
||||
$this->_output = (string)$options['output']; |
||||
} else { |
||||
$this->_output = 'html'; |
||||
} |
||||
|
||||
if (isset($options['width']) && $options['width']) { |
||||
$this->_width = (int)$options['width']; |
||||
} else { |
||||
$this->_width = 200; |
||||
} |
||||
|
||||
if (!empty($options['length'])) { |
||||
$this->_length = $options['length']; |
||||
} else { |
||||
$this->_length = 6; |
||||
} |
||||
|
||||
if (!isset($options['phrase']) || empty($options['phrase'])) { |
||||
$phraseOptions = (isset($options['phraseOptions']) |
||||
&& is_array($options['phraseOptions'])) |
||||
? $options['phraseOptions'] : array(); |
||||
$this->_textPasswordOptions = $phraseOptions; |
||||
} else { |
||||
$this->setPhrase($options['phrase']); |
||||
} |
||||
|
||||
if (!empty($options['style']) |
||||
&& is_array($options['style']) |
||||
) { |
||||
$this->_style = $options['style']; |
||||
} |
||||
|
||||
if (empty($this->_style['padding'])) { |
||||
$this->_style['padding'] = '5px'; |
||||
} |
||||
|
||||
if (!empty($options['font_file'])) { |
||||
if (is_array($options['font_file'])) { |
||||
$arr = $options['font_file']; |
||||
$this->_font = $arr[array_rand($arr)]; |
||||
} else { |
||||
$this->_font = $options['font_file']; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create the passphrase. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function createPhrase() |
||||
{ |
||||
$options = $this->_textPasswordOptions; |
||||
$textPassword = new Text_Password(); |
||||
if (!is_array($options) || count($options) === 0) { |
||||
$this->setPhrase($textPassword->create($this->_length)); |
||||
} else { |
||||
if (count($options) === 1) { |
||||
$this->setPhrase($textPassword->create($this->_length, $options[0])); |
||||
} else { |
||||
$this->setPhrase( |
||||
$textPassword->create($this->_length, $options[0], $options[1]) |
||||
); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create CAPTCHA image. |
||||
* |
||||
* This method creates a CAPTCHA image. |
||||
* |
||||
* @return void on error |
||||
* @throws Text_CAPTCHA_Exception when loading font fails |
||||
*/ |
||||
public function createCAPTCHA() |
||||
{ |
||||
$pear = new PEAR(); |
||||
$figlet = new Text_Figlet(); |
||||
if ($pear->isError($figlet->loadFont($this->_font))) { |
||||
throw new Text_CAPTCHA_Exception('Error loading Text_Figlet font'); |
||||
} |
||||
|
||||
$outputString = $figlet->lineEcho($this->getPhrase()); |
||||
|
||||
switch ($this->_output) { |
||||
case 'text': |
||||
$this->setCaptcha($outputString); |
||||
break; |
||||
case 'html': |
||||
$this->setCaptcha($this->_getCAPTCHAAsHTML($outputString)); |
||||
break; |
||||
case 'javascript': |
||||
$this->setCaptcha($this->_getCAPTCHAAsJavascript($outputString)); |
||||
break; |
||||
default: |
||||
throw new Text_CAPTCHA_Exception('Invalid output option given'); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return CAPTCHA as HTML. |
||||
* |
||||
* This method returns the CAPTCHA as HTML. |
||||
* |
||||
* @param string $figletOutput output string from Figlet. |
||||
* |
||||
* @return string HTML Figlet image or PEAR error |
||||
*/ |
||||
private function _getCAPTCHAAsHTML($figletOutput) |
||||
{ |
||||
$charWidth = strpos($figletOutput, "\n"); |
||||
$data = str_replace("\n", '<br />', $figletOutput); |
||||
$textSize = ($this->_width / $charWidth) * 1.4; |
||||
$cssOutput = ""; |
||||
foreach ($this->_style as $key => $value) { |
||||
$cssOutput .= "$key: $value;"; |
||||
} |
||||
|
||||
$htmlOutput = '<div style="font-family: courier; |
||||
font-size: ' . $textSize . 'px; |
||||
width:' . $this->_width . 'px; |
||||
text-align:center;">'; |
||||
$htmlOutput .= '<div style="' . $cssOutput . 'margin:0px;"> |
||||
<pre style="padding: 0px; margin: 0px;">' . $data . '</pre></div></div>'; |
||||
|
||||
return $htmlOutput; |
||||
} |
||||
|
||||
/** |
||||
* Return CAPTCHA as Javascript version of HTML. |
||||
* |
||||
* This method returns the CAPTCHA as a Javascript string. |
||||
* I'm not exactly sure what the point of doing this would be. |
||||
* |
||||
* @param string $figletOutput output string from Figlet. |
||||
* |
||||
* @return string javascript string or PEAR error |
||||
*/ |
||||
private function _getCAPTCHAAsJavascript($figletOutput) |
||||
{ |
||||
$obfusData = rawurlencode($figletOutput); |
||||
$javascript = "<script language=\"javascript\"> |
||||
document.write(unescape(\"$obfusData\" ) ); |
||||
</script>"; |
||||
return $javascript; |
||||
} |
||||
} |
@ -0,0 +1,286 @@ |
||||
<?php |
||||
/** |
||||
* Require Image_Text class for generating the text. |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
require_once 'Text/CAPTCHA/Driver/Base.php'; |
||||
require_once 'Image/Text.php'; |
||||
|
||||
/** |
||||
* Text_CAPTCHA_Driver_Image - Text_CAPTCHA driver graphical CAPTCHAs |
||||
* |
||||
* Class to create a graphical Turing test |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
* @todo refine the obfuscation algorithm :-) |
||||
* @todo consider removing Image_Text dependency |
||||
*/ |
||||
class Text_CAPTCHA_Driver_Image extends Text_CAPTCHA_Driver_Base |
||||
{ |
||||
/** |
||||
* Text_Password options. |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $_textPasswordOptions; |
||||
/** |
||||
* Width of CAPTCHA |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $_width; |
||||
|
||||
/** |
||||
* Height of CAPTCHA |
||||
* |
||||
* @var int |
||||
*/ |
||||
private $_height; |
||||
|
||||
/** |
||||
* CAPTCHA output format |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $_output; |
||||
|
||||
/** |
||||
* Further options (here: for Image_Text) |
||||
* |
||||
* @var array |
||||
*/ |
||||
private $_imageOptions = array( |
||||
'font_size' => 24, |
||||
'font_path' => './', |
||||
'font_file' => 'COUR.TTF', |
||||
'text_color' => '#000000', |
||||
'lines_color' => '#CACACA', |
||||
'background_color' => '#555555', |
||||
'antialias' => false); |
||||
|
||||
/** |
||||
* Init function |
||||
* |
||||
* Initializes the new Text_CAPTCHA_Driver_Image object and creates a GD image |
||||
* |
||||
* @param array $options CAPTCHA options |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function initDriver($options = array()) |
||||
{ |
||||
if (is_array($options)) { |
||||
if (isset($options['width']) && is_int($options['width'])) { |
||||
$this->_width = $options['width']; |
||||
} else { |
||||
$this->_width = 200; |
||||
} |
||||
if (isset($options['height']) && is_int($options['height'])) { |
||||
$this->_height = $options['height']; |
||||
} else { |
||||
$this->_height = 80; |
||||
} |
||||
if (!isset($options['phrase']) || empty($options['phrase'])) { |
||||
$phraseOptions = (isset($options['phraseOptions']) |
||||
&& is_array($options['phraseOptions'])) |
||||
? $options['phraseOptions'] : array(); |
||||
$this->_textPasswordOptions = $phraseOptions; |
||||
} else { |
||||
$this->setPhrase($options['phrase']); |
||||
} |
||||
if (!isset($options['output']) || empty($options['output'])) { |
||||
$this->_output = 'resource'; |
||||
} else { |
||||
$this->_output = $options['output']; |
||||
} |
||||
if (isset($options['imageOptions']) |
||||
&& is_array($options['imageOptions']) |
||||
&& count($options['imageOptions']) > 0 |
||||
) { |
||||
$this->_imageOptions = array_merge( |
||||
$this->_imageOptions, $options['imageOptions'] |
||||
); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create CAPTCHA image. |
||||
* |
||||
* This method creates a CAPTCHA image. |
||||
* |
||||
* @return void |
||||
* @throws Text_CAPTCHA_Exception when image generation with Image_Text produces |
||||
* an error |
||||
*/ |
||||
public function createCAPTCHA() |
||||
{ |
||||
$options['canvas'] = array( |
||||
'width' => $this->_width, |
||||
'height' => $this->_height |
||||
); |
||||
$options['width'] = $this->_width - 20; |
||||
$options['height'] = $this->_height - 20; |
||||
$options['cx'] = ceil(($this->_width) / 2 + 10); |
||||
$options['cy'] = ceil(($this->_height) / 2 + 10); |
||||
$options['angle'] = rand(0, 30) - 15; |
||||
$options['font_size'] = $this->_imageOptions['font_size']; |
||||
$options['font_path'] = $this->_imageOptions['font_path']; |
||||
$options['font_file'] = $this->_imageOptions['font_file']; |
||||
$options['color'] = array($this->_imageOptions['text_color']); |
||||
$options['background_color'] = $this->_imageOptions['background_color']; |
||||
$options['max_lines'] = 1; |
||||
$options['mode'] = 'auto'; |
||||
do { |
||||
$imageText = new Image_Text($this->getPhrase(), $options); |
||||
$imageText->init(); |
||||
$result = $imageText->measurize(); |
||||
} while ($result === false && --$options['font_size'] > 0); |
||||
if ($result === false) { |
||||
throw new Text_CAPTCHA_Exception( |
||||
'The text provided does not fit in the image dimensions' |
||||
); |
||||
} |
||||
$imageText->render(); |
||||
$image = $imageText->getImg(); |
||||
|
||||
if ($this->_imageOptions['antialias'] && function_exists('imageantialias')) { |
||||
imageantialias($image, true); |
||||
} |
||||
|
||||
$colors = Image_Text::convertString2RGB( |
||||
$this->_imageOptions['lines_color'] |
||||
); |
||||
$linesColor = imagecolorallocate( |
||||
$image, $colors['r'], $colors['g'], $colors['b'] |
||||
); |
||||
//some obfuscation |
||||
for ($i = 0; $i < 3; $i++) { |
||||
$x1 = rand(0, $this->_width - 1); |
||||
$y1 = rand(0, round($this->_height / 10, 0)); |
||||
$x2 = rand(0, round($this->_width / 10, 0)); |
||||
$y2 = rand(0, $this->_height - 1); |
||||
imageline($image, $x1, $y1, $x2, $y2, $linesColor); |
||||
$x1 = rand(0, $this->_width - 1); |
||||
$y1 = $this->_height - rand(1, round($this->_height / 10, 0)); |
||||
$x2 = $this->_width - rand(1, round($this->_width / 10, 0)); |
||||
$y2 = rand(0, $this->_height - 1); |
||||
imageline($image, $x1, $y1, $x2, $y2, $linesColor); |
||||
$cx = rand(0, $this->_width - 50) + 25; |
||||
$cy = rand(0, $this->_height - 50) + 25; |
||||
$w = rand(1, 24); |
||||
imagearc($image, $cx, $cy, $w, $w, 0, 360, $linesColor); |
||||
} |
||||
|
||||
if ($this->_output == 'gif' && imagetypes() & IMG_GIF) { |
||||
$this->setCaptcha($this->_getCAPTCHAAsGIF($image)); |
||||
} else if (($this->_output == 'jpg' && imagetypes() & IMG_JPG) |
||||
|| ($this->_output == 'jpeg' && imagetypes() & IMG_JPEG) |
||||
) { |
||||
$this->setCaptcha($this->_getCAPTCHAAsJPEG($image)); |
||||
} else if ($this->_output == 'png' && imagetypes() & IMG_PNG) { |
||||
$this->setCaptcha($this->_getCAPTCHAAsPNG($image)); |
||||
} else if ($this->_output == 'resource') { |
||||
$this->setCaptcha($image); |
||||
} else { |
||||
throw new Text_CAPTCHA_Exception( |
||||
"Unknown or unsupported output type specified" |
||||
); |
||||
} |
||||
|
||||
imagedestroy($image); |
||||
} |
||||
|
||||
/** |
||||
* Return CAPTCHA as PNG. |
||||
* |
||||
* This method returns the CAPTCHA as PNG. |
||||
* |
||||
* @param resource $image generated image |
||||
* |
||||
* @return string image contents |
||||
*/ |
||||
private function _getCAPTCHAAsPNG($image) |
||||
{ |
||||
ob_start(); |
||||
imagepng($image); |
||||
$data = ob_get_contents(); |
||||
ob_end_clean(); |
||||
return $data; |
||||
} |
||||
|
||||
/** |
||||
* Return CAPTCHA as JPEG. |
||||
* |
||||
* This method returns the CAPTCHA as JPEG. |
||||
* |
||||
* @param resource $image generated image |
||||
* |
||||
* @return string image contents |
||||
*/ |
||||
private function _getCAPTCHAAsJPEG($image) |
||||
{ |
||||
ob_start(); |
||||
imagejpeg($image); |
||||
$data = ob_get_contents(); |
||||
ob_end_clean(); |
||||
return $data; |
||||
} |
||||
|
||||
/** |
||||
* Return CAPTCHA as GIF. |
||||
* |
||||
* This method returns the CAPTCHA as GIF. |
||||
* |
||||
* @param resource $image generated image |
||||
* |
||||
* @return string image contents |
||||
*/ |
||||
private function _getCAPTCHAAsGIF($image) |
||||
{ |
||||
ob_start(); |
||||
imagegif($image); |
||||
$data = ob_get_contents(); |
||||
ob_end_clean(); |
||||
return $data; |
||||
} |
||||
|
||||
/** |
||||
* Create random CAPTCHA phrase, Image edition (with size check). |
||||
* |
||||
* This method creates a random phrase, maximum 8 characters or width / 25, |
||||
* whatever is smaller. |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function createPhrase() |
||||
{ |
||||
$len = intval(min(8, $this->_width / 25)); |
||||
$options = $this->_textPasswordOptions; |
||||
$textPassword = new Text_Password(); |
||||
if (!is_array($options) || count($options) === 0) { |
||||
$this->setPhrase($textPassword->create($len)); |
||||
} else { |
||||
if (count($options) === 1) { |
||||
$this->setPhrase($textPassword->create($len, $options[0])); |
||||
} else { |
||||
$this->setPhrase( |
||||
$textPassword->create($len, $options[0], $options[1]) |
||||
); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,268 @@ |
||||
<?php |
||||
/** |
||||
* Class used for numeral captchas |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author David Coallier <davidc@agoraproduction.com> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
require_once 'Text/CAPTCHA/Driver/Base.php'; |
||||
/** |
||||
* Class used for numeral captchas |
||||
* |
||||
* This class is intended to be used to generate numeral captchas as such as: |
||||
* Example: |
||||
* Give me the answer to "54 + 2" to prove that you are human. |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author David Coallier <davidc@agoraproduction.com> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
class Text_CAPTCHA_Driver_Numeral extends Text_CAPTCHA_Driver_Base |
||||
{ |
||||
/** |
||||
* This variable holds the minimum range value default set to "1". |
||||
* |
||||
* @var integer $_minValue The minimum value of the number range. |
||||
*/ |
||||
private $_minValue = 1; |
||||
|
||||
/** |
||||
* This variable holds the maximum range value default set to "50". |
||||
* |
||||
* @var integer $_maxValue The maximum value of the number range. |
||||
*/ |
||||
private $_maxValue = 50; |
||||
|
||||
/** |
||||
* The valid operators to use in the numeral captcha. We could use / and * but |
||||
* not yet. |
||||
* |
||||
* @var array $_operators The operations for the captcha. |
||||
*/ |
||||
private $_operators = array('-', '+'); |
||||
|
||||
/** |
||||
* This variable is basically the operation that we're going to be using in the |
||||
* numeral captcha we are about to generate. |
||||
* |
||||
* @var string $_operator The operation's operator to use. |
||||
*/ |
||||
private $_operator = ''; |
||||
|
||||
/** |
||||
* This variable holds the first number of the numeral operation we are about to |
||||
* generate. |
||||
* |
||||
* @var integer $_firstNumber The first number of the operation. |
||||
*/ |
||||
private $_firstNumber = 0; |
||||
|
||||
/** |
||||
* This variable holds the value of the second variable of the operation we are |
||||
* about to generate for the captcha. |
||||
* |
||||
* @var integer $_secondNumber The second number of the operation. |
||||
*/ |
||||
private $_secondNumber = 0; |
||||
|
||||
/** |
||||
* Initialize numeric CAPTCHA. |
||||
* |
||||
* @param array $options CAPTCHA options with these keys:<br> |
||||
* minValue minimum value<br> |
||||
* maxValue maximum value |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function initDriver($options = array()) |
||||
{ |
||||
if (isset($options['minValue'])) { |
||||
$this->_minValue = (int)$options['minValue']; |
||||
} else { |
||||
$this->_minValue = 1; |
||||
} |
||||
if (isset($options['maxValue'])) { |
||||
$this->_maxValue = (int)$options['maxValue']; |
||||
} else { |
||||
$this->_maxValue = 50; |
||||
} |
||||
if (isset($options['operator'])) { |
||||
$this->_operator = $options['operator']; |
||||
} else { |
||||
$this->_operator = ''; |
||||
} |
||||
if (isset($options['firstValue'])) { |
||||
$this->_firstNumber = (int)$options['firstValue']; |
||||
} else { |
||||
$this->_firstNumber = 0; |
||||
} |
||||
if (isset($options['secondValue'])) { |
||||
$this->_secondNumber = (int)$options['secondValue']; |
||||
} else { |
||||
$this->_secondNumber = 0; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create the CAPTCHA (the numeral expression). |
||||
* |
||||
* This function determines a random numeral expression and set the associated |
||||
* class properties. |
||||
* |
||||
* @return void |
||||
* @see _generateFirstNumber() |
||||
* @see _generateSecondNumber() |
||||
* @see _generateOperator() |
||||
* @see _generateOperation() |
||||
*/ |
||||
public function createCAPTCHA() |
||||
{ |
||||
if ($this->_firstNumber == 0) { |
||||
$this->_firstNumber = $this->_generateNumber(); |
||||
} |
||||
if ($this->_secondNumber == 0) { |
||||
$this->_secondNumber = $this->_generateNumber(); |
||||
} |
||||
if (empty($this->_operator)) { |
||||
$this->_operator = $this->_operators[array_rand($this->_operators)]; |
||||
} |
||||
$this->_generateOperation(); |
||||
} |
||||
|
||||
/** |
||||
* Set operation. |
||||
* |
||||
* This variable sets the operation variable by taking the firstNumber, |
||||
* secondNumber and operator. |
||||
* |
||||
* @return void |
||||
* @see _operation |
||||
* @see _firstNumber |
||||
* @see _operator |
||||
* @see _secondNumber |
||||
*/ |
||||
private function _setOperation() |
||||
{ |
||||
$this->setCaptcha( |
||||
$this->_firstNumber . ' ' . $this->_operator . ' ' . $this->_secondNumber |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Generate a number. |
||||
* |
||||
* This function takes the parameters that are in the $this->_maxValue and |
||||
* $this->_minValue and get the random number from them using mt_rand(). |
||||
* |
||||
* @return integer Random value between _minValue and _maxValue |
||||
* @see _minValue |
||||
* @see _maxValue |
||||
*/ |
||||
private function _generateNumber() |
||||
{ |
||||
return mt_rand($this->_minValue, $this->_maxValue); |
||||
} |
||||
|
||||
/** |
||||
* Adds values. |
||||
* |
||||
* This function will add the firstNumber and the secondNumber value and then |
||||
* call setAnswer to set the answer value. |
||||
* |
||||
* @return void |
||||
* @see _firstNumber |
||||
* @see _secondNumber |
||||
* @see _setAnswer() |
||||
*/ |
||||
private function _doAdd() |
||||
{ |
||||
$phrase = $this->_firstNumber + $this->_secondNumber; |
||||
$this->setPhrase($phrase); |
||||
} |
||||
|
||||
/** |
||||
* Does a subtract on the values. |
||||
* |
||||
* This function executes a subtraction on the firstNumber and the secondNumber |
||||
* to then call $this->setAnswer to set the answer value. |
||||
* |
||||
* If the _firstNumber value is smaller than the _secondNumber value then we |
||||
* regenerate the first number and regenerate the operation. |
||||
* |
||||
* @return void |
||||
* @see _firstNumber |
||||
* @see _secondNumber |
||||
* @see _setOperation() |
||||
* @see Text_CAPTCHA::setPhrase() |
||||
*/ |
||||
private function _doSubtract() |
||||
{ |
||||
$first = $this->_firstNumber; |
||||
$second = $this->_secondNumber; |
||||
|
||||
/** |
||||
* Check if firstNumber is smaller than secondNumber |
||||
*/ |
||||
if ($first < $second) { |
||||
$this->_firstNumber = $second; |
||||
$this->_secondNumber = $first; |
||||
$this->_setOperation(); |
||||
} |
||||
|
||||
$phrase = $this->_firstNumber - $this->_secondNumber; |
||||
$this->setPhrase($phrase); |
||||
} |
||||
|
||||
/** |
||||
* Generate the operation |
||||
* |
||||
* This function will call the _setOperation() function to set the operation |
||||
* string that will be called to display the operation, and call the function |
||||
* necessary depending on which operation is set by this->operator. |
||||
* |
||||
* @return void |
||||
* @see _setOperation() |
||||
* @see _operator |
||||
* @see _doAdd() |
||||
* @see _doSubtract() |
||||
*/ |
||||
private function _generateOperation() |
||||
{ |
||||
$this->_setOperation(); |
||||
switch ($this->_operator) { |
||||
case '+': |
||||
$this->_doAdd(); |
||||
break; |
||||
case '-': |
||||
$this->_doSubtract(); |
||||
break; |
||||
default: |
||||
$this->_operator = "+"; |
||||
$this->_setOperation(); |
||||
$this->_doAdd(); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create random CAPTCHA phrase. This method is a placeholder, since the equation |
||||
* is created in createCAPTCHA() |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function createPhrase() |
||||
{ |
||||
$this->setCaptcha(null); |
||||
} |
||||
} |
@ -0,0 +1,127 @@ |
||||
<?php |
||||
/** |
||||
* Text_CAPTCHA_Driver_Word - Text_CAPTCHA driver word CAPTCHAs |
||||
* Class to create a textual Turing test |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Tobias Schlitt <schlitt@php.net> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
require_once 'Text/CAPTCHA/Driver/Base.php'; |
||||
require_once 'Numbers/Words.php'; |
||||
/** |
||||
* Require Numbers_Words class for generating the text. |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Tobias Schlitt <schlitt@php.net> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
class Text_CAPTCHA_Driver_Word extends Text_CAPTCHA_Driver_Base |
||||
{ |
||||
/** |
||||
* Phrase length. |
||||
* This variable holds the length of the Word. |
||||
* |
||||
* @var integer |
||||
*/ |
||||
private $_length; |
||||
|
||||
/** |
||||
* Numbers_Words mode. |
||||
* This variable holds the mode for Numbers_Words. |
||||
* |
||||
* @var String |
||||
*/ |
||||
private $_mode; |
||||
|
||||
/** |
||||
* Locale |
||||
* This variable holds the locale for Numbers_Words |
||||
* |
||||
* @var string |
||||
*/ |
||||
private $_locale; |
||||
|
||||
/** |
||||
* Initializes the new Text_CAPTCHA_Driver_Word object. |
||||
* |
||||
* @param array $options CAPTCHA options with these keys:<br> |
||||
* phrase The "secret word" of the CAPTCHA<br> |
||||
* length The number of characters in the phrase<br> |
||||
* locale The locale for Numbers_Words<br> |
||||
* mode The mode for Numbers_Words |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function initDriver($options = array()) |
||||
{ |
||||
if (isset($options['length']) && is_int($options['length'])) { |
||||
$this->_length = $options['length']; |
||||
} else { |
||||
$this->_length = 4; |
||||
} |
||||
if (isset($options['phrase']) && !empty($options['phrase'])) { |
||||
$this->setPhrase((string)$options['phrase']); |
||||
} else { |
||||
$this->createPhrase(); |
||||
} |
||||
if (isset($options['mode']) && !empty($options['mode'])) { |
||||
$this->_mode = $options['mode']; |
||||
} else { |
||||
$this->_mode = 'single'; |
||||
} |
||||
if (isset($options['locale']) && !empty($options['locale'])) { |
||||
$this->_locale = $options['locale']; |
||||
} else { |
||||
$this->_locale = 'en_US'; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create random CAPTCHA phrase, "Word edition" (numbers only). |
||||
* This method creates a random phrase |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function createPhrase() |
||||
{ |
||||
$phrase = new Text_Password(); |
||||
$this->setPhrase( |
||||
$phrase->create( |
||||
$this->_length, 'unpronounceable', 'numeric' |
||||
) |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Place holder for the real _createCAPTCHA() method |
||||
* used by extended classes to generate CAPTCHA from phrase |
||||
* |
||||
* @return void |
||||
*/ |
||||
public function createCAPTCHA() |
||||
{ |
||||
$res = ''; |
||||
$numberWords = new Numbers_Words(); |
||||
$phrase = $this->getPhrase(); |
||||
if ($this->_mode == 'single') { |
||||
$phraseArr = str_split($phrase); |
||||
for ($i = 0; $i < strlen($phrase); $i++) { |
||||
$res .= ' ' . $numberWords->toWords($phraseArr[$i], $this->_locale); |
||||
} |
||||
} else { |
||||
$res = $numberWords->toWords($phrase, $this->_locale); |
||||
} |
||||
$this->setCaptcha($res); |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
<?php |
||||
/** |
||||
* Exception for Text_CAPTCHA |
||||
* |
||||
* PHP version 5 |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Christian Weiske <cweiske@php.net> |
||||
* @author Christian Wenz <wenz@php.net> |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
require_once 'PEAR/Exception.php'; |
||||
/** |
||||
* Exception for Text_CAPTCHA |
||||
* |
||||
* @category Text |
||||
* @package Text_CAPTCHA |
||||
* @author Michael Cramer <michael@bigmichi1.de> |
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
||||
* @link http://pear.php.net/package/Text_CAPTCHA |
||||
*/ |
||||
class Text_CAPTCHA_Exception extends PEAR_Exception |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,533 @@ |
||||
<?php |
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
||||
|
||||
/** |
||||
* Class to create passwords |
||||
* |
||||
* PHP versions 4 and 5 |
||||
* |
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license |
||||
* that is available through the world-wide-web at the following URI: |
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
||||
* the PHP License and are unable to obtain it through the web, please |
||||
* send a note to license@php.net so we can mail you a copy immediately. |
||||
* |
||||
* @category Text |
||||
* @package Text_Password |
||||
* @author Martin Jansen <mj@php.net> |
||||
* @author Olivier Vanhoucke <olivier@php.net> |
||||
* @copyright 2004-2005 Martin Jansen, Olivier Vanhoucke |
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
||||
* @version CVS: $Id: Password.php,v 1.18 2008/11/30 13:38:56 mj Exp $ |
||||
* @link http://pear.php.net/package/Text_Password |
||||
*/ |
||||
|
||||
/** |
||||
* Number of possible characters in the password |
||||
*/ |
||||
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 0; |
||||
|
||||
/** |
||||
* Main class for the Text_Password package |
||||
* |
||||
* @category Text |
||||
* @package Text_Password |
||||
* @author Martin Jansen <mj@php.net> |
||||
* @author Olivier Vanhoucke <olivier@php.net> |
||||
* @copyright 2004-2005 Martin Jansen, Olivier Vanhoucke |
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
||||
* @version Release: @package_version@ |
||||
* @link http://pear.php.net/package/Text_Password |
||||
*/ |
||||
class Text_Password { |
||||
|
||||
/** |
||||
* Create a single password. |
||||
* |
||||
* @access public |
||||
* @param integer Length of the password. |
||||
* @param string Type of password (pronounceable, unpronounceable) |
||||
* @param string Character which could be use in the |
||||
* unpronounceable password ex : 'ABCDEFG' |
||||
* or numeric, alphabetical or alphanumeric. |
||||
* @return string Returns the generated password. |
||||
*/ |
||||
function create($length = 10, $type = 'pronounceable', $chars = '') |
||||
{ |
||||
switch ($type) { |
||||
case 'unpronounceable' : |
||||
return Text_Password::_createUnpronounceable($length, $chars); |
||||
|
||||
case 'pronounceable' : |
||||
default : |
||||
return Text_Password::_createPronounceable($length); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create multiple, different passwords |
||||
* |
||||
* Method to create a list of different passwords which are |
||||
* all different. |
||||
* |
||||
* @access public |
||||
* @param integer Number of different password |
||||
* @param integer Length of the password |
||||
* @param string Type of password (pronounceable, unpronounceable) |
||||
* @param string Character which could be use in the |
||||
* unpronounceable password ex : 'A,B,C,D,E,F,G' |
||||
* or numeric, alphabetical or alphanumeric. |
||||
* @return array Array containing the passwords |
||||
*/ |
||||
function createMultiple($number, $length = 10, $type = 'pronounceable', $chars = '') |
||||
{ |
||||
$passwords = array(); |
||||
|
||||
while ($number > 0) { |
||||
while (true) { |
||||
$password = Text_Password::create($length, $type, $chars); |
||||
if (!in_array($password, $passwords)) { |
||||
$passwords[] = $password; |
||||
break; |
||||
} |
||||
} |
||||
$number--; |
||||
} |
||||
return $passwords; |
||||
} |
||||
|
||||
/** |
||||
* Create password from login |
||||
* |
||||
* Method to create password from login |
||||
* |
||||
* @access public |
||||
* @param string Login |
||||
* @param string Type |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function createFromLogin($login, $type, $key = 0) |
||||
{ |
||||
switch ($type) { |
||||
case 'reverse': |
||||
return strrev($login); |
||||
|
||||
case 'shuffle': |
||||
return Text_Password::_shuffle($login); |
||||
|
||||
case 'xor': |
||||
return Text_Password::_xor($login, $key); |
||||
|
||||
case 'rot13': |
||||
return str_rot13($login); |
||||
|
||||
case 'rotx': |
||||
return Text_Password::_rotx($login, $key); |
||||
|
||||
case 'rotx++': |
||||
return Text_Password::_rotxpp($login, $key); |
||||
|
||||
case 'rotx--': |
||||
return Text_Password::_rotxmm($login, $key); |
||||
|
||||
case 'ascii_rotx': |
||||
return Text_Password::_asciiRotx($login, $key); |
||||
|
||||
case 'ascii_rotx++': |
||||
return Text_Password::_asciiRotxpp($login, $key); |
||||
|
||||
case 'ascii_rotx--': |
||||
return Text_Password::_asciiRotxmm($login, $key); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create multiple, different passwords from an array of login |
||||
* |
||||
* Method to create a list of different password from login |
||||
* |
||||
* @access public |
||||
* @param array Login |
||||
* @param string Type |
||||
* @param integer Key |
||||
* @return array Array containing the passwords |
||||
*/ |
||||
function createMultipleFromLogin($login, $type, $key = 0) |
||||
{ |
||||
$passwords = array(); |
||||
$number = count($login); |
||||
$save = $number; |
||||
|
||||
while ($number > 0) { |
||||
while (true) { |
||||
$password = Text_Password::createFromLogin($login[$save - $number], $type, $key); |
||||
if (!in_array($password, $passwords)) { |
||||
$passwords[] = $password; |
||||
break; |
||||
} |
||||
} |
||||
$number--; |
||||
} |
||||
return $passwords; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function _xor($login, $key) |
||||
{ |
||||
$tmp = ''; |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++) { |
||||
$next = ord($login{$i}) ^ $key; |
||||
if ($next > 255) { |
||||
$next -= 255; |
||||
} elseif ($next < 0) { |
||||
$next += 255; |
||||
} |
||||
$tmp .= chr($next); |
||||
} |
||||
|
||||
return $tmp; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* lowercase only |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function _rotx($login, $key) |
||||
{ |
||||
$tmp = ''; |
||||
$login = strtolower($login); |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++) { |
||||
if ((ord($login{$i}) >= 97) && (ord($login{$i}) <= 122)) { // 65, 90 for uppercase |
||||
$next = ord($login{$i}) + $key; |
||||
if ($next > 122) { |
||||
$next -= 26; |
||||
} elseif ($next < 97) { |
||||
$next += 26; |
||||
} |
||||
$tmp .= chr($next); |
||||
} else { |
||||
$tmp .= $login{$i}; |
||||
} |
||||
} |
||||
|
||||
return $tmp; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* lowercase only |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function _rotxpp($login, $key) |
||||
{ |
||||
$tmp = ''; |
||||
$login = strtolower($login); |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++, $key++) { |
||||
if ((ord($login{$i}) >= 97) && (ord($login{$i}) <= 122)) { // 65, 90 for uppercase |
||||
$next = ord($login{$i}) + $key; |
||||
if ($next > 122) { |
||||
$next -= 26; |
||||
} elseif ($next < 97) { |
||||
$next += 26; |
||||
} |
||||
$tmp .= chr($next); |
||||
} else { |
||||
$tmp .= $login{$i}; |
||||
} |
||||
} |
||||
|
||||
return $tmp; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* lowercase only |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function _rotxmm($login, $key) |
||||
{ |
||||
$tmp = ''; |
||||
$login = strtolower($login); |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++, $key--) { |
||||
if ((ord($login{$i}) >= 97) && (ord($login{$i}) <= 122)) { // 65, 90 for uppercase |
||||
$next = ord($login{$i}) + $key; |
||||
if ($next > 122) { |
||||
$next -= 26; |
||||
} elseif ($next < 97) { |
||||
$next += 26; |
||||
} |
||||
$tmp .= chr($next); |
||||
} else { |
||||
$tmp .= $login{$i}; |
||||
} |
||||
} |
||||
|
||||
return $tmp; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function _asciiRotx($login, $key) |
||||
{ |
||||
$tmp = ''; |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++) { |
||||
$next = ord($login{$i}) + $key; |
||||
if ($next > 255) { |
||||
$next -= 255; |
||||
} elseif ($next < 0) { |
||||
$next += 255; |
||||
} |
||||
switch ($next) { // delete white space |
||||
case 0x09: |
||||
case 0x20: |
||||
case 0x0A: |
||||
case 0x0D: |
||||
$next++; |
||||
} |
||||
$tmp .= chr($next); |
||||
} |
||||
|
||||
return $tmp; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function _asciiRotxpp($login, $key) |
||||
{ |
||||
$tmp = ''; |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++, $key++) { |
||||
$next = ord($login{$i}) + $key; |
||||
if ($next > 255) { |
||||
$next -= 255; |
||||
} elseif ($next < 0) { |
||||
$next += 255; |
||||
} |
||||
switch ($next) { // delete white space |
||||
case 0x09: |
||||
case 0x20: |
||||
case 0x0A: |
||||
case 0x0D: |
||||
$next++; |
||||
} |
||||
$tmp .= chr($next); |
||||
} |
||||
|
||||
return $tmp; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @param integer Key |
||||
* @return string |
||||
*/ |
||||
function _asciiRotxmm($login, $key) |
||||
{ |
||||
$tmp = ''; |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++, $key--) { |
||||
$next = ord($login{$i}) + $key; |
||||
if ($next > 255) { |
||||
$next -= 255; |
||||
} elseif ($next < 0) { |
||||
$next += 255; |
||||
} |
||||
switch ($next) { // delete white space |
||||
case 0x09: |
||||
case 0x20: |
||||
case 0x0A: |
||||
case 0x0D: |
||||
$next++; |
||||
} |
||||
$tmp .= chr($next); |
||||
} |
||||
|
||||
return $tmp; |
||||
} |
||||
|
||||
/** |
||||
* Helper method to create password |
||||
* |
||||
* Method to create a password from a login |
||||
* |
||||
* @access private |
||||
* @param string Login |
||||
* @return string |
||||
*/ |
||||
function _shuffle($login) |
||||
{ |
||||
$tmp = array(); |
||||
|
||||
for ($i = 0; $i < strlen($login); $i++) { |
||||
$tmp[] = $login{$i}; |
||||
} |
||||
|
||||
shuffle($tmp); |
||||
|
||||
return implode($tmp, ''); |
||||
} |
||||
|
||||
/** |
||||
* Create pronounceable password |
||||
* |
||||
* This method creates a string that consists of |
||||
* vowels and consonats. |
||||
* |
||||
* @access private |
||||
* @param integer Length of the password |
||||
* @return string Returns the password |
||||
*/ |
||||
function _createPronounceable($length) |
||||
{ |
||||
|
||||
$retVal = ''; |
||||
|
||||
/** |
||||
* List of vowels and vowel sounds |
||||
*/ |
||||
$v = array('a', 'e', 'i', 'o', 'u', 'ae', 'ou', 'io', |
||||
'ea', 'ou', 'ia', 'ai' |
||||
); |
||||
|
||||
/** |
||||
* List of consonants and consonant sounds |
||||
*/ |
||||
$c = array('b', 'c', 'd', 'g', 'h', 'j', 'k', 'l', 'm', |
||||
'n', 'p', 'r', 's', 't', 'u', 'v', 'w', |
||||
'tr', 'cr', 'fr', 'dr', 'wr', 'pr', 'th', |
||||
'ch', 'ph', 'st', 'sl', 'cl' |
||||
); |
||||
|
||||
$v_count = 12; |
||||
$c_count = 29; |
||||
|
||||
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = $v_count + $c_count; |
||||
|
||||
for ($i = 0; $i < $length; $i++) { |
||||
$retVal .= $c[mt_rand(0, $c_count-1)] . $v[mt_rand(0, $v_count-1)]; |
||||
} |
||||
|
||||
return substr($retVal, 0, $length); |
||||
} |
||||
|
||||
/** |
||||
* Create unpronounceable password |
||||
* |
||||
* This method creates a random unpronounceable password |
||||
* |
||||
* @access private |
||||
* @param integer Length of the password |
||||
* @param string Character which could be use in the |
||||
* unpronounceable password ex : 'ABCDEFG' |
||||
* or numeric, alphabetical or alphanumeric. |
||||
* @return string Returns the password |
||||
*/ |
||||
function _createUnpronounceable($length, $chars) |
||||
{ |
||||
$password = ''; |
||||
|
||||
/** |
||||
* List of character which could be use in the password |
||||
*/ |
||||
switch($chars) { |
||||
|
||||
case 'alphanumeric': |
||||
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
||||
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 62; |
||||
break; |
||||
|
||||
case 'alphabetical': |
||||
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; |
||||
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 52; |
||||
break; |
||||
|
||||
case 'numeric': |
||||
$chars = '0123456789'; |
||||
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 10; |
||||
break; |
||||
|
||||
case '': |
||||
$chars = '_#@%&ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
||||
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 67; |
||||
break; |
||||
|
||||
default: |
||||
/** |
||||
* Some characters shouldn't be used |
||||
*/ |
||||
$chars = trim($chars); |
||||
$chars = str_replace(array('+', '|', '$', '^', '/', '\\', ','), '', $chars); |
||||
|
||||
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = strlen($chars); |
||||
} |
||||
|
||||
/** |
||||
* Generate password |
||||
*/ |
||||
for ($i = 0; $i < $length; $i++) { |
||||
$num = mt_rand(0, $GLOBALS['_Text_Password_NumberOfPossibleCharacters'] - 1); |
||||
$password .= $chars{$num}; |
||||
} |
||||
|
||||
/** |
||||
* Return password |
||||
*/ |
||||
return $password; |
||||
} |
||||
} |
||||
?> |
Loading…
Reference in new issue