PageRenderTime 37ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Form/Element/Captcha.php

https://bitbucket.org/openfisma-ondemand/openfisma
PHP | 313 lines | 182 code | 22 blank | 109 comment | 25 complexity | afb970a7813fa2eae2466892d809bf1d MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, GPL-3.0, Apache-2.0, EPL-1.0
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Form
  17. * @subpackage Element
  18. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /** @see Zend_Form_Element_Xhtml */
  23. // require_once 'Zend/Form/Element/Xhtml.php';
  24. /** @see Zend_Captcha_Adapter */
  25. // require_once 'Zend/Captcha/Adapter.php';
  26. /**
  27. * Generic captcha element
  28. *
  29. * This element allows to insert CAPTCHA into the form in order
  30. * to validate that human is submitting the form. The actual
  31. * logic is contained in the captcha adapter.
  32. *
  33. * @see http://en.wikipedia.org/wiki/Captcha
  34. *
  35. * @category Zend
  36. * @package Zend_Form
  37. * @subpackage Element
  38. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  39. * @license http://framework.zend.com/license/new-bsd New BSD License
  40. */
  41. class Zend_Form_Element_Captcha extends Zend_Form_Element_Xhtml
  42. {
  43. /**
  44. * Captcha plugin type constant
  45. */
  46. const CAPTCHA = 'CAPTCHA';
  47. /**
  48. * Captcha adapter
  49. *
  50. * @var Zend_Captcha_Adapter
  51. */
  52. protected $_captcha;
  53. /**
  54. * Get captcha adapter
  55. *
  56. * @return Zend_Captcha_Adapter
  57. */
  58. public function getCaptcha()
  59. {
  60. return $this->_captcha;
  61. }
  62. /**
  63. * Set captcha adapter
  64. *
  65. * @param string|array|Zend_Captcha_Adapter $captcha
  66. * @param array $options
  67. */
  68. public function setCaptcha($captcha, $options = array())
  69. {
  70. if ($captcha instanceof Zend_Captcha_Adapter) {
  71. $instance = $captcha;
  72. } else {
  73. if (is_array($captcha)) {
  74. if (array_key_exists('captcha', $captcha)) {
  75. $name = $captcha['captcha'];
  76. unset($captcha['captcha']);
  77. } else {
  78. $name = array_shift($captcha);
  79. }
  80. $options = array_merge($options, $captcha);
  81. } else {
  82. $name = $captcha;
  83. }
  84. $name = $this->getPluginLoader(self::CAPTCHA)->load($name);
  85. if (empty($options)) {
  86. $instance = new $name;
  87. } else {
  88. $r = new ReflectionClass($name);
  89. if ($r->hasMethod('__construct')) {
  90. $instance = $r->newInstanceArgs(array($options));
  91. } else {
  92. $instance = $r->newInstance();
  93. }
  94. }
  95. }
  96. $this->_captcha = $instance;
  97. $this->_captcha->setName($this->getName());
  98. return $this;
  99. }
  100. /**
  101. * Constructor
  102. *
  103. * $spec may be:
  104. * - string: name of element
  105. * - array: options with which to configure element
  106. * - Zend_Config: Zend_Config with options for configuring element
  107. *
  108. * @param string|array|Zend_Config $spec
  109. * @return void
  110. */
  111. public function __construct($spec, $options = null)
  112. {
  113. parent::__construct($spec, $options);
  114. $this->setAllowEmpty(true)
  115. ->setRequired(true)
  116. ->setAutoInsertNotEmptyValidator(false)
  117. ->addValidator($this->getCaptcha(), true);
  118. }
  119. /**
  120. * Return all attributes
  121. *
  122. * @return array
  123. */
  124. public function getAttribs()
  125. {
  126. $attribs = get_object_vars($this);
  127. unset($attribs['helper']);
  128. foreach ($attribs as $key => $value) {
  129. if ('_' == substr($key, 0, 1)) {
  130. unset($attribs[$key]);
  131. }
  132. }
  133. return $attribs;
  134. }
  135. /**
  136. * Set options
  137. *
  138. * Overrides to allow passing captcha options
  139. *
  140. * @param array $options
  141. * @return Zend_Form_Element_Captcha
  142. */
  143. public function setOptions(array $options)
  144. {
  145. if (array_key_exists('captcha', $options)) {
  146. if (array_key_exists('captchaOptions', $options)) {
  147. $this->setCaptcha($options['captcha'], $options['captchaOptions']);
  148. unset($options['captchaOptions']);
  149. } else {
  150. $this->setCaptcha($options['captcha']);
  151. }
  152. unset($options['captcha']);
  153. }
  154. parent::setOptions($options);
  155. return $this;
  156. }
  157. /**
  158. * Render form element
  159. *
  160. * @param Zend_View_Interface $view
  161. * @return string
  162. */
  163. public function render(Zend_View_Interface $view = null)
  164. {
  165. $captcha = $this->getCaptcha();
  166. $captcha->setName($this->getFullyQualifiedName());
  167. if (!$this->loadDefaultDecoratorsIsDisabled()) {
  168. $decorators = $this->getDecorators();
  169. $decorator = $captcha->getDecorator();
  170. $key = get_class($this->_getDecorator($decorator, null));
  171. if (!empty($decorator) && !array_key_exists($key, $decorators)) {
  172. array_unshift($decorators, $decorator);
  173. }
  174. $decorator = array('Captcha', array('captcha' => $captcha));
  175. $key = get_class($this->_getDecorator($decorator[0], $decorator[1]));
  176. if ($captcha instanceof Zend_Captcha_Word && !array_key_exists($key, $decorators)) {
  177. array_unshift($decorators, $decorator);
  178. }
  179. $this->setDecorators($decorators);
  180. }
  181. $this->setValue($this->getCaptcha()->generate());
  182. return parent::render($view);
  183. }
  184. /**
  185. * Retrieve plugin loader for validator or filter chain
  186. *
  187. * Support for plugin loader for Captcha adapters
  188. *
  189. * @param string $type
  190. * @return Zend_Loader_PluginLoader
  191. * @throws Zend_Loader_Exception on invalid type.
  192. */
  193. public function getPluginLoader($type)
  194. {
  195. $type = strtoupper($type);
  196. if ($type == self::CAPTCHA) {
  197. if (!isset($this->_loaders[$type])) {
  198. // require_once 'Zend/Loader/PluginLoader.php';
  199. $this->_loaders[$type] = new Zend_Loader_PluginLoader(
  200. array('Zend_Captcha' => 'Zend/Captcha/')
  201. );
  202. }
  203. return $this->_loaders[$type];
  204. } else {
  205. return parent::getPluginLoader($type);
  206. }
  207. }
  208. /**
  209. * Add prefix path for plugin loader for captcha adapters
  210. *
  211. * This method handles the captcha type, the rest is handled by
  212. * the parent
  213. * @param string $prefix
  214. * @param string $path
  215. * @param string $type
  216. * @return Zend_Form_Element
  217. * @see Zend_Form_Element::addPrefixPath
  218. */
  219. public function addPrefixPath($prefix, $path, $type = null)
  220. {
  221. $type = strtoupper($type);
  222. switch ($type) {
  223. case null:
  224. $loader = $this->getPluginLoader(self::CAPTCHA);
  225. $cPrefix = rtrim($prefix, '_') . '_Captcha';
  226. $cPath = rtrim($path, '/\\') . '/Captcha';
  227. $loader->addPrefixPath($cPrefix, $cPath);
  228. return parent::addPrefixPath($prefix, $path);
  229. case self::CAPTCHA:
  230. $loader = $this->getPluginLoader($type);
  231. $loader->addPrefixPath($prefix, $path);
  232. return $this;
  233. default:
  234. return parent::addPrefixPath($prefix, $path, $type);
  235. }
  236. }
  237. /**
  238. * Load default decorators
  239. *
  240. * @return Zend_Form_Element_Captcha
  241. */
  242. public function loadDefaultDecorators()
  243. {
  244. if ($this->loadDefaultDecoratorsIsDisabled()) {
  245. return $this;
  246. }
  247. $decorators = $this->getDecorators();
  248. if (empty($decorators)) {
  249. $this->addDecorator('Errors')
  250. ->addDecorator('Description', array('tag' => 'p', 'class' => 'description'))
  251. ->addDecorator('HtmlTag', array('tag' => 'dd', 'id' => $this->getName() . '-element'))
  252. ->addDecorator('Label', array('tag' => 'dt'));
  253. }
  254. return $this;
  255. }
  256. /**
  257. * Is the captcha valid?
  258. *
  259. * @param mixed $value
  260. * @param mixed $context
  261. * @return boolean
  262. */
  263. public function isValid($value, $context = null)
  264. {
  265. $this->getCaptcha()->setName($this->getName());
  266. $belongsTo = $this->getBelongsTo();
  267. if (empty($belongsTo) || !is_array($context)) {
  268. return parent::isValid($value, $context);
  269. }
  270. $name = $this->getFullyQualifiedName();
  271. $root = substr($name, 0, strpos($name, '['));
  272. $segments = substr($name, strpos($name, '['));
  273. $segments = ltrim($segments, '[');
  274. $segments = rtrim($segments, ']');
  275. $segments = explode('][', $segments);
  276. array_unshift($segments, $root);
  277. array_pop($segments);
  278. $newContext = $context;
  279. foreach ($segments as $segment) {
  280. if (array_key_exists($segment, $newContext)) {
  281. $newContext = $newContext[$segment];
  282. }
  283. }
  284. return parent::isValid($value, $newContext);
  285. }
  286. }