Skip to content

Instantly share code, notes, and snippets.

@schnippy
Created September 21, 2019 20:42
Show Gist options
  • Save schnippy/1cd96fbb4495b7186131ed5f7888f799 to your computer and use it in GitHub Desktop.
Save schnippy/1cd96fbb4495b7186131ed5f7888f799 to your computer and use it in GitHub Desktop.

Drupal 8: Create controller to load random node by type

On many projects, I often have a need to be able to see a random node of a particular content type for debugging or load testing. I use this function on Drupal 8 sites in my core module to add a route of:

http://mysite/random/my-content-type

I use this instead of a view sorted by random because I want to be redirected to the full path of the node.

Leaving off the content-type will use a random type from the array of valid content types I have provided. Providing an invalid content type will redirect it to an item from my core (or default) content-type.

For Drupal 8, I need to add a route in my base_module.routing.yml file:

base_module.random_node:
  path: '/random/{type}'
  defaults:
    _controller: '\Drupal\base_module\Controller\RandomNode::random_node'
    _title: ''
  requirements:
    _permission: 'access content'

Then, in my base_module/src/Controller/RandomNode.php file, I add the following:

<?php

namespace Drupal\base_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\RedirectResponse;

class RandomNode extends ControllerBase {
 /**
  * Redirects to a single node
  *
  */
 public function random_node($type) {

   $valid_types = array("CONTENT_TYPE1","CONTENT_TYPE2","CONTENT_TYPE3");

   // If no type selected (ex. /random), select a random type from above list
   if (!$type) { $tmp = array_rand($valid_types); $type = $valid_types[$tmp]; }

   // If type is invalid, send them to the default_type
   if (!in_array($type,$valid_types)) { $type = "CONTENT_TYPE1"; }

   $query = \Drupal::database()->select('node_field_data', 'n')
     ->fields('n', ['nid'])
     ->condition('type', $type)
     ->range(0, 1)
     ->orderRandom();

   $result = $query->execute()->fetchCol();
   $path = \Drupal::service('path.alias_manager')->getAliasByPath('/node/'.$result[0]);

   $response = new RedirectResponse($path);
   $response->send();
   return;
 }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment