I'm using this code to retrieve a remote file, during the process of creating a new a media entity.

$url = 'https://example.com/example.jpg';
$image = system_retrieve_file($url, NULL, TRUE);
$entity_array['field_example'] = [
  'target_id' => $image->id(),

The second parameter in system_retrieve_file() determines that the file is stored in the public:// directory.

How can I retrieve the tokenised defined in the file fields settings?

1 Answer 1


So I had to make a function that I pass a bundle and field name too. Both are in the form of strings. The function then returns a uri with the tokens replaced.

function getFileDirectory($media_type, $field_name) {
        // Fetch all field definitions for the media bundle.
        $fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('media', $media_type);
        foreach ($fields as $field => $field_definition) {
            $bundle = $field_definition->getTargetBundle();
            // Look for the field we need
            if ($bundle == $media_type && $field == $field_name) {
                // Get the settings for the field, in order to start building the directory path
                $settings = $field_definition->getSettings();
                $file_directory_path_tokens = $settings['file_directory'];
                $uri_scheme = $settings['uri_scheme']; 
                // Convert tokens in files directory string
                $token = \Drupal::token();
                $directory_path = $token->replace($file_directory_path_tokens);

                // If there is a value for the file directory setting on the file field, ensure the directory exists, 
                // if not create it.
                if ($directory_path) {
                    $directory = $uri_scheme . '://' . $directory_path;
                    /** @var \Drupal\Core\File\FileSystemInterface $file_system */
                    $file_system = \Drupal::service('file_system');
                    $file_system->prepareDirectory($directory, FileSystemInterface:: CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
                    return $directory;
                // Otherwise just return the uri_scheme ie public:// or private://
                else {
                    return $uri_scheme . '://';

This is specific for media entities. It wouldn't be too much bother to extend it to be more generic to cover all entities.

I hope this saves someone some pain.

Not the answer you're looking for? Browse other questions tagged or ask your own question.