Forráskód Böngészése

will commit later on in a PR with some updates

Nicolas Ricci 11 éve
szülő
commit
1e9368a88e
1 módosított fájl, 0 hozzáadás és 283 törlés
  1. 0 283
      Resources/doc/cookbook/recipe_sortable_listing.rst

+ 0 - 283
Resources/doc/cookbook/recipe_sortable_listing.rst

@@ -1,283 +0,0 @@
-Sortable behavior in admin listing
-==================================
-
-This is a full working example of how to implement a sortable feature in your Sonata admin listing
-
-Background
-----------
-
-A sortable behavior is already available for one-to-many relationships (http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html#advanced-usage-one-to-many). 
-However there is no packaged solution to have some up and down arrows to sort your records such as showed in the following screen
-
-list.jpg
-
-
-Pre-requisites
---------------
-
-- you already have SonataAdmin and DoctrineORM up and running
-- you already have an Entity class for which you want to implement a sortable feature. For the purpose of the example we are going to call it ``Client``.
-- you already have an Admin set up, in this example we will call it ``ClientAdmin``
-- you already have gedmo/doctrine-extensions bundle in your project (check stof/doctrine-extensions or knplabs/doctrine-behaviors for easier integration in your project) with the sortable feature enabled
-
-The recipe
-----------
-
-First of are going to add a position field in our ``Client`` entity.
-
-.. code-block:: php
-
-    /**
-     * @Gedmo\SortablePosition
-     * @ORM\Column(name="position", type="integer")
-     */
-    private $position;
-
-
-
-In ``ClientAdmin`` our we are going to add in the ``configureListFields`` method a custom action
-
-.. code-block:: php
-
-	$listMapper
-	->add('_action', 'actions', array(
-                'actions' => array(
-                    'move' => array('template' => 'AcmeDemoBundle:Admin:_sort.html.twig'),
-                )
-            ));
-
-
-
-In order to add new routes for these actions we are also adding the following method
-
-.. code-block:: php
-
-	protected function configureRoutes(RouteCollection $collection)
-	{
-	collection->add('move', $this->getRouterIdParameter() . '/move/{position}');
-	}
-
-
-Moving up the position is not a problem since we now the top position will be 0. However moving down requires a bit more of logic since we need to know what is the last position. In order to get this done we are going to implement a service with a method returning the last position and another returning the position to move our object to.
-
-
-.. code-block:: php
-
-	<?php
-	
-	namespace Acme\DemoBundle\Services;
-	
-	use Doctrine\ORM\EntityManager;
-	
-	class PositionHandler
-	{
-	
-	    /**
-	     *
-	     * @var EntityManager
-	     */
-	    protected $em;
-	
-	    public function __construct(EntityManager $entityManager)
-	    {
-	        $this->em = $entityManager;
-	    }
-
-	    public function getPosition($object, $position, $last_position)
-	    {
-	        switch ($position) {
-	            case 'up' :
-	                if ($object->getPosition() > 0) {
-	                    $position = $object->getPosition() - 1;
-	                }
-	                break;
-	
-	            case 'down':
-	                if ($object->getPosition() < $last_position) {
-	                    $position = $object->getPosition() + 1;
-	                }
-	                break;
-	
-	            case 'top':
-	                if ($object->getPosition() < $last_position) {
-	                    $position = 0;
-	                }
-	                break;
-	
-	            case 'bottom':
-	                if ($object->getPosition() < $last_position) {
-	                    $position = $last_position;
-	                }
-	                break;
-	        }
-	
-	
-	        return $position;
-
-
-	    public function getLastPosition()
-	    {
-	
-	        $query = $this->em->createQuery('SELECT MAX(c.position) FROM AcmeDemoBundle:Client c');
-	        $result = $query->getResult();
-	        
-	        if (array_key_exists(0, $result)) {
-	            return $result[0][1];
-	        }
-	
-	        return 0;
-	    }
-	}
-
-We then need to declare this service
-
-.. code-block:: yaml
-
-	services:
-	    acme_demo.client.position:
-	        class: Acme\DemoBundle\Services\PositionHandler
-	        arguments:
-	            entityManager: "@doctrine.orm.entity_manager"
-
-
-
-We can now create our controller to implement the action defined in our Admin class.
-
-.. code-block:: php
-
-	<?php
-	
-	namespace Acme\DemoBundle\Controller;
-	
-	use Sonata\AdminBundle\Controller\CRUDController;
-	use Symfony\Component\HttpFoundation\RedirectResponse;
-	
-	class ClientAdminController extends CRUDController
-	{
-	   /**
-	     * Move element
-	     *
-	     * @param integer $id
-	     * @param string $position
-	     */
-	    public function moveAction($id, $position)
-	    {
-	        $object = $this->admin->getObject($id);
-	
-	        $position_service = $this->get('acme_demo.client.position');
-	        $last_position = $position_service->getLastPosition();
-	        $position = $position_service->getPosition($object, $position, $last_position);
-	
-	        $object->setPosition($position);
-	        $this->admin->update($object);
-	
-	        $this->get('session')->setFlash('sonata_flash_info', 'Position updated');
-	
-	        return new RedirectResponse($this->admin->generateUrl('list', $this->admin->getFilterParameters()));
-	    }
-	}
-
-
-We now need to creat a handler for the new controller in ``admin.yml``
-
-.. code-block:: yaml
-
-	services:
-	    acme.admin.client:
-	        class: Acme\DemoBundle\Admin\ClientAdmin
-	        tags:
-	            - { name: sonata.admin, manager_type: orm, label: "Clients" }
-	        arguments:
-	            - ~
-	            - Acme\DemoBundle\Entity\Client
-	            - 'AcmeDemoBundle:ClientAdmin' # define the new controller via the third argument
-	        calls:
-	            - [ setTranslationDomain, [AcmeDemoBundle]]
-
-
-Last tricky part, in order to get the last position available in our twig template we inject the service container in our admin class, define a public variable ``$last_position`` and retrieve the value from our service in the ``configureListFields`` method. We also define the sort by field to be position 
-
-.. code-block:: php
-
-   class ClientAdmin extends Admin
-   {
-
-    public $last_position = 0;
-
-    private $container;
-
-    public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container)
-    {
-        $this->container = $container;
-    }
-
-    protected $datagridValues = array(
-        '_page' => 1,
-        '_sort_order' => 'ASC',
-        '_sort_by' => 'position',
-    );
-
-
-    protected function configureListFields(ListMapper $listMapper)
-    {
-        $position_service = $this->container->get('pix_equipe_medicale.medecin.position');
-        $this->last_position = $position_service->getLastPosition();
-
-        $listMapper
-            ->addIdentifier('name')
-            ->add('enabled')
-            ->add('_action', 'actions', array(
-                'actions' => array(
-                    'move' => array('template' => 'AcmeDemoBundle:Admin:_sort.html.twig'),
-                )
-            ));
-    }
-
-And in  the admin.yml add the following call
-
-.. code-block:: yaml
-    
-	- [ setContainer, [ @service_container ] ]
-
-Finally the twig files to display our up and down arrows in the listing
-
-.. code-block:: jinja
-
-	{# Acme/DemoBundle/Resources/views/Admin/_sort.html.twig #}
-	{% if object.position < admin.last_position %}
-	    <a class="movebottom_link" href="{{ admin.generateObjectUrl('move', object, {'position': 'bottom'}) }}" title="Move bottom">⇊</a>
-	{% endif %}
-	
-	{% if object.position < admin.last_position %}
-	    <a class="movedown_link" href="{{ admin.generateObjectUrl('move', object, {'position': 'down'}) }}" title="Move down">↓</a>
-	{% endif %}
-	
-	{% if object.position > 0 %}
-	    <a class="moveup_link" href="{{ admin.generateObjectUrl('move', object, {'position': 'up'}) }}" title="Move up">↑</a>
-	{% endif %}
-	
-	{% if object.position > 0 %}
-	    <a class="movetop_link" href="{{ admin.generateObjectUrl('move', object, {'position': 'top'}) }}" title="Move top">⇈</a>
-	{% endif %}
-
-
-Further work
-------------
-
-* handle ajax request
-* create a separate bundle
-* pull request for DoctrineOrm?
-* interface for SonataAdmin?
-
-
-Resources
----------
-
-Adding a new action is explained in the Sonata documentation (http://sonata-project.org/bundles/admin/master/doc/reference/routing.html#create-a-route)
-
-Controller code has been inspired from http://www.symfony.it/articoli/690/sonata-e-sortable/
-
-
-
-
-