The Drop Times: Unmanaged Files in Drupal (Part 6): Category-Aware Random Selection

Jeff Greenberg, The Accidental Coder


That concludes the six-part Unmanaged Files in Drupal series: from raw file discovery to fully themed, category-aware randomization—no managed-file overhead, pure performance and flexibility.

Folder Structure Example

  • public://segregated_maps/
    • africa
    • antarctica
    • asia
    • australia
    • caribbean
    • central america
    • europe
    • mideast
    • north america
    • pacific islands
    • south america

This tutorial concludes the Unmanaged Files in Drupal series. In Part 1 we explored what unmanaged files are and when to use them. Part 2 built the foundation for our custom module and introduced the first file handler. Part 3 rendered unmanaged files dynamically within a custom block. Part 4 extended that output to Twig templates, and Part 5 introduced random selection logic. In this final installment, Part 6, we make that randomness category-aware—selecting three distinct images from separate subfolders within public://segregated_maps, ensuring each category is represented only once.

RandomCategoryFileHandler.php

<?php
namespace Drupalunmanaged_filesService;
use DrupalCoreFileFileSystemInterface;

class RandomCategoryFileHandler {
protected FileSystemInterface $fileSystem;
protected string $basePath;
public function __construct(FileSystemInterface $file_system) {
$this->fileSystem = $file_system;
$this->basePath = 'public://segregated_maps';
}

public function getCategoryConstrainedFiles(int $limit = 3): array {
$selected = [];
$base = $this->fileSystem->realpath($this->basePath);
if (!$base || !is_dir($base)) {
return $selected;
}
$dirs = glob($base . '/*', GLOB_ONLYDIR);
if (empty($dirs)) {
return $selected;
}
shuffle($dirs);
foreach ($dirs as $dir) {
$files = glob($dir . '/*.{jpg,jpeg,png,gif,webp}', GLOB_BRACE);
if (!empty($files)) {
$selected[] = $files[array_rand($files)];
}
if (count($selected) >= $limit) {
break;
}
}
shuffle($selected);
return $selected;
}

public function getRenderableCategoryConstrainedFiles(int $limit = 3): array {
$real_public = $this->fileSystem->realpath('public://');
$base_url = '/sites/default/files';
$files = $this->getCategoryConstrainedFiles($limit);
$renderable = [];
foreach ($files as $file) {
$url = str_replace($real_public, $base_url, $file);
$renderable[] = [
'#theme' => 'image',
'#uri' => $url,
'#alt' => 'Random map image',
'#attributes' => ['loading' => 'lazy'],
];
}
return $renderable;
}
}

RandomCategoryFileHandler.php

RandomCategoryFilesBlock.php

Editor’s note: This article is the sixth and final part of Jeff Greenberg’s “Unmanaged Files in Drupal” tutorial series. Each entry has explored practical, database-free file handling techniques in Drupal. In this concluding part, Jeff introduces category-aware randomization, allowing developers to fetch unique images from distinct subfolders. The full series showcases a progression from concept to custom block output using services and Twig templates.Each folder represents a region category. The handler guarantees that each image in the output comes from a unique category, producing a balanced, randomized trio.

Similar Posts