delobelf@gmail.com
1/26/2017 - 1:27 PM

Twig Extension howto example of twig extension (filter : sorting of an array)

Twig Extension howto example of twig extension (filter : sorting of an array)

<?php

namespace RG\Dashboard\Extension;

use Patchwork\Utf8;
use Symfony\Component\DependencyInjection\ContainerInterface;
use /** @noinspection PhpUndefinedClassInspection */ Twig_Extension;


/**
 * Twig Extension filter : sort an array with differents strategies
 *
 * USORT : alphabetical order on a choosen field
 *  fill the parameters array with fields 'method' and possibly 'usortColName'
 *  Use example : {% ..... arrayName|rg_sort({'method':'usort', 'usortColName':'name'}) %}
 *
 * Other sorting methods
 *  fill the parameters array fields 'method' and possibly 'sortFlag' (see http://php.net/manual/fr/function.sort.php)
 *      Use example : {% arrayName|rg_sort({'method':'arsort', 'sortFlag':constant('SORT_REGULAR')}) %}
 * to deal with special chars (È, ...)
 */

// todo: params  en lc
// todo: gérer le flag SORT_FLAG_CASE et les OR ?

/** @noinspection PhpUndefinedClassInspection */
class TwigSortExtensions extends Twig_Extension
{
    protected $allowedMethods;
    protected $defaultMethod;
    protected $defaultSortflag;
    protected $allowedSortFlags;
    protected $container;
    protected $logger;
    protected $usortColName;

    public function __construct()
    {
        $this->allowedMethods = ['asort', 'arsort', 'krsort', 'natcasesort', 'narsort', 'rsort', 'sort', 'usort'];
        $this->defaultMethod = "asort" ;

        $this->allowedSortFlags = [SORT_REGULAR, SORT_NUMERIC, SORT_STRING, SORT_LOCALE_STRING, SORT_NATURAL];
        $this->defaultSortflag = SORT_REGULAR;

        $this->usortColName = null;
    }


    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
        $this->logger = $container->get('logger');
    }

    /**
     * Returns the name of the extension.
     * @return string The extension name
     */
    public function getName()
    {
        return 'Twig Sort Extensions';
    }

    /**
     * filter name
     * @return array
     */
    public function getFilters()
    {
        return array(
            'rg_sort' => new \Twig_Filter_Method($this, 'twigSort')
        );
    }

    /**
     * sorting method
     * @param $arrayToSort
     * @param $parameters: see class comments for détails
     * @return mixed: sorted array
     */
    public function twigSort($arrayToSort, $parameters=null)
    {
        $method = $this->defaultMethod;
        $sortFlag = $this->defaultSortflag;

        if ($parameters != null) {
            if (isset($parameters["method"]))
                $method = $parameters["method"];
            if (isset($parameters["sortFlag"]));
                $sortFlag = $parameters["sortFlag"];
        }

        if (! in_array($method, $this->allowedMethods))
            $method = $this->defaultMethod;
        if (! in_array($sortFlag, $this->allowedSortFlags))
            $sortFlag = $this->defaultSortflag;

        if ($method == "usort") {
            if ( (isset($parameters["usortColName"])) && (array_key_exists($parameters["usortColName"], reset($arrayToSort))) ) {
                $this->usortColName = $parameters["usortColName"];
            }

            $method($arrayToSort, [$this, "usort"]);
        }
        else {
            $method($arrayToSort, $sortFlag);
        }
        return $arrayToSort;
    }

    /**
     * usort method
     * @param $a
     * @param $b
     * @return int
     */
    protected function usort($a, $b)
    {
        $firstValue = ($this->usortColName != null) ? ($a[$this->usortColName]) : ($a);
        $secondValue = ($this->usortColName != null) ? ($b[$this->usortColName]) : ($b);

        $aConv = Utf8::toAscii($firstValue);
        $bConv = Utf8::toAscii($secondValue);

        return strcasecmp($aConv, $bConv);
    }


}
.
.
.

    exemple_extensions:
        class: ....\Extension\TwigSortExtensions
        tags:
            -  { name: twig.extension }
    {% for name, service in services|rg_sort %}
    {% for name, service in services|rg_sort({'method':'arsort', 'sortFlag':constant('SORT_REGULAR')}) %}
    {% for name, service in services|rg_sort({'method':'usort', 'usortColName':'name'}) %}