Я пишу контроллер для обработки основных функций CRUD и хотел бы знать, правильно ли я понял.
Symfony обладает множеством отличных функциональных возможностей. Интересно, если я изобрету велосипед в этом случае. У меня есть около 20 классов, которые будут расширены CRUDController и я хотел бы использовать лучшие практики, как можно раньше.
Заранее спасибо!
CRUDController.php
namespace myApp\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\BrowserKit\Response;
use Symfony\Component\HttpFoundation\Request;
class CRUDController extends Controller {
protected $repo;
protected $em = 'doctrine.orm.entity_manager';
protected $templatePath;
protected $itemsAlias = 'items';
protected $itemAlias = 'item';
protected $listingTemplate = 'list';
protected $saveTemplate = 'save';
protected $templateFileExtension = '.html.twig';
protected $entity;
protected $formType;
protected $formMethod = 'POST';
protected $indexRoute;
protected $addSuccessMessage = 'Added.';
protected $addErrorMessage = 'Not added';
protected $editSuccessMessage = 'Edited.';
protected $editErrorMessage = 'Not Edited.';
public function indexAction()
{
return $this->render($this->templatePath . $this->listingTemplate . $this->templateFileExtension, array(
$this->itemsAlias => $this->get($this->repo)->findAll()
));
}
public function addAction(Request $request) {
return $this->save($request);
}
public function editAction($id, Request $request) {
return $this->save($request, $id);
}
protected function save(Request $request, $id = null) {
if (is_null($id)) {
$item = new $this->entity();
} else {
$item = $this->get($this->repo)->find($id);
}
$form = $this->createForm(new $this->formType(), $item);
if ($request->isMethod($this->formMethod)) {
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->get($this->em);
$em->persist($item);
$em->flush();
$this->get('session')->getFlashBag()->add(
'success',
is_null($id) ? $this->addSuccessMessage : $this->editSuccessMessage
);
} else {
$this->get('session')->getFlashBag()->add(
'error',
is_null($id) ? $this->addErrorMessage : $this->editErrorMessage
);
}
return $this->redirect($this->generateUrl($this->indexRoute));
}
return $this->render($this->templatePath . $this->saveTemplate . $this->templateFileExtension, array(
'form' => $form->createView(),
$this->itemAlias => $item
));
}
}
MyController.php
namespace myApp\MyBundle\Controller;
use myApp\MyBundle\CRUDController;
class MyController extends CRUDController {
public function __construct() {
parent::__construct();
$this->repo = 'myapp.service.repository.item';
$this->templatePath = '@myapp/items/';
$this->itemsAlias = 'myItems';
$this->itemAlias = 'myItem';
$this->entity = 'myApp\myBundle\Entity\Item';
$this->formType = 'myApp\myBundle\Form\Type\ItemType';
$this->indexRoute = 'items_index';
}
}
Основываясь на моем опыте — «Универсальный контроллер Crud» полезен только при запуске проекта. Во время разработки многие объекты требуют пользовательских модификаций.
Вторая вещь о вашей идее: в методе сохранения вы должны иметь IF $em->persist($item);
потому что существующие сущности не могут быть сохранены снова.
И последнее: во время разработки (и использования этого кода) вам следует подумать о «собственной стороне» отношений, поскольку Doctrine может обрабатывать изменения только на собственной стороне. Это производит проблему как это:
Товар имеет много категорий — отношение двунаправленное. Таблица соединений находится в аннотации продукта. Вы можете добавить категорию в продукт и сохранить ее успешно. Но добавление продукта в категорию не приведет к сохранению изменений в базе данных (конечно, вы можете обработать это вручную во время сохранения:]).
Других решений пока нет …