在全局应用程序级别更改默认的Zend Form Decorator?

时间:2012-02-08 09:59:54

标签: zend-framework plugins zend-form bootstrapping zend-decorators

当然,我不想改变库/ Zend。 我知道我可以创建类My_Form,它扩展了Zend_Form并设置了自定义装饰器。比,每个表格都扩展了新类My_Form ...

有没有办法在某些插件或引导程序中设置Zend Form Decorator(更改默认装饰),而不更改现有表单?

或者,覆盖所有表单的默认表单装饰器的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

我不确定我的回答是否会有所帮助,但是你走了。 有一种方法可以用自己的装饰器替换ZF装饰器,而无需自己编辑表单。

解决方案#1:

描述的方法here。或者简而言之:

假设你有一张表格:

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

然后在application.ini

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

添加新文件application / views / helpers / FormText.php

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

就是这样。

解决方案#2:

让我们有这个抽象类:

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

然后是后代。

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' => '     '))
            ;
        }
}

在onApply()方法中可以是任何适合你的方法。例如,添加或删除装饰器。然后你可以在你的表单上调用这个样式:

new Application_Style_AdminForm ($this);

允许您操作表单表示但不直接更改它。

答案 1 :(得分:0)

许多人尝试过,没有我知道成功完成它而没有扩展Zend_Form。有关次优解决方案,请参阅thisthis

答案 2 :(得分:0)

我有一个解决方案。您可以在bootsrap中定义装饰器。

前: -

$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);

现在您可以将它用于所有表单文本字段。

前: -

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

所以你可以使用这个全局装饰器。

答案 3 :(得分:0)

这是完整的解决方案。

在" .ini"中设置装饰器的文件夹。文件:

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

接下来,为装饰器使用相同名称来覆盖默认装饰器。 例如,要替换默认" DtDdWrapper"装饰, 你可以使用Application_Form_Decorator_DtDdWrapper:

class Application_Form_Decorator_DtDdWrapper extends Zend_Form_Decorator_DtDdWrapper

装饰器将由该名称的最后一部分加载。