diff --git a/embargo.install b/embargo.install
new file mode 100644
index 0000000..bb5dda8
--- /dev/null
+++ b/embargo.install
@@ -0,0 +1,39 @@
+setLabel(t('Embargoed File'))
+ ->setDescription(t('New field for attaching media to the Embargo node.'))
+ ->setSetting('target_type', 'media')
+ ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED);
+
+ // Install the new definition.
+ $definition_manager->installFieldStorageDefinition('embargoed_file', $entity_type_id, $bundle, $new_field);
+ }
+ catch (UpdateException $e) {
+ // Handle exception if needed.
+ \Drupal::logger('embargo')->error('Error adding field: @error', ['@error' => $e->getMessage()]);
+ return t('Update failed: @error', ['@error' => $e->getMessage()]);
+ }
+
+ // Provide a message indicating the update has been applied.
+ return t('Added embargoed_file to the Embargo entity.');
+}
diff --git a/embargo.libraries.yml b/embargo.libraries.yml
new file mode 100644
index 0000000..3aff315
--- /dev/null
+++ b/embargo.libraries.yml
@@ -0,0 +1,7 @@
+custom_select_all_library:
+ version: 1.x
+ js:
+ js/custom_select_all.js: {}
+ dependencies:
+ - core/jquery
+ - core/once
diff --git a/embargo.module b/embargo.module
index c5b35dc..881f49a 100644
--- a/embargo.module
+++ b/embargo.module
@@ -9,6 +9,8 @@ use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\embargo\EmbargoStorage;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\node\NodeInterface;
/**
* Implements hook_entity_type_alter().
@@ -97,3 +99,69 @@ function embargo_theme($existing, $type, $theme, $path) {
],
];
}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function embargo_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+ if ($form_id == 'embargo_add_form' || $form_id == 'embargo_edit_form') {
+ // Set up visibility conditions for the embargoed_file field.
+ $form['embargoed_file']['#states'] = [
+ 'visible' => [
+ ':input[name="embargo_type"]' => ['value' => 0],
+ ],
+ ];
+
+ // Check if the URL contains a node ID.
+ $node_id = \Drupal::routeMatch()->getParameter('node');
+
+ if ($node_id instanceof NodeInterface) {
+ $node_id = $node_id->id();
+ }
+
+ // If its edit form, need to select node id differently.
+ if ($form_id == 'embargo_edit_form') {
+ $entity = $form_state->getFormObject()->getEntity();
+ $field_value = $entity->embargoed_node->getValue();
+ $node_id = $field_value[0]['target_id'];
+ }
+
+ // If a node ID is present, filter the options of embargoed_file.
+ if (!empty($node_id)) {
+ $options = embargo_get_filtered_file_options($node_id);
+ $form['embargoed_file']['widget']['#options'] = $options;
+ }
+ else {
+ // @todo Need to update file list via ajax when Embargoed Node available.
+ unset($form['embargoed_file']);
+ }
+
+ // JS to add Select/Unselect All link and functionality.
+ $form['#attached']['library'][] = 'embargo/custom_select_all_library';
+
+ }
+}
+
+/**
+ * Helper function to get filtered options based on the node ID.
+ */
+function embargo_get_filtered_file_options($node_id) {
+ // Initialize an empty array to store matching media entities.
+ $matching_media = [];
+
+ // Check if the node ID is valid.
+ if (!empty($node_id)) {
+ // Filter media entities based on the referenced node ID.
+ $matching_media = \Drupal::entityTypeManager()
+ ->getStorage('media')
+ ->loadByProperties(['field_media_of' => $node_id]);
+ }
+
+ // Build an array of matching media labels and IDs for the checkbox options.
+ $options = [];
+ foreach ($matching_media as $media) {
+ $options[$media->id()] = $media->label();
+ }
+
+ return $options;
+}
diff --git a/js/custom_select_all.js b/js/custom_select_all.js
new file mode 100644
index 0000000..3cfb4a8
--- /dev/null
+++ b/js/custom_select_all.js
@@ -0,0 +1,21 @@
+(function ($, Drupal, once) {
+ Drupal.behaviors.customSelectAll = {
+ attach: function (context, settings) {
+ // Create the link element
+ var selectAllLink = $('Select/Unselect All');
+
+ // Use `once()` to ensure the link is prepended only once
+ $(once('custom-select-all', '#edit-embargoed-file', context)).prepend(selectAllLink);
+
+ // Attach the click handler directly to the link element
+ selectAllLink.on('click', function (event) {
+ event.preventDefault();
+
+ var checkboxes = $(':checkbox', context); // Target checkboxes within relevant context
+
+ // Toggle checked state based on current state of the first checkbox
+ checkboxes.prop('checked', !checkboxes.first().prop('checked'));
+ });
+ }
+ };
+})(jQuery, Drupal, once);
diff --git a/src/EmbargoInterface.php b/src/EmbargoInterface.php
index 62003e2..691931f 100644
--- a/src/EmbargoInterface.php
+++ b/src/EmbargoInterface.php
@@ -249,4 +249,22 @@ public function isUserExempt(AccountInterface $user): bool;
*/
public function ipIsExempt(string $ip): bool;
+ /**
+ * Gets the embargoed files.
+ *
+ * @return \Drupal\media\MediaInterface[]
+ * An array of media entities representing the embargoed files.
+ */
+ public function getEmbargoedFiles(): array;
+
+ /**
+ * Sets the embargoed files.
+ *
+ * @param \Drupal\media\MediaInterface[] $files
+ * An array of media entities representing the embargoed files.
+ *
+ * @return $this
+ */
+ public function setEmbargoedFiles(array $files): EmbargoInterface;
+
}
diff --git a/src/Entity/Embargo.php b/src/Entity/Embargo.php
index 03f8b57..2376936 100644
--- a/src/Entity/Embargo.php
+++ b/src/Entity/Embargo.php
@@ -94,6 +94,27 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
])
->setSetting('allowed_values', static::getEmbargoTypeLabels());
+ $fields['embargoed_file'] = BaseFieldDefinition::create('entity_reference')
+ ->setLabel(t('Embargoed Media'))
+ ->setDescription(t('Media attached to the Embargoed node.'))
+ ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
+ ->setSetting('target_type', 'media')
+ ->setSetting('handler', 'default:media')
+ ->setDisplayOptions('view', [
+ 'label' => 'above',
+ 'type' => 'entity_reference_label',
+ 'weight' => 0,
+ ])
+ ->setDisplayOptions('form', [
+ 'type' => 'options_buttons',
+ 'weight' => 0,
+ 'settings' => [
+ 'match_operator' => 'CONTAINS',
+ 'size' => '60',
+ 'placeholder' => '',
+ ],
+ ]);
+
$fields['expiration_type'] = BaseFieldDefinition::create('list_integer')
->setLabel(t('Expiration Type'))
->setDescription(t('A Indefinite embargo is never lifted.
A Scheduled embargo is lifted on the specified date.'))
@@ -377,6 +398,24 @@ public function setEmbargoedNode(NodeInterface $node): EmbargoInterface {
return $this;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getEmbargoedFiles(): array {
+ /** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $field */
+ $field = $this->get('embargoed_file');
+ $files = $field->referencedEntities();
+ return $files;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setEmbargoedFiles(array $files): EmbargoInterface {
+ $this->set('embargoed_file', $files);
+ return $this;
+ }
+
/**
* The maximum age for which this object may be cached.
*