Skip to content
Snippets Groups Projects
Unverified Commit 6d8b1b3d authored by Derek Reese's avatar Derek Reese Committed by GitHub
Browse files

Merge pull request #73 from drupal-pattern-lab/feature/cybtachyon/alpha-5-8

Updates alpha 5 library block upgrade drush cmd
parents 29596960 79a9c2a3
No related branches found
No related tags found
No related merge requests found
......@@ -2,12 +2,15 @@
namespace Drupal\patternkit\Commands;
use Drupal\block\BlockInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay;
use Drupal\patternkit\Entity\Pattern;
use Drupal\patternkit\Entity\PatternInterface;
use Drupal\patternkit\Plugin\Derivative\PatternkitBlock;
use Drush\Commands\DrushCommands;
/**
......@@ -15,14 +18,51 @@ use Drush\Commands\DrushCommands;
*/
class PatternkitCommands extends DrushCommands {
/**
* Block storage manager.
*
* @var $blockStorage
*/
protected $blockStorage;
/**
* Asset Library manager.
*
* @var \Drupal\patternkit\Asset\LibraryInterface $library
*/
protected $library;
/**
* Pattern storage manager.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $patternStorage;
/**
*
*/
public function __construct() {
parent::__construct();
$entity_type_manager = \Drupal::entityTypeManager();
$this->blockStorage = $entity_type_manager->getStorage('patternkit_block');
$this->patternStorage = $entity_type_manager->getStorage('patternkit_pattern');
$this->library =\Drupal::service('patternkit.asset.library');
}
/**
* Update from an old dev version of Patternkit.
*
* Note: this is a brute-force method for updating from dev versions
* to stable releases. Use with caution.
*
* @command patternkit:devUpdate
* @aliases pkdu, patternkit-dev-update
*/
public function devUpdate() {
$logger = $this->logger();
if (!\Drupal::moduleHandler()->moduleExists('layout_builder')) {
$this->logger()->notice(t('Patternkit from-dev updates only apply to Layout Builder, which is not enabled. Skipping Patternkit from-dev updates.'));
$logger->notice(t('Patternkit from-dev updates only apply to Layout Builder, which is not enabled. Skipping Patternkit from-dev updates.'));
return;
}
......@@ -32,15 +72,14 @@ class PatternkitCommands extends DrushCommands {
$entity_type_manager = \Drupal::entityTypeManager();
/** @var \Drupal\Core\Block\BlockManager $block_manager */
$block_manager = \Drupal::service('plugin.manager.block');
$block_storage = $entity_type_manager->getStorage('patternkit_block');
/** @var \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface $section_storage_manager */
$section_storage_manager = \Drupal::service('plugin.manager.layout_builder.section_storage');
$storage_definitions = $section_storage_manager->getDefinitions();
/** @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $tempstore_repository */
$tempstore_repository = \Drupal::service('layout_builder.tempstore_repository');
/** @var \Drupal\patternkit\Asset\LibraryInterface $library */
$library =\Drupal::service('patternkit.asset.library');
$logger = $this->logger();
$block_storage = $this->blockStorage;
$library = $this->library;
$pattern_storage = $this->patternStorage;
$section_storages = [];
// Gather section storages from all entities and entity type layouts.
......@@ -94,7 +133,7 @@ class PatternkitCommands extends DrushCommands {
foreach ($section_storage->getSections() as $section_delta => $section) {
foreach ($section->getComponents() as $component_delta => $component) {
$plugin_id = $component->getPluginId();
if (!strstr($plugin_id, 'patternkit')) {
if (strpos($plugin_id, 'patternkit') === FALSE) {
continue;
}
$config = $component->get('configuration');
......@@ -112,8 +151,6 @@ class PatternkitCommands extends DrushCommands {
if (strpos($plugin_id, '.')) {
$config['id'] = 'patternkit_block:' . str_replace('.', '_', str_replace('_', '__', substr($plugin_id, strlen('patternkit_block:'))));
}
/** @var \Drupal\Core\Entity\ContentEntityStorageInterface $pattern_storage */
$pattern_storage = $entity_type_manager->getStorage('patternkit_pattern');
$pattern_id = '@' . str_replace('//', '_', str_replace('_', '/', substr($config['id'], strlen('patternkit_block:'))));
$pattern_asset = $library->getLibraryAsset($pattern_id);
if ($pattern_asset === NULL) {
......@@ -135,7 +172,7 @@ class PatternkitCommands extends DrushCommands {
$pattern_cache = $pattern_storage->loadByProperties(['library' => $pattern->getLibrary(), 'path' => $pattern->getPath()]);
/** @var PatternInterface $pattern_loaded */
$pattern_loaded = end($pattern_cache);
if (!empty($pattern_loaded)) {
if ($pattern_loaded !== NULL) {
if ($pattern_loaded->getHash() !== $pattern->getHash()) {
$pattern->setNewRevision();
$pattern->isDefaultRevision(TRUE);
......@@ -160,11 +197,224 @@ class PatternkitCommands extends DrushCommands {
$tempstore_repository->set($section_storage);
$entity_count++;
}
$this->logger()->info(t('Updated @entities entity layouts with @blocks Patternkit blocks.',
$logger->info(t('Updated @entities entity layouts with @blocks Patternkit blocks.',
['@entities' => $entity_count, '@blocks' => $block_count]));
$block_manager->clearCachedDefinitions();
$entity_type_manager->clearCachedDefinitions();
$this->logger()->notice(t('Successfully ran Patternkit from-dev updates.'));
$logger->notice(t('Successfully ran Patternkit from-dev updates.'));
}
/**
* Update all patterns in a library.
*
* @command patternkit:libUpdate
* @aliases pklu, patternkit-lib-update
*
* @param string $library_name
* The id of the pattern library to update from *.libraries.yml.
* @return array|bool
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function libUpdate($library_name) {
$logger = $this->logger();
if (empty($library_name)) {
throw new \InvalidArgumentException('Library name argument is empty or falsey.');
}
$lb_enabled = false;
if (\Drupal::moduleHandler()->moduleExists('layout_builder')) {
$lb_enabled = true;
}
$entity_count = 0;
$block_count = 0;
$entity_type_manager = \Drupal::entityTypeManager();
/** @var \Drupal\Core\Block\BlockManager $block_manager */
$block_manager = \Drupal::service('plugin.manager.block');
$block_storage = $this->blockStorage;
if ($lb_enabled) {
/** @var \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface $section_storage_manager */
$section_storage_manager = \Drupal::service('plugin.manager.layout_builder.section_storage');
$storage_definitions = $section_storage_manager->getDefinitions();
/** @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $tempstore_repository */
$tempstore_repository = \Drupal::service('layout_builder.tempstore_repository');
$section_storages = [];
// Gather section storages from all entities and entity type layouts.
/** @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $view_mode_storage */
$display_storage = $entity_type_manager->getStorage('entity_view_display');
$displays = $display_storage->loadMultiple();
/** @var \Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay $display */
foreach ($displays as $display) {
if (!$display instanceof LayoutBuilderEntityViewDisplay) {
continue;
}
if (!$display->isLayoutBuilderEnabled()) {
continue;
}
foreach ($storage_definitions as $section_storage_type => $storage_definition) {
$contexts = [];
$contexts['display'] = EntityContext::fromEntity($display);
$contexts['view_mode'] = new Context(new ContextDefinition('string'), $display->getMode());
// Gathers entity type layouts.
if ($section_storage = $section_storage_manager->load($section_storage_type, $contexts)) {
$section_storages[] = $section_storage;
}
// Gathers entity layouts.
$entity_storage = $entity_type_manager->getStorage($display->getTargetEntityTypeId());
foreach ($entity_storage->loadMultiple() as $entity) {
$contexts['entity'] = EntityContext::fromEntity($entity);
$section_storages[] = $section_storage_manager->findByContext($contexts, new CacheableMetadata());
}
}
}
// Gather section storages from the tempstore, to update layout drafts.
/** @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $key_value_factory */
$key_value_factory = \Drupal::service('keyvalue.expirable');
foreach (array_keys($storage_definitions) as $section_storage_type) {
$key_value = $key_value_factory->get("tempstore.shared.layout_builder.section_storage.$section_storage_type");
foreach ($key_value->getAll() as $key => $value) {
$key = substr($key, 0, strpos($key, '.', strpos($key, '.') + 1));
$contexts = $section_storage_manager->loadEmpty($section_storage_type)
->deriveContextsFromRoute($key, [], '', []);
$section_storages[] = $value->data['section_storage'];
if ($section_storage = $section_storage_manager->load($section_storage_type, $contexts)) {
$section_storages[] = $section_storage;
}
}
}
foreach ($section_storages as $section_storage) {
foreach ($section_storage->getSections() as $section_delta => $section) {
/** @var \Drupal\block\BlockInterface $component */
foreach ($section->getComponents() as $component_delta => $component) {
if (!$configuration = $this->updateBlockComponentPluginPattern($component)) {
continue;
}
$section_storage
->getSection($section_delta)
->getComponent($component->getUuid())
->setConfiguration($configuration);
$block_count++;
}
$section_storage->save();
$tempstore_repository->set($section_storage);
$entity_count++;
}
}
}
/** @var \Drupal\block\BlockInterface $block */
foreach ($block_storage->loadMultiple() as $block) {
if (!$block instanceof BlockInterface) {
continue;
}
$plugin = $block->getPlugin();
$this->updateBlockComponentPluginPattern($plugin);
$block_count++;
}
$logger->info(t('Parsed @entities entity layouts with @blocks Patternkit blocks.',
['@entities' => $entity_count, '@blocks' => $block_count]));
$block_manager->clearCachedDefinitions();
$entity_type_manager->clearCachedDefinitions();
$logger->notice(t('Completed running Patternkit library updates for @library.',
['@library' => $library_name]));
return true;
}
/**
* Updates a Patternkit Block Component Plugin's Pattern to latest.
*
* @param \Drupal\block\BlockInterface $component
* The block plugin or component to update.
* @param null|string $library_name
* The name of the library to match against, or NULL to skip matching.
*
* @return false|array The updated configuration, or FALSE if it failed.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
private function updateBlockComponentPluginPattern($component, $library_name = NULL) {
$logger = $this->logger();
$block_storage = $this->blockStorage;
$pattern_storage = $this->patternStorage;
$library = $this->library;
$plugin_id = $component->getPluginId();
if (strpos($plugin_id, 'patternkit') === FALSE) {
return FALSE;
}
$configuration = $component->get('configuration');
if (!isset($configuration['patternkit_block_id'])
&& !((int)$configuration['patternkit_block_id'] > 0)) {
return FALSE;
}
/** @var \Drupal\patternkit\Entity\PatternkitBlock $patternkit_block */
if (isset($configuration['patternkit_block_rid'])
&& (int)$configuration['patternkit_block_rid'] > 0) {
$patternkit_block = $block_storage->loadRevision($configuration['patternkit_block_rid']);
if ($patternkit_block === NULL) {
return FALSE;
}
} else {
$patternkit_block = $block_storage->load($configuration['patternkit_block_id']);
if ($patternkit_block === NULL) {
return FALSE;
}
$configuration['patternkit_block_rid'] = $patternkit_block->getLoadedRevisionId();
}
$logger->debug(t('Updating block plugin with id @plugin:',
['@plugin' => $plugin_id]));
try {
$plugin = $component->getPlugin();
$pattern_id = PatternkitBlock::derivativeToAssetId($plugin->getDerivativeId());
/** @var \Drupal\patternkit\entity\PatternInterface $pattern */
if (!empty($configuration['pattern'])) {
$pattern = $pattern_storage->loadRevision($configuration['pattern']);
} else {
$pattern = $library->getLibraryAsset($pattern_id);
}
} catch (\Exception $exception) {
$logger->error(t('Unable to load the pattern @pattern. Check the logs for more info.', ['@pattern' => $pattern_id ?? $plugin->getPluginId()]));
return FALSE;
}
if ($library_name && $pattern->getLibrary() !== $library_name) {
return FALSE;
}
if (!$asset = $library->getLibraryAsset($pattern_id)) {
$logger->error(t("Failed to get library asset for @pattern.", ['@pattern' => $pattern_id]));
return FALSE;
}
$base_pattern = Pattern::create($asset);
if ($base_pattern === NULL) {
return FALSE;
}
if ($base_pattern->getHash() === $pattern->getHash()) {
return FALSE;
}
$logger->debug(t('Updating pattern from @old to @new.',
['@old' => $pattern->getVersion(), '@new' => $base_pattern->getVersion()]));
$pattern->setNewRevision();
$pattern->isDefaultRevision(TRUE);
$pattern->setSchema($base_pattern->getSchema());
$pattern->setTemplate(($base_pattern->getTemplate()));
$pattern->setVersion($base_pattern->getVersion());
$pattern->save();
$configuration['pattern'] = $pattern->getRevisionId();
/** @var \Drupal\patternkit\Entity\PatternkitBlock $patternkit_block */
$patternkit_block = $block_storage->load($configuration['patternkit_block_id']);
$configuration['patternkit_block_rid'] = $patternkit_block->getRevisionId();
return $configuration;
}
}
......@@ -658,10 +658,17 @@ class PatternkitBlock extends BlockBase implements ContainerFactoryPluginInterfa
}
/**
* Returns an array of available token replacements.
*
* @param bool $prepared
* Whether to return the raw token info for each token or an array of
* prepared tokens for each type. E.g. "[view:name]".
* @param array $types
* An array of additional token types to return, defaults to 'site' and
* 'view'.
*
* @return array|bool
* An array of available token replacement info or tokens, grouped by type.
*
* @see \Drupal\views\Plugin\views\PluginBase
*/
......@@ -677,19 +684,42 @@ class PatternkitBlock extends BlockBase implements ContainerFactoryPluginInterfa
// Construct the token string for each token.
if ($prepared) {
$prepared = [];
$prepared_tokens = [];
foreach ($available as $type => $tokens) {
foreach (array_keys($tokens) as $token) {
$prepared[$type][] = "[$type:$token]";
$prepared_tokens[$type][] = "[$type:$token]";
}
}
return $prepared;
return $prepared_tokens;
}
return $available;
}
/**
* {@inheritdoc}
*
* @return array
* - string id => $this->getPluginId(),
* - string label => '',
* - string provider => $this->pluginDefinition['provider'],
* - int label_display => BlockPluginInterface::BLOCK_LABEL_VISIBLE,
* - int patternkit_block_id => non-zero id,
* - int patternkit_block_rid => non-zero rid,
* - string instance_uuid => universally unique id string,
* - boolean reusable => TRUE if the patternkit block is reusable,
* - Pattern pattern => Pattern cached with the block,
* - string presentation_style => PatternLibrary plugin-based config string,
* - string version => library version used when caching the pattern,
* - array context => an array of Context objects provided to the block,
* - array fields => the form data configured via the pattern schema,
*
* @see this->baseConfigurationDefaults()
*/
public function getConfiguration() {
return parent::getConfiguration();
}
/**
* @param $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment