Posted By

jiewmeng on 07/27/10


Tagged

zend-framework


Versions (?)

Zend Form: Customized to include honeyot anti-bot measure and other functionality


 / Published in: PHP
 

in this custom Zend_Form, i added the following customizations\r\n\r\n - customized default decorators\r\n - added functions to set values of inputs (mainly for request params)\r\n- added honey pot anti-bot measure (see __construct())\r\n - messenging functionality - simply rendering out divs with a css class and the message inside\r\n\r\ncode includes \r\n - the custom form abstract class\r\n - honey pot validator\r\n - FormMessages decorator

  1. class Application_Form_Abstract extends Zend_Form {
  2. protected $_messages = array();
  3.  
  4. // customizing default decorators ...
  5. function loadDefaultDecorators() {
  6. if ($this->loadDefaultDecoratorsIsDisabled()) {
  7. return $this;
  8. }
  9.  
  10. // ... for elements
  11. $decorators = $this->_elementDecorators;
  12. if (empty($decorators)) {
  13. $this->setElementDecorators(array(
  14. 'ViewHelper',
  15. 'Errors',
  16. array('Description', array('tag' => 'p')),
  17. 'Label',
  18. array('HtmlTag', array('tag' => 'p'))
  19. ));
  20. $this->getElement('submit')->removeDecorator('Label'); // remove the label from submit buttons
  21. }
  22.  
  23. // ... for form
  24. $this->addPrefixPath('Application_Form_Decorator', 'Application/Form/Decorator', 'decorator');
  25. $decorators = $this->getDecorators();
  26. if (empty($decorators)) {
  27. $this->addDecorator('FormElements')
  28. ->addDecorator(new Application_Form_Decorator_FormMessages)
  29. ->addDecorator('Description', array('placement' => 'PREPEND', 'tag' => 'p'))
  30. ->addDecorator('Form');
  31. }
  32. return $this;
  33. }
  34.  
  35. // set values mainly used to set values from the request params
  36. function setValues($values) {
  37. foreach ($this->getElements() as $elem) {
  38. if (!$elem->getIgnore() && array_key_exists($elem->getName(), $values)) {
  39. $elem->setValue($values[$elem->getName()]);
  40. }
  41. }
  42. }
  43.  
  44. function __construct($options = null) {
  45. // set default form method
  46. $this->setMethod('post');
  47.  
  48. // add honey pot with a validator that basically gives an error if the input is filled
  49. // hidden using css
  50. $this->addElement('text', 'honeypot', array(
  51. 'label' => 'Humans, please DO NOT fill this up',
  52. 'validators' => array(
  53. new Application_Validator_HoneyPot
  54. ),
  55. 'decorators' => array(
  56. 'ViewHelper',
  57. 'Errors',
  58. array('Description', array('tag' => 'p')),
  59. 'Label',
  60. array('HtmlTag', array('tag' => 'p', 'class' => 'honeypot', 'style' => 'display: none'))
  61. )
  62. ));
  63.  
  64. // call parent constructor
  65. parent::__construct($options);
  66. }
  67.  
  68. // messenging functionality
  69. // i actually tried to use Zend_Form's error messages but they includes error messages from its Zend_Form_Elements, not something i wanted
  70. // so i created this to create messages specific to the form
  71. // also messages have a $class param for css styling. eg. errors vs warning vs info
  72. function addMessage($message, $class = 'info') {
  73. $this->_messages[] = array('msg' => $message, 'class' => $class);
  74. }
  75. function getMessages() {
  76. return $this->_messages;
  77. }
  78. }
  79.  
  80. // honey pot validator
  81. class Application_Validator_HoneyPot extends Zend_Validate_Abstract {
  82. const BOT = 'bot';
  83. protected $_messageTemplates = array(
  84. self::BOT => 'Bot detected! Please do not fill up the honey pot field!'
  85. );
  86.  
  87. function isValid($value) {
  88. if ($value != "") {
  89. $this->_error(self::BOT);
  90. return false;
  91. }
  92. return true;
  93. }
  94. }
  95.  
  96. // FormMessages decorator
  97. class Application_Form_Decorator_FormMessages extends Zend_Form_Decorator_Abstract {
  98. protected $_placement = 'PREPEND';
  99.  
  100. function render($content) {
  101. $element = $this->getElement();
  102. $view = $element->getView();
  103. if (null === $view) {
  104. return $content;
  105. }
  106.  
  107. $messages = $element->getMessages();
  108. if (empty($messages)) {
  109. return $content;
  110. }
  111.  
  112. $separator = $this->getSeparator();
  113. $placement = $this->getPlacement();
  114. $messagesStr = '';
  115. foreach ($messages as $message) {
  116. $messagesStr .= $this->renderMessage($message['msg'], $message['class']);
  117. }
  118.  
  119. switch ($this->_placement) {
  120. case self::APPEND:
  121. return $content . $separator . $messagesStr;
  122. case self::PREPEND:
  123. return $messagesStr . $separator . $content;
  124. }
  125. }
  126.  
  127. function renderMessage($message, $class) {
  128. $html = '<div class="formMsg formMsg-' . $class . '">';
  129. $html .= strtoupper($class) . ': ' . $message;
  130. $html .= '</div>';
  131. return $html;
  132. }
  133. }

Report this snippet  

You need to login to post a comment.