Renaming files with a random name.

Submitted by victor.bourgade on

Sometimes for security reasons or for randomizing visitors input data on your server, you might want to randomize file names.

The best way to do this is to take the file entity at the very beginning of its creation using hook_entity_presave. At this specific time, the entity object holds the filename uploaded by the user and the temporary URI (/tmp/XXXXX.ext) of the file on your server. So changing the filename at this stage will let Drupal do the rest for you, moving the file from the /tmp folder to the Drupal file folder with the updated random name.

To create a random name, we can use the Drupal utility Random::name();

If by any chance we get a non-unique name, the entity creation process will still rename the file as XXXX_1.ext as it usually does. Also, you can use the unique second parameter of Random::name(int, unique = TRUE) if you really want unique file names.

You can try this snippet, it'll do the job for you:

 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Component\Utility\Random;
  
/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function HOOK_file_presave(EntityInterface $entity) {
  // Rename files with a random name.
    if ($entity->isNew()) {
    $filename = $entity->get('filename')->value;
    $parts = explode('.', $filename);
    $file_ext = end($parts);
    $random = new Random;
    $new_filename = $random->name(12) . '.' . $file_ext; 
    $entity->set('filename', $new_filename);
  }
}

Depending on the widget you use for uploading file, you might want/need to hardcode the uri with the new filename. Simply use the snippet below then:

/**
 * Implements hook_ENTITY_TYPE_create().
 */
function HOOK_file_presave(EntityInterface $entity) {
  /// Rename files with a random name.
  if ($entity->isNew()) {
    $uri = $entity->getFileUri();
    $filename = $entity->get('filename')->value;
    list($name, $file_ext) = explode('.', $filename);
    $unique_id = FALSE;
    while ($unique_id == FALSE) {
      $random = new Random();
      $new_filename = $random->name(12) . '.' . $file_ext;
      $uri = $entity->getFileUri();
      $parts = explode('/', $uri);
      $last_key = array_key_last($parts);
      $parts[$last_key] = $new_filename;
      $new_uri = implode('/', $parts);
      $entity->setFileUri($new_uri);
      // Makes sure we have a unique filename.
      $file_system = \Drupal::service('file_system');
      $real_path = $file_system->realpath($new_uri);
      if (!file_exists($real_path)) {
        $unique_id = TRUE;
        $file_system->move($uri, $new_uri);
      }
    }
    $entity->setFilename($new_filename);
  }
}

Oznake

Drupal 8 Drupal 9

About the writer

victor.bourgade

Victor is a web developer passionnated in drupal and bootstrap technologies. He likes challenges and beautiful designs.

When not behind his computer you'll find him drinking beers with friends or in the middle of nowhere hiking with his dog.