home *** CD-ROM | disk | FTP | other *** search
- <?php
- /**
- * Equation driver for Text_CAPTCHA.
- * Returns simple equations as string, e.g. "9 - 2"
- *
- * @author Christian Weiske <cweiske@php.net>
- * @author Christian Wenz <wenz@php.net>
- */
- require_once 'Text/CAPTCHA.php';
-
- class Text_CAPTCHA_Driver_Equation extends Text_CAPTCHA
- {
- /**
- * 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.
- *
- * @access protected
- * @var array
- */
- var $_operators = array(
- '%s * %s',
- '%s + %s',
- '%s - %s',
- 'min(%s, %s)',
- 'max(%s, %s)'
- );
-
- /**
- * The equation to solve.
- *
- * @access protected
- * @var string
- */
- var $_equation = null;
-
- /**
- * Minimal number to use in an equation.
- *
- * @access protected
- * @var int
- */
- var $_min = 1;
-
- /**
- * Maximum number to use in an equation.
- *
- * @access protected
- * @var int
- */
- var $_max = 10;
-
- /**
- * Whether numbers shall be converted to text
- *
- * @access protected
- * @var bool
- */
- var $_numbersToText = false;
-
- /**
- * Complexity of the generated equations.
- * 1 - simple ones such as "1 + 10"
- * 2 - harder ones such as "(3-2)*(min(5,6))"
- *
- * @access protected
- * @var int
- */
- var $_severity = 1;
-
- /**
- * Last error
- *
- * @access protected
- * @var PEAR_Error
- */
- var $_error = null;
-
-
- /**
- * Initialize the driver.
- *
- * @access public
- * @return true on success, PEAR_Error on error.
- */
- function init($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['severity'])) {
- $this->_severity = (int)$options['severity'];
- } else {
- $this->_severity = 1;
- }
-
- if ($this->_numbersToText) {
- include_once 'Numbers/Words.php';
- if (!class_exists('Numbers_Words')) {
- $this->_error = PEAR::raiseError('Number_Words package required', true);
- return $this->_error;
- }
- }
-
- return $this->_createPhrase();
- }
-
- /**
- * Create random CAPTCHA equation.
- *
- * This method creates a random equation. The equation is
- * stored in $this->_equation, the solution in $this->_phrase.
- *
- * @access protected
- * @return mixed true on success, PEAR_Error on error
- */
- function _createPhrase()
- {
- switch ($this->_severity) {
- case 1:
- list($this->_equation, $this->_phrase) = $this->_createSimpleEquation();
- break;
-
- case 2:
- list($eq1, $sol1) = $this->_createSimpleEquation();
- list($eq2, $sol2) = $this->_createSimpleEquation();
- $op3 = $this->_operators[rand(0, count($this->_operators) - 1)];
- list($eq3, $this->_phrase) = $this->_solveSimpleEquation($sol1, $sol2, $op3);
- $this->_equation = sprintf($op3, '(' . $eq1 . ')', '(' . $eq2 . ')');
- break;
-
- default:
- $this->_error = PEAR::raiseError('Equation complexity of ' . $this->_severity . ' not supported', true);
- return $this->_error;
- }
- return true;
- }
-
- /**
- * Creates a simple equation of type (number operator number)
- *
- * @access protected
- * @return array Array with equation and solution
- */
- function _createSimpleEquation()
- {
- $one = rand($this->_min, $this->_max);
- $two = rand($this->_min, $this->_max);
- $operator = $this->_operators[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.
- *
- * @access protected
- * @return array Array with equation and solution
- */
- function _solveSimpleEquation($one, $two, $operator)
- {
- $equation = sprintf($operator, $one, $two);
- $code = '$solution=' . $equation . ';';
- eval($code);
-
- if ($this->_numbersToText) {
- $equation = sprintf($operator, Numbers_Words::toWords($one), Numbers_Words::toWords($two));
- }
-
- return array($equation, $solution);
- }
-
- /**
- * Return the solution to the equation.
- *
- * This method returns the CAPTCHA phrase, which is
- * the solution to the equation.
- *
- * @access public
- * @return string secret phrase
- */
- function getPhrase()
- {
- return $this->_phrase;
- }
-
- /**
- * Creates the captcha. This method is a placeholder,
- * since the equation is created in _createPhrase()
- *
- * @access protected
- * @return PEAR_Error
- */
- function _createCAPTCHA() {
- //is already done in _createPhrase();
- }
-
- /**
- * Returns the CAPTCHA (as a string)
- *
- * @access public
- * @return string
- */
- function getCAPTCHA() {
- return $this->_equation;
- }
-
- }//class Text_CAPTCHA_Driver_TextEquation extends Text_CAPTCHA
- ?>