diff --git a/config/install/system.action.media_file_privacy_move_node_media_private.yml b/config/install/system.action.media_file_privacy_move_node_media_private.yml new file mode 100644 index 0000000..3a3839b --- /dev/null +++ b/config/install/system.action.media_file_privacy_move_node_media_private.yml @@ -0,0 +1,11 @@ +langcode: en +status: true +dependencies: + module: + - media_file_privacy + - node +id: media_file_privacy_move_node_media_private +label: 'Move associated unpublished media files to private storage' +type: node +plugin: media_file_privacy_move_node_media_private +configuration: { } diff --git a/config/install/system.action.media_file_privacy_move_node_media_public.yml b/config/install/system.action.media_file_privacy_move_node_media_public.yml new file mode 100644 index 0000000..9595a9f --- /dev/null +++ b/config/install/system.action.media_file_privacy_move_node_media_public.yml @@ -0,0 +1,11 @@ +langcode: en +status: true +dependencies: + module: + - media_file_privacy + - node +id: media_file_privacy_move_node_media_public +label: 'Move associated published media files to public storage' +type: node +plugin: media_file_privacy_move_node_media_public +configuration: { } diff --git a/media_file_privacy.install b/media_file_privacy.install new file mode 100644 index 0000000..eb7c20c --- /dev/null +++ b/media_file_privacy.install @@ -0,0 +1,42 @@ + $id, + 'label' => 'Move associated unpublished media files to private storage', + 'type' => 'node', + 'plugin' => 'media_file_privacy_move_node_media_private', + 'configuration' => [], + ])->save(); + } +} + +/** + * Adds the node action for moving associated published media files public. + */ +function media_file_privacy_update_10002(): void { + $id = 'media_file_privacy_move_node_media_public'; + + if (!Action::load($id)) { + Action::create([ + 'id' => $id, + 'label' => 'Move associated published media files to public storage', + 'type' => 'node', + 'plugin' => 'media_file_privacy_move_node_media_public', + 'configuration' => [], + ])->save(); + } +} diff --git a/src/Plugin/Action/MoveNodeMediaFilesPrivate.php b/src/Plugin/Action/MoveNodeMediaFilesPrivate.php new file mode 100644 index 0000000..e390399 --- /dev/null +++ b/src/Plugin/Action/MoveNodeMediaFilesPrivate.php @@ -0,0 +1,114 @@ +get('entity_type.manager'), + $container->get('plugin.manager.action'), + $container->get('current_user'), + ); + } + + /** + * {@inheritdoc} + */ + public function execute($entity = NULL): void { + if (!$entity instanceof NodeInterface || !$entity->id()) { + return; + } + + $media_storage = $this->entityTypeManager->getStorage('media'); + + // Find all media whose field_media_of references this node. + $media_ids = $media_storage->getQuery() + ->accessCheck(FALSE) + ->condition('field_media_of.target_id', $entity->id()) + ->execute(); + + if (!$media_ids) { + return; + } + + $media_action = $this->actionManager->createInstance( + 'media_file_privacy_move_unpublished_private', + ); + + foreach ($media_storage->loadMultiple($media_ids) as $media) { + if (!$media instanceof MediaInterface) { + continue; + } + + // Reuse the access rules of the media action before executing it. + if (!$media_action->access($media, $this->currentUser)) { + continue; + } + + $media_action->execute($media); + } + } + + /** + * {@inheritdoc} + */ + public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { + if (!$object instanceof NodeInterface) { + return FALSE; + } + + return $object->access('update', $account, $return_as_object); + } + +} diff --git a/src/Plugin/Action/MoveNodeMediaFilesPublic.php b/src/Plugin/Action/MoveNodeMediaFilesPublic.php new file mode 100644 index 0000000..e84631c --- /dev/null +++ b/src/Plugin/Action/MoveNodeMediaFilesPublic.php @@ -0,0 +1,114 @@ +get('entity_type.manager'), + $container->get('plugin.manager.action'), + $container->get('current_user'), + ); + } + + /** + * {@inheritdoc} + */ + public function execute($entity = NULL): void { + if (!$entity instanceof NodeInterface || !$entity->id()) { + return; + } + + $media_storage = $this->entityTypeManager->getStorage('media'); + + // Find all media whose field_media_of references this node. + $media_ids = $media_storage->getQuery() + ->accessCheck(FALSE) + ->condition('field_media_of.target_id', $entity->id()) + ->execute(); + + if (!$media_ids) { + return; + } + + $media_action = $this->actionManager->createInstance( + 'media_file_privacy_move_published_public', + ); + + foreach ($media_storage->loadMultiple($media_ids) as $media) { + if (!$media instanceof MediaInterface) { + continue; + } + + // Reuse the access rules of the media action before executing it. + if (!$media_action->access($media, $this->currentUser)) { + continue; + } + + $media_action->execute($media); + } + } + + /** + * {@inheritdoc} + */ + public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { + if (!$object instanceof NodeInterface) { + return FALSE; + } + + return $object->access('update', $account, $return_as_object); + } + +}