From bfcec3fe7fba5925710029a0ff6d045b23ab22cc Mon Sep 17 00:00:00 2001 From: Prashant Kanse Date: Wed, 17 Jan 2024 19:17:35 +0530 Subject: [PATCH 1/6] DGIR-148 : Add embargoed_file to embargo entity --- embargo.install | 36 ++++++++++++++++++++++ embargo.libraries.yml | 7 +++++ embargo.module | 66 ++++++++++++++++++++++++++++++++++++++++ js/custom_select_all.js | 21 +++++++++++++ src/EmbargoInterface.php | 18 +++++++++++ src/Entity/Embargo.php | 43 ++++++++++++++++++++++++-- 6 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 embargo.install create mode 100644 embargo.libraries.yml create mode 100644 js/custom_select_all.js diff --git a/embargo.install b/embargo.install new file mode 100644 index 0000000..a4e81b9 --- /dev/null +++ b/embargo.install @@ -0,0 +1,36 @@ +setLabel(t('New 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('new_embargoed_file', $entity_type_id, $bundle, $new_field); + + // Clear the cache. + drupal_flush_all_caches(); + } 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 new_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..e32d777 100644 --- a/embargo.module +++ b/embargo.module @@ -9,6 +9,7 @@ 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; /** * Implements hook_entity_type_alter(). @@ -97,3 +98,68 @@ 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') { + // Get the current value of the embargo_type field. + $embargo_type_value = $form_state->getValue('embargo_type'); + + // 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 \Drupal\node\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; + } + + // 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..a7bc9b5 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', array( + 'label' => 'above', + 'type' => 'entity_reference_label', + 'weight' => 0, + )) + ->setDisplayOptions('form', array( + '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. * @@ -422,8 +461,8 @@ public function isUserExempt(AccountInterface $user): bool { $exempt_users = $this->getExemptUsers(); $has_permission = $user->hasPermission('bypass embargo access'); return $has_permission || in_array($user->id(), array_map(function (UserInterface $user) { - return $user->id(); - }, $exempt_users)); + return $user->id(); + }, $exempt_users)); } /** From feba60bbf206215eff90ebbe16bfe5da53fcb7c6 Mon Sep 17 00:00:00 2001 From: Prashant Kanse Date: Wed, 17 Jan 2024 19:21:56 +0530 Subject: [PATCH 2/6] DGIR-148 : Fix linting error --- embargo.install | 8 +++++++- embargo.module | 3 --- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/embargo.install b/embargo.install index a4e81b9..b97da50 100644 --- a/embargo.install +++ b/embargo.install @@ -1,5 +1,10 @@ error('Error adding field: @error', ['@error' => $e->getMessage()]); return t('Update failed: @error', ['@error' => $e->getMessage()]); diff --git a/embargo.module b/embargo.module index e32d777..e0c4af1 100644 --- a/embargo.module +++ b/embargo.module @@ -104,9 +104,6 @@ function embargo_theme($existing, $type, $theme, $path) { */ function embargo_form_alter(&$form, FormStateInterface $form_state, $form_id) { if ($form_id == 'embargo_add_form' || $form_id == 'embargo_edit_form') { - // Get the current value of the embargo_type field. - $embargo_type_value = $form_state->getValue('embargo_type'); - // Set up visibility conditions for the embargoed_file field. $form['embargoed_file']['#states'] = [ 'visible' => [ From 5a81c4ffb63422ab4f8a92513623da2327bd5e49 Mon Sep 17 00:00:00 2001 From: Prashant Kanse Date: Wed, 17 Jan 2024 19:26:45 +0530 Subject: [PATCH 3/6] DGIR-148 : Fix linting error --- embargo.module | 3 ++- src/Entity/Embargo.php | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/embargo.module b/embargo.module index e0c4af1..f13ad5a 100644 --- a/embargo.module +++ b/embargo.module @@ -10,6 +10,7 @@ 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(). @@ -114,7 +115,7 @@ function embargo_form_alter(&$form, FormStateInterface $form_state, $form_id) { // Check if the URL contains a node ID. $node_id = \Drupal::routeMatch()->getParameter('node'); - if ($node_id instanceof \Drupal\node\NodeInterface) { + if ($node_id instanceof NodeInterface) { $node_id = $node_id->id(); } diff --git a/src/Entity/Embargo.php b/src/Entity/Embargo.php index a7bc9b5..b9bbe57 100644 --- a/src/Entity/Embargo.php +++ b/src/Entity/Embargo.php @@ -100,12 +100,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) ->setSetting('target_type', 'media') ->setSetting('handler', 'default:media') - ->setDisplayOptions('view', array( + ->setDisplayOptions('view', [ 'label' => 'above', 'type' => 'entity_reference_label', 'weight' => 0, - )) - ->setDisplayOptions('form', array( + ]) + ->setDisplayOptions('form', [ 'type' => 'options_buttons', 'weight' => 0, 'settings' => [ @@ -113,7 +113,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { 'size' => '60', 'placeholder' => '', ], - )); + ]); $fields['expiration_type'] = BaseFieldDefinition::create('list_integer') ->setLabel(t('Expiration Type')) @@ -461,8 +461,7 @@ public function isUserExempt(AccountInterface $user): bool { $exempt_users = $this->getExemptUsers(); $has_permission = $user->hasPermission('bypass embargo access'); return $has_permission || in_array($user->id(), array_map(function (UserInterface $user) { - return $user->id(); - }, $exempt_users)); + return $user->id();}, $exempt_users)); } /** From bde9406649b67f2f66e2507afc56564db4d1a024 Mon Sep 17 00:00:00 2001 From: Prashant Kanse Date: Wed, 17 Jan 2024 22:16:11 +0530 Subject: [PATCH 4/6] DGIR-148 : Hide file list when no node selected --- embargo.module | 5 +++++ src/Entity/Embargo.php | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/embargo.module b/embargo.module index f13ad5a..45a4ded 100644 --- a/embargo.module +++ b/embargo.module @@ -131,6 +131,11 @@ function embargo_form_alter(&$form, FormStateInterface $form_state, $form_id) { $options = embargo_get_filtered_file_options($node_id); $form['embargoed_file']['widget']['#options'] = $options; } + else { + // todo : we need to update file list when user add node in Embargoed Node + // field. + unset($form['embargoed_file']); + } // JS to add Select/Unselect All link and functionality. $form['#attached']['library'][] = 'embargo/custom_select_all_library'; diff --git a/src/Entity/Embargo.php b/src/Entity/Embargo.php index b9bbe57..d24bda7 100644 --- a/src/Entity/Embargo.php +++ b/src/Entity/Embargo.php @@ -461,7 +461,9 @@ public function isUserExempt(AccountInterface $user): bool { $exempt_users = $this->getExemptUsers(); $has_permission = $user->hasPermission('bypass embargo access'); return $has_permission || in_array($user->id(), array_map(function (UserInterface $user) { - return $user->id();}, $exempt_users)); + return $user->id(); + }, $exempt_users)); + } /** From 700aa9fab107a0042a616cf1a288eb8fcfb125f3 Mon Sep 17 00:00:00 2001 From: Prashant Kanse Date: Wed, 17 Jan 2024 22:21:16 +0530 Subject: [PATCH 5/6] DGIR-148 : Hide file list when no node selected --- embargo.module | 3 +-- src/Entity/Embargo.php | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/embargo.module b/embargo.module index 45a4ded..881f49a 100644 --- a/embargo.module +++ b/embargo.module @@ -132,8 +132,7 @@ function embargo_form_alter(&$form, FormStateInterface $form_state, $form_id) { $form['embargoed_file']['widget']['#options'] = $options; } else { - // todo : we need to update file list when user add node in Embargoed Node - // field. + // @todo Need to update file list via ajax when Embargoed Node available. unset($form['embargoed_file']); } diff --git a/src/Entity/Embargo.php b/src/Entity/Embargo.php index d24bda7..2376936 100644 --- a/src/Entity/Embargo.php +++ b/src/Entity/Embargo.php @@ -462,8 +462,7 @@ public function isUserExempt(AccountInterface $user): bool { $has_permission = $user->hasPermission('bypass embargo access'); return $has_permission || in_array($user->id(), array_map(function (UserInterface $user) { return $user->id(); - }, $exempt_users)); - + }, $exempt_users)); } /** From 9778b28abb955ea6a763ee06661af5c31bf508e0 Mon Sep 17 00:00:00 2001 From: Prashant Kanse Date: Thu, 18 Jan 2024 17:48:38 +0530 Subject: [PATCH 6/6] DGIR-148 : Fix update hook issue --- embargo.install | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/embargo.install b/embargo.install index b97da50..bb5dda8 100644 --- a/embargo.install +++ b/embargo.install @@ -6,7 +6,7 @@ */ use Drupal\Core\Field\BaseFieldDefinition; -use Drupal\Core\Update\UpdateException; +use Drupal\Core\Utility\UpdateException; /** * Add a new field to the existing Embargo entity type. @@ -20,16 +20,13 @@ function embargo_update_8001() { try { // Create a new field definition. $new_field = BaseFieldDefinition::create('entity_reference') - ->setLabel(t('New Embargoed File')) + ->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('new_embargoed_file', $entity_type_id, $bundle, $new_field); - - // Clear the cache. - drupal_flush_all_caches(); + $definition_manager->installFieldStorageDefinition('embargoed_file', $entity_type_id, $bundle, $new_field); } catch (UpdateException $e) { // Handle exception if needed. @@ -38,5 +35,5 @@ function embargo_update_8001() { } // Provide a message indicating the update has been applied. - return t('Added new_embargoed_file to the Embargo entity.'); + return t('Added embargoed_file to the Embargo entity.'); }