File indexing completed on 2025-01-12 05:22:02

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Form
0017  * @subpackage Decorator
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  */
0021 
0022 /** @see Zend_Form_Decorator_Abstract */
0023 // require_once 'Zend/Form/Decorator/Abstract.php';
0024 
0025 /**
0026  * ReCaptcha-based captcha decorator
0027  *
0028  * Adds hidden fields for challenge and response input, and JS for populating 
0029  * from known recaptcha IDs
0030  *
0031  * @category   Zend
0032  * @package    Zend_Form
0033  * @subpackage Element
0034  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0035  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0036  */
0037 class Zend_Form_Decorator_Captcha_ReCaptcha extends Zend_Form_Decorator_Abstract
0038 {
0039     /**
0040      * Render captcha
0041      *
0042      * @param  string $content
0043      * @return string
0044      */
0045     public function render($content)
0046     {
0047         $element = $this->getElement();
0048         if (!$element instanceof Zend_Form_Element_Captcha) {
0049             return $content;
0050         }
0051 
0052         $view    = $element->getView();
0053         if (null === $view) {
0054             return $content;
0055         }
0056 
0057         $id            = $element->getId();
0058         $name          = $element->getBelongsTo();
0059         $placement     = $this->getPlacement();
0060         $separator     = $this->getSeparator();
0061         $challengeName = empty($name) ? 'recaptcha_challenge_field' : $name . '[recaptcha_challenge_field]';
0062         $responseName  = empty($name) ? 'recaptcha_response_field'  : $name . '[recaptcha_response_field]';
0063         $challengeId   = $id . '-challenge';
0064         $responseId    = $id . '-response';
0065         $captcha       = $element->getCaptcha();
0066         $markup        = $captcha->render($view, $element);
0067 
0068         // Create hidden fields for holding the final recaptcha values
0069         // Placing "id" in "attribs" to ensure it is not overwritten with the name
0070         $hidden = $view->formHidden(array(
0071             'name'    => $challengeName,
0072             'attribs' => array('id' => $challengeId),
0073         ));
0074         $hidden .= $view->formHidden(array(
0075             'name'    => $responseName,
0076             'attribs' => array('id'   => $responseId),
0077         ));
0078 
0079         // Create a window.onload event so that we can bind to the form.
0080         // Once bound, add an onsubmit event that will replace the hidden field 
0081         // values with those produced by ReCaptcha
0082         // zendBindEvent mediates between Mozilla's addEventListener and
0083         // IE's sole support for addEvent.
0084         $js =<<<EOJ
0085 <script type="text/javascript" language="JavaScript">
0086 function windowOnLoad(fn) {
0087     var old = window.onload;
0088     window.onload = function() {
0089         if (old) {
0090             old();
0091         }
0092         fn();
0093     };
0094 }
0095 function zendBindEvent(el, eventName, eventHandler) {
0096     if (el.addEventListener){
0097         el.addEventListener(eventName, eventHandler, false); 
0098     } else if (el.attachEvent){
0099         el.attachEvent('on'+eventName, eventHandler);
0100     }
0101 }
0102 windowOnLoad(function(){
0103     zendBindEvent(
0104         document.getElementById("$challengeId").form,
0105         'submit',
0106         function(e) {
0107             document.getElementById("$challengeId").value = document.getElementById("recaptcha_challenge_field").value;
0108             document.getElementById("$responseId").value = document.getElementById("recaptcha_response_field").value;
0109         }    
0110     );
0111 });
0112 </script>
0113 EOJ;
0114 
0115         // Always place the hidden fields before the captcha markup, and follow 
0116         // with the JS from above
0117         switch ($placement) {
0118             case 'PREPEND':
0119                 $content = $hidden . $markup . $js . $separator . $content;
0120                 break;
0121             case 'APPEND':
0122             default:
0123                 $content = $content . $separator . $hidden . $markup . $js;
0124         }
0125         return $content;
0126     }
0127 }
0128