pattern_library-8.x-2.x-dev/src/Plugin/Layout/PatternLibraryLayout.php
src/Plugin/Layout/PatternLibraryLayout.php
<?php
namespace Drupal\pattern_library\Plugin\Layout;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Layout\Annotation\Layout;
use Drupal\Core\Layout\LayoutDefault;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Render\Element;
use Drupal\pattern_library\Exception\InvalidModifierException;
use Drupal\pattern_library\Exception\NotFoundModifierException;
use Drupal\pattern_library\PatternModifierTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Pattern library layout.
*
* @Layout(
* id = "pattern_library",
* deriver = "Drupal\pattern_library\Plugin\Deriver\PatternLibraryLayoutDeriver"
* )
*/
class PatternLibraryLayout extends LayoutDefault implements PluginFormInterface, ContainerFactoryPluginInterface {
/**
* @var \Drupal\pattern_library\PatternModifierTypeManagerInterface
*/
protected $modifierTypeManager;
/**
* {@inheritdoc}
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
PatternModifierTypeManagerInterface $modifier_type_manager
) {
parent::__construct(
$configuration,
$plugin_id,
$plugin_definition
);
$this->modifierTypeManager = $modifier_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(
ContainerInterface $container,
array $configuration,
$plugin_id,
$plugin_definition
) {
return new self(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('plugin.manager.pattern_modifier_type')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return parent::defaultConfiguration() + [
'modifiers' => [],
];
}
/**
* {@inheritdoc}
*/
public function build(array $regions) {
$build = [];
foreach ($this->getPluginDefinition()->getRegionNames() as $region_name) {
if (array_key_exists($region_name, $regions)) {
$build[$region_name] = $regions[$region_name];
}
}
$pattern = $this->getPatternDefinition();
$build['#pattern'] = $pattern;
$build['#source'] = $pattern->getSource();
$build['#theme'] = 'pattern_library_layout';
$build['#layout'] = $this->pluginDefinition;
$build['#modifiers'] = $this->processModifiers();
if ($library = $this->pluginDefinition->getLibrary()) {
$build['#attached']['library'][] = $library;
}
return $build;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form['modifiers'] = [
'#type' => 'details',
'#title' => $this->t('Modifiers'),
'#open' => TRUE,
];
/** @var \Drupal\pattern_library\Plugin\Pattern $pattern */
$pattern = $this->getPatternDefinition();
foreach ($pattern->getModifiers() as $name => $modifier) {
if (!$pattern->hasRegion($name) || !isset($modifier['type'])) {
continue;
}
$configurations = isset($modifier['configurations'])
? $modifier['configurations']
: [];
$this->attachDefaultConfigurations($name, $configurations);
$form['modifiers'][$name]['type'] = [
'#type' => 'hidden',
'#value' => $modifier['type']
];
try {
$form['modifiers'][$name]['value'] = $this
->createModifierType($modifier['type'], $configurations)
->render();
}
catch (\Exception $exception) {
throw new InvalidModifierException(
$exception->getMessage()
);
}
}
if (empty(Element::children($form['modifiers']))) {
unset($form['modifiers']);
}
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration = $form_state->cleanValues()->getValues();
}
/**
* Create modifier type instance.
*
* @param $plugin_id
* The modifier type plugin identifier.
* @param array $configurations
* An array of plugin configurations.
*
* @return \Drupal\pattern_library\Plugin\PatternModifierTypeInterface
* The pattern modifier type instance.
*
* @throws \Drupal\pattern_library\Exception\NotFoundModifierException
*/
protected function createModifierType($plugin_id, array $configurations = []) {
$modifier_manager = $this->modifierTypeManager;
if (!$modifier_manager->hasDefinition($plugin_id)) {
throw new NotFoundModifierException(
sprintf('The provided modifier %s type', $plugin_id)
);
}
return $modifier_manager->createInstance($plugin_id, $configurations);
}
/**
* Attach modifier default configurations.
*
* @param $region
* The region name.
* @param array $configurations
* An array of the region configurations.
*
* @throws \Drupal\Core\TypedData\Exception\MissingDataException
* @throws \Drupal\pattern_library\Exception\InvalidPatternException
*/
protected function attachDefaultConfigurations($region, array &$configurations) {
$parents = ['modifiers', $region];
$regions = $this->getPatternDefinition()->getRegions();
$configurations += [
'title' => $this->t('@region Modifier', [
'@region' => $regions[$region]['label']
])->render()
];
$default_value = $this->getConfigurationValue(
array_merge($parents, ['value'])
);
if (isset($default_value) && !empty($default_value)) {
$configurations['default_value'] = $default_value;
}
}
/**
* Process the modifier configurations.
*
* @return array
* An array of the processed modifiers.
*/
protected function processModifiers() {
$modifiers = [];
foreach ($this->getConfigurationModifiers() as $region => $modifier) {
if (!isset($modifier['type'])) {
continue;
}
$modifiers[$region] = $this->formatModifierValue(
$modifier['type'], $modifier['value']
);
}
return $modifiers;
}
/**
* Get pattern library pattern definition.
*
* @return \Drupal\pattern_library\Plugin\PatternInterface
* The library pattern definition.
*/
protected function getPatternDefinition() {
/** @var \Drupal\pattern_library\Plugin\Layout\PatternLayoutDefinition $definition */
$definition = $this->getPluginDefinition();
return $definition->getPatternDefinition();
}
/**
* Get configuration modifiers.
*
* @return array
* An array of unprocessed configuration modifiers.
*/
protected function getConfigurationModifiers() {
$configuration = $this->getConfiguration();
if (!isset($configuration['modifiers'])) {
return [];
}
return $configuration['modifiers'];
}
/**
* Get a specific configuration value.
*
* @param array $parents
* An array of value parents.
*
* @return array
* The configuration value.
*/
protected function getConfigurationValue(array $parents) {
$configuration = $this->getConfiguration();
return NestedArray::getValue($configuration, $parents);
}
/**
* Format the modifier type value.
*
* @param $plugin_id
* The modifier type id.
* @param $value
* The modifier type value.
*
* @return mixed
* The casted and/or transformed modifier value.
*/
protected function formatModifierValue($plugin_id, $value) {
return $this->modifierTypeManager->processModifierValue($plugin_id, $value);
}
}
