sites_group_overrides-1.x-dev/src/FormDecorator/LayoutBuilderOverrides.php
src/FormDecorator/LayoutBuilderOverrides.php
<?php
declare(strict_types=1);
namespace Drupal\sites_group_overrides\FormDecorator;
use Drupal\Core\Access\CsrfTokenGenerator;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\ContentEntityFormInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\sites\ContextProvider\CurrentSiteContextInterface;
use Drupal\sites_group\SitesGroupServiceInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\form_decorator\ContentEntityFormDecoratorBase;
use Drupal\group\Entity\GroupRelationshipInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage;
/**
* Adjust layout builder override forms to allow site overrides.
*
* @FormDecorator()
*/
final class LayoutBuilderOverrides extends ContentEntityFormDecoratorBase implements ContainerFactoryPluginInterface {
/**
* The corresponding group relationship entity.
*
* @var GroupRelationshipInterface
*/
protected GroupRelationshipInterface $groupRelationship;
/**
* The sites_group_overrides third party settings.
*
* @var array
*/
protected array $settings;
/**
* {@inheritdoc}
*
* @param \Drupal\sites\ContextProvider\CurrentSiteContextInterface $currentSiteContext
* The current site context.
*/
public static function create(ContainerInterface $container, $configuration, $plugin_id, $plugin_definition) {
return new self($configuration, $plugin_id, $plugin_definition,
$container->get('sites_group.service'),
$container->get('entity_type.manager'),
$container->get('sites.current_site'),
$container->get('csrf_token'),
);
}
/**
* {@inheritdoc}
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
protected SitesGroupServiceInterface $sitesGroupService,
protected EntityTypeManagerInterface $entityTypeManager,
protected readonly CurrentSiteContextInterface $currentSiteContext,
protected readonly CsrfTokenGenerator $csrfToken,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public function applies(): bool {
if (!$this->inner instanceof ContentEntityFormInterface) {
return FALSE;
}
$entity = $this->getEntity();
if (!($entity instanceof ContentEntityInterface) || !$entity->hasField(OverridesSectionStorage::FIELD_NAME)) {
return FALSE;
}
if ($entity->get(OverridesSectionStorage::FIELD_NAME)->isEmpty()) {
return FALSE;
}
if (!str_ends_with($this->inner->getFormId(), 'layout_builder_form')) {
return FALSE;
}
if ($group_relationship = $this->sitesGroupService->getRelationship($this->getEntity())) {
$this->groupRelationship = $group_relationship;
}
else {
return FALSE;
}
$this->settings = $entity->get(OverridesSectionStorage::FIELD_NAME)
->getFieldDefinition()
->getThirdPartySetting('sites_group_overrides', $this->groupRelationship->bundle(), []);
if (empty($this->settings['use_overrides'])) {
return FALSE;
}
return $group_relationship->hasField($this->settings['target_field_name']);
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ...$args) {
$form = $this->inner->buildForm($form, $form_state, ...$args);
if (!$this->groupRelationship->getEntityType()->isRevisionable()) {
$form['revision']['#disabled'] = TRUE;
$form['revision']['#default_value'] = FALSE;
$form['revision']['#description'] = $this->t('The @entity_type does not support revisions.', [
'@entity_type' => $this->groupRelationship->getEntityType()->getLabel(),
]);
}
$form['layout_builder_message']['message']['#message_list']['status'][] = $this->t('Override for @group', [
'@group' => $this->groupRelationship->getGroup()->label(),
]);
$relationship = $this->entityTypeManager->getStorage('group_relationship')->loadUnchanged($this->groupRelationship->id());
$form['layout_builder_message']['message']['#message_list']['status'][] = $this->t('Currently: @status', [
'@status' => $relationship->get($this->settings['target_field_name'])->isEmpty() ? $this->t('Default override') : $this->t('Overridden'),
]);
$form['actions']['revert']['#value'] = $this->t('Revert to default override');
// Save the current site_id to the form to make sure the submission always
// gets processed in the right site context.
$form['site_id'] = [
'#type' => 'hidden',
'#value' => $this->currentSiteContext->getSiteFromContext()->getPluginId(),
];
// Add a SCRF Token so that we can evaluate if the site_id post param is legitimite.
$form['sites_csrf'] = [
'#type' => 'hidden',
'#value' => $this->csrfToken->get('sites_csrf'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state) {
$entity = $this->getEntity();
$layout = $entity->get(OverridesSectionStorage::FIELD_NAME)->getValue();
// Write layout override to relationship and don't save entity at all.
$this->groupRelationship->set($this->settings['target_field_name'], $layout);
$this->setEntity($this->groupRelationship);
$this->inner->save($form, $form_state);
}
}
