Skip to content

Commit

Permalink
HPC-8770: First steps at supporting automatic one-time import of GHO …
Browse files Browse the repository at this point in the history
…2021 content
  • Loading branch information
berliner committed Dec 16, 2024
1 parent 6d6b5c9 commit e377cd8
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 1 deletion.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"drupal/replicate_actions": "^1.2",
"drupal/replicate_ui": "^1.0",
"drupal/seckit": "^2.0",
"drupal/single_content_sync": "^1.4",
"drupal/social_auth_hid": "^3.1",
"drupal/stage_file_proxy": "^2",
"drupal/taxonomy_max_depth": "^2.1",
Expand Down
77 changes: 76 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions config/core.extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ module:
metatag_twitter_cards: 0
monitoring: 0
mysql: 0
ncms_gho_import: 0
ncms_graphql: 0
ncms_paragraphs: 0
ncms_publisher: 0
Expand All @@ -96,6 +97,7 @@ module:
responsive_image: 0
search: 0
seckit: 0
single_content_sync: 0
social_api: 0
social_auth: 0
social_auth_hid: 0
Expand Down
9 changes: 9 additions & 0 deletions config/single_content_sync.settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
_core:
default_config_hash: F--1EKAki5zF_jdKTc4ZLmgN89WJ2SDrMOkwbqj06-Y
allowed_entity_types:
block_content: { }
media: { }
menu_link_content: { }
node: { }
taxonomy_term: { }
site_uuid_check: true
15 changes: 15 additions & 0 deletions config/system.action.content_bulk_export.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
uuid: 4c371e86-cfef-422e-96ab-7a5280569a51
langcode: en
status: true
dependencies:
module:
- single_content_sync
_core:
default_config_hash: h64R0kZquzABmTQ3k2X7VbJJvANnn0p3ubKUYNtQj8s
id: content_bulk_export
label: 'Export content'
type: node
plugin: content_bulk_export
configuration:
assets: true
translation: true
7 changes: 7 additions & 0 deletions html/modules/custom/ncms_gho_import/ncms_gho_import.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: GHO Import
type: module
description: 'Support module for importing content from previous GHO sites'
package: HPC Content Module
dependencies:
- single_content_sync:single_content_sync
core_version_requirement: ^9.3 || ^10
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
ncms_gho_import.manager:
class: Drupal\ncms_gho_import\ContentImportManager
arguments: ['@entity_type.manager']
ncms_gho_import.import_event_subscriber:
class: Drupal\ncms_gho_import\EventSubscriber\ImportEventSubscriber
arguments: ['@ncms_gho_import.manager']
tags:
- { name: event_subscriber }
120 changes: 120 additions & 0 deletions html/modules/custom/ncms_gho_import/src/ContentImportManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace Drupal\ncms_gho_import;

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\ncms_ui\Entity\Content\ContentBase;
use Drupal\ncms_ui\Entity\ContentSpaceAwareInterface;

/**
* Helper class for content import.
*/
class ContentImportManager {

/**
* A list of paragraph types that can be safely removed.
*/
private const OBSOLETE_PARAGRAPH_TYPES = [
'needs_and_requirements',
];

/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* Public constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}

/**
* Set the content space for the imported content.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity to be created.
*/
public function setContentSpace(ContentEntityInterface &$entity) {
if (!$entity instanceof ContentSpaceAwareInterface) {
return;
}
$content_space = $this->loadTermByName('Global', 'content_space');
if (!$content_space) {
return;
}
$entity->get('field_content_space')->setValue([
// Global content space.
'target_id' => $content_space->id(),
]);
}

/**
* Set some properties for the imported content.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity to be created.
*/
public function setContentProperties(ContentEntityInterface &$entity) {
if (!$entity instanceof ContentBase) {
return;
}
$entity->get('field_short_title')->setValue($entity->label());
if ($document_type = $this->loadTermByName('GHO', 'document_type')) {
$entity->get('field_document_type')->setValue(['target_id' => $document_type->id()]);
}
if ($year = $this->loadTermByName('2021', 'year')) {
$entity->get('field_year')->setValue(['target_id' => $year->id()]);
}
}

/**
* Remove obsolete paragraph types from the incoming content array.
*
* @param array $content
* An array containing the content.
*/
public function removeObsoleteParagraphs(array &$content) {
if (empty($content['custom_fields']['field_paragraphs'])) {
return;
}
foreach ($content['custom_fields']['field_paragraphs'] as $key => $item) {
if (in_array($item['bundle'], self::OBSOLETE_PARAGRAPH_TYPES)) {
unset($content['custom_fields']['field_paragraphs'][$key]);
continue;
}
if ($item['bundle'] == 'sub_article') {
foreach ($item['custom_fields']['field_article'] as &$article) {
$this->removeObsoleteParagraphs($article);
}
}
}
}

/**
* Load a term by name and vocabulary.
*
* @param string $name
* The name of the term.
* @param string $vid
* The vocabulary id.
*
* @return \Drupal\taxonomy\TermInterface|null
* A taxonomy term object or NULL.
*/
private function loadTermByName($name, $vid) {
$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadByProperties([
'vid' => $vid,
'name' => $name,
]);
return count($terms) == 1 ? reset($terms) : NULL;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Drupal\ncms_gho_import\EventSubscriber;

use Drupal\ncms_gho_import\ContentImportManager;
use Drupal\single_content_sync\Event\ImportEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Event subscriber to react to import events.
*/
class ImportEventSubscriber implements EventSubscriberInterface {

/**
* Our custom content import manager.
*
* @var \Drupal\ncms_gho_import\ContentImportManager
*/
private $contentImportManager;

/**
* Public constructor.
*
* @param \Drupal\ncms_gho_import\ContentImportManager $content_import_manager
* The content import manager.
*/
public function __construct(ContentImportManager $content_import_manager) {
$this->contentImportManager = $content_import_manager;
}

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[ImportEvent::class] = ['onImport'];
return $events;
}

/**
* React to content being imported.
*
* @param \Drupal\single_content_sync\Event\ImportEvent $event
* The import event.
*/
public function onImport(ImportEvent $event) {
$content = $event->getContent();
$entity = $event->getEntity();

$this->contentImportManager->setContentSpace($entity);
$this->contentImportManager->setContentProperties($entity);

$this->contentImportManager->removeObsoleteParagraphs($content, $entity);

$event->setContent($content);
$event->setEntity($entity);
}

}

0 comments on commit e377cd8

Please sign in to comment.