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.
 
 
 
 
 
 

186 lines
4.2 KiB

<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
class Captcha_Questions extends Laminas\Captcha\AbstractWord
{
protected $name = "questions";
/**
* CAPTCHA label
* @type string
*/
protected $label = '';
private $questions = []; // array for quesiotns and answers passed to ctor
private $current = null; // int current q & a
/**#@+
* Error codes
*/
const MISSING_VALUE = 'missingValue';
const ERR_CAPTCHA = 'errCaptcha';
const BAD_CAPTCHA = 'badCaptcha';
const MISSING_ID = 'missingID';
/**#@-*/
/**
* Error messages
* @var array
*/
protected $messageTemplates = [
self::MISSING_VALUE => 'Missing captcha fields',
self::ERR_CAPTCHA => 'Failed to validate CAPTCHA',
self::BAD_CAPTCHA => 'Captcha value is wrong: %value%',
self::MISSING_ID => 'missingID',
];
/**
* Constructor
*
* @param array|$questions
*/
public function __construct($questions)
{
$this->questions = $questions;
$this->abstractOptions['messageTemplates'] = $this->messageTemplates;
}
/**
* 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;
}
/**
* Render the captcha
*
* @param $view
* @param mixed $element
* @return string
*/
public function render($view = null, $element = null)
{
$question = $this->questions[$this->current];
return tra($question[0]);
}
/**
* Validate the answer
*
* @see Laminas\Validator\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'];
$word = $this->getWord();
if (empty($word)) {
$this->error(self::MISSING_VALUE);
return false;
}
if (
! (preg_match('#^/.*/[imsxADSUXJu]*$#', $word) && preg_match($word, $input)) && // regex answer?
$input !== $word
) {
$this->error(self::BAD_CAPTCHA);
return false;
}
return true;
}
/**
* Get captcha word (actually answer in this case)
*
* @return string
*/
public function getWord()
{
if (empty($this->word)) {
$session = $this->getSession();
$this->word = $session->word;
}
return $this->word;
}
/**
* Generate new random answer
*
* @return string
*/
protected function generateWord()
{
$this->current = array_rand($this->questions);
$question = $this->questions[$this->current];
$word = $question[1];
return $word;
}
/**
* Set the label for the CAPTCHA
* @param string $label
*/
public function setLabel($label)
{
$this->label = $label;
}
/**
* Retrieve the label for the CAPTCHA
* @return string
*/
public function getLabel()
{
return $this->label;
}
}