You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
5.8 KiB
176 lines
5.8 KiB
<?php |
|
|
|
namespace Drupal\islandora\Plugin\ContextReaction; |
|
|
|
use Drupal\Core\Config\ConfigFactoryInterface; |
|
use Drupal\Core\Entity\EntityInterface; |
|
use Drupal\Core\Form\FormStateInterface; |
|
use Drupal\islandora\ContextReaction\NormalizerAlterReaction; |
|
use Drupal\islandora\MediaSource\MediaSourceService; |
|
use Drupal\jsonld\Normalizer\NormalizerBase; |
|
use Drupal\media\MediaInterface; |
|
use Drupal\islandora\IslandoraUtils; |
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
|
|
|
/** |
|
* Create a self-reference in RDF when creating JSON-LD. |
|
* |
|
* Formerly called "Map URI to predicate". Renamed for clarity. |
|
* |
|
* @ContextReaction( |
|
* id = "islandora_map_uri_predicate", |
|
* label = @Translation("JSON-LD self-reference") |
|
* ) |
|
*/ |
|
class JsonldSelfReferenceReaction extends NormalizerAlterReaction { |
|
|
|
const SELF_REFERENCE_PREDICATE = 'drupal_uri_predicate'; |
|
|
|
/** |
|
* Media source service. |
|
* |
|
* @var \Drupal\islandora\MediaSource\MediaSourceService |
|
*/ |
|
protected $mediaSource; |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function __construct(array $configuration, |
|
$plugin_id, |
|
$plugin_definition, |
|
ConfigFactoryInterface $config_factory, |
|
IslandoraUtils $utils, |
|
MediaSourceService $media_source) { |
|
|
|
parent::__construct( |
|
$configuration, |
|
$plugin_id, |
|
$plugin_definition, |
|
$config_factory, |
|
$utils |
|
); |
|
$this->mediaSource = $media_source; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { |
|
return new static( |
|
$configuration, |
|
$plugin_id, |
|
$plugin_definition, |
|
$container->get('config.factory'), |
|
$container->get('islandora.utils'), |
|
$container->get('islandora.media_source_service') |
|
); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function summary() { |
|
return $this->t('When creating the JSON-LD for this Drupal entity, add a relationship to itself using this predicate.'); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function execute(EntityInterface $entity = NULL, array &$normalized = NULL, array $context = NULL) { |
|
$config = $this->getConfiguration(); |
|
$self_ref_predicate = $config[self::SELF_REFERENCE_PREDICATE]; |
|
if (!is_null($self_ref_predicate) && !empty($self_ref_predicate)) { |
|
$url = $this->getSubjectUrl($entity); |
|
if ($context['needs_jsonldcontext'] === FALSE) { |
|
$self_ref_predicate = NormalizerBase::escapePrefix($self_ref_predicate, $context['namespaces']); |
|
} |
|
if (isset($normalized['@graph']) && is_array($normalized['@graph'])) { |
|
foreach ($normalized['@graph'] as &$graph) { |
|
if (isset($graph['@id']) && $graph['@id'] == $url) { |
|
// Swap media and file urls. |
|
if ($entity instanceof MediaInterface) { |
|
$file = $this->mediaSource->getSourceFile($entity); |
|
$graph['@id'] = $this->utils->getDownloadUrl($file); |
|
} |
|
if (isset($graph[$self_ref_predicate])) { |
|
if (!is_array($graph[$self_ref_predicate])) { |
|
if ($graph[$self_ref_predicate] == $url) { |
|
// Don't add it if it already exists. |
|
return; |
|
} |
|
$tmp = $graph[$self_ref_predicate]; |
|
$graph[$self_ref_predicate] = [$tmp]; |
|
} |
|
elseif (array_search($url, array_column($graph[$self_ref_predicate], '@id'))) { |
|
// Don't add it if it already exists. |
|
return; |
|
} |
|
} |
|
else { |
|
$graph[$self_ref_predicate] = []; |
|
} |
|
$graph[$self_ref_predicate][] = ["@id" => $url]; |
|
return; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function buildConfigurationForm(array $form, FormStateInterface $form_state) { |
|
$config = $this->getConfiguration(); |
|
$form[self::SELF_REFERENCE_PREDICATE] = [ |
|
'#type' => 'textfield', |
|
'#title' => $this->t('Self-reference predicate'), |
|
'#description' => $this->t("When creating the JSON-LD for this Drupal entity, add a relationship from the entity to itself using this predicate. It must use a defined RDF namespace prefix."), |
|
'#default_value' => isset($config[self::SELF_REFERENCE_PREDICATE]) ? $config[self::SELF_REFERENCE_PREDICATE] : '', |
|
'#size' => 35, |
|
]; |
|
return $form; |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { |
|
$self_ref_predicate = $form_state->getValue(self::SELF_REFERENCE_PREDICATE); |
|
if (!is_null($self_ref_predicate) and !empty($self_ref_predicate)) { |
|
if (preg_match('/^https?:\/\//', $self_ref_predicate)) { |
|
// Can't validate all URIs so we have to trust them. |
|
return; |
|
} |
|
elseif (preg_match('/^([^\s:]+):/', $self_ref_predicate, $matches)) { |
|
$predicate_prefix = $matches[1]; |
|
$rdf = rdf_get_namespaces(); |
|
$rdf_prefixes = array_keys($rdf); |
|
if (!in_array($predicate_prefix, $rdf_prefixes)) { |
|
$form_state->setErrorByName( |
|
self::SELF_REFERENCE_PREDICATE, |
|
$this->t('Namespace prefix @prefix is not registered.', |
|
['@prefix' => $predicate_prefix] |
|
) |
|
); |
|
} |
|
} |
|
else { |
|
$form_state->setErrorByName( |
|
self::SELF_REFERENCE_PREDICATE, |
|
$this->t('Predicate must use a defined prefix or be a full URI') |
|
); |
|
} |
|
} |
|
parent::validateConfigurationForm($form, $form_state); |
|
} |
|
|
|
/** |
|
* {@inheritdoc} |
|
*/ |
|
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { |
|
$this->setConfiguration([self::SELF_REFERENCE_PREDICATE => $form_state->getValue(self::SELF_REFERENCE_PREDICATE)]); |
|
} |
|
|
|
}
|
|
|