【问题标题】:Customize zend_form Captcha output?自定义 zend_form 验证码输出?
【发布时间】:2011-07-05 03:24:57
【问题描述】:

我在我的 zend_form 中使用验证码。

$captcha_element = new Zend_Form_Element_Captcha(
    'captcha',
    array('label' => 'Write the chars to the field',
        'captcha' => array(
            'captcha' => 'Image',
            'wordLen' => 6,
            'timeout' => 300,
            'font' => DOC_ROOT . '/data/fonts/Vera.ttf',
            'imgDir' => $imagedir,
            'imgUrl' => $umageurl
        )
    )
);

这会生成:

<dt id="captcha-input-label">
    <label for="captcha-input" class="required">Write the chars to the field</label>
</dt>

<dd id="captcha-element">
    <img width="200" height="50" alt="" src="http://sitename.com/captcha/09dd951939c6cdf7fa28f2b7d322ea95.png">
    <input type="hidden" name="captcha[id]" value="09dd951939c6cdf7fa28f2b7d322ea95" id="captcha-id">
    <input type="text" name="captcha[input]" id="captcha-input" value="">
</dd>

但是。 - 我需要以下内容(验证码元素单独包装到一些标签中):

<dt id="captcha-input-label">
    <label for="captcha-input" class="required">Write the chars to the field</label>
</dt>

<dd id="captcha-element">
    <div><span>
        <input type="text" name="captcha[input]" id="captcha-input" value="">
    </span></div>
    <div><span>
        <img width="200" height="50" alt="" src="http://sitename.com/captcha/09dd951939c6cdf7fa28f2b7d322ea95.png">
        <input type="hidden" name="captcha[id]" value="09dd951939c6cdf7fa28f2b7d322ea95" id="captcha-id">
    </span></div>
</dd>

我不知道该怎么做。我可以通过使用一些自定义装饰器来实现这一点吗?还是涉及自定义验证码?

【问题讨论】:

  • 这不是一项简单的任务。例如,您正在更改验证码表单元素中的字段顺序。此订单是硬编码的。因此,要更改它,您需要修改 Zend_Form_Element_Captcha 或创建您自己的 Zend_Form_Element_Captcha 版本。

标签: zend-framework zend-form zend-form-element


【解决方案1】:

回答; Bootstrap 3 语法的验证码、提交和其他文本元素

祝你好运

<?php
/**
 * User: semihs
 * Date: 05.08.2013
 * Time: 23:46
 */

class Form_Decorator_Horizontal extends Zend_Form_Decorator_Abstract {

    public function buildLabel() {
        $element = $this->getElement();
        $label   = $element->getLabel();
        if ($translator = $element->getTranslator()) {
            $label = $translator->translate($label);
        }

        if ($element->getType() == 'Zend_Form_Element_Submit') {
            return "<label for='{$element->getName()}' class='col-lg-4 control-label'></label>";
        } else {
            return "<label for='{$element->getName()}' class='col-lg-4 control-label'>{$label}</label>";
        }
    }

    public function buildInput() {
        $element = $this->getElement();
        $helper  = $element->helper;

        $element->setAttrib('class', $element->getAttrib('class') . " form-control");

        if ($element->getType() == 'Zend_Form_Element_Submit') {
            return "<div class='col-lg-8'>" . $element->getView()->$helper(
                $element->getName(),
                $element->getValue(),
                $element->getAttribs(),
                $element->options
            ) . "</div>";
        } else {
            return "<div class='col-lg-8'>" . $element->getView()->$helper(
                $element->getName(),
                $element->getValue(),
                $element->getAttribs(),
                $element->options
            ) . "</div>";
        }
    }

    public function buildErrors() {
        $element  = $this->getElement();
        $messages = $element->getMessages();
        if (empty($messages)) {
            return '';
        }

        return '<div class="errors">' . $element->getView()->formErrors($messages) . '</div>';
    }

    public function buildDescription() {
        $element = $this->getElement();
        $desc    = $element->getDescription();
        if (empty($desc)) {
            return '';
        }

        return '<div class="description">' . $desc . '</div>';
    }

