Skip to content

Commit

Permalink
Back over to property, instead of a calculated field.
Browse files Browse the repository at this point in the history
Calculated field was getting hit by context, but also leading to some
other oddities. Easier just to roll back into the processor, for now.
  • Loading branch information
adam-vessey committed Mar 11, 2024
1 parent 92b4b05 commit 3477650
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 48 deletions.
36 changes: 0 additions & 36 deletions embargo.module
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\embargo\EmbargoInterface;
use Drupal\embargo\EmbargoItemList;
use Drupal\embargo\EmbargoStorage;
use Drupal\islandora_hierarchical_access\LUTGeneratorInterface;

Expand Down Expand Up @@ -105,38 +101,6 @@ function embargo_theme($existing, $type, $theme, $path) {
];
}

/**
* Implements hook_entity_base_field_info().
*/
function embargo_entity_base_field_info(EntityTypeInterface $entity_type) {
if (!in_array($entity_type->id(), ['file', 'media', 'node'])) {
return [];
}

$fields = [];

$fields['embargo'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Embargoes'))
->setDescription(t('Embargoes affecting this item.'))
->setTranslatable(FALSE)
->setRevisionable(FALSE)
->setRequired(FALSE)
->setDisplayConfigurable('view', FALSE)
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setComputed(TRUE)
->setClass(EmbargoItemList::class)
->setSetting('target_type', 'embargo')
->setSetting('embargo_types', match($entity_type->id()) {
'file', 'media' => [
EmbargoInterface::EMBARGO_TYPE_NODE,
EmbargoInterface::EMBARGO_TYPE_FILE,
],
'node' => [EmbargoInterface::EMBARGO_TYPE_NODE],
});

return $fields;
}

/**
* Implements hook_ENTITY_TYPE_insert() for embargo entities.
*/
Expand Down
89 changes: 77 additions & 12 deletions src/Plugin/search_api/processor/EmbargoProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\embargo\EmbargoInterface;
use Drupal\embargo\Plugin\search_api\processor\Property\ListableEntityProcessorProperty;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Query\ConditionGroupInterface;
use Drupal\search_api\Query\QueryInterface;
use Drupal\search_api\SearchApiException;
use Drupal\search_api\Utility\Utility;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

Expand All @@ -24,6 +29,7 @@
* description = @Translation("Add information regarding embargo access
* constraints."),
* stages = {
* "add_properties" = 20,
* "pre_index_save" = 20,
* "preprocess_query" = 20,
* },
Expand Down Expand Up @@ -77,23 +83,82 @@ public static function create(ContainerInterface $container, array $configuratio
return $instance;
}

/**
* {@inheritdoc}
*/
public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) : array {
if ($datasource === NULL) {
return [];
}

return [
'embargo' => ListableEntityProcessorProperty::create('embargo')
->setList()
->setProcessorId($this->getPluginId()),
];
}

/**
* {@inheritdoc}
*
* Adapted from search_api's reverse_entity_references processor.
*
* @see \Drupal\search_api\Plugin\search_api\processor\ReverseEntityReferences::addFieldValues()
*/
public function addFieldValues(ItemInterface $item) : void {
if (!in_array($item->getDatasource()->getEntityTypeId(), static::ENTITY_TYPES)) {
return;
}
try {
$entity = $item->getOriginalObject()->getValue();
}
catch (SearchApiException) {
return;
}
if (!($entity instanceof EntityInterface)) {
return;
}

$datasource_id = $item->getDatasourceId();

/** @var \Drupal\search_api\Item\FieldInterface[][][] $to_extract */
$to_extract = [];
foreach ($item->getFields(FALSE) as $field) {
$property_path = $field->getPropertyPath();
[$direct, $nested] = Utility::splitPropertyPath($property_path, FALSE);
if ($field->getDatasourceId() === $datasource_id
&& $direct === 'embargo') {
$to_extract[$nested][] = $field;
}
}

/** @var \Drupal\embargo\EmbargoStorageInterface $embargo_storage */
$embargo_storage = $this->entityTypeManager->getStorage('embargo');
$embargoes = $embargo_storage->getApplicableEmbargoes($entity);

foreach ($embargoes as $embargo) {
$this->getFieldsHelper()->extractFields($embargo->getTypedData(), $to_extract);
}

}

/**
* {@inheritDoc}
*/
public function preIndexSave() {
public function preIndexSave() : void {
parent::preIndexSave();

foreach ($this->index->getDatasources() as $datasource_id => $datasource) {
if (!in_array($datasource->getEntityTypeId(), static::ENTITY_TYPES)) {
continue;
}

$this->ensureField($datasource_id, 'embargo:entity:id', 'integer');
$this->ensureField($datasource_id, 'embargo:entity:embargo_type', 'integer');
$this->ensureField($datasource_id, 'embargo:entity:expiration_date', 'date');
$this->ensureField($datasource_id, 'embargo:entity:expiration_type', 'integer');
$this->ensureField($datasource_id, 'embargo:entity:exempt_ips:entity:id', 'integer');
$this->ensureField($datasource_id, 'embargo:entity:exempt_users:entity:uid', 'integer');
$this->ensureField($datasource_id, 'embargo:id', 'integer');
$this->ensureField($datasource_id, 'embargo:embargo_type', 'integer');
$this->ensureField($datasource_id, 'embargo:expiration_date', 'date');
$this->ensureField($datasource_id, 'embargo:expiration_type', 'integer');
$this->ensureField($datasource_id, 'embargo:exempt_ips:entity:id', 'integer');
$this->ensureField($datasource_id, 'embargo:exempt_users:entity:uid', 'integer');
}
}

Expand Down Expand Up @@ -142,19 +207,19 @@ protected function addEmbargoFilters(string $datasource_id, QueryInterface $quer
]);

// No embargo.
if ($field = $this->findField($datasource_id, 'embargo:entity:id')) {
if ($field = $this->findField($datasource_id, 'embargo:id')) {
$or_group->addCondition($field->getFieldIdentifier(), NULL);
$query->addCacheTags(['embargo_list']);
}

// Embargo duration/schedule.
if ($expiration_type_field = $this->findField($datasource_id, 'embargo:entity:expiration_type')) {
if ($expiration_type_field = $this->findField($datasource_id, 'embargo:expiration_type')) {
$schedule_group = $query->createConditionGroup(tags: ['embargo_schedule']);
// No indefinite embargo.
$schedule_group->addCondition($expiration_type_field->getFieldIdentifier(), EmbargoInterface::EXPIRATION_TYPE_INDEFINITE, '<>');

// Scheduled embargo in the past and none in the future.
if ($scheduled_field = $this->findField($datasource_id, 'embargo:entity:expiration_date')) {
if ($scheduled_field = $this->findField($datasource_id, 'embargo:expiration_date')) {
$schedule_group->addCondition($expiration_type_field->getFieldIdentifier(), EmbargoInterface::EXPIRATION_TYPE_SCHEDULED);
// Embargo in the past.
$schedule_group->addCondition($scheduled_field->getFieldIdentifier(), date('Y-m-d', $this->time->getRequestTime()), '<=');
Expand All @@ -173,12 +238,12 @@ protected function addEmbargoFilters(string $datasource_id, QueryInterface $quer
if ($this->currentUser->isAnonymous()) {
$query->addCacheContexts(['user.roles:anonymous']);
}
elseif ($field = $this->findField($datasource_id, 'embargo:entity:exempt_users:entity:uid')) {
elseif ($field = $this->findField($datasource_id, 'embargo:exempt_users:entity:uid')) {
$or_group->addCondition($field->getFieldIdentifier(), $this->currentUser->id());
$query->addCacheContexts(['user']);
}

if ($field = $this->findField($datasource_id, 'embargo:entity:exempt_ips:entity:id')) {
if ($field = $this->findField($datasource_id, 'embargo:exempt_ips:entity:id')) {
/** @var \Drupal\embargo\IpRangeStorageInterface $ip_range_storage */
$ip_range_storage = $this->entityTypeManager->getStorage('embargo_ip_range');
foreach ($ip_range_storage->getApplicableIpRanges($this->requestStack->getCurrentRequest()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Drupal\embargo\Plugin\search_api\processor\Property;

use Drupal\search_api\Processor\EntityProcessorProperty;

/**
* Extended EntityProcessorProperty class with some additional setters.
*/
class ListableEntityProcessorProperty extends EntityProcessorProperty {

/**
* Set to represent a list.
*
* @param bool $value
* The value to set. Defaults to true.
*/
public function setList(bool $value = TRUE) : self {
$this->definition['is_list'] = $value;
return $this;
}

/**
* Set the processor ID.
*
* @param string $processor_id
* The processor ID to set.
*/
public function setProcessorId(string $processor_id) : self {
$this->definition['processor_id'] = $processor_id;
return $this;
}

}

0 comments on commit 3477650

Please sign in to comment.