Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Config][Feature] Extending routing config with some more options!? #4436

Copy link
Copy link
Closed
@sensi

Description

@sensi
Issue body actions

Some time ago I've start writing a bundle which allows me to add some custom options to the routing config.
And now I'm finished with it and I'm using it in different projects successfully.
Ok so now here my idea:

Here is one of my basic config which I get from my customized crud generator.

# Basic show action which should basicle render a show.html.twig template...
m3panel_project_show:
    pattern: /{id}/show
    defaults: { _controller: "M3AppTbBundle:Project:show" }
    requirements: 
       id: \d+
    options:
        m3args:
            template: M3AppTbBundle:Project:show.html.twig
            onError:
                action: render
                flash: { 0:'No Project found!' }
                template: M3AppTbBundle:Project:show.html.twig

# Same as above but here defined some default params for the template.
m3panel_project_list:
    pattern: /list/{count}/{order}/{opt}
    defaults: { _controller: "M3AppTbBundle:Project:show" }
    requirements: 
       count: \d+ | all
       order: 
       opt: ASC | DESC | asc | desc
    options:
        m3args:
            template: M3AppTbBundle:Project:list.html.twig
            onError:
                action: render
                flash: { 0:'No Project found!' }
                template: M3AppTbBundle:Project:list.html.twig
                params: {'count':'all' 'order':'id' 'opt':'desc'}

# Something advanced: You can add validation_groups to use in current form.
# What should happen after form submit: 2 Options => onSuccess or onError
# after selecting the status of your form you the given action (possible: render or redirect) will be executed. 
# The callback is an optional method with get's called to execute some custom code before the data gets persisted.

m3panel_project_new:
    pattern:  /new
    defaults: { _controller: "M3AppTbBundle:Project:new" }
    options:
        m3args:
            form_options:
                validation_groups: create
            template: M3AppTbBundle:Project:new.html.twig
            callback: _newHook
            onSuccess:
                action: redirect
                route: m3panel_project_new
                flash: { 0:'Project [%s] succussfully created.' 1:'id' }  # Notice: you can here select any method name. By default id is used because every entity has an id!
            onError:
                action: render
                flash: { 0:'Creation of Project failed!' }
                template: M3AppTbBundle:Project:new.html.twig

m3panel_project_edit:
    pattern:  /{id}/edit
    defaults: { _controller: "M3AppTbBundle:Project:edit" }
    options:
        m3args:
            template: M3AppTbBundle:Project:edit.html.twig
            callback: _editHook
            onSuccess:
                action: redirect
                route: m3panel_project_edit
                flash: { 0:'Project [%s] succussfully updated.' 1:'name' }  
                params: {0:'id'}
            onError:
                action: render
                flash: { 0:'Update failed! Your form is not valid.' }
                template: M3AppTbBundle:Project:edit.html.twig
                params: {0:'id'}

m3panel_project_delete:
    pattern:  /delete/{id}
    defaults: { _controller: "M3AppTbBundle:Project:delete" }
    requirements: { _method: post }
    options:
        m3args:
            onSuccess:
                action: redirect
                route: m3panel_project_show_all
                flash: { 0:'Project [%s] succussfully deleted.' 1:'name' }
            onError:
                action: redirect
                route: m3panel_project_show_all
                flash: { 0:'Can not delete Project [%s]!' 1:'id' }

Next I've written an abstract EntityController which handles all this options shown above.

So at this point my customized CRUD generator does also the work for me and a simple controller can look like this:

<?php

namespace M3\App\TbBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;

use M3\Bundle\FrameworkBundle\Controller\EntityController;

use M3\App\TbBundle\Entity\Project;
use M3\App\TbBundle\Form\ProjectType;

/**
 * Project controller.
 *
 */
class ProjectController extends EntityController
{
    public function __construct() {
        $this->setEntity( new Project() );
        $this->setFormType( new ProjectType() );
        $this->sEntityRepository = 'M3AppTbBundle:Project'; 
    }
    /**
     * Finds and displays a Project entity.
     *
     */
    public function showAction(Request $request)
    {
        $aResult = parent::showAction($request);
        $id = $request->get('id', null);
        if (!is_null($id)) {
            $deleteForm = $this->createDeleteForm($id);
            $aResult['delete_form'] = $deleteForm->createView();
            return $this->render('M3AppTbBundle:Project:show.html.twig', $aResult);
        }
                $aResult['delete_form'] = $this->createFormBuilder(array('action' => 'delete_entities'))
            ->getForm()
            ->createView()
        ;        
        return $this->render('M3AppTbBundle:Project:list.html.twig', $aResult);
    }

    /**
     * Displays a form to create a new Project entity.
     *
     */
    public function newAction(Request $request) {

        $form = parent::newAction($request);

        if ($form instanceof RedirectResponse) {
            return $form;
        }

        if ($form instanceof Response) {
            return $form;
        }


        // Data for the template
        $aResult = array( 'entity' => $this->oEntity,
                          'form' => $form->createView());


        // Process m3args template if exists
        if (null !== $this->getM3ArgsKey('template')) {
            return $this->render($this->getM3ArgsKey('template'), $aResult);    
        } 

        // Notice by default it is also possible to return the $form directly instead of $aResult. But we wanna customize the data a little before we give it to the template...
        return $this->render('M3AppTbBundle:Project:new.html.twig', $aResult);
    }

    /**
     * New persistence hook. Gets executed before entity is created/persited.
     *
     * @param Project $entity
     * @return Project
     */
    protected function _newHook($entity) {
        // Place your custom code here. Gets executed before entity gets persited (create)
        if (false) {
            // Return false to stop entity persistence...
            return false; // => executeFormError()
            // Return true if you allready have persist the entity manually
            return true; // => executeFormSuccess()
        }

        return $entity;     // Do not remove this line!
    }

    /**
     * Displays a form to edit an existing Project entity.
     *
     */
    public function editAction(Request $request)
    {
                $aResult = array();
                $editForm = parent::editAction($request);

        if ($editForm instanceof RedirectResponse) {
            return $editForm;
        }

        if ($editForm instanceof Response) {
            return $editForm;
        }

        $id = $request->get('id');
        $aResult['edit_form'] = $editForm->createView();
        $aResult['delete_form'] = $this->createDeleteForm($id)->createView();
        $aResult['context'] = $editForm->getData();

        // Process m3args template if exists
        if (null !== $this->getM3ArgsKey('template')) {
            return $this->render($this->getM3ArgsKey('template'), $aResult);    
        }

        return $this->render('M3AppTbBundle:Project:edit.html.twig', $aResult);
    }

    /**
     * Edit persistence hook. Gets executed before an entity is updated/persited.
     *
     * @param Project $entity
     * @return Project
     */
    protected function _editHook($entity) {

        $entity = $this->_newHook($entity, true);
        $this->executeFormSuccess($entity, true, true, false);
        $this->persist($entity);

        return true;
    }

    public function deleteAction(Request $request)
    {
        $aResult = parent::deleteAction($request);

        return $aResult;
    }


}

That's it. No I've have a fully functional CRUD which is confinable in routing config file.
I hope my explanation for the first is enough to understand how it basically works.

My question is now. Does it make sense to implement this feature into the symfony core by adding a new controller (I call it EntityController) which everyone can use if necessary...
Or is a standalone bundle the better choice??

I think it would be a nice feature in the symfony2 core because in future it should be possible to config a big range of things only with the config files and get a really good and working generated skeleton to work with.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.