Commit 98ff992c authored by Chris Shantz's avatar Chris Shantz
Browse files

Merge branch '1.0.x' into prod/1.0.x

parents 2daec0d0 e6cd0887
......@@ -33,7 +33,7 @@ process:
default_value: 0
default_layout:
plugin: default_value
default_value: 'layout_onecol'
default_value: 'uw_1_column'
destination:
plugin: layout_builder:block
migration_dependencies:
......
<?php
namespace Drupal\uw_migrate\EventSubscriber;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\migrate\Event\MigrateEvents;
use Drupal\migrate\Event\MigratePostRowSaveEvent;
use Drupal\pathauto\PathautoGeneratorInterface;
use Drupal\pathauto\PathautoState;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Event subscriber for custom migrations.
*/
class MigrateSubscriber implements EventSubscriberInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The key value factory.
*
* @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
*/
protected $keyValue;
/**
* The pathauto generator.
*
* @var \Drupal\pathauto\PathautoGeneratorInterface
*/
protected $pathautoGenerator;
/**
* Constructs an instance.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value
* The key value factory.
* @param \Drupal\pathauto\PathautoGeneratorInterface $pathauto_generator
* The pathauto generator.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, KeyValueFactoryInterface $key_value, PathautoGeneratorInterface $pathauto_generator) {
$this->entityTypeManager = $entity_type_manager;
$this->keyValue = $key_value;
$this->pathautoGenerator = $pathauto_generator;
}
/**
* Saves pathauto states.
*
* @param \Drupal\migrate\Event\MigratePostRowSaveEvent $event
* The post row save event.
*/
public function onPostRowSave(MigratePostRowSaveEvent $event): void {
$migration = $event->getMigration();
$row = $event->getRow();
$migrations = [
'uw_url_alias' => [
'entity_type' => 'node',
'id_key' => 'new_nid',
],
'uw_url_alias_taxonomy' => [
'entity_type' => 'taxonomy_term',
'id_key' => 'new_tid',
],
];
if (!isset($migrations[$migration->id()])) {
return;
}
$entity_type = $migrations[$migration->id()]['entity_type'];
$entity_id = $row->getDestinationProperty($migrations[$migration->id()]['id_key']);
$entity = $this->entityTypeManager->getStorage($entity_type)->load($entity_id);
// Force generating entity path alias, but do not save it.
$pathauto_alias = \Drupal::service('pathauto.generator')->updateEntityAlias($entity, 'return', ['force' => TRUE]);
$migrated_alias = $row->getDestinationProperty('alias');
// Determine if migrated alias matches the configured pattern.
// If there is a match, then we set pathauto state to be 1, which means the
// alias is generated automatically.
if ($pathauto_alias === $migrated_alias) {
$this->keyValue->get("pathauto_state.$entity_type")
->set(PathautoState::getPathautoStateKey($entity_id), PathautoState::CREATE);
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
MigrateEvents::POST_ROW_SAVE => ['onPostRowSave'],
];
}
}
......@@ -12,6 +12,7 @@ use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Row;
use Drupal\pathauto\PathautoState;
use Drupal\uw_migrate\UwMigrateTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -110,8 +111,13 @@ class LayoutBuilderBlock extends DestinationBase implements ContainerFactoryPlug
}
}
/** @var \Drupal\layout_builder\Field\LayoutSectionItemList $node_layout */
$node_layout = $node->get('layout_builder__layout');
// Append a component to given section/region of page layout.
$dest_section = $row->getDestinationProperty('section');
$dest_layout = $row->getDestinationProperty('default_layout');
if (isset($dest_section)) {
// First value is entity ID, the second is section delta.
if (is_array($dest_section)) {
......@@ -120,26 +126,33 @@ class LayoutBuilderBlock extends DestinationBase implements ContainerFactoryPlug
else {
$section_delta = $dest_section;
}
$section = $node->get('layout_builder__layout')->getSection($section_delta);
/** @var \Drupal\layout_builder\Section $section */
$section = $node_layout->getSection($section_delta);
}
else {
// If section wasn't created during migration, we append a block to the
// existing section (last one) or a new one.
$sections = $node->get('layout_builder__layout')->getSections();
// Create a new section if there are no any at the moment.
if (empty($sections)) {
$section = new Section($row->getDestinationProperty('default_layout'));
$node->get('layout_builder__layout')->appendSection($section);
}
else {
$section = end($sections);
if (empty($section) || !$this->isSectionApplicable($section, $row)) {
// If section wasn't created during migration, we choose either one of the
// existing sections or create a new one here.
$sections = $node_layout->getSections();
$section = end($sections);
// Make sure the section has the expected layout. And if not, then create
// a new one.
if (empty($sections) || !$this->isSectionApplicable($section, $row)) {
$section = new Section($dest_layout);
// Finally, insert or append a new section into layout field.
if (isset($dest_section)) {
$node_layout->insertSection($dest_section, $section);
}
else {
$node_layout->appendSection($section);
}
}
}
$uuid = $this->uuid->generate();
$region = $row->getDestinationProperty('region');
$component = new SectionComponent($uuid, $region, $configuration);
$component = new SectionComponent($this->uuid->generate(), $region, $configuration);
// Insert a component to the given delta or append to the end if the delta
// is missing.
......@@ -152,8 +165,9 @@ class LayoutBuilderBlock extends DestinationBase implements ContainerFactoryPlug
}
$node->changed->preserve = TRUE;
$node->path->pathauto = PathautoState::SKIP;
$node->save();
return [$node->id(), $uuid];
return [$node->id(), $component->getUuid()];
}
/**
......@@ -261,4 +275,15 @@ class LayoutBuilderBlock extends DestinationBase implements ContainerFactoryPlug
return $config;
}
/**
* Checks whether given layout builder sections is applicable for the row.
*/
protected function isSectionApplicable(Section $section, Row $row) {
// No layout - no restrictions.
if (!$row->hasDestinationProperty('default_layout')) {
return TRUE;
}
return $section->getLayout()->getPluginId() === $row->getDestinationProperty('default_layout');
}
}
......@@ -10,6 +10,7 @@ use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Row;
use Drupal\pathauto\PathautoState;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
......@@ -96,6 +97,7 @@ class LayoutBuilderSection extends DestinationBase implements ContainerFactoryPl
}
$node->changed->preserve = TRUE;
$node->path->pathauto = PathautoState::SKIP;
$node->save();
return [$node->id(), $delta];
}
......
......@@ -4,6 +4,7 @@ namespace Drupal\uw_migrate\Plugin\migrate\destination;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\pathauto\PathautoState;
/**
* Custom destination class to preserve changed property during the migration.
......@@ -20,6 +21,7 @@ class UwEntityContentBase extends EntityContentBase {
if ($entity->hasField('changed')) {
$entity->changed->preserve = TRUE;
}
$entity->path->pathauto = PathautoState::SKIP;
return parent::save($entity, $old_destination_id_values);
}
......
......@@ -98,18 +98,19 @@ class UmMenuLink extends MenuLink {
];
// Skip menu links from main, that are not pointing to node pages.
if ($row->getSourceProperty('menu_name') === 'main-menu' && $source_path !== 'node/%') {
if ($source_path && $source_path !== 'node/%' && $row->getSourceProperty('menu_name') === 'main-menu') {
// Update the status based on source value.
if (isset($default_links[$source_path])) {
$plugin_id = $default_links[$source_path];
/** @var \Drupal\Core\Menu\MenuLinkBase $link_plugin */
$link_plugin = $this->menuLinkManager->createInstance($plugin_id);
$overrides = [
'enabled' => !$row->getSourceProperty('hidden'),
'expanded' => $row->getSourceProperty('expanded'),
'weight' => $row->getSourceProperty('weight'),
'enabled' => $row->getSourceProperty('enabled'),
];
$link_plugin->updateLink($overrides, TRUE);
}
return FALSE;
}
return parent::prepareRow($row);
......
......@@ -398,10 +398,10 @@ class UwWebform extends D7Webform {
}
if (!empty($extra['field_prefix'])) {
$new_element['#field_prefix'] = $extra['field_prefix'];
$new_element['#field_prefix'] = (string) $extra['field_prefix'];
}
if (!empty($extra['field_suffix'])) {
$new_element['#field_suffix'] = $extra['field_suffix'];
$new_element['#field_suffix'] = (string) $extra['field_suffix'];
}
if (!empty($extra['title_display']) && $extra['title_display'] != 'before') {
$title_display = $extra['title_display'];
......@@ -416,7 +416,7 @@ class UwWebform extends D7Webform {
// The description key can be missing (since description is optional and
// it isn't saved by Drupal 7 webform when it is left empty).
if (!empty($extra['description'])) {
$new_element['#description'] = $extra['description'];
$new_element['#description'] = (string) $extra['description'];
}
}
if (!empty($element['required'])) {
......
......@@ -11,6 +11,9 @@ trait UwWebformTrait {
* Returns destination form_key for the given webform element.
*/
protected function getDestinationFormKey($form_key, $pid) {
// Not sure why/how, but D7 form keys may have commas.
$form_key = str_replace([',', '.'], '_', $form_key);
// Truncate name if it's too long (the limit is 128 characters).
if (strlen($form_key) > 128) {
$form_key = substr($form_key, 128);
......
......@@ -54,6 +54,7 @@ class UwMigrateTest extends MigrateDrupal7TestBase {
'geofield', 'geofield_map', 'smart_date', 'markup', 'webform_migrate',
'webform', 'path_alias', 'webform_node', 'filter', 'editor', 'linkit',
'ckeditor', 'views_taxonomy_term_name_into_id', 'migrate_scanner',
'content_moderation', 'workflows',
'uw_media', 'uw_migrate', 'uw_cfg_common', 'uw_ct_blog', 'uw_ct_catalog',
'uw_ct_contact', 'uw_ct_event', 'uw_ct_news_item', 'uw_ct_web_page',
......@@ -117,7 +118,7 @@ class UwMigrateTest extends MigrateDrupal7TestBase {
}
// Check the amount of custom migrations.
$this->assertCount(83, $definitions);
$this->assertCount(84, $definitions);
// Check some random migrations.
$this->assertArrayHasKey('uw_user', $definitions);
......
......@@ -24,7 +24,8 @@ class UwSummaryTest extends KernelTestBase {
protected static $modules = [
'system', 'migrate', 'text', 'filter', 'file', 'media', 'simplify_menu',
'editor', 'linkit', 'ckeditor', 'token', 'media_embed_extra', 'node',
'uw_cfg_common', 'taxonomy', 'user',
'uw_cfg_common', 'taxonomy', 'user', 'content_moderation', 'workflows',
'path', 'path_alias',
];
/**
......
services:
uw_migrate.migrate_subscriber:
class: Drupal\uw_migrate\EventSubscriber\MigrateSubscriber
arguments: ['@entity_type.manager', '@keyvalue', '@pathauto.generator']
tags:
- { name: event_subscriber }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment