<?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);
}
}
Copyright 2K16 - 2K18 Indonesian Hacker Rulez