Skip to content

Instantly share code, notes, and snippets.

@maximecolin
Last active August 29, 2015 14:07
Show Gist options
  • Save maximecolin/72fe8ccb2fb3be220335 to your computer and use it in GitHub Desktop.
Save maximecolin/72fe8ccb2fb3be220335 to your computer and use it in GitHub Desktop.
Admin
<?php
namespace Colin\Bundle\AdminBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Provides CRUD actions.
*/
abstract class AdminController extends Controller
{
/**
* Get name
*
* @return string
*/
abstract public function getName();
/**
* Get entity
*
* @return string
*/
abstract public function getEntity();
/**
* Generate list url
*
* @return string
*/
protected function generateListUrl()
{
return $this->generateUrl(sprintf('%s_index', $this->getName()));
}
/**
* Generate create url
*
* @return string
*/
protected function generateCreateUrl()
{
return $this->generateUrl(sprintf('%s_create', $this->getName()));
}
/**
* Generate read url
*
* @param object $entity
* @return string
*/
protected function generateReadUrl($entity)
{
return $this->generateUrl(sprintf('%s_read', $this->getName()), array('id' => $entity->getId()));
}
/**
* Generate update url
*
* @param object $entity
* @return string
*/
protected function generateUpdateUrl($entity)
{
return $this->generateUrl(sprintf('%s_update', $this->getName()), array('id' => $entity->getId()));
}
/**
* Generate delete url
*
* @param object $entity
* @return string
*/
protected function generateDeleteUrl($entity)
{
return $this->generateUrl(sprintf('%s_delete', $this->getName()), array('id' => $entity->getId()));
}
/**
* Add flash message
*
* @param string $type
* @param string $message
*/
protected function addFlash($type, $message)
{
$this->getSession()->getFlashBag()->add($type, $message);
}
/**
* Paginate list
*
* @param array $filters
* @param integer $page
* @param integer $maxPerPage
* @param array $options
* @return \Knp\Component\Pager\Pagination\PaginationInterface
*/
protected function paginate(array $filters = array(), $page = 1, $maxPerPage = 10, array $options = array())
{
$entityManager = $this->getDoctrine()->getManager();
$repository = $entityManager->getRepository($this->getEntity());
$query = method_exists($repository, 'getListQuery') ?
$repository->getListQuery($filters) :
$repository->createQueryBuilder('entity')->getQuery();
return $this->getPaginator()->paginate($query, $page, $maxPerPage, $options);
}
/**
* Get session
*
* @return \Symfony\Component\HttpFoundation\Session\SessionInterface
*/
protected function getSession()
{
return $this->get('session');
}
/**
* Set filters to session
*
* @param array $data
*/
protected function setFilters(array $data = array())
{
$data = $this->flat($data);
$this->getSession()->set(sprintf('%s.filters', $this->getName()), $data);
}
/**
* Get filters from session
*
* @param array $data
* @return array
*/
protected function getFilters(array $data = array())
{
$data = array_merge(
$data,
$this->unflat($this->getSession()->get(sprintf('%s.filters', $this->getName()), array()))
);
return $data;
}
/**
* Get paginator
*
* @return \Knp\Component\Pager\PaginatorInterface
*/
protected function getPaginator()
{
return $this->get('knp_paginator');
}
/**
* Flat data for session storage
*
* @param mixed $value
* @return array
*/
private function flat($value)
{
// @todo Replace by an object filter and a normalizer
if (is_array($value)) {
return array(
'type' => 'array',
'values' => array_map(array($this, 'flat'), $value)
);
} else {
if (is_object($value)) {
if (!$value instanceof \DateTime) {
return array(
'type' => 'entity',
'class' => get_class($value),
'id' => $value->getId()
);
}
}
return array(
'type' => 'scalar',
'value' => $value
);
}
}
/**
* Unflat data from session
*
* @param mixed $value
* @return array
*/
private function unflat($value)
{
// @todo Replace by an object filter and a normalizer
$entityManager = $this->getDoctrine()->getManager();
if (is_array($value) && isset($value['type'])) {
if ($value['type'] === 'entity') {
return $entityManager->getRepository($value['class'])->find($value['id']);
}
if ($value['type'] === 'scalar') {
return $value['value'];
}
if ($value['type'] === 'array') {
return array_map(array($this, 'unflat'), $value['values']);
}
return $value;
}
return $value;
}
/**
* List entities
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\Form\FormTypeInterface $type
* @param array $filters
* @return array
*/
protected function index(Request $request, FormTypeInterface $type = null, array $filters = array(), $maxPerPage = 10)
{
$filters = $this->getFilters($filters);
if ($type) {
$form = $this->createFilterForm($type, $filters);
if ($form->handleRequest($request)->isValid()) {
$this->setFilters($form->getData());
return $this->redirect($this->generateListUrl());
}
} else {
$form = false;
}
$entities = $this->paginate($filters, $request->query->get('page', 1), $maxPerPage);
return array(
'entities' => $entities,
'form' => $form ? $form->createView() : $form,
);
}
/**
* Create filter form
*
* @param \Symfony\Component\Form\FormTypeInterface $type
* @param array $filters
* @return \Symfony\Component\Form\Form
*/
protected function createFilterForm(FormTypeInterface $type, array $filters = array())
{
$form = $this->createForm($type, $filters, array(
'action' => $this->generateListUrl(),
'method' => 'POST'
));
$form->add('filter', 'submit', array('label' => 'Filter'));
$form->add('reset', 'submit', array('label' => 'Reset'));
return $form;
}
/**
* Create entity
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\Form\FormTypeInterface $type
* @param object $entity
* @return array
*/
protected function create(Request $request, FormTypeInterface $type, $entity)
{
$form = $this->createCreateForm($type, $entity);
if ($form->handleRequest($request)->isSubmitted()) {
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($entity);
$entityManager->flush();
$this->addFlash('success', sprintf('%s.create.success', $this->getName()));
return $this->redirect($this->generateListUrl());
} else {
$this->addFlash('error', sprintf('%s.create.error', $this->getName()));
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
/**
* Create create form
*
* @param \Symfony\Component\Form\FormTypeInterface $type
* @param object $entity
* @return \Symfony\Component\Form\Form
*/
protected function createCreateForm(FormTypeInterface $type, $entity)
{
$form = $this->createForm($type, $entity, array(
'action' => $this->generateCreateUrl(),
'method' => 'POST'
));
$form->add('submit', 'submit', array('label' => 'Add'));
return $form;
}
/**
* Read entity
*
* @param object $entity
* @return array
*/
protected function read($entity)
{
return array(
'entity' => $entity
);
}
/**
* Update entity
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\Form\FormTypeInterface $type
* @param object $entity
* @return array
*/
protected function update(Request $request, FormTypeInterface $type, $entity, array $data = array())
{
$form = $this->createUpdateForm($type, $entity);
if ($form->handleRequest($request)->isSubmitted()) {
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->flush();
$this->addFlash('success', sprintf('%s.update.success', $this->getName()));
return $this->redirect($this->generateUpdateUrl($entity));
} else {
$this->addFlash('error', sprintf('%s.update.error', $this->getName()));
}
}
return array_merge($data, array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Create update form
*
* @param \Symfony\Component\Form\FormTypeInterface $type
* @param object $entity
* @return \Symfony\Component\Form\Form
*/
protected function createUpdateForm(FormTypeInterface $type, $entity)
{
$form = $this->createForm($type, $entity, array(
'action' => $this->generateUpdateUrl($entity),
'method' => 'POST'
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Delete entity
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param object $entity
* @return array
*/
protected function delete(Request $request, $entity)
{
$form = $this->createDeleteForm($entity);
if ($form->handleRequest($request)->isSubmitted()) {
if ($form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($entity);
$entityManager->flush();
$this->addFlash('success', sprintf('%s.delete.success', $this->getName()));
return $this->redirect($this->generateListUrl());
} else {
$this->addFlash('error', sprintf('%s.delete.error', $this->getName()));
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
/**
* Create delete form
*
* @param object $entity
* @return \Symfony\Component\Form\Form
*/
protected function createDeleteForm($entity)
{
$form = $this
->createFormBuilder($entity, array(
'action' => $this->generateDeleteUrl($entity),
'method' => 'DELETE'
))
->add('submit', 'submit', array('label' => 'Delete'))
->getForm();
return $form;
}
}
<?php
namespace Colin\Bundle\AdminBundle\Controller\Blog;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Colin\Bundle\AdminBundle\Form\Type\Blog\CategoryType;
use Colin\Bundle\AdminBundle\Controller\AdminController;
use Colin\Entity\Blog\Category;
/**
* Blog category admin controller
*
* @Route("/blog/category")
*/
class CategoryController extends AdminController
{
/**
* {@inheritdoc}
*/
public function getName()
{
return 'admin_blog_category';
}
/**
* {@inheritdoc}
*/
public function getEntity()
{
return 'Colin:Blog\Category';
}
/**
* @Route("/", name="admin_blog_category_index")
* @Template()
*/
public function indexAction(Request $request)
{
return $this->index($request, new CategoryFilterType());
}
/**
* @Route("/create", name="admin_blog_category_create")
* @Template()
*/
public function createAction(Request $request)
{
$entity = new Category();
return $this->create($request, new CategoryType(), $entity);
}
/**
* @Route("/{id}", name="admin_blog_category_read")
* @Template()
*/
public function readAction(Category $entity)
{
return array(
'entity' => $entity
);
}
/**
* @Route("/{id}/update", name="admin_blog_category_update")
* @Template()
*/
public function updateAction(Request $request, Category $entity)
{
return $this->update($request, new CategoryType(), $entity);
}
/**
* @Route("/{id}/delete", name="admin_blog_category_delete")
* @Template()
*/
public function deleteAction(Request $request, Category $entity)
{
return $this->delete($request, $entity);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment