Issues

ZF-12021: Custom decorators in Zend_Form_Element constructor produces "Plugin by name 'Mylabel' was not found in the registry; used paths: Zend_Form_Decorator_: Zend/Form/Decorator/ " error

Issue Type: Bug Created: 2012-01-23T21:45:40.000+0000 Last Updated: 2012-01-23T22:59:11.000+0000 Status: Resolved Fix version(s): Reporter: Ross Smith (rasa7777) Assignee: Ryan Mauger (bittarman) Tags: - Zend_Form

  • zend-form-element

Related issues: Attachments:

Description

<pre class="highlight">
class Application_Form_MyForm extends Zend_Form
{
    public function init()
    {
        $this->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
        $element = new Zend_Form_Element_Text('email', array(
            'label' => 'Email',
            'decorators' => array(
                'ViewHelper',
                'Mylabel',
            ),
        ));
        $this->addElement($element);
    }
}

fails with the following error: Plugin by name 'Mylabel' was not found in the registry; used paths: Zend_Form_Decorator_: Zend/Form/Decorator/

The following does work:

<pre class="highlight">
class Application_Form_MyForm extends Zend_Form
{
    public function init()
    {
        $this->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');
        $element = new Zend_Form_Element_Text('email', array(
            'label' => 'Email',
            'decorators' => array(
                'ViewHelper',
            ),
        ));
        $element->addDecorator('Mylabel');
        $this->addElement($element);
    }
}

It is not obvious from http://framework.zend.com/manual/en/… that the first example is not supported.

We should either fix the code to support this usage, or spell out in the documentation that custom decorators are not supported in Zend_Form_Element constructors.

Comments

Posted by Ryan Mauger (bittarman) on 2012-01-23T22:13:41.000+0000

This is untrue.

You can pass a key "prefixPath" with an array of prefix paths to be added, which if you use the notation given in your issue, you would have to pass to every element rather than the form.

I'm closing this as not an issue, though you may want to consider opening a documentation issue to clear this up.

Posted by Aleksey 'Xerkus' Khudyakov (xerkus) on 2012-01-23T22:21:53.000+0000

Why should it work? You configured form, but then created separate element. How configuration from one object should appear in unrelated other?

Your second example works only because your decorator lazy loaded on access. And that access occurs after element added to form, where decorator prefixes are injected into element instance.

You must either provide decorator prefixes to element constructor or create it from form instance, see Zend_Form::addElement() and Zend_From::createElement()

Posted by Ross Smith (rasa7777) on 2012-01-23T22:23:45.000+0000

Ryan,

Thanks for your prompt response.

You are correct, the following code works:

<pre class="highlight">
class Application_Form_MyForm extends Zend_Form
{
    public function init()
    {
        $element = new Zend_Form_Element_Text('email', array(
            'label' => 'Email',
            'prefixPath' => array(
                'decorator' => array(
                    'prefix'    => 'My_Decorator', 
                    'path'      => 'My/Decorator/', 
                 ),
             ),
            'decorators' => array(
                'ViewHelper',
                'Mylabel',
            ),
        ));
        $this->addElement($element);
    }
}

Posted by Ross Smith (rasa7777) on 2012-01-23T22:31:37.000+0000

Aleksey 'Xerkus' Khudyakov states:

Why should it work? You configured form, but then created separate element. How configuration from one object should appear in unrelated other?

I think it's reasonable to assume that by calling

<pre class="highlight">
$this->addElementPrefixPath('My_Decorator', 'My/Decorator/', 'decorator');

that this would apply to all future calls to addElement(), regardless of how the object was created that was passed to it.

It is not obvious (at least to me) that this is not the case.

I've reviewed the documentation, and don't find this requirement mentioned anywhere. Should it be updated?

Posted by Aleksey 'Xerkus' Khudyakov (xerkus) on 2012-01-23T22:58:25.000+0000

{quote}that this would apply to all future calls to addElement(), regardless of how the object was created that was passed to it.{quote}

Exactly. But check exception's stack trace: it thrown BEFORE $this->addElement($element); call. It should be something like Element::__construct() -> addDefaultDecorators() -> getDecorators() -> _loadDecorator(). Do not remember exact api.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts