Drupal's great little helpers: Random utility class

Drupal's API has a huge number of very useful utitlity classes and functions, especially in Drupal 8. Although the API docs are great, it's rather impossible to always find every little feature. Today I want to show you the Random utility class, which I've nearly overseen and found rather by accident.

On a project I'm currently working on, I have defined a custom entity type, for which I needed a quick way to autogenerate dummy and test data. In a first shot, the code generated 50 identical items, all having assigned the same staic "lorem ipsum" title and description text, all having assigned the same test image file. To improve that behaviour and get distinct data, I was looking in the Drupal API docs for a suitable helper, which I however didn't find at first glance. I was already on the way to integrate a simple text generation script I've found on Github, when I had to pause work. A few days later, while working on a different project, I've stumbled across the \Drupal\Component\Utility\Random class, which covers exactly the kind of functionality I was looking for.

The Random class offers different functions to generate names, strings, words (there are semantical differences, e.g. "words" look are strings looking like real words ~ blind text), whole sentences and paragraphs (consisting of sentences), PHP objects and even generated images.

Here's a snippet out of my generation script, that shows the generation of words, names, paragraphs and especially images, that are stored as file entities and assigned to an image field:


    for ($i = 0; $i < $count; $i++) {
      // Randomly choose the item's owner.
      $owner = array_rand($uids);

      // Define the full image path.
      $destination_dir = sprintf('public://uploads/%s/%s.jpg', $owner, $random->name(10, TRUE));
      // Generate the random image (width 700px, height 466px).
      $image_path = $random->image($destination_dir, '700x466', '700x466');
      // Save the generated image as file entity.
      $image_file = File::create([
        'uri' => $image_path,
        'uid' => $owner,
        'status' => 1,
      ]);
      $image_file->save();

      $item = RentableItem::create([
        'type' => 'default',
        'title' => $random->word(rand(5, 12)),
        'state' => 'draft',
        'category' => array_rand($category_ids),
        'description' => $random->paragraphs(2),
        'rent' => rand(1, 15),
        'deposit' => rand(5, 200),
        'uid' => $owner,
        'images' => $image_file->id(),
      ]);
      $item->publish(TRUE);
    }

Please note:

  1. don't forget to import the namespace of the Random und File classes or fully qualify them. (use Drupal\Component\Utility\Random; and use Drupal\file\Entity\File;)
  2. the RentableItem class referes to a cusom entity type, you won't find anywhere. You can use nodes, taxonomy terms or any other content entity instead, that's not the important part of this script.
  3. for better understanding: $uids and $category_ids are arrays of user entity ids and taxonomy term ids, defined earlier in the script.
  4. If you look into the docs of the image() function, you'll find wrong and incomplete documentation of the parameters. Stick to the code in my example instead. I've already opened up an issue at drupal.org and proposed a patch.

That's it. Have fun generating your own dummy content :) And when you're looking at the Random class, go along and have a look at its siblings in the Drupal\Component\Utility namespace, you'll probably find a lot of other stuff, you'll need quite often.

Kommentare

Thanks for your post: "In a first shot, the code generated 50 identical items..." What tool did you use at first? Did you use devel generate?

Hi, thanks for your comment!

I was using custom code already before that. But title and description were set to a static blind text, also we were using the same image for every item. I know, that there's devel generate, but I haven't considered it. First of all, I'm not sure, if it is designed for entity types other than nodes and taxonomy terms, and further I didn't want to depend on Devel. Instead I now have a custom Drush command, which I may use later on in any test and dev environment directly, without having to enable Drush first.

Neuen Kommentar schreiben