protected function PremiumContent::addPremiumAccess in Node Option Premium 8
Adds a premium access filter to a search query, if applicable.
Parameters
\Drupal\search_api\Query\QueryInterface $query: The query to which a node access filter should be added, if applicable.
\Drupal\Core\Session\AccountInterface $account: The user for whom the search is executed.
Throws
\Drupal\search_api\SearchApiException Thrown if not all necessary fields are indexed on the index.
1 call to PremiumContent::addPremiumAccess()
- PremiumContent::preprocessSearchQuery in src/
Plugin/ search_api/ processor/ PremiumContent.php - Preprocesses a search query.
File
- src/
Plugin/ search_api/ processor/ PremiumContent.php, line 176
Class
- PremiumContent
- Adds premium information to the indexes.
Namespace
Drupal\nopremium\Plugin\search_api\processorCode
protected function addPremiumAccess(QueryInterface $query, AccountInterface $account) {
// Don't do anything if the user can access all premium content.
if ($account
->hasPermission('view full premium content of any type')) {
return;
}
// Gather the affected datasources, grouped by entity type, as well as the
// unaffected ones.
$affected_datasources = [];
$unaffected_datasources = [];
foreach ($this->index
->getDatasources() as $datasource_id => $datasource) {
if ($datasource
->getEntityTypeId() === 'node') {
$affected_datasources['node'][] = $datasource_id;
}
else {
$unaffected_datasources[] = $datasource_id;
}
}
// The filter structure we want looks like this:
// @code
// [belongs to other datasource]
// OR
// (
// [is enabled (or was created by the user, if applicable)]
// AND
// [grants view access to one of the user's gid/realm combinations]
// )
// @endcode
// If there are no "other" datasources, we don't need the nested OR,
// however, and can add the inner conditions directly to the query.
if ($unaffected_datasources) {
$outer_conditions = $query
->createConditionGroup('OR', [
'content_access',
]);
$query
->addConditionGroup($outer_conditions);
foreach ($unaffected_datasources as $datasource_id) {
$outer_conditions
->addCondition('search_api_datasource', $datasource_id);
}
$access_conditions = $query
->createConditionGroup('AND');
$outer_conditions
->addConditionGroup($access_conditions);
}
else {
$access_conditions = $query;
}
// If the user does not have the permission to see any content at all, deny
// access to all items from affected datasources.
if (!$affected_datasources) {
// If there were "other" datasources, the existing filter will already
// remove all results of node or comment datasources. Otherwise, we should
// not return any results at all.
if (!$unaffected_datasources) {
$query
->abort($this
->t('You have no access to any results in this search.'));
}
return;
}
// Authors of premium nodes may always view their own nodes.
$premium_conditions = $query
->createConditionGroup('OR');
if ($account
->isAuthenticated()) {
$author_conditions = $query
->createConditionGroup('OR');
foreach ($affected_datasources as $entity_type => $datasources) {
foreach ($datasources as $datasource_id) {
if ($entity_type == 'node') {
$author_field = $this
->findField($datasource_id, 'uid', 'integer');
if ($author_field) {
$author_conditions
->addCondition($author_field
->getFieldIdentifier(), $account
->id());
}
}
}
}
$premium_conditions
->addConditionGroup($author_conditions);
}
foreach (NodeType::loadMultiple() as $type) {
$type_id = $type
->id();
if (!$account
->hasPermission("view full {$type_id} premium content")) {
// User may only view non-premium nodes of this type.
$node_type_conditions = $query
->createConditionGroup('AND');
$node_type_conditions
->addCondition('type', $type_id);
$node_type_conditions
->addCondition('premium', FALSE);
$premium_conditions
->addConditionGroup($node_type_conditions);
}
else {
$premium_conditions
->addCondition('type', $type_id);
}
}
$access_conditions
->addConditionGroup($premium_conditions);
}