    public function render($content) {
        $element = $this->getElement();

        if (!$element instanceof Zend_Form_Element) {
            return $content;
        }
        if (null === $element->getView()) {
            return $content;
        }

        $separator = $this->getSeparator();
        $placement = $this->getPlacement();
        $label     = $this->buildLabel();
        $input     = $this->buildInput();
        $errors    = $this->buildErrors();
        $desc      = $this->buildDescription();

        if ($element->getType() == 'Zend_Form_Element_Captcha') {
            $view = $element->getView();
            if (null === $view) {
                return $content;
            }

            $name = $element->getFullyQualifiedName();

            $hiddenName = $name . '[id]';
            $textName   = $name . '[input]';
            $captcha    = $element->getCaptcha();
            $markup     = $captcha->render($view, $element);
            $hidden     = $view->formHidden($hiddenName, $element->getValue(), $element->getAttribs());
            $text       = $view->formText($textName, '', $element->getAttribs());

            $output = '<div class="form-group">'
                . $label
                . "<div class='col-lg-8'>" . $markup . "</div>"
                . "</div>"
                . "<div class='form-group'>"
                . "<label class='col-lg-4'></label>"
                . "<div class='col-lg-8'>" . $text . "</div>"
                . $hidden
                . $errors
                . $desc
                . "</div>";
        } else {
            $output = '<div class="form-group">'
                . $label
                . $input
                . $errors
                . $desc
                . '</div>';
        }

        switch ($placement) {
            case (self::PREPEND):
                return $output . $separator . $content;
            case (self::APPEND):
            default:
                return $separator . $output;
        }
    }
}

【讨论】:

  • 你应该添加一个解释。
【解决方案2】:

我用的很简单

$captcha->setDescription('Enter code:')->setDecorators(array('captcha', array('ViewScript', array('viewScript' => 'auth/captcha.phtml')));

和内部视图:

<input id="captcha" type="text" name="captcha[input]" />

<input type="hidden" name="captcha[id]" value="<?php echo $this->element->getValue() ?>" >
<div  id="captcha-element">
    <?php echo $this->element->getCaptcha()->render(); ?>
</div>

【讨论】:

    【解决方案3】:

    这有点棘手,但我准备了一个自定义验证码元素。我还需要准备自定义验证码装饰器。在这两种情况下,我都需要覆盖Zend_Form_Element_CaptchaZend_Form_Decorator_Captcha 中的默认渲染方法。我还删除了Zend_Form_Decorator_Captcha_Word,因为我将它的功能直接合并到My_Form_Decorator_Captcha 中。这有两个原因。第一个是表单元素的顺序发生了变化,即从默认的img,input hidden,input text变为input text,img,input hidden。第二个原因是需要添加div和span标签。

    希望它们会有所帮助:

    My_Form_Element_Captcha

    class My_Form_Element_Captcha extends Zend_Form_Element_Captcha {
    
        public function render(Zend_View_Interface $view = null)     {
            $captcha    = $this->getCaptcha();
            $captcha->setName($this->getFullyQualifiedName());
    
            $decorators = $this->getDecorators();
    
            // BELOW IS WHERE THE NEW DECORATOR IS USED
    
            $decorator = new My_Form_Decorator_Captcha(array('captcha' => $captcha));
    
            array_unshift($decorators, $decorator);
    
            $decorator  = $captcha->getDecorator();
    
            $this->setDecorators($decorators);
    
    
            $this->setValue($this->getCaptcha()->generate());
    
            return Zend_Form_Element::render($view);
        }
    }
    

    My_Form_Decorator_Captcha

    class My_Form_Decorator_Captcha extends Zend_Form_Decorator_Captcha {
    
         public function render($content) {
            $element = $this->getElement();
            if (!method_exists($element, 'getCaptcha')) {
                return $content;
            }
    
            $view = $element->getView();
            if (null === $view) {
                return $content;
            }
    
    
            $name = $element->getFullyQualifiedName();
    
            $hiddenName = $name . '[id]';
            $textName = $name . '[input]';
    
            $label = $element->getDecorator("Label");
            if ($label) {
                $label->setOption("id", $element->getId() . "-input");
            }
    
            $placement = $this->getPlacement();
            $separator = $this->getSeparator();
    
            $captcha = $element->getCaptcha();
            $markup = $captcha->render($view, $element);
            $hidden = $view->formHidden($hiddenName, $element->getValue(), $element->getAttribs());
            $text = $view->formText($textName, '', $element->getAttribs());
    
    
            // CHANGE THE ORDER OF ELEMENTS AND ADD THE div AND span TAGS.
    
            switch ($placement) {
                case 'PREPEND':
                    $content = '<div><span>' . $text . '</div></span>' .
                            '<div><span>' . $markup . $hidden . '</div></span>' .
                            $separator . $content;
                    break;
                case 'APPEND':
                default:
                    $content = $content . $separator .
                            '<div><span>' . $text . '</div></span>' .
                            '<div><span>' . $markup . $hidden . '</div></span>';
            }
    
            return $content;
        }
    
    }
    

    【讨论】:

    • omg Marcin - 你是我的英雄。我只是在跟踪相同的代码,试图弄清楚如何实现这一点。非常感谢。
    • @Andre。我很高兴你喜欢它。
    • Marcin 我正在使用没有 zend_form 的验证码。我直接在控制器中使用验证码,我如何更改视图 html
    • Marcin ,我们如何调用 phtml 文件这个自定义渲染
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 2011-05-16
    • 1970-01-01
    相关资源
    最近更新 更多