Кажется, вы перепутали некоторые обязанности в вашей форме, модели и контроллере. Обычно я представляю сервисный уровень, когда у меня есть некоторые взаимодействия с моделями из контроллера, основанные на данных формы.
Кроме того, я вижу, что вы обрабатываете несколько функций в одном действии, которое я бы разделил между различными действиями. Если вы работаете с моделью Company
, я бы предложил создать CompanyController:
class CompanyController extends Zend_Controller_Action {}
Затем, возможно, вы захотите просмотреть сведения о компании на одной странице, изменить их на другой и создать новый экземпляр на третьей странице. Я обычно делаю это с viewAction()
, editAction()
и newAction()
:
public function indexAction ()
{
$service = new Cas_Service_Company;
$companies = $service->getAllCompanies();
if (!count($companies)) {
throw new Zend_Controller_Action_Exception('No companies found');
}
$this->view->companies = $companies;
}
public function viewAction ()
{
$service = new Cas_Service_Company;
$company = $service->getCompany($this->getRequest()->getQuery('id'));
if (false === $company) {
throw new Zend_Controller_Action_Exception('Company not found');
}
$this->view->company = $company;
}
public function editAction ()
{
$request = $this->getRequest();
$service = new Cas_Service_Company;
$company = $service->getCompany($request->getQuery('id'));
if (false === $company) {
throw new Zend_Controller_Action_Exception('Company not found');
}
$form = new Cas_Form_Company(array('company' => $company));
if ($request->isPost() && $form->isValid($request->getPost())) {
$service->updateCompany($company, $form);
// redirect here to company view for example
}
$this->view->form = $form;
$this->view->company = $company;
}
public function newAction ()
{
$request = $this->getRequest();
$form = new Cas_Form_Company;
if ($request->isPost() && $form->isValid($request->getPost())) {
$company = $service->createCompany($form);
// redirect here to company view for example
}
$this->view->form = $form;
}
public function deleteAction ()
{
$request = $this->getRequest();
$form = new Cas_Form_DeleteCompany;
if ($request->isPost() && $form->isValid($request->getPost())) {
$service->deleteCompany($form);
// redirect here to index for example
}
$this->view->form = $form;
}
Теперь у вас есть отдельные действия для всех функций, довольно просто настроить форму для Company
:
class Cas_Form_Company extends Zend_Form
{
protected $_company;
public function init ()
{
$this->addElement('text', 'name', array(
'label' => 'Name'
));
// More elements here
if (null !== $this->_company) {
$this->populate($this->_company->toArray());
}
}
public function setCompany (Cas_Model_Company $company)
{
$this->_company = $company;
}
}
В форме я использую несколько полезных функций:
- Используйте
init()
вместо __construct()
, не нужно звонить parent::__construct()
и вызывается setOptions()
. Это полезно для № 2 здесь:
- Используйте сеттер для
Cas_Model_Company
. Когда вам нужно больше зависимостей, нужно просто поместить их в массив при создании формы (см. editAction()
в качестве примера в контроллере)
- Внедрить данные формы просто путем проверки, если вы установили
$this->_company
. В моем случае я использую Doctrine, поэтому toArray()
уже есть. В противном случае вам нужно создать этот метод самостоятельно.
Последний кусок, который соберет все воедино - это сервисный уровень. Мартин Фаулер также описал это в своей книге P EAA и на своем сайте: http://martinfowler.com/eaaCatalog/serviceLayer.html
Типичный класс обслуживания в моем случае всегда выглядит так:
class Cas_Service_Company
{
public function getCompany ($id)
{
// Get a Cas_Model_Company and load data from database
// Example for Doctrine:
$company = new Cas_Model_Company;
$company = $company->find($id);
return $company;
}
public function getAllCompanies ()
{
// Get a Cas_Model_Company and load all data from database
// Example for Doctrine:
$company = new Cas_Model_Company;
$companies = $company->findAll();
return $companies;
}
public function updateCompany (Cas_Model_Company $company, Cas_Form_Company $form)
{
// Update model with new form data
// Example for Doctrine:
$company->fromArray($form->toArray());
$company->save();
return $company;
}
public function createCompany (Cas_Form_Company $form)
{
// Create model with form data
// Example for Doctrine:
$company = new Cas_Model_Company;
$company->fromArray($form->toArray());
$company->save();
return $company;
}
public function deleteCompany (Cas_Form_DeleteCompany $form)
{
// Get a Cas_Model_Company and load data from database
// Example for Doctrine:
$company = new Cas_Model_Company;
$company = $company->find($form->getValue('id'));
// Remove this instance
if (false !== $company) {
$company->delete();
return true;
} else {
return false;
}
}
}
С этим видом сервисного уровня вы храните весь код для доступа и изменения моделей в одном месте. Когда вам нужен еще один запрос (найдите компанию на основе определенных критериев), вы можете просто добавить этот метод в класс вашего сервера и вызвать метод (например) в контроллере. Он сохранит ваш код очень в чистоте.
В заключение: используйте сервисный уровень и просто используйте контроллер в качестве информационного агента: получите данные из источника A и перенесите их в точку B. Сделайте установщик для вашей формы, чтобы принять модель и использовать ее как своего рода декоратор рисунок