Skip to content
This repository has been archived by the owner on May 23, 2018. It is now read-only.

Latest commit

 

History

History
151 lines (119 loc) · 3.94 KB

README.md

File metadata and controls

151 lines (119 loc) · 3.94 KB

Packagist

mevSortableTreeBundle

Offers a sortable feature for your Symfony2/3 admin tree listing

screenshot

Install requirements

SonataAdminBundle
- the SonataAdminBundle provides a installation article here:
http://symfony.com/doc/current/cmf/tutorial/sonata-admin.html

Install and enable Tree Extension from gedmo/doctrine-extensions
- nested behavior will implement the standard Nested-Set behavior on your Entity
(check stof/doctrine-extensions-bundle for easier integration in your project) https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/tree.md

Installation

composer require mikeevstropov/sortable-tree-bundle

Configuration

Enable the mevSortableTreeBundle to your kernel:

// app/AppKernel.php

class AppKernel extends Kernel
{
	public function registerBundles()
	{
		$bundles = [
			// ...
			new Mev\SortableTreeBundle\MevSortableTreeBundle(),
		];
		// ...
	}
}

Include MevSortableTreeBundle:SortableTree to third service argument:

# app/config/services.yml

#   SonataAdminBundle Category
    admin.category:
        class: AppBundle\Admin\CategoryAdmin
        arguments:
            - ~
            - AppBundle\Entity\Category
            - 'MevSortableTreeBundle:SortableTree'
        tags:
            - { name: sonata.admin, manager_type: orm, label: Category }

Create new routes and the action field in Admin Class:

// src/AppBundle/Admin/CategoryAdmin.php

// ...

use Sonata\AdminBundle\Route\RouteCollection;

class CategoryAdmin extends AbstractAdmin
{
	// ...
	protected function configureRoutes(RouteCollection $collection)
	{
		$collection->add('up', $this->getRouterIdParameter().'/up');
        $collection->add('down', $this->getRouterIdParameter().'/down');
    }
    
    protected function configureFormFields(FormMapper $formMapper)
    {
        // create custom query to hide the current element by `id`

        $subjectId = $this->getRoot()->getSubject()->getId();
        $query = null;

        if ($subjectId)
        {
            $query = $this->modelManager
                ->getEntityManager('AppBundle\Entity\Category')
                ->createQueryBuilder('c')
                ->select('c')
                ->from('AppBundle:Category', 'c')
                ->where('c.id != '. $subjectId);
        }
        
        // ...
        $formMapper->add('parent', 'sonata_type_model', array(
            'query' => $query,
            'required' => false, // remove this row after the root element is created
            'btn_add' => false,
            'property' => 'name'
        ));
    }

	protected function configureListFields(ListMapper $listMapper)
	{
		// ...
		$listMapper->add('_action', null, array(
			'actions' => array(
				'up' => array(
                    'template' => 'MevSortableTreeBundle:Default:list__action_up.html.twig'
                ),
                'down' => array(
                    'template' => 'MevSortableTreeBundle:Default:list__action_down.html.twig'
                )
			)
		));
	}
}

Configure sort the list of models by root and lft fields:

// src/AppBundle/Admin/CategoryAdmin.php

// ...

class CategoryAdmin extends AbstractAdmin
{
	// ...
	public function createQuery($context = 'list')
	{
		$proxyQuery = parent::createQuery('list');
        // Default Alias is "o"
        // You can use `id` to hide root element
        // $proxyQuery->where('o.id != 1');
        $proxyQuery->addOrderBy('o.root', 'ASC');
        $proxyQuery->addOrderBy('o.lft', 'ASC');
    
		return $proxyQuery;
	}
	// ...
}

That's it!

ToDo

  • Sortable behaveor for root elements (but, you can hide root element)