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
Description
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:
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:
Posted by Ross Smith (rasa7777) on 2012-01-23T22:31:37.000+0000
Aleksey 'Xerkus' Khudyakov states:
I think it's reasonable to assume that by calling
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.