I can't get Zend to autoload a custom form element class. I did things exactly as Marcin describes here (except that my classes start with 'Zend' and not 'my' but I'm getting this error:
Warning: include_once(Zend\Form\Element\Div.php) [function.include-once]: failed to open stream: No such file or directory
I have Zend_Form_Element_Div
inside forms\elements\
and Zend_View_Helper_FormDiv
inside views\helpers\
Basically, every folder in the error message is missng an 's', the right path is Zend\Forms\Elements\Div.php
I also have this in my bootstrap, though I'm not sure if it's necessary, but I'm also using this for my forms and models folder (and some others, but I don't think there's need to post them all):
<?php
$resourceLoader->addResourceTypes(array(
'model' => array(
'namespace' => 'Model',
'path' => 'models'
),
'element' => array(
'namespace' => 'Element',
'path' => 'elements'
),
'form' => array(
'namespace' => 'Form',
'path' => 'forms'
)
));
?>
(Is there actually any other way of doing this autoloading? Instead of declaring every single folder?)
$this->addElementPrefixPath('Element_', APPLICATION_PATH . '/forms/elements');
Fatal error: Class 'Element_Div' not found in C:\xampplite\htdocs\code\application\forms\PostForm.php on line 63
You essentially have to tell the form where to find custom elements by using:
$form->addElementPrefixPath()
In your case, you would use - either within the form's init()
or __construct()
method - something like:
$this->addElementPrefixPath('Zend_Form_Element_', APPLICATION_PATH . '/elements);
;
However, I have agree with @Marcin. Naming your own classes with the Zend_
pseudo-namespace is ill-advised. Either:
Decide on an application namespace and declare it in your Bootstrap
when you create your $resourceLoader
Create an custom library that resides on your include path - probably at the same level as the Zend library - and put your custom stuff out there.
Let me know if you need more details on either of these suggestions and I'll fatten up the explanations a bit.
Update based on comments
Using an empty appnamespace, your call to addElementPrefixPath()
now changes to:
$this->addElementPrefixPath('Element_', APPLICATION_PATH . '/elements);
And I guess you could remove the elements
entry from the $resourceLoader
definition in your Bootstrap
since it's really not doing anything.
Update 2
I assumed that you were adding the element to the form using the shortname, something like:
$form->addElement('div', 'my_div');
In this circumstance, we need to tell the $form
and its plugin registry where to find an element of type 'div'. That's why we dealt with $form->addElementPrefixPath()
.
However, from the error message you are reporting, it appears that you are adding your custom element to the form using something like:
$div = new Element_Div();
$form->addElement($div, 'my_div');
In this case, it is not the $form
and its plugin registry that has to worry about finding/loading/instantiating the custom element; it is the $autoloader
via its $resourceLoader
. In that case, there is no need for the $form->addElementPrefixPath()
, which is essentially a hint to the form on how to find custom elements invoked by shortname.
What we need is to configure the $resourceLoader
back in Bootstrap
so it knows where to find the class. Assuming you stick with empty appnamespace (so your class is named Element_Div
) and you place the file in application/forms/elements/Div.php
, then the $resourceLoader
call is as follows:
$resourceLoader->addResourceTypes(array(
'model' => array(
'namespace' => 'Model_',
'path' => 'models'
),
'element' => array(
'namespace' => 'Element_',
'path' => 'forms/elements'
),
'form' => array(
'namespace' => 'Form_',
'path' => 'forms'
)
));
That should do it. [Famous last words, eh?]