Current File : //opt/RZphp74/includes/Text/CAPTCHA/Numeral.php |
<?php
/**
* Numeral Captcha
*
* PHP version 5
*
* @category Text
* @package Text_CAPTCHA_Numeral
* @author David Coallier <davidc@agoraproduction.com>
* @author Marcelo Araujo <msaraujo@php.net>
* @copyright 2002-2007 Agora Production (http://agoraproduction.com)
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @link http://pear.php.net/package/Text_CAPTCHA_Numeral
*/
require_once 'Text/CAPTCHA/Numeral/NumeralInterface.php';
// {{{ Class Text_CAPTCHA_Numeral
/**
* 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_Numeral
* @author David Coallier <davidc@agoraproduction.com>
* @author Marcelo Araujo <msaraujo@php.net>
* @copyright 2002-2007 Agora Production (http://agoraproduction.com)
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @link http://pear.php.net/package/Text_CAPTCHA_Numeral
*/
class Text_CAPTCHA_Numeral implements Text_CAPTCHA_Numeral_Interface
{
// {{{ Variables
/**
* Minimum range value
*
* This variable holds the minimum range value
* default set to "1"
*
* @var integer $minValue The minimum range value
*/
protected $minValue = '1';
/**
* Maximum range value
*
* This variable holds the maximum range value
* default set to "50"
*
* @var integer $maxValue The maximum value of the number range
*/
protected $maxValue = '50';
/**
* Operators
*
* The valid operators to use
* in the numeral captcha. We could
* use / and * but not yet.
*
* @var array $operators The operations for the captcha
*/
protected $operators = array('+','-');
/**
* Operator to use
*
* 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
*/
protected $operator = '';
/**
* Mathematical Operation
*
* This is the mathematical operation
* that we are displaying to the user.
*
* @var string $operation The math operation
*/
protected $operation = '';
/**
* First number of the operation
*
* This variable holds the first number
* of the numeral operation we are about
* to generate.
*
* @var integer $firstNumber The first number of the operation
*/
protected $firstNumber = '';
/**
* Second Number of the operation
*
* 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
*/
protected $secondNumber = '';
/**
* The operation answer
*
* The answer to the numeral operation
* we are about to do.
*
* @var integer $answer The mathematical operation answer value.
*/
protected $answer;
/**
* A constant that indicates the complexity of mathematical operations
*
* @access public
*
*/
const COMPLEXITY_ELEMENTARY = 1;
/**
* A constant that indicates the complexity of mathematical operations
*
* @access public
*
*/
const COMPLEXITY_HIGH_SCHOOL = 2;
/**
* A constant that indicates the complexity of mathematical operations
*
* @access public
*
*/
const COMPLEXITY_UNIVERSITY = 4;
/**
* Kept for backwards compatibility only; use the short constant.
*
* @deprecated
*/
const TEXT_CAPTCHA_NUMERAL_COMPLEXITY_ELEMENTARY = 1;
/**
* Kept for backwards compatibility only; use the short constant.
*
* @deprecated
*/
const TEXT_CAPTCHA_NUMERAL_COMPLEXITY_HIGH_SCHOOL = 2;
/**
* Kept for backwards compatibility only; use the short constant.
*
* @deprecated
*/
const TEXT_CAPTCHA_NUMERAL_COMPLEXITY_UNIVERSITY = 4;
// }}}
// {{{ Constructor
/**
* Constructor with different levels of mathematical operations sets
*
* @param constant $complexityType How complex the captcha equation shall be.
* See the COMPLEXITY constants.
* @param integer $minValue Minimal value of a number
* @param integer $maxValue Maximal value of a number
*/
public function __construct(
$complexityType = self::COMPLEXITY_ELEMENTARY,
$minValue = 1, $maxValue = 50
) {
$this->prepare($complexityType, $minValue, $maxValue);
}
// }}}
// {{{ protected function setRangeMinimum
/**
* Set Range Minimum value
*
* This function give the developer the ability
* to set the range minimum value so the operations
* can be bigger, smaller, etc.
*
* @param integer $minValue The minimum value
*
* @return void
*/
protected function setRangeMinimum($minValue = '1')
{
$this->minValue = (int)$minValue;
}
// }}}
// {{{ protected function generateFirstNumber
/**
* Sets the first number
*
* This function sets the first number
* of the operation by calling the generateNumber
* function that generates a random number.
*
* @return void
*
* @see $this->firstNumber, $this->generateNumber
*/
protected function generateFirstNumber()
{
$this->setFirstNumber($this->generateNumber());
}
// }}}
// {{{ protected function generateSecondNumber
/**
* Sets second number
*
* This function sets the second number of the
* operation by calling generateNumber()
*
* @return void
*
* @see $this->secondNumber, $this->generateNumber()
*/
protected function generateSecondNumber()
{
$this->setSecondNumber($this->generateNumber());
}
// }}}
// {{{ protected function generateOperator
/**
* Sets the operation operator
*
* This function sets the operation operator by
* getting the array value of an array_rand() of
* the $this->operators() array.
*
* @return void
*
* @see $this->operators, $this->operator
*/
protected function generateOperator()
{
$this->operator = $this->operators[array_rand($this->operators)];
}
// }}}
// {{{ protected function setAnswer
/**
* Sets the answer value
*
* This function will accept the parameters which is
* basically the result of the function we have done
* and it will set $this->answer with it.
*
* @param integer $answerValue The answer value
*
* @return void
*
* @see $this->answer
*/
protected function setAnswer($answerValue)
{
$this->answer = $answerValue;
return $this;
}
// }}}
// {{{ protected function setFirstNumber
/**
* Set First number
*
* This function sets the first number
* to the value passed to the function
*
* @param integer $value The first number value.
*
* @return Text_CAPTCHA_Numeral The self object
*/
protected function setFirstNumber($value)
{
$this->firstNumber = (int)$value;
return $this;
}
// }}}
// {{{ protected function setSecondNumber
/**
* Sets the second number
*
* This function sets the second number
* with the value passed to it.
*
* @param integer $value The second number new value.
*
* @return Text_CAPTCHA_Numeral The self object
*/
protected function setSecondNumber($value)
{
$this->secondNumber = (int)$value;
return $this;
}
// }}}
// {{{ protected function setOperation
/**
* Set "operation" string the user needs to solve.
*
* This variable sets the operation variable
* by taking the firstNumber, secondNumber and operator
*
* @param string $type May be null, or "F" to indicate a factorial operation
*
* @return void
*
* @see $this->operation
*/
protected function setOperation($type = null)
{
if ($type == 'F') {
$this->operation = $this->getFirstNumber() . ' ' . $this->operator;
} else {
$this->operation = $this->getFirstNumber() . ' ' .
$this->operator . ' ' .
$this->getSecondNumber();
}
return $this;
}
// }}}
// {{{ protected function generateNumber
/**
* 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
*/
protected function generateNumber()
{
return mt_rand($this->minValue, $this->maxValue);
}
// }}}
// {{{ protected function doAdd
/**
* Adds values
*
* This function will add the firstNumber and the
* secondNumber value and then call setAnswer to
* set the answer value.
*
* @return void
*
* @see $this->firstNumber, $this->secondNumber, $this->setAnswer()
*/
protected function doAdd()
{
$answer = $this->getFirstNumber() + $this->getSecondNumber();
$this->setAnswer($answer);
}
// }}}
// {{{ protected function doMultiplication
/**
* Do Multiplication
*
* This method will multiply two numbers
*
* @return void
*
* @see $this->firstNumber, $this->secondNumber, $this->setAnswer
*/
protected function doMultiplication()
{
$this->setAnswer($this->getFirstNumber() * $this->getSecondNumber());
}
// }}}
// {{{ protected function doDivision
/**
* Do Division
*
* This function executes a division based on the two
* numbers.
*
* @param integer $firstNumber The first number of the operation.
* This is by default set to null.
* @param integer $secondNumber The second number of the operation
* This is by default set to null.
*
* @return void
*/
protected function doDivision($firstNumber = null, $secondNumber = null)
{
if (is_null($firstNumber)) {
$firstNumber = $this->getFirstNumber();
}
if (is_null($secondNumber)) {
$secondNumber = $this->getSecondNumber();
}
if ($secondNumber == 0) {
++$secondNumber;
$this->doDivision($firstNumber, $secondNumber);
return;
}
if ($firstNumber == 0) {
$this->doDivision(++$firstNumber, $secondNumber);
return;
}
if ($firstNumber % $secondNumber != 0) {
--$firstNumber;
--$secondNumber;
$this->doDivision($firstNumber, $secondNumber);
return;
}
$this->setFirstNumber($firstNumber)
->setSecondNumber($secondNumber)
->setOperation()
->setAnswer($this->getFirstNumber() / $this->getSecondNumber());
}
// }}}
// {{{ protected function doModulus
/**
* Do modulus
*
* This method will do a modulus operation between two numbers
*
* @return void
*
* @see $this->firstNumber, $this->secondNumber, $this->setAnswer()
*/
protected function doModulus()
{
$first = $this->getFirstNumber();
$second = $this->getSecondNumber();
if ($first == $second) {
$this->generateSecondNumber();
$this->doModulus();
return;
}
$this->setAnswer($this->getFirstNumber() % $this->getSecondNumber());
}
// }}}
// {{{ protected function doSubstract
/**
* Does a substract on the values
*
* This function executes a substraction 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 $this->firstNumber, $this->secondNumber, $this->setAnswer()
*/
protected function doSubstract()
{
$first = $this->getFirstNumber();
$second = $this->getSecondNumber();
/**
* Check if firstNumber is smaller than secondNumber
*/
if ($first < $second) {
$this->setFirstNumber($second)
->setSecondNumber($first)
->setOperation();
}
$answer = $this->getFirstNumber() - $this->getSecondNumber();
$this->setAnswer($answer);
}
// }}}
// {{{ protected function doExponentiation
/**
* Does an exponentiation on the values
*
* This function executes an exponentiation
*
* @return void
*
* @see $this->setOperation, $this->getFirstNumber
* $this->getSecondNumber, $this->setAnswer()
*/
protected function doExponentiation()
{
$this->setOperation()
->setAnswer(pow($this->getFirstNumber(), $this->getSecondNumber()));
}
// }}}
// {{{ protected function doFactorial
/**
* Call static factorial method
*
* @return void
*/
protected function doFactorial()
{
$this->setOperation('F')
->setAnswer($this->calculateFactorial($this->getFirstNumber()));
}
// }}}
// {{{ protected function calculateFactorial
/**
* Calculate factorial given an integer number
*
* @param integer $n The factorial to calculate
*
* @return integer The calculated value
*/
protected function calculateFactorial($n)
{
return $n <= 1 ? 1 : $n * $this->calculateFactorial($n - 1);
}
// }}}
// {{{ protected function generateOperation
/**
* 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 $this->setOperation(), $this->operator
*/
protected function generateOperation()
{
$this->setOperation();
switch ($this->operator) {
case '+':
$this->doAdd();
break;
case '-':
$this->doSubstract();
break;
case '*':
$this->doMultiplication();
break;
case '%':
$this->doModulus();
break;
case '/':
$this->doDivision();
break;
case '^':
$this->minValue = 10;
$this->doExponentiation();
break;
case '!':
$this->minValue = 1;
$this->maxValue = 10;
$this->generateFirstNumber();
$this->doFactorial();
break;
default:
$this->doAdd();
break;
}
}
// }}}
// {{{ public function getOperation
/**
* Get operation
*
* This function will get the operation
* string from $this->operation
*
* @return string The operation String
*/
public function getOperation()
{
return $this->operation;
}
// }}}
// {{{ public function getAnswer
/**
* Get the answer value
*
* This function will retrieve the answer
* value from this->answer and return it so
* we can then display it to the user.
*
* @return string The operation answer value.
*/
public function getAnswer()
{
return $this->answer;
}
// }}}
// {{{ public function getFirstNumber
/**
* Get the first number
*
* This function will get the first number
* value from $this->firstNumber
*
* @return integer $this->firstNumber The firstNumber
*/
public function getFirstNumber()
{
return $this->firstNumber;
}
// }}}
// {{{ public function getSecondNumber
/**
* Get the second number value
*
* This function will return the second number value
*
* @return integer $this->secondNumber The second number
*/
public function getSecondNumber()
{
return $this->secondNumber;
}
// }}}
// {{{ public function prepare
/**
* prepare class with the values
*
* This function prepare configure the values to
* generate the captcha
*
* @param constant $complexityType How complex the captcha equation shall be.
* See the COMPLEXITY constants.
* @param integer $minValue Minimal value of a number
* @param integer $maxValue Maximal value of a number
*
* @return void
*/
public function prepare($complexityType, $minValue, $maxValue)
{
$this->minValue = (int)$minValue;
$this->maxValue = (int)$maxValue;
switch ($complexityType) {
case self::COMPLEXITY_HIGH_SCHOOL:
$this->operators[] = '*';
if ($this->maxValue < 70) {
$this->maxValue = '70';
}
break;
case self::COMPLEXITY_UNIVERSITY:
$this->operators[] = '*';
$this->operators[] = '%';
$this->operators[] = '/';
$this->operators[] = '^';
$this->operators[] = '!';
if ($this->maxValue < 100) {
$this->maxValue = '100';
}
break;
case self::COMPLEXITY_ELEMENTARY:
default:
break;
}
$this->generateFirstNumber();
$this->generateSecondNumber();
$this->generateOperator();
$this->generateOperation();
}
// }}}
}
// }}}