I'm still wondering when and where I have to register new classes and how to extend old ones. For example I found a nice code which extends Zend_Form_Element_Select so that I can use it in each form and pass my database specifications to.
Because I thought, it would be a good idea to have an own directory I added a folder src\Service at modulelevel.
First question: Is that clever to have it at modulelevel? Would it be more convenient to have it at rootlevel so that I could use it in several modules? Do I have to register it?
The class extends Zend_Form_Element_Select which I added with a use statement:
use Zend\Form\Element\Select;
This causes a fatal error :
Fatal error: Class 'Import\Service\Zend_Form_Element_Select' not found
This would be my next question: How can I add this Zend_Form_Element properly. I think the problem might be that Zend doesn't look in the Zend-Directory. But I used the Zend_Form_Element_Select in other forms so it is there. But my new class doesn't know it. How would I do it, if I want to use own classes which of course use Zend-Classes?
I'm searching basically for a way how to do it in general. The target would be to easy reuse classes in other projects.
EDIT1: additional code snippets
here is the class I found online:
Module\Import\src\Service\CU_Form_Element_DbSelect
<?php
namespace Import\Service;
use Zend\Form\Form;
use Zend\Form\Element\Select;
use Zend\Form\Element;
class CU_Form_Element_DbSelect extends Zend_Form_Element_Select {
private $_dbAdapter;
private $_dbSelect;
private $_identityColumn = 'id';
private $_valueColumn = '';
/**
* Set the database adapter used
* @param Zend_Db_Adapter_Abstract $adapter
*/
public function setDbAdapter(Zend_Db_Adapter_Abstract $adapter) {
$this->_dbAdapter = $adapter;
}
/**
* Set the query used to fetch the data
* @param string|Zend_Db_Select $select
*/
public function setDbSelect($select) {
$this->_dbSelect = $select;
}
/**
* Set the column where the identifiers for the options are fetched
* @param string $name
*/
public function setIdentityColumn($name) {
$this->_identityColumn = $name;
}
/**
* Set the column where the visible values in the options are fetched
* @param string $name
*/
public function setValueColumn($name) {
$this->_valueColumn = $name;
}
public function render(Zend_View_Interface $view = null) {
$this->_performSelect();
return parent::render($view);
}
private function _performSelect() {
if(!$this->_dbAdapter)
$this->_dbAdapter = Zend_Db_Table::getDefaultAdapter();
$stmt = $this->_dbAdapter->query($this->_dbSelect);
$results = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
$options = array();
foreach($results as $r) {
if(!isset($r[$this->_identityColumn])) {
throw new Zend_Form_Element_Exception(
'Identity column is not present in the result');
}
if(!isset($r[$this->_valueColumn])) {
throw new Zend_Form_Element_Exception(
'Value column is not present in the result');
}
$options[$r[$this->_identityColumn]] = $r[$this->_valueColumn];
}
$this->setMultiOptions($options);
}
}
Here also a snippet of my first form in which I wanted to use it in:
namespace Import\Form;
use Zend\Form\Form;
use Import\Service\CU_Form_Element_DbSelect;
.....
$this->add(new CU_Form_Element_DbSelect(array(
'name' => 'ProjectID',
'dbAdapter' => $this->db,
'dbSelect' => 'SELECT ProjectID, Projectname FROM t_project',
'valueColumn' => 'ProjectID',
'label' => 'Choose project'
)));
For me the error message looks like extends Zend_Form_Element_Select is not found.
There is no problem to have your own class on module level. You also can use it on another module. Just call the class using
use. As long as the module registered inconfig/modules.config.phpyou can use it in another modules.Where is to put the
class? Depend on your need. You can put it in root of moduleor you can put it on
Servicefolder. I usually put my own class on this folder if this class can be used as serviceAnd about this error, please add
namespace Import\Serviceto yourZend_Form_Element_Selectclass.I see this caused by
Autoloadercannot find it because it don't use the correctnamespace. Please use the correct namespace, related the module name and path (eg:Import\Service).To make your class reusable in another project, you can follow how
Zend Modulescreated. They can be install and uninstall using composer. The first, you need to know how composer work.