From e41dc58c603963d46cf056e75814b8ae3f3f1c25 Mon Sep 17 00:00:00 2001 From: Denis Rudoi Date: Wed, 5 Feb 2025 18:38:28 +0300 Subject: [PATCH] Entitlements logic improve - final. --- modules/quanthub_core/quanthub_core.module | 27 ++---- .../quanthub_core/quanthub_core.services.yml | 2 +- .../src/AllowedContentManager.php | 96 ++++++++++--------- .../FieldType/QuantHubUrnComputedList.php | 5 +- .../views/filter/AllowedContentFilter.php | 7 +- .../filter/AllowedContentFilterSearchApi.php | 13 ++- 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/modules/quanthub_core/quanthub_core.module b/modules/quanthub_core/quanthub_core.module index 61794d06..80551c43 100644 --- a/modules/quanthub_core/quanthub_core.module +++ b/modules/quanthub_core/quanthub_core.module @@ -13,6 +13,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; use Drupal\node\NodeInterface; +use Drupal\quanthub_core\AllowedContentManager; use Drupal\quanthub_core\Form\PowerBiMediaDirectoriesForm; use Drupal\quanthub_core\Form\PowerBIMediaForm; @@ -23,7 +24,7 @@ function quanthub_core_node_access(NodeInterface $node, $operation, AccountInter if ( $operation !== 'view' || \Drupal::currentUser()->id() !== $account->id() || - !$node->hasField('field_quanthub_urn') || + !$node->hasField(AllowedContentManager::URN_FIELD) || getenv('WSO_IGNORE') === 'TRUE' ) { return AccessResult::neutral(); @@ -37,7 +38,7 @@ function quanthub_core_node_access(NodeInterface $node, $operation, AccountInter $allowed_datasets = \Drupal::service('allowed_content_manager') ->getAllowedDatasetList(); $node_datasets = []; - $field = $node->get('field_quanthub_urn'); + $field = $node->get(AllowedContentManager::URN_FIELD); if ($field instanceof CacheableDependencyInterface) { $cacheable_metadata->addCacheableDependency($field); } @@ -61,6 +62,7 @@ function quanthub_core_node_access(NodeInterface $node, $operation, AccountInter * Implements hook_views_data_alter(). */ function quanthub_core_views_data_alter(array &$data) { + $field_name = AllowedContentManager::URN_FIELD; $base = [ 'title' => t('Allowed Content Filter'), 'help' => t('Content Filter By Dataset Urn'), @@ -71,21 +73,21 @@ function quanthub_core_views_data_alter(array &$data) { ], ]; - if (!empty($data['node__field_quanthub_urn']['field_quanthub_urn_value'])) { - $table = 'node__field_quanthub_urn'; + if (!empty($data["node__$field_name"]["{$field_name}_value"])) { + $table = "node__$field_name"; $data[$table]['allowed_content_filter'] = $base; $data[$table]['allowed_content_filter']['filter']['id'] = 'allowed_content_filter'; - $data[$table]['allowed_content_filter']['filter'] += $data[$table]['field_quanthub_urn_value']['filter']; + $data[$table]['allowed_content_filter']['filter'] += $data[$table]["{$field_name}_value"]['filter']; } foreach (array_keys($data) as $table) { - if (!str_starts_with($table, 'search_api_index') || empty($data[$table]['field_quanthub_urn'])) { + if (!str_starts_with($table, 'search_api_index') || empty($data[$table][$field_name])) { continue; } $data[$table]['allowed_content_filter'] = $base; - $data[$table]['allowed_content_filter']['real field'] = 'field_quanthub_urn'; + $data[$table]['allowed_content_filter']['real field'] = $field_name; $data[$table]['allowed_content_filter']['filter']['id'] = 'allowed_content_filter_search_api'; - $data[$table]['allowed_content_filter']['filter'] += $data[$table]['field_quanthub_urn']['filter']; + $data[$table]['allowed_content_filter']['filter'] += $data[$table][$field_name]['filter']; } } @@ -277,12 +279,3 @@ function quanthub_core_language_switch_links_alter(array &$links, $type, Url $ur } } } - -/** - * Workaround to fix the CodeSniffer. - * - * @todo review how to fix the circular dependency without it. - */ -function quanthub_core_container() { - return \Drupal::getContainer(); -} diff --git a/modules/quanthub_core/quanthub_core.services.yml b/modules/quanthub_core/quanthub_core.services.yml index fb5e7f1c..e828af2a 100644 --- a/modules/quanthub_core/quanthub_core.services.yml +++ b/modules/quanthub_core/quanthub_core.services.yml @@ -24,7 +24,7 @@ services: # Managing allowed content in user data. Work sdmx_client. allowed_content_manager: class: '\Drupal\quanthub_core\AllowedContentManager' - arguments: ['@current_user', '@cache.default', '@language_manager', '@datetime.time'] + arguments: ['@current_user', '@cache.default', '@language_manager', '@datetime.time', '@entity_type.manager'] # Event subscriber for getting and storing user info attributes for authenticated user. user_info_attributes_subscriber: diff --git a/modules/quanthub_core/src/AllowedContentManager.php b/modules/quanthub_core/src/AllowedContentManager.php index c97b9f60..052a3c97 100644 --- a/modules/quanthub_core/src/AllowedContentManager.php +++ b/modules/quanthub_core/src/AllowedContentManager.php @@ -3,8 +3,8 @@ namespace Drupal\quanthub_core; use Drupal\Component\Datetime\Time; -use Drupal\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Language\LanguageManager; use Drupal\Core\Session\AccountProxy; @@ -16,29 +16,15 @@ class AllowedContentManager implements QuanthubCoreInterface { /** - * Name of user data argument for datasets. + * Dataset URN field name. */ - const USER_DATA_DATASETS = 'allowed_datasets'; + const URN_FIELD = 'field_quanthub_urn'; /** * The 15 minutes cache time. */ const CACHE_TIME = 900; - /** - * The (lazy loaded) dependency injection (DI) container. - * - * @var ?\Drupal\Component\DependencyInjection\ContainerInterface - */ - protected ?ContainerInterface $container; - - /** - * The (lazy loaded) SDMX client. - * - * @var ?\Drupal\quanthub_core\QuanthubSdmxClient - */ - protected ?QuanthubSdmxClient $quanthubSdmxClient; - /** * The time service. * @@ -68,11 +54,18 @@ class AllowedContentManager implements QuanthubCoreInterface { protected $languageManager; /** - * Dataset List. + * The node storage. + * + * @var \Drupal\node\NodeStorageInterface + */ + protected $nodeStorage; + + /** + * The prohibited datasets cache. * * @var array */ - protected $datasets = []; + private $datasets = []; /** * {@inheritDoc} @@ -82,11 +75,13 @@ public function __construct( CacheBackendInterface $cache, LanguageManager $language_manager, Time $time, + EntityTypeManagerInterface $entity_type_manager, ) { $this->currentUser = $current_user; $this->cache = $cache; $this->languageManager = $language_manager; $this->time = $time; + $this->nodeStorage = $entity_type_manager->getStorage('node'); } /** @@ -97,32 +92,59 @@ public function getAllowedDatasetList() { // Check that dataset list is not already saved to cache. if ($cache = $this->cache->get($this->getCacheCid())) { if (!empty($cache->data)) { - $this->datasets = $cache->data; + $datasets = $cache->data; } else { - $this->datasets = []; + $datasets = []; } } else { - $this->datasets = $this->getUserDatasetList(); + $datasets = $this->getUserDatasetList(); // Support latest version. - foreach ($this->datasets as $dataset) { + foreach ($datasets as $dataset) { $latest_dataset = preg_replace('/\(.+\)$/', '(~)', $dataset); if ($latest_dataset !== $dataset) { - $this->datasets[] = $latest_dataset; + $datasets[] = $latest_dataset; } } // Update datasets in cache. $this->cache->set( $this->getCacheCid(), - $this->datasets, + $datasets, $this->time->getCurrentTime() + $this::CACHE_TIME ); } - return $this->datasets; + return $datasets; + } + + /** + * Gets prohibited datasets list. + * + * The list is calculated from DB data based on URN default field + * or user specified one. + */ + public function getProhibitedDatasetList($field_name = self::URN_FIELD) { + if (!isset($this->datasets[$field_name])) { + $datasets = []; + $result = $this->nodeStorage->getAggregateQuery() + ->accessCheck(FALSE) + ->condition('status', 1) + ->exists($field_name) + ->groupby($field_name) + ->execute(); + foreach ($result as $item) { + if (!empty($item[$field_name])) { + $datasets[] = $item[$field_name]; + } + } + + $this->datasets[$field_name] = array_diff($datasets, $this->getAllowedDatasetList()); + } + + return $this->datasets[$field_name]; } /** @@ -139,20 +161,7 @@ public function getCacheCid() { * Get User's Dataset List. */ public function getUserDatasetList() { - return $this->quanthubSdmxClient()->getDatasetList(); - } - - /** - * Get Dependency Injection container. - * - * @return \Drupal\Component\DependencyInjection\ContainerInterface - * Current Dependency Injection container. - */ - protected function getContainer(): ContainerInterface { - if (!isset($this->container)) { - $this->container = quanthub_core_container(); - } - return $this->container; + return self::quanthubSdmxClient()->getDatasetList(); } /** @@ -161,11 +170,8 @@ protected function getContainer(): ContainerInterface { * @return \Drupal\quanthub_core\QuanthubSdmxClient * QuanthubSdmxClient service. */ - protected function quanthubSdmxClient(): QuanthubSdmxClient { - if (!isset($this->quanthubSdmxClient)) { - $this->quanthubSdmxClient = $this->getContainer()->get('sdmx_client'); - } - return $this->quanthubSdmxClient; + protected static function quanthubSdmxClient(): QuanthubSdmxClient { + return \Drupal::service('sdmx_client'); } } diff --git a/modules/quanthub_core/src/Plugin/Field/FieldType/QuantHubUrnComputedList.php b/modules/quanthub_core/src/Plugin/Field/FieldType/QuantHubUrnComputedList.php index a5c288b4..54797f96 100644 --- a/modules/quanthub_core/src/Plugin/Field/FieldType/QuantHubUrnComputedList.php +++ b/modules/quanthub_core/src/Plugin/Field/FieldType/QuantHubUrnComputedList.php @@ -8,6 +8,7 @@ use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Field\FieldItemList; use Drupal\Core\TypedData\ComputedItemListTrait; +use Drupal\quanthub_core\AllowedContentManager; /** * Computed field to proxy QuantHub URN from references. @@ -37,14 +38,14 @@ protected function computeValue() { foreach ($references->referencedEntities() as $referencedEntity) { if ( !$referencedEntity instanceof FieldableEntityInterface || - !$referencedEntity->hasField('field_quanthub_urn') + !$referencedEntity->hasField(AllowedContentManager::URN_FIELD) ) { continue; } $this->addCacheableDependency($referencedEntity); - $field = $referencedEntity->get('field_quanthub_urn'); + $field = $referencedEntity->get(AllowedContentManager::URN_FIELD); if ($field instanceof CacheableDependencyInterface) { $this->addCacheableDependency($field); } diff --git a/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilter.php b/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilter.php index f2f6157c..08fa49d3 100644 --- a/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilter.php +++ b/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilter.php @@ -165,17 +165,18 @@ protected function getNodeTypesMapping() { /** @var \Drupal\Core\Entity\Sql\TableMappingInterface $table_mapping */ $table_mapping = $this->entityTypeManager->getStorage('node')->getTableMapping(); $bundles = $this->entityFieldManager->getFieldMap()['node']['nid']['bundles']; + $field_name = $this->definition['field_name'] ?? $this->allowedContentManager::URN_FIELD; foreach ($bundles as $bundle) { $definitions = $this->entityFieldManager->getFieldDefinitions('node', $bundle); - if (empty($definitions['field_quanthub_urn'])) { + if (empty($definitions[$field_name])) { continue; } - if (!$definitions['field_quanthub_urn']->isComputed()) { + if (!$definitions[$field_name]->isComputed()) { $mapping['_root']['bundles'][$bundle] = $bundle; continue; } - $base_field = $definitions['field_quanthub_urn']->getSetting('field_reference_name'); + $base_field = $definitions[$field_name]->getSetting('field_reference_name'); if ($base_field && $definitions[$base_field]->getFieldStorageDefinition()->getMainPropertyName() === 'target_id') { $mapping[$base_field]['table'] = $table_mapping->getFieldTableName($base_field); $mapping[$base_field]['data_table'] = $table_mapping->getDataTable() ?? $table_mapping->getBaseTable(); diff --git a/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilterSearchApi.php b/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilterSearchApi.php index 0c5de594..442f8a0e 100644 --- a/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilterSearchApi.php +++ b/modules/quanthub_core/src/Plugin/views/filter/AllowedContentFilterSearchApi.php @@ -29,14 +29,13 @@ public function query() { $this->ensureMyTable(); - $conditions = $this->getQuery()->createConditionGroup('OR'); - $conditions->addCondition($this->realField, NULL); - - if ($datasets = $this->allowedContentManager->getAllowedDatasetList()) { - $conditions->addCondition($this->realField, $datasets, 'IN'); + if ($this->allowedContentManager->getAllowedDatasetList()) { + $datasets = $this->allowedContentManager->getProhibitedDatasetList(); + $this->query->addWhere($this->options['group'], $this->realField, $datasets, 'NOT IN'); + } + else { + $this->query->addWhere($this->options['group'], $this->realField, NULL, 'IS NULL'); } - - $this->query->addConditionGroup($conditions, $this->options['group']); } }