Adding pear captcha code from source.

1.9.x
Julio Montoya 11 years ago
parent b8aaab9b72
commit f817d5da57
  1. 267
      main/inc/lib/pear/HTML/QuickForm/CAPTCHA.php
  2. 93
      main/inc/lib/pear/HTML/QuickForm/CAPTCHA/Equation.php
  3. 126
      main/inc/lib/pear/HTML/QuickForm/CAPTCHA/Figlet.php
  4. 165
      main/inc/lib/pear/HTML/QuickForm/CAPTCHA/Image.php
  5. 90
      main/inc/lib/pear/HTML/QuickForm/CAPTCHA/Word.php
  6. 152
      main/inc/lib/pear/Text/CAPTCHA.php
  7. 56
      main/inc/lib/pear/Text/CAPTCHA/Driver.php
  8. 97
      main/inc/lib/pear/Text/CAPTCHA/Driver/Base.php
  9. 215
      main/inc/lib/pear/Text/CAPTCHA/Driver/Equation.php
  10. 233
      main/inc/lib/pear/Text/CAPTCHA/Driver/Figlet.php
  11. 286
      main/inc/lib/pear/Text/CAPTCHA/Driver/Image.php
  12. 268
      main/inc/lib/pear/Text/CAPTCHA/Driver/Numeral.php
  13. 127
      main/inc/lib/pear/Text/CAPTCHA/Driver/Word.php
  14. 28
      main/inc/lib/pear/Text/CAPTCHA/Exception.php
  15. 533
      main/inc/lib/pear/Text/Password.php

@ -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…
Cancel
Save