Пара предложений:
Прежде всего - используйте функцию init()
вместо конструкторов, чтобы добавить свои элементы, когда вы создаете подклассы формы. Функция init () происходит после установки параметров, которые вы передаете классу.
Второй - вместо того, чтобы создавать подклассы для вашей формы - вы можете просто установить «опцию», чтобы включить админ:
class My_Record_Form extends Zend_Form {
protected $_record = null;
public function setRecord($record) {
$this->_record = $record;
}
public function getRecord() {
if ($this->_record === null || (!$this->_record instanceOf My_Record)) {
throw new Exception("Record not set - or not the right type");
}
return $this->_record;
}
protected $_admin = false;
public function setAdmin($admin) {
$this->_admin = $admin;
}
public function getAdmin() { return $this->_admin; }
public function init() {
$record = $this->getRecord();
$this->addElement(......);
$this->addElement(......);
$this->addElement(......);
if ($this->getAdmin()) {
$this->addElement(.....);
}
$this->setDefaults($record->toArray());
}
public function process(array $data) {
if ($this->isValid($data)) {
$record = $this->getRecord();
if (isset($this->delete) && $this->delete->getValue()) {
// delete button was clicked
$record->delete();
return true;
}
$record->setFromArray($this->getValues());
$record->save();
return true;
}
}
}
Тогда в вашем контроллере вы можете сделать что-то вроде:
$form = new My_Record_Form(array(
'record'=>$record,
'admin'=>My_Auth::getInstance()->hasPermission($record, 'admin')
));
Нет ничего "неправильного" в создании My_Record_Admin_Form, который также обрабатывает административные материалы - но я обнаружил, что этот метод хранит весь код "формы записи" в одном месте и его немного проще поддерживать.
Чтобы ответить на раздел 2: формы редактирования в моем коде возвращаются из функции модели: $record->getEditForm()
Код контроллера в конечном итоге выглядит примерно так:
protected $_domain = null;
protected function _getDomain($allowNew = false)
{
if ($this->_domain)
{
return $this->view->domain = $this->_domain;
} else {
$id = $this->_request->getParam('id');
if (($id == 'new' || $id=='') && $allowNew)
{
MW_Auth::getInstance()->requirePrivilege($this->_table, 'create');
$domain = $this->_table->createRow();
} else {
$domain = $this->_table->find($id)->current();
if (!$domain) throw new MW_Controller_404Exception('Domain not found');
}
return $this->view->domain = $this->_domain = $domain;
}
}
public function editAction()
{
$domain = $this->_getDomain(true);
MW_Auth::getInstance()->requirePrivilege($domain,'edit');
$form = $domain->getEditForm();
if ($this->_request->isPost() && $form->process($this->_request->getPost()))
{
if ($form->delete && $form->delete->getValue())
{
return $this->_redirect($this->view->url(array(
'controller'=>'domain',
'action'=>'index',
), null, true));
} else {
return $this->_redirect($this->view->url(array(
'controller'=>'domain',
'action'=>'view',
'id'=>$form->getDomain()->id,
), null, true));
}
}
$this->view->form = $form;
}
Итак - фактический идентификатор записи передается, например, в URI / domain / edit / id / 10. Если вам нужно разместить несколько таких форм на странице - вы должны обязательно установить атрибут «action» формы, чтобы он указывал на действие, специфичное для этой формы.