From e5b8641dc054ee392196a514d09483b61456f124 Mon Sep 17 00:00:00 2001 From: "Peter Droogmans (attiks)" Date: Mon, 16 Dec 2019 12:09:59 +0100 Subject: [PATCH] Use private media files --- .../field.storage.media.field_media_file.yml | 2 +- .../custom/iasc_content/iasc_content.install | 27 ++++++ .../custom/iasc_content/iasc_content.module | 89 +++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) diff --git a/config/field.storage.media.field_media_file.yml b/config/field.storage.media.field_media_file.yml index 84bce1d3f..24084eabb 100644 --- a/config/field.storage.media.field_media_file.yml +++ b/config/field.storage.media.field_media_file.yml @@ -15,7 +15,7 @@ field_name: field_media_file entity_type: media type: file settings: - uri_scheme: public + uri_scheme: private target_type: file display_field: false display_default: false diff --git a/html/modules/custom/iasc_content/iasc_content.install b/html/modules/custom/iasc_content/iasc_content.install index 9abf6e54b..062aaa658 100644 --- a/html/modules/custom/iasc_content/iasc_content.install +++ b/html/modules/custom/iasc_content/iasc_content.install @@ -563,3 +563,30 @@ function iasc_content_update_8018() { $entities = $storage_handler->loadByProperties(['type' => 'oa_ical_importer']); $storage_handler->delete($entities); } + +/** + * Make media files private. + */ +function iasc_content_update_8019() { + $connection = \Drupal::database(); + + $sql = "select f.fid, f.uri from {media} m inner join {media__field_media_file} mf on m.mid = mf.entity_id inner join {file_managed} f on mf.field_media_file_target_id = f.fid where m.bundle='file' and f.uri not like 'private://%'"; + $query = $connection->query($sql); + $result = $query->fetchAll(); + + $fids = []; + foreach ($result as $row) { + $fids[] = $row->fid; + if (file_exists($row->uri)) { + $target = str_replace('public://', 'private://', $row->uri); + $target_dir = 'private://' . dirname(file_uri_target($target)); + file_prepare_directory($target_dir, FILE_CREATE_DIRECTORY); + file_unmanaged_move($row->uri, $target, FILE_EXISTS_REPLACE); + } + } + + $sql = "update file_managed set uri = replace(uri, 'public://', 'private://') where fid in (:fids[])"; + $connection->query($sql, [ + ':fids[]' => $fids, + ]); +} diff --git a/html/modules/custom/iasc_content/iasc_content.module b/html/modules/custom/iasc_content/iasc_content.module index 00d3d1e1a..f9ba7eb44 100644 --- a/html/modules/custom/iasc_content/iasc_content.module +++ b/html/modules/custom/iasc_content/iasc_content.module @@ -958,3 +958,92 @@ function iasc_content_theme() { ], ]; } + +/** + * Implements hook_file_download(). + */ +function iasc_content_file_download($uri) { + $entity_types_to_check = [ + 'node' => [ + 'field_media_files', + ], + 'paragraph' => [ + 'field_media', + ], + ]; + // Only check private files. + $scheme = file_uri_scheme($uri); + if ($scheme != 'private') { + return; + } + + // Load the file(s). + $files = \Drupal::entityTypeManager() + ->getStorage('file') + ->loadByProperties(['uri' => $uri]); + + if (count($files)) { + foreach ($files as $file) { + // Case sensitive names. + if ($file->getFileUri() !== $uri) { + continue; + } + + $usage_list = \Drupal::service('file.usage')->listUsage($file); + $referencing_entity_is_accessible = FALSE; + $references = empty($usage_list['file']) ? [] : $usage_list['file']; + foreach ($references as $entity_type => $entity_ids_usage_count) { + $referencing_entities = entity_load_multiple($entity_type, array_keys($entity_ids_usage_count)); + + /** @var \Drupal\Core\Entity\EntityInterface $referencing_entity */ + foreach ($referencing_entities as $referencing_entity) { + // Check for media. + if ($entity_type == 'media') { + $media_id = $referencing_entity->id(); + + // Load items referencing this item. + foreach ($entity_types_to_check as $entity_type_to_check => $fields) { + $query = \Drupal::entityQuery($entity_type_to_check); + if (count($fields) > 1) { + $group = $query->orConditionGroup(); + foreach ($fields as $field_name) { + $group->condition($field_name . '.%delta.target_id', $media_id); + } + } + else { + $field_name = reset($fields); + $query->condition($field_name . '.%delta.target_id', $media_id); + } + $ids = $query->execute(); + + $entities = \Drupal::entityTypeManager() + ->getStorage($entity_type_to_check) + ->loadMultiple($ids); + + foreach ($entities as $entity) { + if ($entity + ->access('view', NULL, TRUE) + ->isAllowed()) { + $referencing_entity_is_accessible = TRUE; + break 4; + } + } + } + } + else { + if ($referencing_entity + ->access('view', NULL, TRUE) + ->isAllowed()) { + $referencing_entity_is_accessible = TRUE; + break 2; + } + } + } + } + + if (!$referencing_entity_is_accessible) { + return -1; + } + } + } +}