stanford_profile.install
<?php
/**
* @file
* stanford_profile.install
*/
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\node\NodeInterface;
use Drupal\field\Entity\FieldConfig;
/**
* Save the system pages from the original config values into state.
*/
function stanford_profile_update_8002() {
$state = \Drupal::state();
$state->set('stanford_profile.403_page', '/node/3');
$state->set('stanford_profile.404_page', '/node/2');
$state->set('stanford_profile.front_page', '/node/1');
}
/**
* Create the new layout paragraph type.
*/
function stanford_profile_update_9000(&$sandbox) {
\Drupal::service('module_installer')->install([
'layout_paragraphs',
'stanford_layout_paragraphs',
]);
$plugins = [
'layout_paragraphs' => [
'enabled' => TRUE,
'available_layouts' => [
'layout_paragraphs_1_column' => '1 Column',
'layout_paragraphs_2_column' => '2 Column',
'layout_paragraphs_3_column' => '3 Column',
],
],
];
/** @var \Drupal\paragraphs\ParagraphsTypeInterface $paragraph_type */
$paragraph_type = \Drupal::entityTypeManager()
->getStorage('paragraphs_type')
->create([
'uuid' => 'c935e784-07eb-4fbf-afab-f687901abe5a',
'id' => 'stanford_layout',
'label' => 'Layout',
]);
$paragraph_type->set('behavior_plugins', $plugins);
$paragraph_type->save();
}
/**
* Install Claro theme and uninstall Seven.
*/
function stanford_profile_update_9001() {
/** @var \Drupal\Core\Extension\ThemeInstallerInterface $theme_installer */
$theme_installer = \Drupal::service('theme_installer');
$theme_installer->install(['claro', 'stanford_profile_admin']);
\Drupal::configFactory()
->getEditable('system.theme')
->set('admin', 'stanford_profile_admin')
->save();
try {
$theme_installer->uninstall(['seven']);
}
catch (\Exception $e) {
// Theme was already uninstalled.
}
}
/**
* Correct path aliases that somehow are incorrectly formatted.
*/
function stanford_profile_update_9004() {
$database = \Drupal::database();
$query = $database->select('path_alias', 'p')
->fields('p');
$conditions = $query->orConditionGroup()
->condition('alias', '%http:/%', 'LIKE')
->condition('alias', '%https:/%', 'LIKE');
$query->condition($conditions);
$results = $query->execute();
while ($row = $results->fetchAssoc()) {
$new_alias = trim(preg_replace('/:\/([a-z0-9])/', '://$1', $row['alias']), '/');
if (!str_starts_with($new_alias, 'http')) {
throw new \Exception('Unknown path alias pattern to correct');
}
$new_alias = parse_url($new_alias);
if (empty($new_alias['path'])) {
throw new \Exception('Unknown path alias pattern to correct');
}
$new_alias = $new_alias['path'];
$database->update('path_alias')
->fields(['alias' => $new_alias])
->condition('id', $row['id'])
->execute();
$database->update('path_alias_revision')
->fields(['alias' => $new_alias])
->condition('id', $row['id'])
->execute();
}
}
/**
* Migrate Basic Page react paragraphs to layout paragraphs.
*/
function stanford_profile_update_9005(&$sandbox) {
$node_storage = \Drupal::entityTypeManager()
->getStorage('node');
if (!isset($sandbox['count'])) {
$nids = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('type', 'stanford_page')
->sort('created')
->execute();
$sandbox['nids'] = $nids;
$sandbox['count'] = count($sandbox['nids']);
}
drupal_static_reset();
$row_storage = \Drupal::entityTypeManager()->getStorage('paragraph_row');
$paragraph_storage = \Drupal::entityTypeManager()->getStorage('paragraph');
$node_ids = array_splice($sandbox['nids'], 0, 25);
/** @var \Drupal\node\NodeInterface[] $nodes */
$nodes = $node_storage->loadMultiple($node_ids);
$delete_entities = [];
foreach ($nodes as $node) {
$changed_time = $node->getChangedTime();
$new_components = [];
/** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $row */
foreach ($node->get('su_page_components') as $row) {
$row_entity = $row_storage->loadRevision($row->get('target_revision_id')
->getString());
$delete_entities[] = $row_entity;
$number_of_items = min($row_entity->get('su_page_components')
->count(), 3);
$layout_id = "layout_paragraphs_{$number_of_items}_column";
$new_row_entity = $paragraph_storage->create(['type' => 'stanford_layout']);
$new_row_entity->setBehaviorSettings('layout_paragraphs', [
'layout' => $layout_id,
'config' => ['label' => ''],
'parent_uuid' => NULL,
'region' => NULL,
]);
$new_row_entity->setParentEntity($node, 'su_page_components');
$new_row_entity->save();
$new_components[] = [
'target_id' => $new_row_entity->id(),
'entity' => $new_row_entity,
];
/** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $row_item */
foreach ($row_entity->get('su_page_components') as $delta => $row_item) {
/** @var \Drupal\paragraphs\ParagraphInterface $paragraph */
$paragraph = $paragraph_storage->loadRevision($row_item->get('target_revision_id')
->getString());
$behaviors = $paragraph->getAllBehaviorSettings();
unset($behaviors['react']);
$behaviors['layout_paragraphs'] = [
'parent_uuid' => $new_row_entity->uuid(),
'region' => _stanford_profile_update_9005_get_item_region($delta, $layout_id),
];
$new_paragraph = $paragraph->createDuplicate();
$new_paragraph->enforceIsNew();
$new_paragraph->setParentEntity($node, 'su_page_components');
$new_paragraph->setAllBehaviorSettings($behaviors);
$new_paragraph->save();
$new_components[] = [
'target_id' => $new_paragraph->id(),
'entity' => $new_paragraph,
];
$delete_entities[] = $paragraph;
}
}
$node->set('su_page_components', $new_components)->save();
_stanford_profile_reset_node_changed_time($node, $changed_time);
}
foreach ($delete_entities as $entity) {
$entity->delete();
}
$sandbox['#finished'] = empty($sandbox['nids']) ? 1 : ($sandbox['count'] - count($sandbox['nids'])) / $sandbox['count'];
}
/**
* Migrate Publications react paragraphs to layout paragraphs.
*/
function stanford_profile_update_9006(&$sandbox) {
$node_storage = \Drupal::entityTypeManager()
->getStorage('node');
if (!isset($sandbox['count'])) {
$nids = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('type', 'stanford_publication')
->execute();
$sandbox['nids'] = $nids;
$sandbox['count'] = count($sandbox['nids']);
}
$row_storage = \Drupal::entityTypeManager()->getStorage('paragraph_row');
$paragraph_storage = \Drupal::entityTypeManager()->getStorage('paragraph');
$node_ids = array_splice($sandbox['nids'], 0, 25);
/** @var \Drupal\node\NodeInterface[] $nodes */
$nodes = $node_storage->loadMultiple($node_ids);
$delete_entities = [];
foreach ($nodes as $node) {
$changed_time = $node->getChangedTime();
$new_components = [];
/** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $row */
foreach ($node->get('su_publication_components') as $row) {
$row_entity = $row_storage->load($row->get('target_id')->getString());
$delete_entities[] = $row_entity;
$number_of_items = $row_entity->get('su_pubs_components')->count();
$layout_id = "layout_paragraphs_{$number_of_items}_column";
$new_row_entity = $paragraph_storage->create(['type' => 'stanford_layout']);
$new_row_entity->setBehaviorSettings('layout_paragraphs', [
'layout' => $layout_id,
'config' => ['label' => ''],
'parent_uuid' => NULL,
'region' => NULL,
]);
$new_row_entity->setParentEntity($node, 'su_publication_components');
$new_row_entity->save();
$new_components[] = [
'target_id' => $new_row_entity->id(),
'target_revision_id' => $new_row_entity->getRevisionId(),
];
/** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $row_item */
foreach ($row_entity->get('su_pubs_components') as $delta => $row_item) {
/** @var \Drupal\paragraphs\ParagraphInterface $paragraph */
$paragraph = $paragraph_storage->load($row_item->get('target_id')
->getString());
$behaviors = $paragraph->getAllBehaviorSettings();
unset($behaviors['react']);
$behaviors['layout_paragraphs'] = [
'parent_uuid' => $new_row_entity->uuid(),
'region' => _stanford_profile_update_9005_get_item_region($delta, $layout_id),
];
$new_paragraph = $paragraph->createDuplicate();
$new_paragraph->enforceIsNew();
$new_paragraph->setParentEntity($node, 'su_publication_components');
$new_paragraph->setAllBehaviorSettings($behaviors);
$new_paragraph->save();
$new_components[] = [
'target_id' => $new_paragraph->id(),
'target_revision_id' => $new_paragraph->getRevisionId(),
];
$delete_entities[] = $paragraph;
}
}
$node->set('su_publication_components', $new_components)->save();
_stanford_profile_reset_node_changed_time($node, $changed_time);
}
foreach ($delete_entities as $entity) {
$entity->delete();
}
$sandbox['#finished'] = empty($sandbox['nids']) ? 1 : ($sandbox['count'] - count($sandbox['nids'])) / $sandbox['count'];
}
/**
* Get the items new region in the layout paragraphs layout.
*
* @param int $delta
* Position of the item in the row.
* @param string $layout_id
* Parent layout id.
*
* @return string
* New region.
*/
function _stanford_profile_update_9005_get_item_region(int $delta, string $layout_id): string {
switch ($layout_id) {
case 'layout_paragraphs_2_column':
return $delta ? 'right' : 'left';
case 'layout_paragraphs_3_column':
$delta_regions = ['left', 'main', 'right', 'right', 'right'];
return $delta_regions[$delta];
}
return 'main';
}
/**
* Update pages with custom layout builder settings.
*/
function stanford_profile_update_9007(&$sandbox) {
$node_storage = \Drupal::entityTypeManager()
->getStorage('node');
if (!isset($sandbox['count'])) {
$nids = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('layout_builder__layout', NULL, 'IS NOT NULL')
->execute();
$sandbox['nids'] = $nids;
$sandbox['count'] = count($sandbox['nids']);
}
$node_ids = array_splice($sandbox['nids'], 0, 25);
/** @var \Drupal\node\NodeInterface[] $nodes */
$nodes = $node_storage->loadMultiple($node_ids);
$database = \Drupal::database();
$convert_fields = [
'field_block:node:stanford_event:su_event_components',
'field_block:node:stanford_event_series:su_event_series_components',
'field_block:node:stanford_news:su_news_components',
'field_block:node:stanford_page:su_page_components',
'field_block:node:stanford_person:su_person_components',
'field_block:node:stanford_person:su_person_components',
'field_block:node:stanford_publication:su_publication_components',
];
foreach ($nodes as $node) {
$changed_time = $node->getChangedTime();
$save_node = FALSE;
/** @var \Drupal\layout_builder\Field\LayoutSectionItemList $layout */
$layout = $node->get('layout_builder__layout');
foreach ($layout->getSections() as $section) {
foreach ($section->getComponents() as $component) {
$config = $component->get('configuration');
if (in_array($config['id'], $convert_fields)) {
$config['formatter']['type'] = 'layout_paragraphs';
$config['formatter']['settings'] = ['view_mode' => 'default'];
$component->setConfiguration($config);
$save_node = TRUE;
}
}
}
if ($save_node) {
$node->save();
_stanford_profile_reset_node_changed_time($node, $changed_time);
}
}
$sandbox['#finished'] = empty($sandbox['nids']) ? 1 : ($sandbox['count'] - count($sandbox['nids'])) / $sandbox['count'];
}
/**
* Uninstall Stable theme.
*/
function stanford_profile_update_9100(&$sandbox) {
try {
\Drupal::service('theme_installer')->uninstall(['stable']);
}
catch (\Exception $e) {
// Theme is already uninstalled.
}
}
/**
* Install menu_link module and configure the field.
*/
function stanford_profile_update_9101() {
$entity_type_manager = \Drupal::entityTypeManager();
\Drupal::service('module_installer')->install(['menu_link']);
$entity_type_manager->getStorage('field_storage_config')
->create([
'uuid' => '963caf4a-7a55-4ed6-961d-765ea7594192',
'field_name' => 'field_menulink',
'type' => 'menu_link',
'entity_type' => 'node',
'cardinality' => 1,
])->save();
$field_config_storage = $entity_type_manager->getStorage('field_config');
$bundles = [
'stanford_page',
'stanford_event_series',
'stanford_person',
'stanford_policy',
];
foreach ($bundles as $bundle) {
$field_config_storage->create([
'entity_type' => 'node',
'field_name' => 'field_menulink',
'bundle' => $bundle,
'label' => 'Menu Link',
])->save();
}
$menu_items = $entity_type_manager->getStorage('menu_link_content')
->loadByProperties(['menu_name' => 'main']);
// Re-save all menu items to update their link uris.
// @see \Drupal\stanford_profile_helper\EventSubscriber\EntityEventSubscriber::preSaveMenuLinkContent()
foreach ($menu_items as $menu_item) {
$menu_item->save();
}
drupal_flush_all_caches();
}
/**
* Update menu links on nodes for the updated version of menu_link_weight.
*/
function stanford_profile_update_9102() {
// Instantiate the path alias path processor because it doesn't get added in
// this update hook.
\Drupal::service('path_processor_manager')
->addOutbound(\Drupal::service('path_alias.path_processor'), 300);
/** @var \Drupal\Core\Menu\MenuLinkTree $menu_link_tree */
$menu_link_tree = \Drupal::service('menu.link_tree');
$parameters = new MenuTreeParameters();
$menu = $menu_link_tree->load('main', $parameters);
_stanford_profile_fix_menu($menu);
}
/**
* Re-run stanford_card update.
*/
function stanford_profile_update_9103(&$sandbox) {
if ($field = FieldConfig::loadByName('paragraph', 'stanford_card', 'su_card_link_display')) {
module_load_install('stanford_paragraph_card');
stanford_paragraph_card_update_8001($sandbox);
/** @var \Drupal\paragraphs\ParagraphsTypeInterface $paragraph_type */
$paragraph_type = \Drupal::entityTypeManager()
->getStorage('paragraphs_type')
->load('stanford_card');
$behaviors = $paragraph_type->get('behavior_plugins');
$behaviors['su_card_styles'] = ['enabeld' => TRUE];
$paragraph_type->set('behavior_plugins', $behaviors);
$paragraph_type->save();
$field->delete();
}
return;
$ns = \Drupal::entityTypeManager()->getStorage('node');
$ps = \Drupal::entityTypeManager()->getStorage('paragraph');
$ids = $ns->getQuery()
->accessCheck(FALSE)
->condition('type', 'stanford_page')
->execute();
foreach ($ns->loadMultiple($ids) as $node) {
foreach ($node->get('su_page_components') as $item) {
if ($p = $ps->load($item->getValue()['target_id'])) {
$p->setParentEntity($node, 'su_page_components');
$p->save();
}
}
}
}
/**
* Update menu links on nodes for the updated version of menu_link_weight.
*
* @param array $menu_items
* Menu items.
* @param string|null $parent
* Parent menu id.
*/
function _stanford_profile_fix_menu(array $menu_items = [], string $parent = NULL): void {
$node_storage = \Drupal::entityTypeManager()
->getStorage('node');
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
$database = \Drupal::database();
foreach ($menu_items as $id => $menu_item) {
/** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $link */
$link = $menu_item->link;
$url = $link->getUrlObject();
try {
if (
$url->isRouted() &&
$url->getRouteName() == 'entity.node.canonical'
) {
$node_id = $link->getUrlObject()->getRouteParameters()['node'] ?? NULL;
/** @var \Drupal\node\NodeInterface $node */
$node = $node_storage->load($node_id);
if (!$node->get('field_menulink')->isEmpty()) {
throw new \Exception('Menu link already exists on node ' . $node->label());
}
$menu_field_data = [
'menu_name' => $link->getMenuName(),
'title' => $link->getTitle(),
'description' => $link->getDescription(),
'parent' => $parent,
'weight' => $link->getweight(),
'expanded' => $link->isExpanded(),
];
$changed_time = $node->getChangedTime();
$node->set('field_menulink', $menu_field_data)->save();
$new_parent = 'menu_link_field:node_field_menulink_' . $node->uuid() . '_und';
_stanford_profile_reset_node_changed_time($node, $changed_time);
if ($menu_item->subtree) {
_stanford_profile_fix_menu($menu_item->subtree, $new_parent);
}
if (!$link->isEnabled()) {
$database->update('menu_tree')
->fields(['enabled' => 0])
->condition('id', $new_parent)
->execute();
}
// Update layout builder settings before deleting the link.
_stanford_profile_update_menu_block($link->getPluginId(), $new_parent);
$link->deleteLink();
continue;
}
}
catch (\Throwable $e) {
\Drupal::logger('stanford_profile')
->error('Unable to update link %title. Error: %error', [
'%title' => $link->getTitle(),
'%error' => $e->getMessage(),
]);
}
if ($parent) {
$link->updateLink(['parent' => $parent], TRUE);
// Saving the link above, updates the entity, but it doesn't update the
// menu tree. So we need to update the menu tree manually.
$menu_link_manager->updateDefinition($link->getPluginId(), $link->getPluginDefinition(), FALSE);
}
if ($menu_item->subtree) {
_stanford_profile_fix_menu($menu_item->subtree, $id);
}
}
}
/**
* If the old menu link id is configured for menu block parent, update it.
*
* @param string $old_id
* Old menu link id.
* @param string $new_id
* New menu link id.
*/
function _stanford_profile_update_menu_block(string $old_id, string $new_id): void {
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
$nids = $node_storage->getQuery()
->accessCheck(FALSE)
->condition('layout_builder__layout', "%main:$old_id%", 'LIKE')
->execute();
/** @var \Drupal\node\NodeInterface $node */
foreach ($node_storage->loadMultiple($nids) as $node) {
$save_node = FALSE;
$changed_time = $node->getChangedTime();
/** @var \Drupal\layout_builder\Field\LayoutSectionItemList $layout */
$layout = $node->get('layout_builder__layout');
foreach ($layout->getSections() as $section) {
foreach ($section->getComponents() as $component) {
$config = $component->get('configuration');
if ($config['provider'] == 'menu_block' && $config['parent'] == "main:$old_id") {
$config['parent'] = "main:$new_id";
$component->setConfiguration($config);
$save_node = TRUE;
}
}
}
if ($save_node) {
$node->save();
_stanford_profile_reset_node_changed_time($node, $changed_time);
}
}
}
/**
* Update the node tables to reset the changed time.
*
* @param \Drupal\node\NodeInterface $node
* Node entity.
* @param int $changed
* Changed time.
*/
function _stanford_profile_reset_node_changed_time(NodeInterface $node, int $changed) {
$database = \Drupal::database();
// Reset the changed time to the value before this process.
$database->update('node_field_data')
->fields(['changed' => $changed])
->condition('nid', $node->id())
->execute();
$database->update('node_field_revision')
->fields(['changed' => $changed])
->condition('vid', $node->getRevisionId())
->execute();
}
/**
* Update configs 'stanford_profile_admin' with 'stanford_profile_admin_theme'.
*/
function stanford_profile_update_9104() {
$config_factory = \Drupal::configFactory();
foreach ($config_factory->listAll() as $config_name) {
$config = $config_factory->getEditable($config_name);
// Delete the admin theme blocks first.
if (str_starts_with($config_name, 'block.block.stanford_profile_admin_')) {
$config->delete();
continue;
}
// Change the dependencies to the new theme name.
if ($theme_dependencies = $config->get('dependencies.theme')) {
$position = array_search('stanford_profile_admin', $theme_dependencies);
if ($position !== FALSE) {
$config->set("dependencies.theme.$position", 'stanford_profile_admin_theme')
->save(TRUE);
}
}
}
$core_extension = $config_factory->getEditable('core.extension');
$core_extension->clear('theme.stanford_profile_admin')
->set('theme.stanford_profile_admin_theme', 0)
->save();
$system_theme = $config_factory->getEditable('system.theme');
if ($system_theme->get('admin') == 'stanford_profile_admin') {
$system_theme->set('admin', 'stanford_profile_admin_theme')->save();
}
}
/**
* Remove data for paragraph rows.
*/
function stanford_profile_update_9105() {
$tables = [
'paragraph_row__su_page_components',
'paragraph_row__su_pubs_components',
'paragraph_row_revision__su_page_components',
'paragraph_row_revision__su_pubs_components',
'paragraph_rows_field_revision',
'paragraph_rows_item',
'paragraph_rows_item_field_data',
'paragraph_rows_revision',
];
foreach ($tables as $table) {
\Drupal::database()->truncate($table)->execute();
}
}