diff --git a/config/core.entity_form_display.node.article.default.yml b/config/core.entity_form_display.node.article.default.yml index 740f7d10f..6c7464116 100644 --- a/config/core.entity_form_display.node.article.default.yml +++ b/config/core.entity_form_display.node.article.default.yml @@ -10,6 +10,7 @@ dependencies: - field.field.node.article.field_image - field.field.node.article.field_inherit_section_image - field.field.node.article.field_remote_article + - field.field.node.article.field_short_title - field.field.node.article.field_summary - field.field.node.article.field_tags - field.field.node.article.layout_builder__layout @@ -32,7 +33,7 @@ third_party_settings: label: Tabs region: content parent_name: '' - weight: 2 + weight: 3 format_type: tabs format_settings: classes: '' @@ -99,7 +100,7 @@ mode: default content: created: type: datetime_timestamp - weight: 4 + weight: 5 region: content settings: { } third_party_settings: { } @@ -159,6 +160,14 @@ content: region: content settings: { } third_party_settings: { } + field_short_title: + type: string_textfield + weight: 1 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } field_summary: type: text_textarea weight: 13 @@ -184,34 +193,34 @@ content: third_party_settings: { } langcode: type: language_select - weight: 1 + weight: 2 region: content settings: include_locked: true third_party_settings: { } path: type: path - weight: 8 + weight: 9 region: content settings: { } third_party_settings: { } promote: type: boolean_checkbox - weight: 6 + weight: 7 region: content settings: display_label: true third_party_settings: { } status: type: boolean_checkbox - weight: 9 + weight: 10 region: content settings: display_label: true third_party_settings: { } sticky: type: boolean_checkbox - weight: 7 + weight: 8 region: content settings: display_label: true @@ -225,13 +234,13 @@ content: placeholder: '' third_party_settings: { } translation: - weight: 5 + weight: 6 region: content settings: { } third_party_settings: { } uid: type: entity_reference_autocomplete - weight: 3 + weight: 4 region: content settings: match_operator: CONTAINS @@ -240,7 +249,7 @@ content: placeholder: '' third_party_settings: { } url_redirects: - weight: 50 + weight: 11 region: content settings: { } third_party_settings: { } diff --git a/config/core.entity_form_display.node.document.default.yml b/config/core.entity_form_display.node.document.default.yml index c1d69c24d..04a506f4b 100644 --- a/config/core.entity_form_display.node.document.default.yml +++ b/config/core.entity_form_display.node.document.default.yml @@ -6,14 +6,12 @@ dependencies: - field.field.node.document.field_base_objects - field.field.node.document.field_crop_hero_image - field.field.node.document.field_display_hero_image - - field.field.node.document.field_entity_reference - field.field.node.document.field_image - field.field.node.document.field_inherit_section_image - field.field.node.document.field_remote_document - field.field.node.document.field_short_title - field.field.node.document.field_summary - field.field.node.document.field_tags - - field.field.node.document.field_team - field.field.node.document.layout_builder__layout - image.style.thumbnail - node.type.document @@ -46,6 +44,7 @@ third_party_settings: children: - field_display_hero_image - field_crop_hero_image + - image_crop - field_inherit_section_image label: Display region: content @@ -140,7 +139,7 @@ content: third_party_settings: { } field_inherit_section_image: type: boolean_checkbox - weight: 17 + weight: 18 region: content settings: display_label: true @@ -177,6 +176,11 @@ content: size: 60 placeholder: '' third_party_settings: { } + image_crop: + weight: 17 + region: content + settings: { } + third_party_settings: { } langcode: type: language_select weight: 2 @@ -240,6 +244,4 @@ content: settings: { } third_party_settings: { } hidden: - field_entity_reference: true - field_team: true layout_builder__layout: true diff --git a/config/core.entity_view_display.node.article.card.yml b/config/core.entity_view_display.node.article.card.yml index e7987069d..10561b20a 100644 --- a/config/core.entity_view_display.node.article.card.yml +++ b/config/core.entity_view_display.node.article.card.yml @@ -11,6 +11,7 @@ dependencies: - field.field.node.article.field_image - field.field.node.article.field_inherit_section_image - field.field.node.article.field_remote_article + - field.field.node.article.field_short_title - field.field.node.article.field_summary - field.field.node.article.field_tags - field.field.node.article.layout_builder__layout @@ -93,7 +94,9 @@ hidden: field_display_hero_image: true field_inherit_section_image: true field_remote_article: true + field_short_title: true field_summary: true langcode: true layout_builder__layout: true links: true + search_api_excerpt: true diff --git a/config/core.entity_view_display.node.article.card_summary.yml b/config/core.entity_view_display.node.article.card_summary.yml index 968aa454d..65f0f2332 100644 --- a/config/core.entity_view_display.node.article.card_summary.yml +++ b/config/core.entity_view_display.node.article.card_summary.yml @@ -11,6 +11,7 @@ dependencies: - field.field.node.article.field_image - field.field.node.article.field_inherit_section_image - field.field.node.article.field_remote_article + - field.field.node.article.field_short_title - field.field.node.article.field_summary - field.field.node.article.field_tags - field.field.node.article.layout_builder__layout @@ -107,6 +108,7 @@ hidden: field_display_hero_image: true field_inherit_section_image: true field_remote_article: true + field_short_title: true field_tags: true langcode: true layout_builder__layout: true diff --git a/config/core.entity_view_display.node.article.default.yml b/config/core.entity_view_display.node.article.default.yml index b9539a5ce..38c19038b 100644 --- a/config/core.entity_view_display.node.article.default.yml +++ b/config/core.entity_view_display.node.article.default.yml @@ -10,6 +10,7 @@ dependencies: - field.field.node.article.field_image - field.field.node.article.field_inherit_section_image - field.field.node.article.field_remote_article + - field.field.node.article.field_short_title - field.field.node.article.field_summary - field.field.node.article.field_tags - field.field.node.article.layout_builder__layout @@ -33,7 +34,23 @@ third_party_settings: layout_settings: label: Content context_mapping: { } - components: { } + components: + 8f0e42b8-302c-435f-877f-0b65259f3ef5: + uuid: 8f0e42b8-302c-435f-877f-0b65259f3ef5 + region: content + configuration: + id: 'field_block:node:article:field_short_title' + label_display: '0' + context_mapping: + entity: layout_builder.entity + formatter: + type: string + label: above + settings: + link_to_entity: false + third_party_settings: { } + weight: 0 + additional: { } third_party_settings: { } layout_builder_restrictions: allowed_block_categories: @@ -158,6 +175,14 @@ content: third_party_settings: { } weight: 1 region: content + field_short_title: + type: string + label: above + settings: + link_to_entity: false + third_party_settings: { } + weight: 108 + region: content field_summary: type: text_default label: above diff --git a/config/core.entity_view_display.node.article.grid.yml b/config/core.entity_view_display.node.article.grid.yml index 436a64722..55a19afce 100644 --- a/config/core.entity_view_display.node.article.grid.yml +++ b/config/core.entity_view_display.node.article.grid.yml @@ -11,6 +11,7 @@ dependencies: - field.field.node.article.field_image - field.field.node.article.field_inherit_section_image - field.field.node.article.field_remote_article + - field.field.node.article.field_short_title - field.field.node.article.field_summary - field.field.node.article.field_tags - field.field.node.article.layout_builder__layout @@ -108,6 +109,7 @@ hidden: field_display_hero_image: true field_inherit_section_image: true field_remote_article: true + field_short_title: true field_summary: true langcode: true layout_builder__layout: true diff --git a/config/core.entity_view_display.node.article.search_result.yml b/config/core.entity_view_display.node.article.search_result.yml index b871678b4..9353d0ff1 100644 --- a/config/core.entity_view_display.node.article.search_result.yml +++ b/config/core.entity_view_display.node.article.search_result.yml @@ -11,6 +11,7 @@ dependencies: - field.field.node.article.field_image - field.field.node.article.field_inherit_section_image - field.field.node.article.field_remote_article + - field.field.node.article.field_short_title - field.field.node.article.field_summary - field.field.node.article.field_tags - field.field.node.article.layout_builder__layout @@ -120,6 +121,7 @@ hidden: field_display_hero_image: true field_inherit_section_image: true field_remote_article: true + field_short_title: true langcode: true layout_builder__layout: true links: true diff --git a/config/core.entity_view_display.node.article.teaser.yml b/config/core.entity_view_display.node.article.teaser.yml index 898e6908c..2ec545934 100644 --- a/config/core.entity_view_display.node.article.teaser.yml +++ b/config/core.entity_view_display.node.article.teaser.yml @@ -11,6 +11,7 @@ dependencies: - field.field.node.article.field_image - field.field.node.article.field_inherit_section_image - field.field.node.article.field_remote_article + - field.field.node.article.field_short_title - field.field.node.article.field_summary - field.field.node.article.field_tags - field.field.node.article.layout_builder__layout @@ -50,6 +51,7 @@ hidden: field_display_hero_image: true field_inherit_section_image: true field_remote_article: true + field_short_title: true field_summary: true langcode: true layout_builder__layout: true diff --git a/config/core.entity_view_display.node.document.default.yml b/config/core.entity_view_display.node.document.default.yml index 574d6f332..18bb3b7df 100644 --- a/config/core.entity_view_display.node.document.default.yml +++ b/config/core.entity_view_display.node.document.default.yml @@ -6,14 +6,12 @@ dependencies: - field.field.node.document.field_base_objects - field.field.node.document.field_crop_hero_image - field.field.node.document.field_display_hero_image - - field.field.node.document.field_entity_reference - field.field.node.document.field_image - field.field.node.document.field_inherit_section_image - field.field.node.document.field_remote_document - field.field.node.document.field_short_title - field.field.node.document.field_summary - field.field.node.document.field_tags - - field.field.node.document.field_team - field.field.node.document.layout_builder__layout - node.type.document module: @@ -123,14 +121,6 @@ content: third_party_settings: { } weight: 109 region: content - field_entity_reference: - type: entity_reference_label - label: above - settings: - link: true - third_party_settings: { } - weight: 112 - region: content field_image: type: image label: above @@ -172,14 +162,6 @@ content: third_party_settings: { } weight: 107 region: content - field_team: - type: entity_reference_label - label: above - settings: - link: true - third_party_settings: { } - weight: 113 - region: content links: settings: { } third_party_settings: { } diff --git a/config/core.entity_view_display.node.document.search_result.yml b/config/core.entity_view_display.node.document.search_result.yml index 6744525d8..c76a324a0 100644 --- a/config/core.entity_view_display.node.document.search_result.yml +++ b/config/core.entity_view_display.node.document.search_result.yml @@ -7,14 +7,12 @@ dependencies: - field.field.node.document.field_base_objects - field.field.node.document.field_crop_hero_image - field.field.node.document.field_display_hero_image - - field.field.node.document.field_entity_reference - field.field.node.document.field_image - field.field.node.document.field_inherit_section_image - field.field.node.document.field_remote_document - field.field.node.document.field_short_title - field.field.node.document.field_summary - field.field.node.document.field_tags - - field.field.node.document.field_team - field.field.node.document.layout_builder__layout - node.type.document - responsive_image.styles.card_hero @@ -108,11 +106,9 @@ hidden: field_base_objects: true field_crop_hero_image: true field_display_hero_image: true - field_entity_reference: true field_inherit_section_image: true field_remote_document: true field_short_title: true - field_team: true langcode: true layout_builder__layout: true links: true diff --git a/config/core.entity_view_display.node.document.teaser.yml b/config/core.entity_view_display.node.document.teaser.yml index e5f513a88..731935200 100644 --- a/config/core.entity_view_display.node.document.teaser.yml +++ b/config/core.entity_view_display.node.document.teaser.yml @@ -7,14 +7,12 @@ dependencies: - field.field.node.document.field_base_objects - field.field.node.document.field_crop_hero_image - field.field.node.document.field_display_hero_image - - field.field.node.document.field_entity_reference - field.field.node.document.field_image - field.field.node.document.field_inherit_section_image - field.field.node.document.field_remote_document - field.field.node.document.field_short_title - field.field.node.document.field_summary - field.field.node.document.field_tags - - field.field.node.document.field_team - field.field.node.document.layout_builder__layout - node.type.document module: @@ -33,13 +31,12 @@ hidden: field_base_objects: true field_crop_hero_image: true field_display_hero_image: true - field_entity_reference: true field_image: true field_inherit_section_image: true field_remote_document: true field_short_title: true field_summary: true field_tags: true - field_team: true langcode: true layout_builder__layout: true + search_api_excerpt: true diff --git a/config/core.entity_view_display.node.section.teaser.yml b/config/core.entity_view_display.node.section.teaser.yml index 03faaae59..75ca6132a 100644 --- a/config/core.entity_view_display.node.section.teaser.yml +++ b/config/core.entity_view_display.node.section.teaser.yml @@ -48,4 +48,5 @@ hidden: field_year: true langcode: true layout_builder__layout: true + search_api_excerpt: true section_menu: true diff --git a/config/field.field.node.article.field_short_title.yml b/config/field.field.node.article.field_short_title.yml new file mode 100644 index 000000000..a282237b6 --- /dev/null +++ b/config/field.field.node.article.field_short_title.yml @@ -0,0 +1,19 @@ +uuid: 321408fe-52aa-4e88-9ecb-0e0c43eb08fb +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_short_title + - node.type.article +id: node.article.field_short_title +field_name: field_short_title +entity_type: node +bundle: article +label: 'Short title' +description: '' +required: true +translatable: false +default_value: { } +default_value_callback: '' +settings: { } +field_type: string diff --git a/config/field.field.node.document.field_entity_reference.yml b/config/field.field.node.document.field_entity_reference.yml deleted file mode 100644 index e38a1356c..000000000 --- a/config/field.field.node.document.field_entity_reference.yml +++ /dev/null @@ -1,31 +0,0 @@ -uuid: d9f9ba81-f2a4-403d-900a-1e8e5cd1f41f -langcode: en -status: true -dependencies: - config: - - field.storage.node.field_entity_reference - - node.type.document - - node.type.global_section - - node.type.section -id: node.document.field_entity_reference -field_name: field_entity_reference -entity_type: node -bundle: document -label: 'Entity reference (deprecated)' -description: '' -required: false -translatable: true -default_value: { } -default_value_callback: '' -settings: - handler: 'default:node' - handler_settings: - target_bundles: - global_section: global_section - section: section - sort: - field: _none - direction: ASC - auto_create: false - auto_create_bundle: global_section -field_type: entity_reference diff --git a/config/field.field.node.document.field_team.yml b/config/field.field.node.document.field_team.yml deleted file mode 100644 index e9fdc52c0..000000000 --- a/config/field.field.node.document.field_team.yml +++ /dev/null @@ -1,29 +0,0 @@ -uuid: 57dfd90b-743d-40a9-b8c8-6c1d95c53cf3 -langcode: en -status: true -dependencies: - config: - - field.storage.node.field_team - - node.type.document - - taxonomy.vocabulary.team -id: node.document.field_team -field_name: field_team -entity_type: node -bundle: document -label: 'Team (deprecated)' -description: '' -required: false -translatable: true -default_value: { } -default_value_callback: '' -settings: - handler: 'default:taxonomy_term' - handler_settings: - target_bundles: - team: team - sort: - field: name - direction: asc - auto_create: false - auto_create_bundle: '' -field_type: entity_reference diff --git a/config/migrate_plus.migration.articles_hpc_content_module.yml b/config/migrate_plus.migration.articles_hpc_content_module.yml index ef06a1450..1e9e3fdfc 100644 --- a/config/migrate_plus.migration.articles_hpc_content_module.yml +++ b/config/migrate_plus.migration.articles_hpc_content_module.yml @@ -24,6 +24,10 @@ source: name: title label: Title selector: title + - + name: title_short + label: 'Title (short)' + selector: title_short - name: chapter label: Chapter @@ -65,6 +69,10 @@ process: plugin: default_value default_value: hpc_content_module field_remote_article/article_id: id + field_short_title/value: title_short + field_short_title/format: + plugin: default_value + default_value: html_text field_chapter: section field_summary/value: summary field_summary/format: @@ -85,6 +93,7 @@ destination: plugin: 'entity:node' overwrite_properties: - title + - field_short_title - field_chapter - field_summary - field_tags diff --git a/html/modules/custom/ghi_content/config/install/migrate_plus.migration.articles_hpc_content_module.yml b/html/modules/custom/ghi_content/config/install/migrate_plus.migration.articles_hpc_content_module.yml index 62e115f83..4b2cd73d0 100644 --- a/html/modules/custom/ghi_content/config/install/migrate_plus.migration.articles_hpc_content_module.yml +++ b/html/modules/custom/ghi_content/config/install/migrate_plus.migration.articles_hpc_content_module.yml @@ -17,6 +17,10 @@ source: name: title label: 'Title' selector: title + - + name: title_short + label: 'Title (short)' + selector: title_short - name: chapter label: 'Chapter' @@ -58,6 +62,10 @@ process: plugin: default_value default_value: hpc_content_module field_remote_article/article_id: id + field_short_title/value: title_short + field_short_title/format: + plugin: default_value + default_value: html_text field_chapter: section field_summary/value: summary field_summary/format: @@ -78,6 +86,7 @@ destination: plugin: 'entity:node' overwrite_properties: - title + - field_short_title - field_chapter - field_summary - field_tags diff --git a/html/modules/custom/ghi_content/ghi_content.api.php b/html/modules/custom/ghi_content/ghi_content.api.php new file mode 100644 index 000000000..5a1ab6c87 --- /dev/null +++ b/html/modules/custom/ghi_content/ghi_content.api.php @@ -0,0 +1,23 @@ +normalizeContentNodeData() + */ +function hook_normalize_content_alter(&$data) { + unset($data['field_my_field'][0]['property']); +} diff --git a/html/modules/custom/ghi_content/ghi_content.module b/html/modules/custom/ghi_content/ghi_content.module index 1c8469142..67aae1141 100644 --- a/html/modules/custom/ghi_content/ghi_content.module +++ b/html/modules/custom/ghi_content/ghi_content.module @@ -20,7 +20,6 @@ use Drupal\ghi_content\RemoteContent\RemoteContentImageInterface; use Drupal\ghi_sections\Entity\Section; use Drupal\ghi_sections\SectionManager; use Drupal\hpc_common\Helpers\RequestHelper; -use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage; use Drupal\layout_builder\SectionStorageInterface; use Drupal\node\NodeInterface; @@ -228,24 +227,6 @@ function ghi_content_current_section_alter(&$section, $node) { } } -/** - * Implements hook_ENTITY_TYPE_presave() for node entities. - */ -function ghi_content_node_presave(NodeInterface $node) { - if (!$node->hasField(OverridesSectionStorage::FIELD_NAME)) { - // We only process nodes that use layout builder. - return; - } - - /** @var \Drupal\ghi_content\ContentManager\ManagerFactory $manager_factory */ - $manager_factory = \Drupal::getContainer()->get('ghi_content.manager.factory'); - $content_manager = $manager_factory->getContentManager($node); - if ($content_manager) { - $content_manager->updateNodeFromRemote($node); - } - -} - /** * Implements hook_ENTITY_TYPE_predelete() for node entities. */ diff --git a/html/modules/custom/ghi_content/ghi_content.services.yml b/html/modules/custom/ghi_content/ghi_content.services.yml index 273213c02..3333c1665 100644 --- a/html/modules/custom/ghi_content/ghi_content.services.yml +++ b/html/modules/custom/ghi_content/ghi_content.services.yml @@ -20,10 +20,10 @@ services: arguments: ['@ghi_content.manager.article', '@ghi_content.manager.document'] ghi_content.manager.article: class: Drupal\ghi_content\ContentManager\ArticleManager - arguments: ['@entity_type.manager', '@renderer', '@current_user', '@plugin.manager.migration', '@plugin.manager.remote_source', '@ghi_content.import', '@request_stack'] + arguments: ['@entity_type.manager', '@renderer', '@current_user', '@request_stack', '@current_route_match', '@plugin.manager.migration', '@plugin.manager.remote_source', '@ghi_content.import', '@module_handler', '@redirect.destination', '@messenger'] ghi_content.manager.document: class: Drupal\ghi_content\ContentManager\DocumentManager - arguments: ['@entity_type.manager', '@renderer', '@current_user', '@plugin.manager.migration', '@plugin.manager.remote_source', '@ghi_content.import', '@request_stack'] + arguments: ['@entity_type.manager', '@renderer', '@current_user', '@request_stack', '@current_route_match', '@plugin.manager.migration', '@plugin.manager.remote_source', '@ghi_content.import', '@module_handler', '@redirect.destination', '@messenger'] ghi_content.contextual_links.block_handler: class: Drupal\ghi_content\ContextualLinks\BlockHandler arguments: ['@entity_type.manager', '@layout_builder.tempstore_repository'] @@ -34,7 +34,7 @@ services: - { name: breadcrumb_builder, priority: 1003 } ghi_content.content_page_path_processor: class: Drupal\ghi_content\Path\ContentPagePathProcessor - arguments: ['@request_stack', '@ghi_content.manager.document'] + arguments: ['@request_stack'] tags: - { name: path_processor_inbound, priority: 1000 } - { name: path_processor_outbound, priority: 100 } \ No newline at end of file diff --git a/html/modules/custom/ghi_content/src/ContentManager/ArticleManager.php b/html/modules/custom/ghi_content/src/ContentManager/ArticleManager.php index ca5b2399f..40c9806cd 100644 --- a/html/modules/custom/ghi_content/src/ContentManager/ArticleManager.php +++ b/html/modules/custom/ghi_content/src/ContentManager/ArticleManager.php @@ -2,16 +2,9 @@ namespace Drupal\ghi_content\ContentManager; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Render\RendererInterface; -use Drupal\Core\Session\AccountInterface; -use Drupal\ghi_content\Import\ImportManager; use Drupal\ghi_content\RemoteContent\RemoteArticleInterface; use Drupal\ghi_content\RemoteContent\RemoteContentInterface; -use Drupal\ghi_content\RemoteSource\RemoteSourceManager; -use Drupal\migrate\Plugin\MigrationPluginManager; use Drupal\node\NodeInterface; -use Symfony\Component\HttpFoundation\RequestStack; /** * Article manager service class. @@ -38,29 +31,6 @@ class ArticleManager extends BaseContentManager { */ const REMOTE_SOURCE_LINK_TYPE = 'ghi_remote_article_source_link'; - /** - * The migration plugin manager. - * - * @var \Drupal\migrate\Plugin\MigrationPluginManager - */ - protected $migrationManager; - - /** - * The remote source manager. - * - * @var \Drupal\ghi_content\Import\ImportManager - */ - protected $importManager; - - /** - * Constructs a document manager. - */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, AccountInterface $current_user, MigrationPluginManager $migration_manager, RemoteSourceManager $remote_source_manager, ImportManager $import_manager, RequestStack $request_stack) { - parent::__construct($entity_type_manager, $renderer, $current_user, $request_stack, $remote_source_manager); - $this->migrationManager = $migration_manager; - $this->importManager = $import_manager; - } - /** * {@inheritdoc} */ @@ -148,6 +118,7 @@ public function createNodeFromRemoteArticle(RemoteArticleInterface $article, $ti if ($team) { $node->field_team = $team; } + $status = $node->save(); return $status == SAVED_NEW ? $node : NULL; } @@ -224,6 +195,9 @@ public function updateNodeFromRemote(NodeInterface $node, $dry_run = FALSE, $res $node->setCreatedTime($article->getCreated()); $node->setChangedTime($article->getUpdated()); + // Import the short title. + $this->importManager->importTextfield($node, $article, $this->t('Short title'), 'getShortTitle', 'field_short_title'); + // Import the summary. $this->importManager->importTextfield($node, $article, $this->t('Summary'), 'getSummary', 'field_summary', 'html_text'); diff --git a/html/modules/custom/ghi_content/src/ContentManager/BaseContentManager.php b/html/modules/custom/ghi_content/src/ContentManager/BaseContentManager.php index 670ead3d4..8b653a985 100644 --- a/html/modules/custom/ghi_content/src/ContentManager/BaseContentManager.php +++ b/html/modules/custom/ghi_content/src/ContentManager/BaseContentManager.php @@ -2,14 +2,20 @@ namespace Drupal\ghi_content\ContentManager; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\Query\QueryInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Render\RendererInterface; +use Drupal\Core\Routing\RedirectDestinationInterface; +use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; +use Drupal\ghi_content\Import\ImportManager; use Drupal\ghi_content\RemoteContent\RemoteContentInterface; use Drupal\ghi_content\RemoteSource\RemoteSourceManager; use Drupal\ghi_sections\Entity\SectionNodeInterface; @@ -18,16 +24,18 @@ use Drupal\hpc_common\Helpers\ArrayHelper; use Drupal\migrate\MigrateExecutable; use Drupal\migrate\Plugin\MigrateIdMapInterface; +use Drupal\migrate\Plugin\MigrationPluginManager; use Drupal\migrate\Row; use Drupal\migrate_plus\Entity\Migration; use Drupal\node\NodeInterface; use Drupal\taxonomy\TermInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RequestStack; /** * Base manager service class.. */ -abstract class BaseContentManager { +abstract class BaseContentManager implements ContainerInjectionInterface { use SectionTrait; use StringTranslationTrait; @@ -61,6 +69,20 @@ abstract class BaseContentManager { */ protected $request; + /** + * The route match. + * + * @var \Drupal\Core\Routing\RouteMatchInterface + */ + protected $routeMatch; + + /** + * The migration plugin manager. + * + * @var \Drupal\migrate\Plugin\MigrationPluginManager + */ + protected $migrationManager; + /** * The remote source manager. * @@ -68,15 +90,68 @@ abstract class BaseContentManager { */ protected $remoteSourceManager; + /** + * The remote source manager. + * + * @var \Drupal\ghi_content\Import\ImportManager + */ + protected $importManager; + + /** + * The module handler service. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * The redirect destination. + * + * @var \Drupal\Core\Routing\RedirectDestinationInterface + */ + protected $redirectDestination; + + /** + * Messenger service. + * + * @var \Drupal\Core\Messenger\MessengerInterface + */ + protected $messenger; + /** * Constructs a document manager. */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, AccountInterface $current_user, RequestStack $request_stack, RemoteSourceManager $remote_source_manager) { + public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, AccountInterface $current_user, RequestStack $request_stack, RouteMatchInterface $route_match, MigrationPluginManager $migration_manager, RemoteSourceManager $remote_source_manager, ImportManager $import_manager, ModuleHandlerInterface $module_handler, RedirectDestinationInterface $redirect_destination, MessengerInterface $messenger) { $this->entityTypeManager = $entity_type_manager; $this->renderer = $renderer; $this->currentUser = $current_user; $this->request = $request_stack->getCurrentRequest(); + $this->routeMatch = $route_match; + $this->migrationManager = $migration_manager; $this->remoteSourceManager = $remote_source_manager; + $this->importManager = $import_manager; + $this->moduleHandler = $module_handler; + $this->redirectDestination = $redirect_destination; + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity_type.manager'), + $container->get('renderer'), + $container->get('current_user'), + $container->get('request_stack'), + $container->get('current_route_match'), + $container->get('plugin.manager.migration'), + $container->get('plugin.manager.remote_source'), + $container->get('ghi_content.import'), + $container->get('module_handler'), + $container->get('redirect.destination'), + $container->get('messenger'), + ); } /** @@ -371,7 +446,7 @@ public function getNodeIdsGroupedByTag(array $nodes, array $additional_tags = [] } /** - * Save an content node programatically. + * Save a content node programatically. * * Besides saving the node, this does 2 additional things. * 1. It handles the presence of an IPE token, which would prevent updates to @@ -442,6 +517,7 @@ protected function normalizeContentNodeData(NodeInterface $node) { unset($data['changed']); ArrayHelper::sortMultiDimensionalArrayByKeys($data); ArrayHelper::reduceArray($data); + $this->moduleHandler->alter('normalize_content', $data); return $data; } @@ -510,7 +586,6 @@ public function updateMigrationState(NodeInterface $node) { $destination_ids = $migration->getIdMap()->lookupDestinationIds($source_id); $destination_id_values = $destination_ids ? reset($destination_ids) : []; - $destination->import($row, $destination_id_values); $migration->getIdMap()->saveIdMapping($row, $destination_id_values, MigrateIdMapInterface::STATUS_IMPORTED, $destination->rollbackAction()); } } @@ -555,7 +630,7 @@ public function nodeEditFormAlter(array &$form, FormStateInterface $form_state) // Add a global message about disabled fields. if (empty($form_state->getUserInput())) { - \Drupal::messenger()->addWarning($this->t('Some of the fields in this form are disabled because their content is automatically synced from the remote source.')); + $this->messenger->addWarning($this->t('Some of the fields in this form are disabled because their content is automatically synced from the remote source.')); } $migration_id = $this->getMigration($node)->id(); @@ -593,7 +668,7 @@ public function nodeEditFormAlter(array &$form, FormStateInterface $form_state) $form[$remote_field]['#disabled'] = TRUE; $form[$remote_field]['#attributes']['title'] = $this->t('This field cannot be edited anymore after the page has been created.'); - $admin_permission = \Drupal::currentUser()->hasPermission('administer content types'); + $admin_permission = $this->currentUser->hasPermission('administer content types'); $form['meta']['#access'] = $admin_permission; $form['meta']['published']['#access'] = $admin_permission; $form['meta']['author']['#access'] = $admin_permission; @@ -664,20 +739,18 @@ public function nodeEditFormAlter(array &$form, FormStateInterface $form_state) } if ($content) { - /** @var \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination */ - $redirect_destination = \Drupal::service('redirect.destination'); - $queryParams = \Drupal::request()->query->all(); - $redirect_url = Url::fromRouteMatch(\Drupal::routeMatch()); + $queryParams = $this->request->query->all(); + $redirect_url = Url::fromRouteMatch($this->routeMatch); if (!empty($queryParams)) { $redirect_url->setOption('query', $queryParams); } - $redirect_destination->set($redirect_url->toString()); + $this->redirectDestination->set($redirect_url->toString()); $form['remote_content_info']['link_label'] = [ '#type' => 'item', '#title' => $this->t('Go to remote system'), '#weight' => 3, ]; - $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node'); + $view_builder = $this->entityTypeManager->getViewBuilder('node'); $form['remote_content_info']['link'] = $view_builder->viewField($node->get($remote_field), [ 'label' => 'hidden', 'type' => $this->getRemoteSourceLinkType(), @@ -718,6 +791,9 @@ public function applyChangesSubmit($form, FormStateInterface $form_state) { $form_object = $form_state->getFormObject(); $node = $form_object->getEntity(); + // Update based on what's new on the remote. + $this->updateNodeFromRemote($node); + // Save the content node, making sure that common logic is applied. $this->saveContentNode($node); @@ -735,7 +811,7 @@ public function formResetSubmit($form, FormStateInterface $form_state) { // Reset the article to it's exact version in the remote system. $this->updateNodeFromRemote($node, FALSE, TRUE); - // Save the article node, making sure that common logic is applied. + // Save the content node, making sure that common logic is applied. $this->saveContentNode($node); $form_state->setRebuild(); diff --git a/html/modules/custom/ghi_content/src/ContentManager/DocumentManager.php b/html/modules/custom/ghi_content/src/ContentManager/DocumentManager.php index fbc8b6c87..007d19c87 100644 --- a/html/modules/custom/ghi_content/src/ContentManager/DocumentManager.php +++ b/html/modules/custom/ghi_content/src/ContentManager/DocumentManager.php @@ -2,17 +2,10 @@ namespace Drupal\ghi_content\ContentManager; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Render\RendererInterface; -use Drupal\Core\Session\AccountInterface; -use Drupal\ghi_content\Import\ImportManager; use Drupal\ghi_content\RemoteContent\RemoteContentInterface; use Drupal\ghi_content\RemoteContent\RemoteDocumentInterface; -use Drupal\ghi_content\RemoteSource\RemoteSourceManager; use Drupal\layout_builder\LayoutEntityHelperTrait; -use Drupal\migrate\Plugin\MigrationPluginManager; use Drupal\node\NodeInterface; -use Symfony\Component\HttpFoundation\RequestStack; /** * Document manager service class. @@ -36,29 +29,6 @@ class DocumentManager extends BaseContentManager { */ const REMOTE_SOURCE_LINK_TYPE = 'ghi_remote_document_source_link'; - /** - * The migration plugin manager. - * - * @var \Drupal\migrate\Plugin\MigrationPluginManager - */ - protected $migrationManager; - - /** - * The remote source manager. - * - * @var \Drupal\ghi_content\Import\ImportManager - */ - protected $importManager; - - /** - * Constructs a document manager. - */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, AccountInterface $current_user, MigrationPluginManager $migration_manager, RemoteSourceManager $remote_source_manager, ImportManager $import_manager, RequestStack $request_stack) { - parent::__construct($entity_type_manager, $renderer, $current_user, $request_stack, $remote_source_manager); - $this->migrationManager = $migration_manager; - $this->importManager = $import_manager; - } - /** * {@inheritdoc} */ diff --git a/html/modules/custom/ghi_content/src/Entity/ContentBase.php b/html/modules/custom/ghi_content/src/Entity/ContentBase.php index 09efc7f69..198320710 100644 --- a/html/modules/custom/ghi_content/src/Entity/ContentBase.php +++ b/html/modules/custom/ghi_content/src/Entity/ContentBase.php @@ -119,6 +119,13 @@ public function toUrl($rel = 'canonical', array $options = []) { return parent::toUrl($rel, $options); } + /** + * Get the short title for a document. + */ + public function getShortTitle() { + return $this->get('field_short_title')->value ?? NULL; + } + /** * Get the meta data for this article. * diff --git a/html/modules/custom/ghi_content/src/Entity/Document.php b/html/modules/custom/ghi_content/src/Entity/Document.php index 27ae9daf5..7cf98bf6c 100644 --- a/html/modules/custom/ghi_content/src/Entity/Document.php +++ b/html/modules/custom/ghi_content/src/Entity/Document.php @@ -24,13 +24,6 @@ public function toLink($text = NULL, $rel = 'canonical', array $options = []) { return parent::toLink($text, $rel, $options); } - /** - * Get the short title for a document. - */ - public function getShortTitle() { - return $this->get('field_short_title')->value ?? NULL; - } - /** * Check if the given article is part of this document. */ diff --git a/html/modules/custom/ghi_content/src/Path/ContentPagePathProcessor.php b/html/modules/custom/ghi_content/src/Path/ContentPagePathProcessor.php index 84efb1d4e..aa785f9da 100644 --- a/html/modules/custom/ghi_content/src/Path/ContentPagePathProcessor.php +++ b/html/modules/custom/ghi_content/src/Path/ContentPagePathProcessor.php @@ -5,7 +5,6 @@ use Drupal\Core\PathProcessor\InboundPathProcessorInterface; use Drupal\Core\PathProcessor\OutboundPathProcessorInterface; use Drupal\Core\Render\BubbleableMetadata; -use Drupal\ghi_content\ContentManager\DocumentManager; use Drupal\ghi_content\Traits\ContentPathTrait; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -32,18 +31,10 @@ class ContentPagePathProcessor implements InboundPathProcessorInterface, Outboun protected $requestStack; /** - * The document manager. - * - * @var \Drupal\ghi_content\ContentManager\DocumentManager - */ - protected $documentManager; - - /** - * Constructs a document manager. + * Constructs a path processor. */ - public function __construct(RequestStack $request_stack, DocumentManager $document_manager) { + public function __construct(RequestStack $request_stack) { $this->requestStack = $request_stack; - $this->documentManager = $document_manager; } /** diff --git a/html/modules/custom/ghi_content/src/RemoteContent/HpcContentModule/RemoteArticle.php b/html/modules/custom/ghi_content/src/RemoteContent/HpcContentModule/RemoteArticle.php index 2c5f2c048..c4309719d 100644 --- a/html/modules/custom/ghi_content/src/RemoteContent/HpcContentModule/RemoteArticle.php +++ b/html/modules/custom/ghi_content/src/RemoteContent/HpcContentModule/RemoteArticle.php @@ -46,6 +46,13 @@ public function getTitle() { return trim($this->data->title); } + /** + * {@inheritdoc} + */ + public function getShortTitle() { + return trim($this->data->title_short); + } + /** * {@inheritdoc} */ diff --git a/html/modules/custom/ghi_content/src/RemoteContent/RemoteArticleInterface.php b/html/modules/custom/ghi_content/src/RemoteContent/RemoteArticleInterface.php index e3e78e517..2cf2deef3 100644 --- a/html/modules/custom/ghi_content/src/RemoteContent/RemoteArticleInterface.php +++ b/html/modules/custom/ghi_content/src/RemoteContent/RemoteArticleInterface.php @@ -7,6 +7,14 @@ */ interface RemoteArticleInterface extends RemoteContentInterface { + /** + * Get the short title for the document. + * + * @return string + * The short title. + */ + public function getShortTitle(); + /** * Get the section of the article. * diff --git a/html/modules/custom/ghi_content/src/RemoteSource/RemoteSourceBaseHpcContentModule.php b/html/modules/custom/ghi_content/src/RemoteSource/RemoteSourceBaseHpcContentModule.php index 6edf54193..8f5314f58 100644 --- a/html/modules/custom/ghi_content/src/RemoteSource/RemoteSourceBaseHpcContentModule.php +++ b/html/modules/custom/ghi_content/src/RemoteSource/RemoteSourceBaseHpcContentModule.php @@ -82,6 +82,7 @@ public function getArticle($id) { $fields = [ 'id', 'title', + 'title_short', 'section', 'summary', 'tags', @@ -477,10 +478,12 @@ public function importArticles(array $tags = NULL) { items { id title + title_short section summary created updated + tags autoVisible } } diff --git a/html/modules/custom/ghi_hero_image/ghi_hero_image.module b/html/modules/custom/ghi_hero_image/ghi_hero_image.module index 4bd1c692e..0c7d32913 100644 --- a/html/modules/custom/ghi_hero_image/ghi_hero_image.module +++ b/html/modules/custom/ghi_hero_image/ghi_hero_image.module @@ -151,3 +151,16 @@ function ghi_hero_image_form_alter(array &$form, FormStateInterface $form_state) ]; } } + +/** + * Implements hook_normalize_content_alter(). + */ +function ghi_hero_image_normalize_content_alter(&$data) { + foreach (HeroImageWidgetCropManager::IMAGE_FIELDS as $field_name) { + if (empty($data[$field_name])) { + continue; + } + unset($data[$field_name][0]['width']); + unset($data[$field_name][0]['height']); + } +} diff --git a/html/modules/custom/ghi_hero_image/src/HeroImageWidgetCropManager.php b/html/modules/custom/ghi_hero_image/src/HeroImageWidgetCropManager.php index 654c06b11..387eb1803 100644 --- a/html/modules/custom/ghi_hero_image/src/HeroImageWidgetCropManager.php +++ b/html/modules/custom/ghi_hero_image/src/HeroImageWidgetCropManager.php @@ -4,6 +4,7 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\DependencyInjection\DependencySerializationTrait; use Drupal\Core\Entity\ContentEntityFormInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; @@ -29,6 +30,8 @@ */ class HeroImageWidgetCropManager extends ImageWidgetCropManager implements ImageWidgetCropInterface, ContainerInjectionInterface { + use DependencySerializationTrait; + /** * Define the supported crop types. */ @@ -117,6 +120,7 @@ public function applyCrop(array $properties, $field_value, CropType $crop_type) */ public function updateCrop(array $properties, $field_value, CropType $crop_type) { $crop_properties = $this->getCropOriginalDimension($field_value, $properties); + $changed = FALSE; if (!empty($crop_properties)) { $image_styles = $this->getImageStylesByCrop($crop_type->id()); if (!empty($image_styles)) { @@ -256,6 +260,9 @@ public function contentEntityFormCropSubmit(array &$form, FormStateInterface $fo $crop_type_names = self::CROP_TYPES; $form_state_values = $form_state->getValues(); $file = $form['image_crop']['image_crop']['#file']; + if (!$file) { + return; + } foreach ($crop_type_names as $crop_type_name) { $flush_styles = FALSE;