Loading modules/custom/entity_access_by_field/entity_access_by_field.module +37 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,43 @@ function entity_access_by_field_node_grants(AccountInterface $account, $op): arr return $grants; } /** * Implements hook_node_grants_alter(). */ function entity_access_by_field_node_grants_alter(array &$grants, AccountInterface $account, string $op): void { if ($op === 'view') { $entity_type_manager = \Drupal::entityTypeManager(); /** @var \Drupal\group\Entity\Storage\GroupContentStorageInterface $group_content_storage */ $group_content_storage = $entity_type_manager->getStorage('group_content'); /** @var \Drupal\user\UserStorageInterface $user_storage */ $user_storage = $entity_type_manager->getStorage('user'); // Get all user's memberships. /** @var \Drupal\user\UserInterface $user */ $user = $user_storage->load($account->id()); $memberships = $group_content_storage->loadByEntity($user); $gids = []; foreach ($memberships as $membership) { $gids[] = $membership->getGroup()->id(); } // Load node types. $node_types = \Drupal::entityTypeManager() ->getStorage('node_type') ->getQuery() ->execute(); // Remove grants of node type if user are not a member in this group. foreach ($node_types as $node_type) { if (isset($grants["gnode:$node_type"])) { $grants["gnode:$node_type"] = array_intersect($grants["gnode:$node_type"], $gids); } } } } /** * Implements hook_node_access_records(). */ Loading modules/custom/entity_access_by_field/entity_access_by_field.post_update.php +44 −0 Original line number Diff line number Diff line Loading @@ -19,3 +19,47 @@ function entity_access_by_field_post_update_10101_rebuild_node_access() { function entity_access_by_field_post_update_10102_rebuild_node_access() { node_access_rebuild(TRUE); } /** * Reindex items in the 'social_all' and 'social_content'. */ function entity_access_by_field_post_update_11001_reindex_search(array &$sandbox): void { if (!isset($sandbox['total'])) { /** @var \Drupal\search_api\IndexInterface[] $search_api_indexes */ $search_api_indexes = \Drupal::entityTypeManager() ->getStorage('search_api_index') ->loadMultiple([ 'social_all', 'social_content', ]); $sandbox['total'] = 0; foreach ($search_api_indexes as $index_id => $index) { $index->clear(); $sandbox[$index_id] = [ 'not_indexed' => $index->hasValidTracker() ? $index->getTrackerInstance()->getRemainingItemsCount() : 0, ]; $sandbox['total'] += $sandbox[$index_id]['not_indexed']; } $sandbox['indexes'] = $search_api_indexes; $sandbox['total_indexed'] = 0; } if (!empty($sandbox['indexes'])) { /** @var \Drupal\search_api\IndexInterface $current_index */ $current_index = reset($sandbox['indexes']); $current_index_id = $current_index->id(); if ($sandbox[$current_index_id]['not_indexed'] <= 0) { unset($sandbox['indexes'][$current_index_id]); } if (isset($sandbox['indexes'][$current_index_id])) { $indexed = $current_index->indexItems(25); $sandbox[$current_index_id]['not_indexed'] -= $indexed; $sandbox['total_indexed'] += $indexed; } $sandbox['#finished'] = empty($sandbox['total']) ? 1 : ($sandbox['total_indexed'] / $sandbox['total']); } } modules/custom/entity_access_by_field/src/Plugin/search_api/processor/EntityAccessByField.php +31 −5 Original line number Diff line number Diff line Loading @@ -40,6 +40,13 @@ class EntityAccessByField extends ContentAccess { */ protected $currentUser; /** * The group content storage handler. * * @var \Drupal\group\Entity\Storage\GroupContentStorageInterface */ protected $groupContentStorage; /** * {@inheritdoc} */ Loading @@ -51,6 +58,10 @@ class EntityAccessByField extends ContentAccess { $processor->setDatabase($container->get('database')); $processor->setCurrentUser($container->get('current_user')); /** @var \Drupal\group\Entity\Storage\GroupContentStorageInterface $group_content_storage */ $group_content_storage = $container->get('entity_type.manager')->getStorage('group_content'); $processor->groupContentStorage = $group_content_storage; return $processor; } Loading Loading @@ -78,8 +89,17 @@ class EntityAccessByField extends ContentAccess { return; } $fields = $item->getFields(); $fields = $this->getFieldsHelper() ->filterForPropertyPath($fields, NULL, 'search_api_node_grants'); // Get the field definitions of the node. $field_definitions = $node->getFieldDefinitions(); // Get all group content entities. $gnodes = $this->groupContentStorage->loadByEntity($node); foreach ($fields as $field) { /** @var \Drupal\Core\Field\FieldConfigInterface $field_definition */ foreach ($field_definitions as $field_name => $field_definition) { // Lets get a node access realm if the field is implemented. Loading @@ -91,11 +111,6 @@ class EntityAccessByField extends ContentAccess { $field_name, ]; $realm = implode('_', $realm); $fields = $item->getFields(); $fields = $this->getFieldsHelper() ->filterForPropertyPath($fields, NULL, 'search_api_node_grants'); foreach ($fields as $field) { // Collect grant records for the node. $sql = 'SELECT gid, realm FROM {node_access} WHERE (nid = 0 OR nid = :nid) AND grant_view = 1 AND realm LIKE :realm'; $args = [ Loading @@ -110,6 +125,17 @@ class EntityAccessByField extends ContentAccess { } } } // Add node access check by node type in group. foreach ($gnodes as $gnode) { $realm = [ 'node_access_gnode', $node->getType(), $gnode->getGroup()->id(), ]; $realm = implode(':', $realm); $field->addValue($realm); } } } Loading Loading
modules/custom/entity_access_by_field/entity_access_by_field.module +37 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,43 @@ function entity_access_by_field_node_grants(AccountInterface $account, $op): arr return $grants; } /** * Implements hook_node_grants_alter(). */ function entity_access_by_field_node_grants_alter(array &$grants, AccountInterface $account, string $op): void { if ($op === 'view') { $entity_type_manager = \Drupal::entityTypeManager(); /** @var \Drupal\group\Entity\Storage\GroupContentStorageInterface $group_content_storage */ $group_content_storage = $entity_type_manager->getStorage('group_content'); /** @var \Drupal\user\UserStorageInterface $user_storage */ $user_storage = $entity_type_manager->getStorage('user'); // Get all user's memberships. /** @var \Drupal\user\UserInterface $user */ $user = $user_storage->load($account->id()); $memberships = $group_content_storage->loadByEntity($user); $gids = []; foreach ($memberships as $membership) { $gids[] = $membership->getGroup()->id(); } // Load node types. $node_types = \Drupal::entityTypeManager() ->getStorage('node_type') ->getQuery() ->execute(); // Remove grants of node type if user are not a member in this group. foreach ($node_types as $node_type) { if (isset($grants["gnode:$node_type"])) { $grants["gnode:$node_type"] = array_intersect($grants["gnode:$node_type"], $gids); } } } } /** * Implements hook_node_access_records(). */ Loading
modules/custom/entity_access_by_field/entity_access_by_field.post_update.php +44 −0 Original line number Diff line number Diff line Loading @@ -19,3 +19,47 @@ function entity_access_by_field_post_update_10101_rebuild_node_access() { function entity_access_by_field_post_update_10102_rebuild_node_access() { node_access_rebuild(TRUE); } /** * Reindex items in the 'social_all' and 'social_content'. */ function entity_access_by_field_post_update_11001_reindex_search(array &$sandbox): void { if (!isset($sandbox['total'])) { /** @var \Drupal\search_api\IndexInterface[] $search_api_indexes */ $search_api_indexes = \Drupal::entityTypeManager() ->getStorage('search_api_index') ->loadMultiple([ 'social_all', 'social_content', ]); $sandbox['total'] = 0; foreach ($search_api_indexes as $index_id => $index) { $index->clear(); $sandbox[$index_id] = [ 'not_indexed' => $index->hasValidTracker() ? $index->getTrackerInstance()->getRemainingItemsCount() : 0, ]; $sandbox['total'] += $sandbox[$index_id]['not_indexed']; } $sandbox['indexes'] = $search_api_indexes; $sandbox['total_indexed'] = 0; } if (!empty($sandbox['indexes'])) { /** @var \Drupal\search_api\IndexInterface $current_index */ $current_index = reset($sandbox['indexes']); $current_index_id = $current_index->id(); if ($sandbox[$current_index_id]['not_indexed'] <= 0) { unset($sandbox['indexes'][$current_index_id]); } if (isset($sandbox['indexes'][$current_index_id])) { $indexed = $current_index->indexItems(25); $sandbox[$current_index_id]['not_indexed'] -= $indexed; $sandbox['total_indexed'] += $indexed; } $sandbox['#finished'] = empty($sandbox['total']) ? 1 : ($sandbox['total_indexed'] / $sandbox['total']); } }
modules/custom/entity_access_by_field/src/Plugin/search_api/processor/EntityAccessByField.php +31 −5 Original line number Diff line number Diff line Loading @@ -40,6 +40,13 @@ class EntityAccessByField extends ContentAccess { */ protected $currentUser; /** * The group content storage handler. * * @var \Drupal\group\Entity\Storage\GroupContentStorageInterface */ protected $groupContentStorage; /** * {@inheritdoc} */ Loading @@ -51,6 +58,10 @@ class EntityAccessByField extends ContentAccess { $processor->setDatabase($container->get('database')); $processor->setCurrentUser($container->get('current_user')); /** @var \Drupal\group\Entity\Storage\GroupContentStorageInterface $group_content_storage */ $group_content_storage = $container->get('entity_type.manager')->getStorage('group_content'); $processor->groupContentStorage = $group_content_storage; return $processor; } Loading Loading @@ -78,8 +89,17 @@ class EntityAccessByField extends ContentAccess { return; } $fields = $item->getFields(); $fields = $this->getFieldsHelper() ->filterForPropertyPath($fields, NULL, 'search_api_node_grants'); // Get the field definitions of the node. $field_definitions = $node->getFieldDefinitions(); // Get all group content entities. $gnodes = $this->groupContentStorage->loadByEntity($node); foreach ($fields as $field) { /** @var \Drupal\Core\Field\FieldConfigInterface $field_definition */ foreach ($field_definitions as $field_name => $field_definition) { // Lets get a node access realm if the field is implemented. Loading @@ -91,11 +111,6 @@ class EntityAccessByField extends ContentAccess { $field_name, ]; $realm = implode('_', $realm); $fields = $item->getFields(); $fields = $this->getFieldsHelper() ->filterForPropertyPath($fields, NULL, 'search_api_node_grants'); foreach ($fields as $field) { // Collect grant records for the node. $sql = 'SELECT gid, realm FROM {node_access} WHERE (nid = 0 OR nid = :nid) AND grant_view = 1 AND realm LIKE :realm'; $args = [ Loading @@ -110,6 +125,17 @@ class EntityAccessByField extends ContentAccess { } } } // Add node access check by node type in group. foreach ($gnodes as $gnode) { $realm = [ 'node_access_gnode', $node->getType(), $gnode->getGroup()->id(), ]; $realm = implode(':', $realm); $field->addValue($realm); } } } Loading