PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://firephp.googlecode.com/
PHP | 259 lines | 165 code | 19 blank | 75 comment | 19 complexity | dd4783e59f164c931ffc8e996655f894 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, MIT, Apache-2.0
  1. <?php
  2. /** Zend_Form_Element_Xhtml */
  3. require_once 'Zend/Form/Element/Xhtml.php';
  4. /** Zend_Captcha_Adapter */
  5. require_once 'Zend/Captcha/Adapter.php';
  6. /**
  7. * Generic captcha element
  8. *
  9. * This element allows to insert CAPTCHA into the form in order
  10. * to validate that human is submitting the form. The actual
  11. * logic is contained in the captcha adapter.
  12. *
  13. * @see http://en.wikipedia.org/wiki/Captcha
  14. *
  15. */
  16. class Zend_Form_Element_Captcha extends Zend_Form_Element_Xhtml
  17. {
  18. /**
  19. * @const string Captch plugin type constant
  20. */
  21. const CAPTCHA = 'CAPTCHA';
  22. /**
  23. * Captcha adapter
  24. *
  25. * @var Zend_Captcha_Adapter
  26. */
  27. protected $_captcha;
  28. /**
  29. * Get captcha adapter
  30. *
  31. * @return Zend_Captcha_Adapter
  32. */
  33. public function getCaptcha()
  34. {
  35. return $this->_captcha;
  36. }
  37. /**
  38. * Set captcha adapter
  39. *
  40. * @param string|array|Zend_Captcha_Adapter $captcha
  41. * @param array $options
  42. */
  43. public function setCaptcha($captcha, $options = array())
  44. {
  45. if ($captcha instanceof Zend_Captcha_Adapter) {
  46. $instance = $captcha;
  47. } else {
  48. if (is_array($captcha)) {
  49. if (array_key_exists('captcha', $captcha)) {
  50. $name = $captcha['captcha'];
  51. unset($captcha['captcha']);
  52. } else {
  53. $name = array_shift($captcha);
  54. }
  55. $options = array_merge($options, $captcha);
  56. } else {
  57. $name = $captcha;
  58. }
  59. $name = $this->getPluginLoader(self::CAPTCHA)->load($name);
  60. if (empty($options)) {
  61. $instance = new $name;
  62. } else {
  63. $r = new ReflectionClass($name);
  64. if ($r->hasMethod('__construct')) {
  65. $instance = $r->newInstanceArgs(array($options));
  66. } else {
  67. $instance = $r->newInstance();
  68. }
  69. }
  70. }
  71. $this->_captcha = $instance;
  72. $this->_captcha->setName($this->getName());
  73. return $this;
  74. }
  75. /**
  76. * Constructor
  77. *
  78. * $spec may be:
  79. * - string: name of element
  80. * - array: options with which to configure element
  81. * - Zend_Config: Zend_Config with options for configuring element
  82. *
  83. * @param string|array|Zend_Config $spec
  84. * @return void
  85. */
  86. public function __construct($spec, $options = null)
  87. {
  88. parent::__construct($spec, $options);
  89. $this->setAllowEmpty(true)
  90. ->setRequired(true)
  91. ->setAutoInsertNotEmptyValidator(false)
  92. ->addValidator($this->getCaptcha(), true);
  93. }
  94. /**
  95. * Set options
  96. *
  97. * Overrides to allow passing captcha options
  98. *
  99. * @param array $options
  100. * @return Zend_Form_Element_Captcha
  101. */
  102. public function setOptions(array $options)
  103. {
  104. if (array_key_exists('captcha', $options)) {
  105. if (array_key_exists('captchaOptions', $options)) {
  106. $this->setCaptcha($options['captcha'], $options['captchaOptions']);
  107. unset($options['captchaOptions']);
  108. } else {
  109. $this->setCaptcha($options['captcha']);
  110. }
  111. unset($options['captcha']);
  112. }
  113. return parent::setOptions($options);
  114. }
  115. /**
  116. * Render form element
  117. *
  118. * @param Zend_View_Interface $view
  119. * @return string
  120. */
  121. public function render(Zend_View_Interface $view = null)
  122. {
  123. $captcha = $this->getCaptcha();
  124. $captcha->setName($this->getFullyQualifiedName());
  125. $decorators = $this->getDecorators();
  126. $decorator = $captcha->getDecorator();
  127. if (!empty($decorator)) {
  128. array_unshift($decorators, $decorator);
  129. }
  130. $decorator = array('Captcha', array('captcha' => $captcha));
  131. array_unshift($decorators, $decorator);
  132. $this->setDecorators($decorators);
  133. $this->setValue($this->getCaptcha()->generate());
  134. return parent::render($view);
  135. }
  136. /**
  137. * Retrieve plugin loader for validator or filter chain
  138. *
  139. * Support for plugin loader for Captcha adapters
  140. *
  141. * @param string $type
  142. * @return Zend_Loader_PluginLoader
  143. * @throws Zend_Loader_Exception on invalid type.
  144. */
  145. public function getPluginLoader($type)
  146. {
  147. $type = strtoupper($type);
  148. if ($type == self::CAPTCHA) {
  149. if (!isset($this->_loaders[$type])) {
  150. require_once 'Zend/Loader/PluginLoader.php';
  151. $this->_loaders[$type] = new Zend_Loader_PluginLoader(
  152. array('Zend_Captcha' => 'Zend/Captcha/')
  153. );
  154. }
  155. return $this->_loaders[$type];
  156. } else {
  157. return parent::getPluginLoader($type);
  158. }
  159. }
  160. /**
  161. * Add prefix path for plugin loader for captcha adapters
  162. *
  163. * This method handles the captcha type, the rest is handled by
  164. * the parent
  165. *
  166. * @param string $path
  167. * @return Zend_Form_Element
  168. * @see Zend_Form_Element::addPrefixPath
  169. */
  170. public function addPrefixPath($prefix, $path, $type = null)
  171. {
  172. $type = strtoupper($type);
  173. switch ($type) {
  174. case null:
  175. $loader = $this->getPluginLoader(self::CAPTCHA);
  176. $cPrefix = rtrim($prefix, '_') . '_Captcha';
  177. $cPath = rtrim($path, '/\\') . '/Captcha';
  178. $loader->addPrefixPath($cPrefix, $cPath);
  179. return parent::addPrefixPath($prefix, $path, $type);
  180. case self::CAPTCHA:
  181. $loader = $this->getPluginLoader($type);
  182. $loader->addPrefixPath($prefix, $path);
  183. return $this;
  184. default:
  185. return parent::addPrefixPath($prefix, $path, $type = null);
  186. }
  187. }
  188. /**
  189. * Load default decorators
  190. *
  191. * @return void
  192. */
  193. public function loadDefaultDecorators()
  194. {
  195. if ($this->loadDefaultDecoratorsIsDisabled()) {
  196. return;
  197. }
  198. $decorators = $this->getDecorators();
  199. if (empty($decorators)) {
  200. $this->addDecorator('Errors')
  201. ->addDecorator('HtmlTag', array('tag' => 'dd'))
  202. ->addDecorator('Label', array('tag' => 'dt'));
  203. }
  204. }
  205. /**
  206. * Is the captcha valid?
  207. *
  208. * @param mixed $value
  209. * @param mixed $context
  210. * @return boolean
  211. */
  212. public function isValid($value, $context = null)
  213. {
  214. $this->getCaptcha()->setName($this->getName());
  215. $belongsTo = $this->getBelongsTo();
  216. if (empty($belongsTo) || !is_array($context)) {
  217. return parent::isValid($value, $context);
  218. }
  219. $name = $this->getFullyQualifiedName();
  220. $root = substr($name, 0, strpos($name, '['));
  221. $segments = substr($name, strpos($name, '['));
  222. $segments = ltrim($segments, '[');
  223. $segments = rtrim($segments, ']');
  224. $segments = explode('][', $segments);
  225. array_unshift($segments, $root);
  226. array_pop($segments);
  227. $newContext = $context;
  228. foreach ($segments as $segment) {
  229. if (array_key_exists($segment, $newContext)) {
  230. $newContext = $newContext[$segment];
  231. }
  232. }
  233. return parent::isValid($value, $newContext);
  234. }
  235. }