123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589 |
- <?php
- /*
- * This file is part of the Sonata package.
- *
- * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Bundle\BaseApplicationBundle\Controller;
- use Symfony\Bundle\FrameworkBundle\Controller\Controller;
- use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
- use Symfony\Component\Form\Form;
- use Bundle\BaseApplicationBundle\Tool\DoctrinePager as Pager;
- class CRUDController extends Controller
- {
- protected $class;
- protected $list_fields = false;
- protected $form_fields = false;
- protected $base_route = '';
- protected $base_controller_name;
- /**
- * Sets the Container associated with this Controller.
- *
- * @param ContainerInterface $container A ContainerInterface instance
- */
- public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container = null)
- {
- $this->container = $container;
- $this->configure();
- }
- public function configure()
- {
- $this->buildFormFields();
- $this->buildListFields();
- }
- public function getClass()
- {
- return $this->class;
- }
- public function getEntityManager()
- {
- return $this->get('doctrine.orm.default_entity_manager');
- }
-
- public function getClassMetaData()
- {
- $em = $this->getEntityManager();
- return $em->getClassMetaData($this->getClass());
- }
- public function getListQueryBuilder()
- {
- $em = $this->getEntityManager();
- $repository = $em->getRepository($this->getClass());
- $query_buidler = $repository
- ->createQueryBuilder('c');
- return $query_buidler;
- }
- public function getBatchActions()
- {
-
- return array(
- 'delete' => 'Delete'
- );
- }
- public function getUrls()
- {
- return array(
- 'list' => array(
- 'url' => $this->base_route.'_list',
- 'params' => array(),
- ),
- 'create' => array(
- 'url' => $this->base_route.'_create',
- 'params' => array(),
- ),
- 'update' => array(
- 'url' => $this->base_route.'_update',
- 'params' => array()
- ),
- 'delete' => array(
- 'url' => $this->base_route.'_delete',
- 'params' => array()
- ),
- 'edit' => array(
- 'url' => $this->base_route.'_edit',
- 'params' => array()
- ),
- 'batch' => array(
- 'url' => $this->base_route.'_batch',
- 'params' => array()
- )
- );
- }
- public function getUrl($name)
- {
- $urls = $this->getUrls();
- if(!isset($urls[$name])) {
- return false;
- }
-
- return $urls[$name];
- }
- public function listAction()
- {
- $pager = new Pager($this->getClass());
- $url = $this->getUrl('list');
- $pager->setRouter($this->get('router'));
- $pager->setRoute($url['url']);
- $pager->setQueryBuilder($this->getListQueryBuilder());
- $pager->setPage($this->get('request')->get('page', 1));
- $pager->init();
- return $this->render($this->getListTemplate(), array(
- 'pager' => $pager,
- 'fields' => $this->getListFields(),
- 'class_meta_data' => $this->getClassMetaData(),
- 'urls' => $this->getUrls(),
- 'batch_actions' => $this->getBatchActions(),
- ));
- }
- public function getListTemplate()
- {
- return 'BaseApplicationBundle:CRUD:list.twig';
- }
- public function getEditTemplate()
- {
- return 'BaseApplicationBundle:CRUD:edit.twig';
- }
- public function getReflectionFields()
- {
- return $this->getClassMetaData()->reflFields;
- }
- /**
- * make sure the base field are set in the correct format
- *
- * @param $selected_fields
- * @return array
- */
- public function getBaseFields($selected_fields)
- {
- // if nothing is defined we display all fields
- if(!$selected_fields) {
- $selected_fields = array_keys($this->getClassMetaData()->reflFields) + array_keys($this->getClassMetaData()->associationMappings);
- }
- $metadata = $this->getClassMetaData();
- // make sure we works with array
- foreach($selected_fields as $name => $options) {
- if(is_array($options)) {
- $fields[$name] = $options;
- } else {
- $fields[$options] = array();
- $name = $options;
- }
- if(isset($metadata->fieldMappings[$name])) {
- $fields[$name] = array_merge(
- $metadata->fieldMappings[$name],
- $fields[$name]
- );
- }
- if(isset($metadata->associationMappings[$name])) {
- $fields[$name] = array_merge(
- $metadata->associationMappings[$name],
- $fields[$name]
- );
- }
- if(isset($metadata->reflFields[$name])) {
- $fields[$name]['reflection'] =& $metadata->reflFields[$name];
- }
- }
- return $fields;
- }
- /**
- * @return void
- */
- public function configureFormFields()
- {
- }
- public function buildFormFields()
- {
- $this->form_fields = $this->getBaseFields($this->form_fields);
- foreach($this->form_fields as $name => $options) {
- if(!isset($this->form_fields[$name]['options'])) {
- $this->form_fields[$name]['options'] = array();
- }
- if(!isset($this->form_fields[$name]['template']) && isset($this->form_fields[$name]['type'])) {
- $this->form_fields[$name]['template'] = sprintf('BaseApplicationBundle:CRUD:edit_%s.twig', $this->form_fields[$name]['type']);
- if($this->form_fields[$name]['type'] == \Doctrine\ORM\Mapping\ClassMetadataInfo::ONE_TO_ONE)
- {
- $this->form_fields[$name]['template'] = 'BaseApplicationBundle:CRUD:edit_one_to_one.twig';
- }
- if($this->form_fields[$name]['type'] == \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY)
- {
- $this->form_fields[$name]['template'] = 'BaseApplicationBundle:CRUD:edit_many_to_many.twig';
- }
- }
- if(isset($this->form_fields[$name]['id'])) {
- unset($this->form_fields[$name]);
- }
- }
- $this->configureFormFields();
- return $this->form_fields;
- }
- public function buildListFields()
- {
- $this->list_fields = $this->getBaseFields($this->list_fields);
- foreach($this->list_fields as $name => $options) {
- if(!isset($this->list_fields[$name]['type'])) {
- $this->list_fields[$name]['type'] = 'string';
- }
- if(!isset($this->list_fields[$name]['template'])) {
- $this->list_fields[$name]['template'] = sprintf('BaseApplicationBundle:CRUD:list_%s.twig', $this->list_fields[$name]['type']);
- }
- if(isset($this->list_fields[$name]['id'])) {
- $this->list_fields[$name]['template'] = 'BaseApplicationBundle:CRUD:list_identifier.twig';
- }
- }
- if(!isset($this->list_fields['_batch'])) {
- $this->list_fields = array('_batch' => array(
- 'template' => 'BaseApplicationBundle:CRUD:list__batch.twig'
- ) ) + $this->list_fields;
- }
-
- }
- /**
- * Construct and build the form field definitions
- *
- * @return list form field definition
- */
- public function getFormFields()
- {
- return $this->form_fields;
- }
- public function getListFields()
- {
- return $this->list_fields;
- }
- public function batchActionDelete($idx)
- {
- $em = $this->getEntityManager();
- $query_builder = $em->createQueryBuilder();
- $objects = $query_builder
- ->select('o')
- ->from($this->getClass(), 'o')
- ->add('where', $query_builder->expr()->in('o.id', $idx))
- ->getQuery()
- ->execute();
- foreach($objects as $object) {
- $em->remove($object);
- }
- $em->flush();
- // todo : add confirmation flash var
- $url = $this->getUrl('list');
- return $this->redirect($this->generateUrl($url['url']));
- }
- public function deleteAction($id)
- {
- }
- public function editAction($id)
- {
- $this->get('session')->start();
- $fields = $this->getFormFields();
- if($id instanceof Form) {
- $object = $id->getData();
- $form = $id;
- } else {
- $object = $this->get('doctrine.orm.default_entity_manager')->find($this->getClass(), $id);
- if(!$object) {
- throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
- }
- $form = $this->getForm($object, $fields);
- }
- return $this->render($this->getEditTemplate(), array(
- 'form' => $form,
- 'object' => $object,
- 'fields' => $fields,
- 'urls' => $this->getUrls()
- ));
- }
- public function getChoices($description)
- {
- $targets = $this->getEntityManager()
- ->createQueryBuilder()
- ->select('t')
- ->from($description['targetEntity'], 't')
- ->getQuery()
- ->execute();
- $choices = array();
- foreach($targets as $target) {
- // todo : puts this into a configuration option and use reflection
- foreach(array('getTitle', 'getName', '__toString') as $getter) {
- if(method_exists($target, $getter)) {
- $choices[$target->getId()] = $target->$getter();
- break;
- }
- }
- }
- return $choices;
- }
- public function getForm($object, $fields)
- {
- $form = new Form('data', $object, $this->get('validator'));
- foreach($fields as $name => $description) {
- if(!isset($description['type'])) {
- continue;
- }
- switch($description['type']) {
- case \Doctrine\ORM\Mapping\ClassMetadataInfo::MANY_TO_MANY:
- $transformer = new \Symfony\Bundle\DoctrineBundle\Form\ValueTransformer\CollectionToChoiceTransformer(array(
- 'em' => $this->getEntityManager(),
- 'className' => $description['targetEntity']
- ));
- $field = new \Symfony\Component\Form\ChoiceField($name, array_merge(array(
- 'expanded' => true,
- 'multiple' => true,
- 'choices' => $this->getChoices($description),
- 'value_transformer' => $transformer,
- ), $description['options']));
- break;
- case \Doctrine\ORM\Mapping\ClassMetadataInfo::ONE_TO_ONE:
- $transformer = new \Symfony\Bundle\DoctrineBundle\Form\ValueTransformer\EntityToIDTransformer(array(
- 'em' => $this->getEntityManager(),
- 'className' => $description['targetEntity']
- ));
-
- $field = new \Symfony\Component\Form\ChoiceField($name, array_merge(array(
- 'expanded' => false,
- 'choices' => $this->getChoices($description),
- 'value_transformer' => $transformer,
- ), $description['options']));
- break;
-
- case 'string':
- $field = new \Symfony\Component\Form\TextField($name, $description['options']);
- break;
- case 'text':
- $field = new \Symfony\Component\Form\TextareaField($name, $description['options']);
- break;
- case 'boolean':
- $field = new \Symfony\Component\Form\CheckboxField($name, $description['options']);
- break;
- case 'integer':
- $field = new \Symfony\Component\Form\IntegerField($name, $description['options']);
- break;
- case 'decimal':
- $field = new \Symfony\Component\Form\NumberField($name, $description['options']);
- break;
- case 'datetime':
- $field = new \Symfony\Component\Form\DateTimeField($name, $description['options']);
- break;
- case 'date':
- $field = new \Symfony\Component\Form\DateField($name, $description['options']);
- break;
- case 'choice':
- $field = new \Symfony\Component\Form\ChoiceField($name, $description['options']);
- break;
- case 'array':
- $field = new \Symfony\Component\Form\FieldGroup($name, $description['options']);
- $values = $description['reflection']->getValue($object);
- foreach((array)$values as $k => $v) {
- $field->add(new \Symfony\Component\Form\TextField($k));
- }
- break;
- default:
- throw new \RuntimeException(sprintf('unknow type `%s`', $description['type']));
- }
- $form->add($field);
- }
- return $form;
- }
- public function updateAction()
- {
- $this->get('session')->start();
- if($this->get('request')->getMethod() != 'POST') {
- throw new \RuntimeException('invalid request type, POST expected');
- }
- $id = $this->get('request')->get('id');
- if(is_numeric($id)) {
- $object = $this->get('doctrine.orm.default_entity_manager')->find($this->getClass(), $id);
- if(!$object) {
- throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
- }
- $action = 'edit';
- } else {
- $class = $this->getClass();
- $object = new $class;
- $action = 'create';
- }
- $fields = $this->getFormFields();
- $form = $this->getForm($object, $fields);
- $form->bind($this->get('request')->get('data'));
- if($form->isValid()) {
- $this->getEntityManager()->persist($object);
- $this->getEntityManager()->flush($object);
- // redirect to edit mode
- $url = $this->getUrl('edit');
- return $this->redirect($this->generateUrl($url['url'], array('id' => $object->getId())));
- }
- return $this->forward(sprintf('%s:%s', $this->getBaseControllerName(), $action), array(
- 'id' => $form
- ));
- }
- public function batchAction()
- {
- if($this->get('request')->getMethod() != 'POST') {
- throw new \RuntimeException('invalid request type, POST expected');
- }
- $action = $this->get('request')->get('action');
- $idx = $this->get('request')->get('idx');
- if(count($idx) == 0) { // no item selected
- // todo : add flash information
- $url = $this->getUrl('list');
- return $this->redirect($this->generateUrl($url['url']));
- }
- // execute the action, batchActionXxxxx
- $final_action = sprintf('batchAction%s', ucfirst($action));
- if(!method_exists($this, $final_action)) {
- throw new \RuntimeException(sprintf('A %s::%s method must be created', get_class($this), $final_action));
- }
- return call_user_func(array($this, $final_action), $idx);
- }
- public function createAction($form = null)
- {
- $this->get('session')->start();
- $fields = $this->getFormFields();
- if($form instanceof Form) {
- $object = $form->getData();
- } else {
- $class = $this->getClass();
- $object = new $class;
- $form = $this->getForm($object, $fields);
- }
- return $this->render($this->getEditTemplate(), array(
- 'form' => $form,
- 'object' => $object,
- 'fields' => $fields,
- 'urls' => $this->getUrls()
- ));
- }
- public function setBaseControllerName($base_controller_name)
- {
- $this->base_controller_name = $base_controller_name;
- }
- public function getBaseControllerName()
- {
- return $this->base_controller_name;
- }
- public function setBaseRoute($base_route)
- {
- $this->base_route = $base_route;
- }
- public function getBaseRoute()
- {
- return $this->base_route;
- }
- }
|