Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customize zend_form Captcha output?

I'm using captcha in my 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
        )
    )
);

This generates:

<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>

However. - I need following instead (captcha elements are wrapped into some tags individually):

<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>

I can't figure out how would I do this. Can I accomplish this by using some custom decorators? or woud that involve custom captcha ?

like image 749
Stann Avatar asked Feb 27 '11 06:02

Stann


3 Answers

It was a bit tricky, but I prepared a custom Captcha element. I also needed to prepare custom Captcha decorator. In both cases I needed to override default render methods in both Zend_Form_Element_Captcha and Zend_Form_Decorator_Captcha. I also eliminated Zend_Form_Decorator_Captcha_Word since I incorporated its functionality directly into My_Form_Decorator_Captcha. There were two reasons for this. The first one is that order of form elements was changed, i.e. from default img, input hidden, input text into input text, img, input hidden. The second reason is that div and span tags needed to be added.

Hopefully, they will be helpful:

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;
    }

}
like image 196
Marcin Avatar answered Oct 18 '22 19:10

Marcin


I use simply

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

and inside viewscript:

<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>
like image 29
Anatejms Avatar answered Oct 18 '22 17:10

Anatejms


answer; Captcha, submit and other text elements for bootstrap 3 syntax

good luck

<?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;
        }
    }
}
like image 45
Semih Sari Avatar answered Oct 18 '22 17:10

Semih Sari