component_library-1.0.x-dev/src/EventSubscriber/EntityFieldYamlPlaceholders.php
src/EventSubscriber/EntityFieldYamlPlaceholders.php
<?php
declare(strict_types=1);
namespace Drupal\component_library\EventSubscriber;
use Drupal\component_library\Event\ConvertYamlPlaceholdersEvent;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\ContentEntityInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
final class EntityFieldYamlPlaceholders implements EventSubscriberInterface {
public static function getSubscribedEvents(): array {
return [
ConvertYamlPlaceholdersEvent::class => ['onConvertYamlPlaceholders'],
];
}
public function onConvertYamlPlaceholders(ConvertYamlPlaceholdersEvent $event): void {
$context = $event->getContext();
foreach ($context as $key => $value) {
if (\is_string($value) && \str_starts_with($value, 'field:')) {
$values = \explode(':', $value);
if (\count($values) !== 3) {
// This isn't a field, so don't set the context item.
continue;
}
[, $context_id, $field_name] = $values;
if (!\array_key_exists($context_id, $context) || !$context[$context_id] instanceof ContentEntityInterface) {
$event->setContextItem($key, []);
continue;
}
$entity = $context[$context_id];
$entity_access = $entity->access('view', NULL, TRUE);
if (!$entity_access->isAllowed()) {
$event->setContextItem($key, []);
continue;
}
if (!$entity->hasField($field_name)) {
$event->setContextItem($key, []);
continue;
}
$field_access = $entity->get($field_name)->access('view', NULL, TRUE);
if (!$field_access->isAllowed()) {
$event->setContextItem($key, []);
continue;
}
$build = $entity->get($field_name)->view($event->getViewMode());
CacheableMetadata::createFromRenderArray($build)
->merge(CacheableMetadata::createFromObject($field_access))
->merge(CacheableMetadata::createFromObject($entity_access))
->merge(CacheableMetadata::createFromObject($entity))
->applyTo($build);
$event->setContextItem($key, $build);
}
}
}
}
