You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
424 lines
9.7 KiB
424 lines
9.7 KiB
<?php |
|
/** |
|
* Zend Framework |
|
* |
|
* LICENSE |
|
* |
|
* This source file is subject to the new BSD license that is bundled |
|
* with this package in the file LICENSE.txt. |
|
* It is also available through the world-wide-web at this URL: |
|
* http://framework.zend.com/license/new-bsd |
|
* If you did not receive a copy of the license and are unable to |
|
* obtain it through the world-wide-web, please send an email |
|
* to license@zend.com so we can send you a copy immediately. |
|
* |
|
* @category Zend |
|
* @package Zend_Captcha |
|
* @subpackage Adapter |
|
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) |
|
* @license http://framework.zend.com/license/new-bsd New BSD License |
|
*/ |
|
|
|
/** @see Zend_Captcha_Base */ |
|
require_once 'Zend/Captcha/Base.php'; |
|
|
|
/** @see Zend_Crypt_Math */ |
|
require_once 'Zend/Crypt/Math.php'; |
|
|
|
/** |
|
* Word-based captcha adapter |
|
* |
|
* Generates random word which user should recognise |
|
* |
|
* @category Zend |
|
* @package Zend_Captcha |
|
* @subpackage Adapter |
|
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) |
|
* @license http://framework.zend.com/license/new-bsd New BSD License |
|
* @version $Id$ |
|
*/ |
|
abstract class Zend_Captcha_Word extends Zend_Captcha_Base |
|
{ |
|
/**#@+ |
|
* @var array Character sets |
|
*/ |
|
static public $V = array("a", "e", "i", "o", "u", "y"); |
|
static public $VN = array("a", "e", "i", "o", "u", "y","2","3","4","5","6","7","8","9"); |
|
static public $C = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z"); |
|
static public $CN = array("b","c","d","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","z","2","3","4","5","6","7","8","9"); |
|
/**#@-*/ |
|
|
|
/** |
|
* Random session ID |
|
* |
|
* @var string |
|
*/ |
|
protected $_id; |
|
|
|
/** |
|
* Generated word |
|
* |
|
* @var string |
|
*/ |
|
protected $_word; |
|
|
|
/** |
|
* Session |
|
* |
|
* @var Zend_Session_Namespace |
|
*/ |
|
protected $_session; |
|
|
|
/** |
|
* Class name for sessions |
|
* |
|
* @var string |
|
*/ |
|
protected $_sessionClass = 'Zend_Session_Namespace'; |
|
|
|
/** |
|
* Should the numbers be used or only letters |
|
* |
|
* @var boolean |
|
*/ |
|
protected $_useNumbers = true; |
|
|
|
/** |
|
* Should both cases be used or only lowercase |
|
* |
|
* @var boolean |
|
*/ |
|
// protected $_useCase = false; |
|
|
|
/** |
|
* Session lifetime for the captcha data |
|
* |
|
* @var integer |
|
*/ |
|
protected $_timeout = 300; |
|
|
|
/** |
|
* Should generate() keep session or create a new one? |
|
* |
|
* @var boolean |
|
*/ |
|
protected $_keepSession = false; |
|
|
|
/**#@+ |
|
* Error codes |
|
*/ |
|
const MISSING_VALUE = 'missingValue'; |
|
const MISSING_ID = 'missingID'; |
|
const BAD_CAPTCHA = 'badCaptcha'; |
|
/**#@-*/ |
|
|
|
/** |
|
* Error messages |
|
* @var array |
|
*/ |
|
protected $_messageTemplates = array( |
|
self::MISSING_VALUE => 'Empty captcha value', |
|
self::MISSING_ID => 'Captcha ID field is missing', |
|
self::BAD_CAPTCHA => 'Captcha value is wrong', |
|
); |
|
|
|
/** |
|
* Length of the word to generate |
|
* |
|
* @var integer |
|
*/ |
|
protected $_wordlen = 8; |
|
|
|
/** |
|
* Retrieve session class to utilize |
|
* |
|
* @return string |
|
*/ |
|
public function getSessionClass() |
|
{ |
|
return $this->_sessionClass; |
|
} |
|
|
|
/** |
|
* Set session class for persistence |
|
* |
|
* @param string $_sessionClass |
|
* @return Zend_Captcha_Word |
|
*/ |
|
public function setSessionClass($_sessionClass) |
|
{ |
|
$this->_sessionClass = $_sessionClass; |
|
return $this; |
|
} |
|
|
|
/** |
|
* Retrieve word length to use when genrating captcha |
|
* |
|
* @return integer |
|
*/ |
|
public function getWordlen() |
|
{ |
|
return $this->_wordlen; |
|
} |
|
|
|
/** |
|
* Set word length of captcha |
|
* |
|
* @param integer $wordlen |
|
* @return Zend_Captcha_Word |
|
*/ |
|
public function setWordlen($wordlen) |
|
{ |
|
$this->_wordlen = $wordlen; |
|
return $this; |
|
} |
|
|
|
/** |
|
* Retrieve captcha ID |
|
* |
|
* @return string |
|
*/ |
|
public function getId() |
|
{ |
|
if (null === $this->_id) { |
|
$this->_setId($this->_generateRandomId()); |
|
} |
|
return $this->_id; |
|
} |
|
|
|
/** |
|
* Set captcha identifier |
|
* |
|
* @param string $id |
|
* @return Zend_Captcha_Word |
|
*/ |
|
protected function _setId($id) |
|
{ |
|
$this->_id = $id; |
|
return $this; |
|
} |
|
|
|
/** |
|
* Set timeout for session token |
|
* |
|
* @param int $ttl |
|
* @return Zend_Captcha_Word |
|
*/ |
|
public function setTimeout($ttl) |
|
{ |
|
$this->_timeout = (int) $ttl; |
|
return $this; |
|
} |
|
|
|
/** |
|
* Get session token timeout |
|
* |
|
* @return int |
|
*/ |
|
public function getTimeout() |
|
{ |
|
return $this->_timeout; |
|
} |
|
|
|
/** |
|
* Sets if session should be preserved on generate() |
|
* |
|
* @param bool $keepSession Should session be kept on generate()? |
|
* @return Zend_Captcha_Word |
|
*/ |
|
public function setKeepSession($keepSession) |
|
{ |
|
$this->_keepSession = $keepSession; |
|
return $this; |
|
} |
|
|
|
/** |
|
* Numbers should be included in the pattern? |
|
* |
|
* @return bool |
|
*/ |
|
public function getUseNumbers() |
|
{ |
|
return $this->_useNumbers; |
|
} |
|
|
|
/** |
|
* Set if numbers should be included in the pattern |
|
* |
|
* @param bool $_useNumbers numbers should be included in the pattern? |
|
* @return Zend_Captcha_Word |
|
*/ |
|
public function setUseNumbers($_useNumbers) |
|
{ |
|
$this->_useNumbers = $_useNumbers; |
|
return $this; |
|
} |
|
|
|
/** |
|
* Get session object |
|
* |
|
* @return Zend_Session_Namespace |
|
*/ |
|
public function getSession() |
|
{ |
|
if (!isset($this->_session) || (null === $this->_session)) { |
|
$id = $this->getId(); |
|
if (!class_exists($this->_sessionClass)) { |
|
require_once 'Zend/Loader.php'; |
|
Zend_Loader::loadClass($this->_sessionClass); |
|
} |
|
$this->_session = new $this->_sessionClass('Zend_Form_Captcha_' . $id); |
|
$this->_session->setExpirationHops(1, null, true); |
|
$this->_session->setExpirationSeconds($this->getTimeout()); |
|
} |
|
return $this->_session; |
|
} |
|
|
|
/** |
|
* Set session namespace object |
|
* |
|
* @param Zend_Session_Namespace $session |
|
* @return Zend_Captcha_Word |
|
*/ |
|
public function setSession(Zend_Session_Namespace $session) |
|
{ |
|
$this->_session = $session; |
|
if ($session) { |
|
$this->_keepSession = true; |
|
} |
|
return $this; |
|
} |
|
|
|
/** |
|
* Get captcha word |
|
* |
|
* @return string |
|
*/ |
|
public function getWord() |
|
{ |
|
if (empty($this->_word)) { |
|
$session = $this->getSession(); |
|
$this->_word = $session->word; |
|
} |
|
return $this->_word; |
|
} |
|
|
|
/** |
|
* Set captcha word |
|
* |
|
* @param string $word |
|
* @return Zend_Captcha_Word |
|
*/ |
|
protected function _setWord($word) |
|
{ |
|
$session = $this->getSession(); |
|
$session->word = $word; |
|
$this->_word = $word; |
|
return $this; |
|
} |
|
|
|
/** |
|
* Generate new random word |
|
* |
|
* @return string |
|
*/ |
|
protected function _generateWord() |
|
{ |
|
$word = ''; |
|
$wordLen = $this->getWordLen(); |
|
$vowels = $this->_useNumbers ? self::$VN : self::$V; |
|
$consonants = $this->_useNumbers ? self::$CN : self::$C; |
|
|
|
$totIndexCon = count($consonants) - 1; |
|
$totIndexVow = count($vowels) - 1; |
|
for ($i=0; $i < $wordLen; $i = $i + 2) { |
|
// generate word with mix of vowels and consonants |
|
$consonant = $consonants[Zend_Crypt_Math::randInteger(0, $totIndexCon, true)]; |
|
$vowel = $vowels[Zend_Crypt_Math::randInteger(0, $totIndexVow, true)]; |
|
$word .= $consonant . $vowel; |
|
} |
|
|
|
if (strlen($word) > $wordLen) { |
|
$word = substr($word, 0, $wordLen); |
|
} |
|
|
|
return $word; |
|
} |
|
|
|
/** |
|
* Generate new session ID and new word |
|
* |
|
* @return string session ID |
|
*/ |
|
public function generate() |
|
{ |
|
if (!$this->_keepSession) { |
|
$this->_session = null; |
|
} |
|
$id = $this->_generateRandomId(); |
|
$this->_setId($id); |
|
$word = $this->_generateWord(); |
|
$this->_setWord($word); |
|
return $id; |
|
} |
|
|
|
protected function _generateRandomId() |
|
{ |
|
return md5(Zend_Crypt_Math::randBytes(32)); |
|
} |
|
|
|
/** |
|
* Validate the word |
|
* |
|
* @see Zend_Validate_Interface::isValid() |
|
* @param mixed $value |
|
* @param array|null $context |
|
* @return boolean |
|
*/ |
|
public function isValid($value, $context = null) |
|
{ |
|
if (!is_array($value) && !is_array($context)) { |
|
$this->_error(self::MISSING_VALUE); |
|
return false; |
|
} |
|
if (!is_array($value) && is_array($context)) { |
|
$value = $context; |
|
} |
|
|
|
$name = $this->getName(); |
|
|
|
if (isset($value[$name])) { |
|
$value = $value[$name]; |
|
} |
|
|
|
if (!isset($value['input'])) { |
|
$this->_error(self::MISSING_VALUE); |
|
return false; |
|
} |
|
$input = strtolower($value['input']); |
|
$this->_setValue($input); |
|
|
|
if (!isset($value['id'])) { |
|
$this->_error(self::MISSING_ID); |
|
return false; |
|
} |
|
|
|
$this->_id = $value['id']; |
|
if ($input !== $this->getWord()) { |
|
$this->_error(self::BAD_CAPTCHA); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
/** |
|
* Get captcha decorator |
|
* |
|
* @return string |
|
*/ |
|
public function getDecorator() |
|
{ |
|
return "Captcha_Word"; |
|
} |
|
}
|
|
|