سؤال

Of course, I don't want to change library/Zend. I know that I can create class My_Form which extends Zend_Form and setup custom decorator. Than, every form extends new class My_Form...

Is there any way to set Zend Form Decorator(change default decoration) in some plugin or bootstrap, without changing existing forms ??

Or, What is the best way to override default form decorator for all forms?

هل كانت مفيدة؟

المحلول

I am not sure whether my answer will be of help, but here you go. There is a way of substituting ZF decorators with your own decorators without editing the forms themselves.

SOLUTION #1:

The method described here. Or in short:

Let's say you've got a form:

class Form extends Zend_Form
{
    function init ()
    {
        $this->addElement ('text', 'a', array (
            'label' => 'Name'
        ));
    }
}

Then have in application.ini

resources.view.helperPath.Default_View_Helper = APPLICATION_PATH "/views/helpers"

Add a new file application/views/helpers/FormText.php

class Default_View_Helper_FormText extends Zend_Form_Decorator_Abstract
{
    function formText ()
    {
        return 'It is I.';
    }
}

And that is it.

SOLUTION #2:

Let's have this abstract class:

abstract class Application_Style
{
    private $_object;



    function __construct ($object = null)
    {
        if (isset ($object))
        {
            $this->apply ($object);
        }
    }


    function apply ($object)
    {
        $this->setObject ($object);
        if ($this->filter ())
        {
            $this->onApply ();
        }

        return $object;
    }


    function __call ($method, $arguments)
    {
        return call_user_func_array (array ($this->getObject (), $method), $arguments);
    }


    abstract protected function onApply ();


    protected function filter ()
    {
        return true;
    }


    function setObject ($_object)
    {
        $this->_object = $_object;
    }


    function getObject ()
    {
        return $this->_object;
    }
}

And then a descendant.

class Application_Style_AdminForm extends Application_Style
{
    function onApply ()
    {
            $this->addElement ($submit = new Zend_Form_Element_Submit ('submit', array(
            'label' => 'Submit',
            )));

            $submit
            ->removeDecorator ('DtDdWrapper')
            ->addDecorator ('HtmlTag', array (
            'placement' => Zend_Form_Decorator_HtmlTag::PREPEND,
            'tag' => 'p',
            'openOnly'  => 1,
            ))
            ->addDecorator ('Custom', array ('text' => '     '))
            ;
        }
}

In the onApply() method could be anything that suits you. Adding or removing decorators, for example. Then you can call this styling upon your form like this:

new Application_Style_AdminForm ($this);

which allows you to manipulate the form representation but without changing it directly.

نصائح أخرى

Many have tried, none that I know of succeeded in doing it without extending Zend_Form. See this and this for sub-optimal solutions.

I have one solution. You can define decorators in bootsrap.

ex:-

$textDecorator = array(
                array('ViewHelper',
                    array('helper' => 'formText')
                ),
                array('Label',
                    array('class' => 'label')
                ),
                array('HtmlTag',
                    array('tag' => 'div', 'class' => 'formfield clearfix')
                )
            ); 

Zend_Registry::set('text_dec', $textDecoration);

Now you can use it for all form text field.

ex:-

class TestForm extends Zend_Form
{
    function init ()
    {
        $this->addElement ('text', 'a', array (
            'label' => 'Name',
            'decorator' => Zend_Registry::get('text_dec')
        ));
    }
}

So you can use some global decorator form this one.

Here is complete solution.

Set folders for your decorators in ".ini" file:

; folder with custom decorators will be loaded for FormElements
form.elementPrefixPath.decorator.prefix =  "Application_Form_Decorator"
form.elementPrefixPath.decorator.path   =  "Application/Form/Decorator/"
form.elementPrefixPath.decorator.type   = "decorator"

; folder with custom decorators will be loaded for Forms
form.prefixPath.decorator.prefix =  "Application_Form_Decorator"
form.prefixPath.decorator.path   =  "Application/Form/Decorator/"
form.prefixPath.decorator.type   = "decorator"

Next, use same name for your decorator to override default decorator. For example, to substitute default "DtDdWrapper" decorator, you can use Application_Form_Decorator_DtDdWrapper:

class Application_Form_Decorator_DtDdWrapper extends Zend_Form_Decorator_DtDdWrapper

Decorator will be loaded by last part of that name.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top