5 changed files with 292 additions and 0 deletions
@ -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: { } |
||||||
@ -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: { } |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Install and update hooks for Media File Privacy. |
||||||
|
*/ |
||||||
|
|
||||||
|
use Drupal\system\Entity\Action; |
||||||
|
|
||||||
|
/** |
||||||
|
* Adds the node action for moving associated unpublished media files private. |
||||||
|
*/ |
||||||
|
function media_file_privacy_update_10001(): void { |
||||||
|
$id = 'media_file_privacy_move_node_media_private'; |
||||||
|
|
||||||
|
if (!Action::load($id)) { |
||||||
|
Action::create([ |
||||||
|
'id' => $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(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,114 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\media_file_privacy\Plugin\Action; |
||||||
|
|
||||||
|
use Drupal\Core\Action\ActionBase; |
||||||
|
use Drupal\Core\Action\ActionManager; |
||||||
|
use Drupal\Core\Action\Attribute\Action; |
||||||
|
use Drupal\Core\Entity\EntityTypeManagerInterface; |
||||||
|
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; |
||||||
|
use Drupal\Core\Session\AccountInterface; |
||||||
|
use Drupal\Core\Session\AccountProxyInterface; |
||||||
|
use Drupal\Core\StringTranslation\TranslatableMarkup; |
||||||
|
use Drupal\media\MediaInterface; |
||||||
|
use Drupal\node\NodeInterface; |
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Moves files for media associated with a node to private storage. |
||||||
|
* |
||||||
|
* Associated media are discovered through field_media_of. The existing |
||||||
|
* media_file_privacy_move_unpublished_private action is then applied to each |
||||||
|
* media item, so publication-state checks and file-moving behavior remain in |
||||||
|
* one place. |
||||||
|
*/ |
||||||
|
#[Action( |
||||||
|
id: 'media_file_privacy_move_node_media_private', |
||||||
|
label: new TranslatableMarkup('Move associated unpublished media files to private storage'), |
||||||
|
type: 'node', |
||||||
|
)] |
||||||
|
final class MoveNodeMediaFilesPrivate extends ActionBase implements ContainerFactoryPluginInterface { |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructs the action. |
||||||
|
*/ |
||||||
|
public function __construct( |
||||||
|
array $configuration, |
||||||
|
$plugin_id, |
||||||
|
$plugin_definition, |
||||||
|
protected EntityTypeManagerInterface $entityTypeManager, |
||||||
|
protected ActionManager $actionManager, |
||||||
|
protected AccountProxyInterface $currentUser, |
||||||
|
) { |
||||||
|
parent::__construct($configuration, $plugin_id, $plugin_definition); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function create( |
||||||
|
ContainerInterface $container, |
||||||
|
array $configuration, |
||||||
|
$plugin_id, |
||||||
|
$plugin_definition, |
||||||
|
): static { |
||||||
|
return new static( |
||||||
|
$configuration, |
||||||
|
$plugin_id, |
||||||
|
$plugin_definition, |
||||||
|
$container->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); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,114 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\media_file_privacy\Plugin\Action; |
||||||
|
|
||||||
|
use Drupal\Core\Action\ActionBase; |
||||||
|
use Drupal\Core\Action\ActionManager; |
||||||
|
use Drupal\Core\Action\Attribute\Action; |
||||||
|
use Drupal\Core\Entity\EntityTypeManagerInterface; |
||||||
|
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; |
||||||
|
use Drupal\Core\Session\AccountInterface; |
||||||
|
use Drupal\Core\Session\AccountProxyInterface; |
||||||
|
use Drupal\Core\StringTranslation\TranslatableMarkup; |
||||||
|
use Drupal\media\MediaInterface; |
||||||
|
use Drupal\node\NodeInterface; |
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Moves files for published media associated with a node to public storage. |
||||||
|
* |
||||||
|
* Associated media are discovered through field_media_of. The existing |
||||||
|
* media_file_privacy_move_published_public action is then applied to each |
||||||
|
* media item, so publication-state checks and file-moving behavior remain in |
||||||
|
* one place. |
||||||
|
*/ |
||||||
|
#[Action( |
||||||
|
id: 'media_file_privacy_move_node_media_public', |
||||||
|
label: new TranslatableMarkup('Move associated published media files to public storage'), |
||||||
|
type: 'node', |
||||||
|
)] |
||||||
|
final class MoveNodeMediaFilesPublic extends ActionBase implements ContainerFactoryPluginInterface { |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructs the action. |
||||||
|
*/ |
||||||
|
public function __construct( |
||||||
|
array $configuration, |
||||||
|
$plugin_id, |
||||||
|
$plugin_definition, |
||||||
|
protected EntityTypeManagerInterface $entityTypeManager, |
||||||
|
protected ActionManager $actionManager, |
||||||
|
protected AccountProxyInterface $currentUser, |
||||||
|
) { |
||||||
|
parent::__construct($configuration, $plugin_id, $plugin_definition); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function create( |
||||||
|
ContainerInterface $container, |
||||||
|
array $configuration, |
||||||
|
$plugin_id, |
||||||
|
$plugin_definition, |
||||||
|
): static { |
||||||
|
return new static( |
||||||
|
$configuration, |
||||||
|
$plugin_id, |
||||||
|
$plugin_definition, |
||||||
|
$container->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); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue