Recent Blog Posts

Change the sorting of a view in Drupal 8

By Ronald van Belzen | February 10, 2017

The situation that required this solution was a view on nodes in which duplicate titles occurred frequently.

Instead of just sorting the list of nodes in the view by the title or the creation date, the sorting on title needed a secundary sorting field. For this I needed to implement the hook "hook_views_query_alter" in the file "mymodule.views_execution.inc" as shown below.

<?php

use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_query_alter().
 *
 * Order by title and created when order by title is requested.
 */
function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == 'my_view_id') {
    if ($query->orderby[0]['field'] == 'node_field_data.title') {
      $query->orderby[1]['field'] = 'node_field_data.created';
      $query->orderby[1]['direction'] = 'DESC';
    }
  }
}

I had some problems getting it to work. Fortunately, a test script made me realize that the hook function needed to placed in the above mentioned ".inc" file. And the test reminded me of the fact that the function parameters are not arrays, as would be the case in Drupal 7, but objects. For that reason you should not use '&$view' nor '&$query' as you would do in Drupal 7, which I did at first. After a cache rebuild the hook does its work by adding the second sorting criteria on the created field when the title field was clicked for the view with id "my_view_id".

Localized number format in Drupal 8

By Ronald van Belzen | July 14, 2016

When building this blog I decided to use the core module statistics to display the view count on blog posts. Because some of my older blog posts have had a lot of views, the counter on those blog post views had grown quite large. For making those large numbers more readable it would be nice that those numbers would be displayed with thousands-seperators, just as can be accomplished with the PHP function number_format() or, even better, with the NumberFormatter class. The statistics module does not do that.

As it turns out Drupal 8 core does not support that either, and a sole module that offers this functionality has no Drupal 8 version. I decided to make a solution specifically for the statistics module. That module implements the hook hook_node_links_alter() in the statistics.module file to add the view count to the list of node links (as text). So I set out to create a copy of this hook that would override this particular hook.

The module to which I will add this hook will be named mystatistics:

# mystatistics.info.yml
name: 'My Statistics'
type: module
description: 'Module to override the display of the Statistics module.'
package: Other
version: '1.0'
core: '8.x'
dependencies:
  - statistics

In the mystatistics.module file I added the following code:

Change the PageUtility class into a service

By Ronald van Belzen | May 1, 2016

In the previous article of this series we concluded writing a class that will take care of the pagination, sorting and filtering of data in a tabular display. Next we are going to transform this class into a service. For this we are going to rename the class and place it in the proper directory in accordance with the namespace for this new class that will be:

namespace AppBundle\DependencyInjection;

For coming up with a new class name let's consider what the service will actually do. It will provide the data to be displayed on a page. For this reason I will call the new class PageDataProvider. With this name we can add the service to our "services.yml" that is imported by the configuration file of our application:

services:
    page.data.provider:
        class: AppBundle\DependencyInjection\PageDataProvider
        arguments: ["@request_stack", "@service_container"]

As you can see we pass the RequestStack and the ContainerInterface as arguments for the class constructor. These parameters do not coincide with the constructor parameter of the PageUtility class. So, let's change the constructor of our new class accordingly:

<?php
namespace AppBundle\DependencyInjection;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;

class PageDataProvider {
    protected $requestStack;
    private $request;
    private $em;
    private $entityName;

    // ...
    
    public function __construct(RequestStack $requestStack, Container $container) {
        $this->requestStack = $requestStack;
        $this->em = $container->get('doctrine')->getManager();
    }

In the constructor we set the new variable $requestStack and set the enity manager $em. We now need a function in which we can set the entity name for which the data need be be delivered:

Adding sorting and filtering to tabular data display in Symfony2

By Ronald van Belzen | April 28, 2016

In the previous article I described how to add pagination to tabular data display. Here I will describe how to add sorting and filtering, which will result in the following end result:

Symfony2 pagination

Sorting

The request parameter sort will receive a value that both contains the name of the field and the sort direction seperated by a dot. This value is included in the parameters passed to the twig file "list.html.twig" together with a value for the request of the reverse sort direction ("pager.sort_reverse") and the name of the current sort field ("pager.sort_field") and sort direction ("pager.sort_order") seperately. In the twig file we first change the table header to the following:

Create pagination, sorting and filtering of tabular data display in Symfony2

By Ronald van Belzen | April 26, 2016

The addition of pagination, sorting and filtering to a tabular display of data is a relatively simple task. No doubt there is more then one bundle in Symfony2 that tackles this task for you (e.g. KnpLabs/KnpPaginatorBundle for a SEO friendly paginator). Here I will demonstrate the relative ease in which you can combine pagination, sorting and filtering of tabular data display. For this example I will use the well known User table. In this case the User table created by the FOSUserBundle to which I added the field fullname.

<?php 
namespace AppBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="app_user")
 */
class User extends BaseUser {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
	
    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    private $fullname;

    /**
     * Set fullname
     *
     * @param string $fullname
     *
     * @return User
     */
    public function setFullname($fullname)
    {
        $this->fullname = $fullname;

        return $this;
    }

    /**
     * Get fullname
     *
     * @return string
     */
    public function getFullname()
    {
        return $this->fullname;
    }
}

The controller class function to which I will add pagination looked like this:

<?php 
namespace AppBundle\Controller;

use AppBundle\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class AdminController extends Controller {
    /**
     * Handle the user listing display
     */
    public function listAction(Request $request) {
        $em = $this->getDoctrine()->getManager();
        
        $users = $em->getRepository('AppBundle:User')
            ->createQueryBuilder('t')
            ->orderBy('t.username', 'ASC')
            ->getQuery()
            ->getResult();
		
        return $this->render('admin/list.html.twig',[
            'users' => $users,
        ]);
    }
    
    // Other functions.
    
}	

And the twig file ("list.html.twig") for the display of the data in a tabular format looked like this: