diff --git a/drupal/.env b/drupal/.env index 6a47a28..c6a34de 100644 --- a/drupal/.env +++ b/drupal/.env @@ -38,8 +38,8 @@ MAILHOG_ENABLE=0 MAILHOG_TAG=v1.0.0 # Solr Container. -SOLR_ENABLE=0 -SOLR_TAG=6-alpine +SOLR_ENABLE=1 +SOLR_TAG=8-alpine # Memcached Container. MEMCACHED_ENABLE=0 diff --git a/drupal/composer.json b/drupal/composer.json index a0b76d0..ff32d9f 100644 --- a/drupal/composer.json +++ b/drupal/composer.json @@ -39,8 +39,10 @@ "drupal/environment_indicator": "^4.0", "drupal/focal_point": "^1.5", "drupal/google_analytics": "^3.1", + "drupal/graphql": "^4.0", "drupal/honeypot": "^2.0", "drupal/image_style_quality": "^1.4", + "drupal/jsonapi_search_api": "^1.0@RC", "drupal/layout_builder_browser": "^1.1", "drupal/layout_builder_iframe_modal": "^1.0", "drupal/media_entity_facebook": "^2.0", diff --git a/drupal/composer.lock b/drupal/composer.lock index 556c3f5..790366a 100644 --- a/drupal/composer.lock +++ b/drupal/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8650f110f328a2ef41286779b25e79c3", + "content-hash": "3b4f3c968ee4b9e2a05c338d9b7ef209", "packages": [ { "name": "asm89/stack-cors", @@ -2949,6 +2949,72 @@ "issues": "https://www.drupal.org/project/issues/google_analytics" } }, + { + "name": "drupal/graphql", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/graphql.git", + "reference": "8.x-4.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/graphql-8.x-4.0.zip", + "reference": "8.x-4.0", + "shasum": "639dd29fb6005ba2b15a389f03a6596308c9f14e" + }, + "require": { + "drupal/core": "^8 || ^9", + "drupal/typed_data": "*", + "php": ">=7.2", + "webonyx/graphql-php": "^14.3.0" + }, + "require-dev": { + "drupal/node-node": "*" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-4.0", + "datestamp": "1607692423", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "fubhy", + "homepage": "https://www.drupal.org/user/761344" + }, + { + "name": "hideaway", + "homepage": "https://www.drupal.org/user/741876" + }, + { + "name": "joaogarin", + "homepage": "https://www.drupal.org/user/612814" + }, + { + "name": "klausi", + "homepage": "https://www.drupal.org/user/262198" + }, + { + "name": "pmelab", + "homepage": "https://www.drupal.org/user/555322" + } + ], + "description": "Exposes your Drupal data model through a GraphQL schema.", + "homepage": "http://drupal.org/project/graphql", + "support": { + "source": "https://git.drupalcode.org/project/graphql" + } + }, { "name": "drupal/honeypot", "version": "2.0.1", @@ -3062,6 +3128,115 @@ "source": "https://git.drupalcode.org/project/image_style_quality" } }, + { + "name": "drupal/jsonapi_resources", + "version": "1.0.0-beta4", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/jsonapi_resources.git", + "reference": "8.x-1.0-beta4" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/jsonapi_resources-8.x-1.0-beta4.zip", + "reference": "8.x-1.0-beta4", + "shasum": "7cef08a40333a854112bc1763c6d4f3a52198604" + }, + "require": { + "drupal/core": "^8.8 || ^9.0" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.0-beta4", + "datestamp": "1608428207", + "security-coverage": { + "status": "not-covered", + "message": "Beta releases are not covered by Drupal security advisories." + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "API-First Initiative", + "homepage": "https://www.drupal.org/user/3616626" + }, + { + "name": "gabesullice", + "homepage": "https://www.drupal.org/user/2287430" + }, + { + "name": "mglaman", + "homepage": "https://www.drupal.org/user/2416470" + } + ], + "description": "This module let's you define custom resources at routes of your choice that use existing resource types.", + "homepage": "https://www.drupal.org/project/jsonapi_resources", + "keywords": [ + "Drupal", + "JSON API" + ], + "support": { + "source": "https://git.drupalcode.org/project/jsonapi_resources" + } + }, + { + "name": "drupal/jsonapi_search_api", + "version": "1.0.0-rc2", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/jsonapi_search_api.git", + "reference": "8.x-1.0-rc2" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/jsonapi_search_api-8.x-1.0-rc2.zip", + "reference": "8.x-1.0-rc2", + "shasum": "c36fa23790a61999830717442508f1bafa4ae9fe" + }, + "require": { + "drupal/core": "^8 || ^9", + "drupal/jsonapi_resources": "^1.0@beta", + "drupal/search_api": "^1.0" + }, + "require-dev": { + "drupal/facets": "^1.0" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.0-rc2", + "datestamp": "1605116431", + "security-coverage": { + "status": "not-covered", + "message": "RC releases are not covered by Drupal security advisories." + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "mglaman", + "homepage": "https://www.drupal.org/user/2416470" + } + ], + "description": "Exposes Search API indexes over JSON:API Resources.", + "homepage": "https://www.drupal.org/project/jsonapi_search_api", + "keywords": [ + "Drupal" + ], + "support": { + "source": "https://git.drupalcode.org/project/jsonapi_search_api", + "issues": "https://www.drupal.org/project/issues/jsonapi_search_api" + } + }, { "name": "drupal/layout_builder_browser", "version": "1.2.0", @@ -4512,6 +4687,55 @@ "issues": "https://www.drupal.org/project/issues/twig_tweak" } }, + { + "name": "drupal/typed_data", + "version": "1.0.0-alpha5", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/typed_data.git", + "reference": "8.x-1.0-alpha5" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/typed_data-8.x-1.0-alpha5.zip", + "reference": "8.x-1.0-alpha5", + "shasum": "44cfaf8f6d6bc0b876e88a8b9d473799818d395f" + }, + "require": { + "drupal/core": "^8.7.7 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.0-alpha5", + "datestamp": "1591397037", + "security-coverage": { + "status": "not-covered", + "message": "Alpha releases are not covered by Drupal security advisories." + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "TR", + "homepage": "https://www.drupal.org/user/202830" + }, + { + "name": "fago", + "homepage": "https://www.drupal.org/user/16747" + } + ], + "description": "Extends the core Typed Data API with new APIs and features.", + "homepage": "https://www.drupal.org/project/typed_data", + "support": { + "source": "https://git.drupalcode.org/project/typed_data", + "issues": "https://www.drupal.org/project/issues/typed_data" + } + }, { "name": "drupal/xmlsitemap", "version": "1.0.0", @@ -9664,6 +9888,72 @@ "source": "https://github.com/webmozart/path-util/tree/2.3.0" }, "time": "2015-12-17T08:42:14+00:00" + }, + { + "name": "webonyx/graphql-php", + "version": "v14.5.1", + "source": { + "type": "git", + "url": "https://github.com/webonyx/graphql-php.git", + "reference": "3af8b92d07e0d7a9085c0b83daf86beaeb76f092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/3af8b92d07e0d7a9085c0b83daf86beaeb76f092", + "reference": "3af8b92d07e0d7a9085c0b83daf86beaeb76f092", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": "^7.1||^8.0" + }, + "require-dev": { + "amphp/amp": "^2.3", + "doctrine/coding-standard": "^6.0", + "nyholm/psr7": "^1.2", + "phpbench/phpbench": "^0.16.10", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "0.12.32", + "phpstan/phpstan-phpunit": "0.12.11", + "phpstan/phpstan-strict-rules": "0.12.2", + "phpunit/phpunit": "^7.2|^8.5", + "psr/http-message": "^1.0", + "react/promise": "2.*", + "simpod/php-coveralls-mirror": "^3.0", + "squizlabs/php_codesniffer": "3.5.4" + }, + "suggest": { + "psr/http-message": "To use standard GraphQL server", + "react/promise": "To leverage async resolving on React PHP platform" + }, + "type": "library", + "autoload": { + "psr-4": { + "GraphQL\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP port of GraphQL reference implementation", + "homepage": "https://github.com/webonyx/graphql-php", + "keywords": [ + "api", + "graphql" + ], + "support": { + "issues": "https://github.com/webonyx/graphql-php/issues", + "source": "https://github.com/webonyx/graphql-php/tree/v14.5.1" + }, + "funding": [ + { + "url": "https://opencollective.com/webonyx-graphql-php", + "type": "open_collective" + } + ], + "time": "2021-02-05T10:51:56+00:00" } ], "packages-dev": [ @@ -13020,6 +13310,7 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { + "drupal/jsonapi_search_api": 5, "drupal/retina_images": 20, "kporras07/composer-symlinks": 20 }, diff --git a/drupal/composer.patches.json b/drupal/composer.patches.json index 95e202c..e7e6eac 100644 --- a/drupal/composer.patches.json +++ b/drupal/composer.patches.json @@ -10,6 +10,9 @@ }, "drupal/media_entity_instagram": { "https://www.drupal.org/node/3118095": "https://www.drupal.org/files/issues/2020-09-03/3118095-10.patch" + }, + "drupal/paragraphs": { + "https://www.drupal.org/node/2901390": "https://www.drupal.org/files/issues/2020-06-25/paragraphs-2901390-51.patch" } } } diff --git a/drupal/config/dev/core.extension.yml b/drupal/config/dev/core.extension.yml index 0916136..01fd914 100644 --- a/drupal/config/dev/core.extension.yml +++ b/drupal/config/dev/core.extension.yml @@ -19,12 +19,14 @@ module: dblog: 0 devel: 0 editor: 0 + entity_reference_revisions: 0 environment_indicator: 0 field: 0 field_ui: 0 file: 0 filter: 0 focal_point: 0 + graphql: 0 image: 0 image_style_quality: 0 inline_form_errors: 0 @@ -34,6 +36,7 @@ module: layout_builder_iframe_modal: 0 layout_discovery: 0 link: 0 + manati_graphql: 0 manati_landing_pages: 0 manati_layout_builder: 0 media: 0 @@ -67,6 +70,7 @@ module: token: 0 toolbar: 0 twig_tweak: 0 + typed_data: 0 update: 0 user: 0 views_ui: 0 @@ -74,6 +78,7 @@ module: pathauto: 1 xmlsitemap: 1 views: 10 + paragraphs: 11 bloom: 1000 theme: stable: 0 diff --git a/drupal/config/dev/devel.settings.yml b/drupal/config/dev/devel.settings.yml index 7bb48ed..76c4792 100644 --- a/drupal/config/dev/devel.settings.yml +++ b/drupal/config/dev/devel.settings.yml @@ -5,7 +5,7 @@ error_handlers: rebuild_theme: false debug_mail_file_format: '%to-%subject-%datetime.mail.txt' debug_mail_directory: 'temporary://devel-mails' -devel_dumper: default +devel_dumper: kint debug_logfile: 'temporary://drupal_debug.txt' debug_pre: true _core: diff --git a/drupal/config/sync/block_content.type.card.yml b/drupal/config/sync/block_content.type.card.yml new file mode 100644 index 0000000..473ccbe --- /dev/null +++ b/drupal/config/sync/block_content.type.card.yml @@ -0,0 +1,8 @@ +uuid: 8418cc87-7b50-4006-9a8d-7938b1c15969 +langcode: en +status: true +dependencies: { } +id: card +label: Card +revision: 1 +description: '' diff --git a/drupal/config/sync/core.base_field_override.node.article.promote.yml b/drupal/config/sync/core.base_field_override.node.article.promote.yml new file mode 100644 index 0000000..1a990c7 --- /dev/null +++ b/drupal/config/sync/core.base_field_override.node.article.promote.yml @@ -0,0 +1,22 @@ +uuid: 4601ce3a-83f5-4c0c-93f2-2e605deb6f38 +langcode: en +status: true +dependencies: + config: + - node.type.article +id: node.article.promote +field_name: promote +entity_type: node +bundle: article +label: 'Promoted to front page' +description: '' +required: false +translatable: true +default_value: + - + value: 0 +default_value_callback: '' +settings: + on_label: 'On' + off_label: 'Off' +field_type: boolean diff --git a/drupal/config/sync/core.entity_form_display.block_content.card.default.yml b/drupal/config/sync/core.entity_form_display.block_content.card.default.yml new file mode 100644 index 0000000..e850c10 --- /dev/null +++ b/drupal/config/sync/core.entity_form_display.block_content.card.default.yml @@ -0,0 +1,69 @@ +uuid: e10de7f9-f608-4c9c-b368-4eaf8e395a9b +langcode: en +status: true +dependencies: + config: + - block_content.type.card + - field.field.block_content.card.body + - field.field.block_content.card.field_cta + - field.field.block_content.card.field_image + - field.field.block_content.card.field_link + module: + - media_library + - paragraphs + - text +id: block_content.card.default +targetEntityType: block_content +bundle: card +mode: default +content: + body: + type: text_textarea_with_summary + weight: 26 + settings: + rows: 9 + summary_rows: 3 + placeholder: '' + show_summary: false + third_party_settings: { } + region: content + field_cta: + type: entity_reference_paragraphs + weight: 28 + settings: + title: Paragraph + title_plural: Paragraphs + edit_mode: open + add_mode: dropdown + form_display_mode: default + default_paragraph_type: '' + third_party_settings: { } + region: content + field_image: + type: media_library_widget + weight: 27 + settings: + media_types: { } + third_party_settings: { } + region: content + field_link: + type: entity_reference_paragraphs + weight: 29 + settings: + title: Paragraph + title_plural: Paragraphs + edit_mode: open + add_mode: dropdown + form_display_mode: default + default_paragraph_type: '' + third_party_settings: { } + region: content + info: + type: string_textfield + weight: -5 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } +hidden: { } diff --git a/drupal/config/sync/core.entity_form_display.node.article.default.yml b/drupal/config/sync/core.entity_form_display.node.article.default.yml new file mode 100644 index 0000000..a2395e9 --- /dev/null +++ b/drupal/config/sync/core.entity_form_display.node.article.default.yml @@ -0,0 +1,77 @@ +uuid: 5b678a15-4711-4865-baee-4a0e45be1a7e +langcode: en +status: true +dependencies: + config: + - field.field.node.article.body + - node.type.article + module: + - path + - text +id: node.article.default +targetEntityType: node +bundle: article +mode: default +content: + body: + type: text_textarea_with_summary + weight: 121 + settings: + rows: 9 + summary_rows: 3 + placeholder: '' + show_summary: false + third_party_settings: { } + region: content + created: + type: datetime_timestamp + weight: 10 + region: content + settings: { } + third_party_settings: { } + path: + type: path + weight: 30 + region: content + settings: { } + third_party_settings: { } + promote: + type: boolean_checkbox + settings: + display_label: true + weight: 15 + region: content + third_party_settings: { } + status: + type: boolean_checkbox + settings: + display_label: true + weight: 120 + region: content + third_party_settings: { } + sticky: + type: boolean_checkbox + settings: + display_label: true + weight: 16 + region: content + third_party_settings: { } + title: + type: string_textfield + weight: -5 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + uid: + type: entity_reference_autocomplete + weight: 5 + settings: + match_operator: CONTAINS + size: 60 + placeholder: '' + match_limit: 10 + region: content + third_party_settings: { } +hidden: { } diff --git a/drupal/config/sync/core.entity_form_display.node.landing_page.default.yml b/drupal/config/sync/core.entity_form_display.node.landing_page.default.yml index c071192..b21a587 100644 --- a/drupal/config/sync/core.entity_form_display.node.landing_page.default.yml +++ b/drupal/config/sync/core.entity_form_display.node.landing_page.default.yml @@ -3,7 +3,6 @@ langcode: en status: true dependencies: config: - - field.field.node.landing_page.field_blocks - field.field.node.landing_page.layout_builder__layout - node.type.landing_page module: @@ -21,16 +20,6 @@ content: region: content settings: { } third_party_settings: { } - field_blocks: - weight: 121 - settings: - match_operator: CONTAINS - match_limit: 10 - size: 60 - placeholder: '' - third_party_settings: { } - type: entity_reference_autocomplete - region: content path: type: path weight: 30 diff --git a/drupal/config/sync/core.entity_form_display.paragraph.cta.default.yml b/drupal/config/sync/core.entity_form_display.paragraph.cta.default.yml new file mode 100644 index 0000000..5762103 --- /dev/null +++ b/drupal/config/sync/core.entity_form_display.paragraph.cta.default.yml @@ -0,0 +1,29 @@ +uuid: 5ce73bd9-cfaf-4bdd-9b6d-dcfe549b2dde +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.cta.field_file_link + - paragraphs.paragraphs_type.cta + module: + - paragraphs +id: paragraph.cta.default +targetEntityType: paragraph +bundle: cta +mode: default +content: + field_file_link: + type: entity_reference_paragraphs + weight: 0 + settings: + title: Paragraph + title_plural: Paragraphs + edit_mode: open + add_mode: dropdown + form_display_mode: default + default_paragraph_type: '' + third_party_settings: { } + region: content +hidden: + created: true + status: true diff --git a/drupal/config/sync/core.entity_form_display.paragraph.file.default.yml b/drupal/config/sync/core.entity_form_display.paragraph.file.default.yml new file mode 100644 index 0000000..e0ac152 --- /dev/null +++ b/drupal/config/sync/core.entity_form_display.paragraph.file.default.yml @@ -0,0 +1,24 @@ +uuid: 278f2ebe-7a2c-471a-8afa-1fc04b140f74 +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.file.field_file + - paragraphs.paragraphs_type.file + module: + - media_library +id: paragraph.file.default +targetEntityType: paragraph +bundle: file +mode: default +content: + field_file: + type: media_library_widget + weight: 0 + settings: + media_types: { } + third_party_settings: { } + region: content +hidden: + created: true + status: true diff --git a/drupal/config/sync/core.entity_form_display.paragraph.link.default.yml b/drupal/config/sync/core.entity_form_display.paragraph.link.default.yml new file mode 100644 index 0000000..771c32d --- /dev/null +++ b/drupal/config/sync/core.entity_form_display.paragraph.link.default.yml @@ -0,0 +1,25 @@ +uuid: 4ffdbd28-cd16-4c74-8fdc-15e3c99b2565 +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.link.field_link + - paragraphs.paragraphs_type.link + module: + - link +id: paragraph.link.default +targetEntityType: paragraph +bundle: link +mode: default +content: + field_link: + weight: 0 + settings: + placeholder_url: '' + placeholder_title: '' + third_party_settings: { } + type: link_default + region: content +hidden: + created: true + status: true diff --git a/drupal/config/sync/core.entity_view_display.block_content.card.default.yml b/drupal/config/sync/core.entity_view_display.block_content.card.default.yml new file mode 100644 index 0000000..451e88e --- /dev/null +++ b/drupal/config/sync/core.entity_view_display.block_content.card.default.yml @@ -0,0 +1,53 @@ +uuid: 68d110bf-9cb4-45ea-800f-e8b23ef991f6 +langcode: en +status: true +dependencies: + config: + - block_content.type.card + - field.field.block_content.card.body + - field.field.block_content.card.field_cta + - field.field.block_content.card.field_image + - field.field.block_content.card.field_link + module: + - entity_reference_revisions + - text +id: block_content.card.default +targetEntityType: block_content +bundle: card +mode: default +content: + body: + label: hidden + type: text_default + weight: 0 + settings: { } + third_party_settings: { } + region: content + field_cta: + type: entity_reference_revisions_entity_view + weight: 2 + label: above + settings: + view_mode: default + link: '' + third_party_settings: { } + region: content + field_image: + type: entity_reference_entity_view + weight: 1 + label: above + settings: + view_mode: default + link: false + third_party_settings: { } + region: content + field_link: + type: entity_reference_revisions_entity_view + weight: 3 + label: above + settings: + view_mode: default + link: '' + third_party_settings: { } + region: content +hidden: { } diff --git a/drupal/config/sync/core.entity_view_display.node.article.default.yml b/drupal/config/sync/core.entity_view_display.node.article.default.yml new file mode 100644 index 0000000..0fb944a --- /dev/null +++ b/drupal/config/sync/core.entity_view_display.node.article.default.yml @@ -0,0 +1,28 @@ +uuid: 220ed13a-5386-4182-8a14-bc4ffbb2c818 +langcode: en +status: true +dependencies: + config: + - field.field.node.article.body + - node.type.article + module: + - text + - user +id: node.article.default +targetEntityType: node +bundle: article +mode: default +content: + body: + label: hidden + type: text_default + weight: 101 + settings: { } + third_party_settings: { } + region: content + links: + weight: 100 + settings: { } + third_party_settings: { } + region: content +hidden: { } diff --git a/drupal/config/sync/core.entity_view_display.node.article.teaser.yml b/drupal/config/sync/core.entity_view_display.node.article.teaser.yml new file mode 100644 index 0000000..d1bfde2 --- /dev/null +++ b/drupal/config/sync/core.entity_view_display.node.article.teaser.yml @@ -0,0 +1,30 @@ +uuid: c61423db-0c90-4ec6-a984-02ab07c254d1 +langcode: en +status: true +dependencies: + config: + - core.entity_view_mode.node.teaser + - field.field.node.article.body + - node.type.article + module: + - text + - user +id: node.article.teaser +targetEntityType: node +bundle: article +mode: teaser +content: + body: + label: hidden + type: text_summary_or_trimmed + weight: 101 + settings: + trim_length: 600 + third_party_settings: { } + region: content + links: + weight: 100 + settings: { } + third_party_settings: { } + region: content +hidden: { } diff --git a/drupal/config/sync/core.entity_view_display.node.landing_page.default.yml b/drupal/config/sync/core.entity_view_display.node.landing_page.default.yml index c028625..4b9d71d 100644 --- a/drupal/config/sync/core.entity_view_display.node.landing_page.default.yml +++ b/drupal/config/sync/core.entity_view_display.node.landing_page.default.yml @@ -3,7 +3,6 @@ langcode: en status: true dependencies: config: - - field.field.node.landing_page.field_blocks - field.field.node.landing_page.layout_builder__layout - node.type.landing_page module: @@ -27,14 +26,6 @@ targetEntityType: node bundle: landing_page mode: default content: - field_blocks: - weight: 101 - label: above - settings: - link: true - third_party_settings: { } - type: entity_reference_label - region: content links: weight: 100 settings: { } diff --git a/drupal/config/sync/core.entity_view_display.node.landing_page.full.yml b/drupal/config/sync/core.entity_view_display.node.landing_page.full.yml index 428e0fa..24753cb 100644 --- a/drupal/config/sync/core.entity_view_display.node.landing_page.full.yml +++ b/drupal/config/sync/core.entity_view_display.node.landing_page.full.yml @@ -4,7 +4,6 @@ status: true dependencies: config: - core.entity_view_mode.node.full - - field.field.node.landing_page.field_blocks - field.field.node.landing_page.layout_builder__layout - node.type.landing_page module: @@ -34,5 +33,4 @@ content: third_party_settings: { } region: content hidden: - field_blocks: true layout_builder__layout: true diff --git a/drupal/config/sync/core.entity_view_display.node.landing_page.teaser.yml b/drupal/config/sync/core.entity_view_display.node.landing_page.teaser.yml index cc20d73..f0c4acf 100644 --- a/drupal/config/sync/core.entity_view_display.node.landing_page.teaser.yml +++ b/drupal/config/sync/core.entity_view_display.node.landing_page.teaser.yml @@ -4,7 +4,6 @@ status: false dependencies: config: - core.entity_view_mode.node.teaser - - field.field.node.landing_page.field_blocks - field.field.node.landing_page.layout_builder__layout - node.type.landing_page module: @@ -22,5 +21,4 @@ content: third_party_settings: { } region: content hidden: - field_blocks: true layout_builder__layout: true diff --git a/drupal/config/sync/core.entity_view_display.paragraph.cta.default.yml b/drupal/config/sync/core.entity_view_display.paragraph.cta.default.yml new file mode 100644 index 0000000..3a4d902 --- /dev/null +++ b/drupal/config/sync/core.entity_view_display.paragraph.cta.default.yml @@ -0,0 +1,24 @@ +uuid: c2161d99-f3bc-4502-a33f-2ff8732d23c7 +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.cta.field_file_link + - paragraphs.paragraphs_type.cta + module: + - entity_reference_revisions +id: paragraph.cta.default +targetEntityType: paragraph +bundle: cta +mode: default +content: + field_file_link: + type: entity_reference_revisions_entity_view + weight: 0 + label: above + settings: + view_mode: default + link: '' + third_party_settings: { } + region: content +hidden: { } diff --git a/drupal/config/sync/core.entity_view_display.paragraph.file.default.yml b/drupal/config/sync/core.entity_view_display.paragraph.file.default.yml new file mode 100644 index 0000000..906aa6d --- /dev/null +++ b/drupal/config/sync/core.entity_view_display.paragraph.file.default.yml @@ -0,0 +1,22 @@ +uuid: 949468a8-48fd-4804-8c3f-e79abaa9799e +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.file.field_file + - paragraphs.paragraphs_type.file +id: paragraph.file.default +targetEntityType: paragraph +bundle: file +mode: default +content: + field_file: + type: entity_reference_entity_view + weight: 0 + label: above + settings: + view_mode: default + link: false + third_party_settings: { } + region: content +hidden: { } diff --git a/drupal/config/sync/core.entity_view_display.paragraph.link.default.yml b/drupal/config/sync/core.entity_view_display.paragraph.link.default.yml new file mode 100644 index 0000000..0ef55f3 --- /dev/null +++ b/drupal/config/sync/core.entity_view_display.paragraph.link.default.yml @@ -0,0 +1,27 @@ +uuid: 1ea23abc-7c91-438c-a7eb-453efc47f707 +langcode: en +status: true +dependencies: + config: + - field.field.paragraph.link.field_link + - paragraphs.paragraphs_type.link + module: + - link +id: paragraph.link.default +targetEntityType: paragraph +bundle: link +mode: default +content: + field_link: + weight: 0 + label: above + settings: + trim_length: 80 + url_only: false + url_plain: false + rel: '' + target: '' + third_party_settings: { } + type: link + region: content +hidden: { } diff --git a/drupal/config/sync/core.entity_view_mode.paragraph.preview.yml b/drupal/config/sync/core.entity_view_mode.paragraph.preview.yml new file mode 100644 index 0000000..928a252 --- /dev/null +++ b/drupal/config/sync/core.entity_view_mode.paragraph.preview.yml @@ -0,0 +1,12 @@ +uuid: 78d9bb88-072f-484b-8196-353f6a1aaa59 +langcode: en +status: true +dependencies: + module: + - paragraphs +_core: + default_config_hash: h3BeHVei4Lnyqbkao3YiF4KqoY-DhRvUNfEgKG8Rgjg +id: paragraph.preview +label: Preview +targetEntityType: paragraph +cache: true diff --git a/drupal/config/sync/core.extension.yml b/drupal/config/sync/core.extension.yml index 3ec2055..d416296 100644 --- a/drupal/config/sync/core.extension.yml +++ b/drupal/config/sync/core.extension.yml @@ -24,6 +24,7 @@ module: file: 0 filter: 0 focal_point: 0 + graphql: 0 image: 0 image_style_quality: 0 inline_form_errors: 0 @@ -33,6 +34,7 @@ module: layout_builder_iframe_modal: 0 layout_discovery: 0 link: 0 + manati_graphql: 0 manati_landing_pages: 0 manati_layout_builder: 0 media: 0 @@ -65,6 +67,7 @@ module: token: 0 toolbar: 0 twig_tweak: 0 + typed_data: 0 update: 0 user: 0 xmlsitemap_engines: 0 diff --git a/drupal/config/sync/field.field.block_content.card.body.yml b/drupal/config/sync/field.field.block_content.card.body.yml new file mode 100644 index 0000000..247091b --- /dev/null +++ b/drupal/config/sync/field.field.block_content.card.body.yml @@ -0,0 +1,23 @@ +uuid: d9810406-914a-46e5-843a-625c042e7cb3 +langcode: en +status: true +dependencies: + config: + - block_content.type.card + - field.storage.block_content.body + module: + - text +id: block_content.card.body +field_name: body +entity_type: block_content +bundle: card +label: Body +description: '' +required: false +translatable: true +default_value: { } +default_value_callback: '' +settings: + display_summary: false + required_summary: false +field_type: text_with_summary diff --git a/drupal/config/sync/field.field.block_content.card.field_cta.yml b/drupal/config/sync/field.field.block_content.card.field_cta.yml new file mode 100644 index 0000000..4cc7ca4 --- /dev/null +++ b/drupal/config/sync/field.field.block_content.card.field_cta.yml @@ -0,0 +1,37 @@ +uuid: 95fcda10-d042-4be0-9a8f-e8ded0ca7dc1 +langcode: en +status: true +dependencies: + config: + - block_content.type.card + - field.storage.block_content.field_cta + - paragraphs.paragraphs_type.cta + module: + - entity_reference_revisions +id: block_content.card.field_cta +field_name: field_cta +entity_type: block_content +bundle: card +label: CTA +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:paragraph' + handler_settings: + negate: 0 + target_bundles: + cta: cta + target_bundles_drag_drop: + cta: + enabled: true + weight: 4 + file: + weight: 5 + enabled: false + link: + weight: 6 + enabled: false +field_type: entity_reference_revisions diff --git a/drupal/config/sync/field.field.block_content.card.field_image.yml b/drupal/config/sync/field.field.block_content.card.field_image.yml new file mode 100644 index 0000000..4bfea2a --- /dev/null +++ b/drupal/config/sync/field.field.block_content.card.field_image.yml @@ -0,0 +1,28 @@ +uuid: a0163cb0-6ca0-49ef-a8e0-55f09d714a31 +langcode: en +status: true +dependencies: + config: + - block_content.type.card + - field.storage.block_content.field_image + - media.type.image +id: block_content.card.field_image +field_name: field_image +entity_type: block_content +bundle: card +label: Image +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:media' + handler_settings: + target_bundles: + image: image + sort: + field: _none + auto_create: false + auto_create_bundle: '' +field_type: entity_reference diff --git a/drupal/config/sync/field.field.block_content.card.field_link.yml b/drupal/config/sync/field.field.block_content.card.field_link.yml new file mode 100644 index 0000000..f739aaf --- /dev/null +++ b/drupal/config/sync/field.field.block_content.card.field_link.yml @@ -0,0 +1,37 @@ +uuid: 54070d39-6337-4f84-9ea1-2c30de38f560 +langcode: en +status: true +dependencies: + config: + - block_content.type.card + - field.storage.block_content.field_link + - paragraphs.paragraphs_type.link + module: + - entity_reference_revisions +id: block_content.card.field_link +field_name: field_link +entity_type: block_content +bundle: card +label: Link +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:paragraph' + handler_settings: + negate: 0 + target_bundles: + link: link + target_bundles_drag_drop: + cta: + weight: 4 + enabled: false + file: + weight: 5 + enabled: false + link: + enabled: true + weight: 6 +field_type: entity_reference_revisions diff --git a/drupal/config/sync/field.field.node.article.body.yml b/drupal/config/sync/field.field.node.article.body.yml new file mode 100644 index 0000000..66073e7 --- /dev/null +++ b/drupal/config/sync/field.field.node.article.body.yml @@ -0,0 +1,23 @@ +uuid: 03c196e3-bcb6-4a28-acdd-c87e6f966629 +langcode: en +status: true +dependencies: + config: + - field.storage.node.body + - node.type.article + module: + - text +id: node.article.body +field_name: body +entity_type: node +bundle: article +label: Body +description: '' +required: false +translatable: true +default_value: { } +default_value_callback: '' +settings: + display_summary: true + required_summary: false +field_type: text_with_summary diff --git a/drupal/config/sync/field.field.node.landing_page.field_blocks.yml b/drupal/config/sync/field.field.node.landing_page.field_blocks.yml deleted file mode 100644 index 94afef6..0000000 --- a/drupal/config/sync/field.field.node.landing_page.field_blocks.yml +++ /dev/null @@ -1,25 +0,0 @@ -uuid: 2a31d91a-17f2-4068-8cbb-70bcd1bd6d75 -langcode: en -status: true -dependencies: - config: - - field.storage.node.field_blocks - - node.type.landing_page -id: node.landing_page.field_blocks -field_name: field_blocks -entity_type: node -bundle: landing_page -label: Blocks -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - handler: views - handler_settings: - view: - view_name: non_reusable_blocks - display_name: entity_reference_1 - arguments: { } -field_type: entity_reference diff --git a/drupal/config/sync/field.field.paragraph.cta.field_file_link.yml b/drupal/config/sync/field.field.paragraph.cta.field_file_link.yml new file mode 100644 index 0000000..c211d9d --- /dev/null +++ b/drupal/config/sync/field.field.paragraph.cta.field_file_link.yml @@ -0,0 +1,39 @@ +uuid: be858eca-3223-4ad8-badb-61de977cc302 +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.field_file_link + - paragraphs.paragraphs_type.cta + - paragraphs.paragraphs_type.file + - paragraphs.paragraphs_type.link + module: + - entity_reference_revisions +id: paragraph.cta.field_file_link +field_name: field_file_link +entity_type: paragraph +bundle: cta +label: 'File or link' +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:paragraph' + handler_settings: + negate: 0 + target_bundles: + file: file + link: link + target_bundles_drag_drop: + cta: + weight: 4 + enabled: false + file: + enabled: true + weight: 5 + link: + enabled: true + weight: 6 +field_type: entity_reference_revisions diff --git a/drupal/config/sync/field.field.paragraph.file.field_file.yml b/drupal/config/sync/field.field.paragraph.file.field_file.yml new file mode 100644 index 0000000..ce858b4 --- /dev/null +++ b/drupal/config/sync/field.field.paragraph.file.field_file.yml @@ -0,0 +1,28 @@ +uuid: 0b821ccf-5a0b-4365-9f1e-8916eb38a5f0 +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.field_file + - media.type.file + - paragraphs.paragraphs_type.file +id: paragraph.file.field_file +field_name: field_file +entity_type: paragraph +bundle: file +label: File +description: '' +required: true +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:media' + handler_settings: + target_bundles: + file: file + sort: + field: _none + auto_create: false + auto_create_bundle: '' +field_type: entity_reference diff --git a/drupal/config/sync/field.field.paragraph.link.field_link.yml b/drupal/config/sync/field.field.paragraph.link.field_link.yml new file mode 100644 index 0000000..3a06e23 --- /dev/null +++ b/drupal/config/sync/field.field.paragraph.link.field_link.yml @@ -0,0 +1,23 @@ +uuid: 03985a60-b53e-4ad1-a4da-8c78e788d725 +langcode: en +status: true +dependencies: + config: + - field.storage.paragraph.field_link + - paragraphs.paragraphs_type.link + module: + - link +id: paragraph.link.field_link +field_name: field_link +entity_type: paragraph +bundle: link +label: Link +description: '' +required: true +translatable: false +default_value: { } +default_value_callback: '' +settings: + link_type: 17 + title: 1 +field_type: link diff --git a/drupal/config/sync/field.storage.block_content.field_cta.yml b/drupal/config/sync/field.storage.block_content.field_cta.yml new file mode 100644 index 0000000..b36cfb7 --- /dev/null +++ b/drupal/config/sync/field.storage.block_content.field_cta.yml @@ -0,0 +1,21 @@ +uuid: 011ca828-5c35-4902-b251-ffd16a30f9d4 +langcode: en +status: true +dependencies: + module: + - block_content + - entity_reference_revisions + - paragraphs +id: block_content.field_cta +field_name: field_cta +entity_type: block_content +type: entity_reference_revisions +settings: + target_type: paragraph +module: entity_reference_revisions +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/drupal/config/sync/field.storage.node.field_blocks.yml b/drupal/config/sync/field.storage.block_content.field_image.yml similarity index 55% rename from drupal/config/sync/field.storage.node.field_blocks.yml rename to drupal/config/sync/field.storage.block_content.field_image.yml index 2c47c6a..dc0db79 100644 --- a/drupal/config/sync/field.storage.node.field_blocks.yml +++ b/drupal/config/sync/field.storage.block_content.field_image.yml @@ -1,19 +1,19 @@ -uuid: ba30c73c-928f-4dbc-a0fb-12a41c2a2a00 +uuid: 43007ce4-1859-4325-88e0-9bdcc8511a71 langcode: en status: true dependencies: module: - block_content - - node -id: node.field_blocks -field_name: field_blocks -entity_type: node + - media +id: block_content.field_image +field_name: field_image +entity_type: block_content type: entity_reference settings: - target_type: block_content + target_type: media module: core locked: false -cardinality: -1 +cardinality: 1 translatable: true indexes: { } persist_with_no_fields: false diff --git a/drupal/config/sync/field.storage.block_content.field_link.yml b/drupal/config/sync/field.storage.block_content.field_link.yml new file mode 100644 index 0000000..6933b88 --- /dev/null +++ b/drupal/config/sync/field.storage.block_content.field_link.yml @@ -0,0 +1,21 @@ +uuid: 3e5ce74a-8043-4bfb-8af7-a549642edf7d +langcode: en +status: true +dependencies: + module: + - block_content + - entity_reference_revisions + - paragraphs +id: block_content.field_link +field_name: field_link +entity_type: block_content +type: entity_reference_revisions +settings: + target_type: paragraph +module: entity_reference_revisions +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/drupal/config/sync/field.storage.paragraph.field_file.yml b/drupal/config/sync/field.storage.paragraph.field_file.yml new file mode 100644 index 0000000..6d82fb1 --- /dev/null +++ b/drupal/config/sync/field.storage.paragraph.field_file.yml @@ -0,0 +1,20 @@ +uuid: ba353fce-fd12-4c60-b5bf-0862f4dddc67 +langcode: en +status: true +dependencies: + module: + - media + - paragraphs +id: paragraph.field_file +field_name: field_file +entity_type: paragraph +type: entity_reference +settings: + target_type: media +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/drupal/config/sync/field.storage.paragraph.field_file_link.yml b/drupal/config/sync/field.storage.paragraph.field_file_link.yml new file mode 100644 index 0000000..58702c4 --- /dev/null +++ b/drupal/config/sync/field.storage.paragraph.field_file_link.yml @@ -0,0 +1,20 @@ +uuid: d0129c33-cf28-40f6-9d23-143994b4dea3 +langcode: en +status: true +dependencies: + module: + - entity_reference_revisions + - paragraphs +id: paragraph.field_file_link +field_name: field_file_link +entity_type: paragraph +type: entity_reference_revisions +settings: + target_type: paragraph +module: entity_reference_revisions +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/drupal/config/sync/field.storage.paragraph.field_link.yml b/drupal/config/sync/field.storage.paragraph.field_link.yml new file mode 100644 index 0000000..47c8369 --- /dev/null +++ b/drupal/config/sync/field.storage.paragraph.field_link.yml @@ -0,0 +1,19 @@ +uuid: eef4ba80-0225-4dc6-824c-e19f8361d310 +langcode: en +status: true +dependencies: + module: + - link + - paragraphs +id: paragraph.field_link +field_name: field_link +entity_type: paragraph +type: link +settings: { } +module: link +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/drupal/config/sync/graphql.graphql_servers.graphql_server.yml b/drupal/config/sync/graphql.graphql_servers.graphql_server.yml new file mode 100644 index 0000000..c644dda --- /dev/null +++ b/drupal/config/sync/graphql.graphql_servers.graphql_server.yml @@ -0,0 +1,16 @@ +uuid: 6491ba3a-d90a-45eb-a9fd-dbf5451ca97e +langcode: en +status: true +dependencies: { } +name: graphql_server +label: 'Graphql Server' +schema: manati +schema_configuration: + composable: + extensions: + manati_extension: manati_extension +persisted_queries_settings: { } +endpoint: /graphql +debug_flag: 0 +caching: true +batching: true diff --git a/drupal/config/sync/layout_builder_browser.layout_builder_browser_block.card.yml b/drupal/config/sync/layout_builder_browser.layout_builder_browser_block.card.yml new file mode 100644 index 0000000..1ecab53 --- /dev/null +++ b/drupal/config/sync/layout_builder_browser.layout_builder_browser_block.card.yml @@ -0,0 +1,11 @@ +uuid: 7a16d682-624b-403e-b3e0-698e7f3b247a +langcode: en +status: true +dependencies: { } +id: card +block_id: 'inline_block:card' +category: components +label: Card +weight: null +image_path: '' +image_alt: '' diff --git a/drupal/config/sync/node.type.article.yml b/drupal/config/sync/node.type.article.yml new file mode 100644 index 0000000..5a73a6b --- /dev/null +++ b/drupal/config/sync/node.type.article.yml @@ -0,0 +1,17 @@ +uuid: 0c16cad1-0f97-4f14-a738-117d431a503e +langcode: en +status: true +dependencies: + module: + - menu_ui +third_party_settings: + menu_ui: + available_menus: { } + parent: '' +name: Article +type: article +description: '' +help: '' +new_revision: true +preview_mode: 1 +display_submitted: false diff --git a/drupal/config/sync/paragraphs.paragraphs_type.cta.yml b/drupal/config/sync/paragraphs.paragraphs_type.cta.yml new file mode 100644 index 0000000..e7e05eb --- /dev/null +++ b/drupal/config/sync/paragraphs.paragraphs_type.cta.yml @@ -0,0 +1,10 @@ +uuid: d7929983-419f-4b13-bbf8-2b339fb31a1c +langcode: en +status: true +dependencies: { } +id: cta +label: CTA +icon_uuid: null +icon_default: null +description: '' +behavior_plugins: { } diff --git a/drupal/config/sync/paragraphs.paragraphs_type.file.yml b/drupal/config/sync/paragraphs.paragraphs_type.file.yml new file mode 100644 index 0000000..56d7c12 --- /dev/null +++ b/drupal/config/sync/paragraphs.paragraphs_type.file.yml @@ -0,0 +1,10 @@ +uuid: be1a0f54-eb06-4a7d-aee5-cf23a2674485 +langcode: en +status: true +dependencies: { } +id: file +label: File +icon_uuid: null +icon_default: null +description: '' +behavior_plugins: { } diff --git a/drupal/config/sync/paragraphs.paragraphs_type.link.yml b/drupal/config/sync/paragraphs.paragraphs_type.link.yml new file mode 100644 index 0000000..003d5a7 --- /dev/null +++ b/drupal/config/sync/paragraphs.paragraphs_type.link.yml @@ -0,0 +1,10 @@ +uuid: ca8234ff-4ac0-401d-962a-5a3919c142ab +langcode: en +status: true +dependencies: { } +id: link +label: Link +icon_uuid: null +icon_default: null +description: '' +behavior_plugins: { } diff --git a/drupal/config/sync/paragraphs.settings.yml b/drupal/config/sync/paragraphs.settings.yml new file mode 100644 index 0000000..cafb409 --- /dev/null +++ b/drupal/config/sync/paragraphs.settings.yml @@ -0,0 +1,3 @@ +show_unpublished: true +_core: + default_config_hash: 7eR0sk71Eol86r_A7BMqn5_46wzenh5J1O5vZRCGKv8 diff --git a/drupal/docker-compose.override.yml b/drupal/docker-compose.override.yml index dbad809..deb61ea 100644 --- a/drupal/docker-compose.override.yml +++ b/drupal/docker-compose.override.yml @@ -1,6 +1,6 @@ version: "3.6" -# services: -# solr: -# volumes: -# - '../../../../solr/config:/config' +services: + solr: + volumes: + - '../../../../solr/config:/config' diff --git a/drupal/modules/custom/manati_graphql/graphql/manati.graphqls b/drupal/modules/custom/manati_graphql/graphql/manati.graphqls new file mode 100644 index 0000000..dc3763b --- /dev/null +++ b/drupal/modules/custom/manati_graphql/graphql/manati.graphqls @@ -0,0 +1,161 @@ +schema { + query: Query +} + +type Query { + landingPage(id: Int!): LandingPage + landingPages( + offset: Int = 0 + limit: Int = 10 + ): LandingPageConnection! + drupalConfig( + configFile: String! + configKey: String! + ): [DrupalConfig]! + search( + fulltext: FulltextInput + range: RangeInput + conditions: [ConditionInput] + conditionGroup: ConditionGroupInput + sort: [SortInput] + languages: [String] + solrParams: [SolrParameterInput] + ): [SearchNode] + terms(vocabulary: String!): [Term] +} + + +type SearchNode { + total: Int! + items: [NodeInterface]! +} + +input RangeInput { + offset: Int! + limit: Int! +} + +input SortInput { + field: String! + value: String! +} + +input FulltextInput { + keys: [String]! + fields: [String] + conjunction: String +} + +input ConditionInput { + name: String! + value: String + operator: String + +} + +input ConditionGroupInput { + conditions: [ConditionInput] + groups: [ConditionGroupInput] + tags: [String] + conjunction: String +} + +input SolrParameterInput { + parameter: String! + value: String! +} + +type Term { + id: ID! + name: String! + children: [Term] +} + +interface NodeInterface { + id: Int! + title: String! + type: String! +} + +type LandingPage implements NodeInterface { + id: Int! + title: String! + type: String! + sections: [Section] +} + + +type Article implements NodeInterface { + id: Int! + title: String! + type: String! +} + +type LandingPageConnection { + total: Int! + items: [LandingPage!] +} + +type Section { + section_id: String! + variant: String + background: String + column_proportions: String + spacing_top: String + spacing_bottom: String + spacing_columns: String + equal_height: Int + side_spacing: Int + components: [Component] +} + +type Component { + region: String! + uuid: String! + type: String! + block: LayoutBuilderBlock +} + +interface LayoutBuilderBlock { + uuid: String! + label: String! +} + +type BasicBlock implements LayoutBuilderBlock { + uuid: String! + label: String! + body: String + field_title: String +} + +type Card implements LayoutBuilderBlock { + uuid: String! + label: String! + body: String + field_image: [MediaBlock] +} + +interface MediaBlock { + id: Int! +} + +type MediaBlockImage implements MediaBlock { + id: Int! + alt: String + file: [File] +} + +type MediaBlockFile implements MediaBlock { + id: Int! + file: [File] +} + +type File { + url: String + name: String +} + +type DrupalConfig { + name: String + value: String +} diff --git a/drupal/modules/custom/manati_graphql/graphql/manati_extension.base.graphqls b/drupal/modules/custom/manati_graphql/graphql/manati_extension.base.graphqls new file mode 100644 index 0000000..e69de29 diff --git a/drupal/modules/custom/manati_graphql/graphql/manati_extension.extension.graphqls b/drupal/modules/custom/manati_graphql/graphql/manati_extension.extension.graphqls new file mode 100644 index 0000000..e69de29 diff --git a/drupal/modules/custom/manati_graphql/manati_graphql.info.yml b/drupal/modules/custom/manati_graphql/manati_graphql.info.yml new file mode 100644 index 0000000..0e6accd --- /dev/null +++ b/drupal/modules/custom/manati_graphql/manati_graphql.info.yml @@ -0,0 +1,9 @@ +name: Manati GraphQL +type: module +description: Main module for Manati +package: MANATI +core: 8.x +core_version_requirement: ^8 || ^9 +dependencies: + - graphql:graphql + - node:node diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/Config/QueryDrupalConfig.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/Config/QueryDrupalConfig.php new file mode 100644 index 0000000..02083ab --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/Config/QueryDrupalConfig.php @@ -0,0 +1,99 @@ +configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('config.factory') + ); + } + + /** + * Undocumented function. + */ + public function resolve($config_file, $config_key) { + $config = $this->configFactory->get($config_file)->get($config_key); + $result = []; + if (empty($config)) { + return $result; + } + if (is_array($config)) { + foreach ($config as $key => $value) { + $result[] = [ + 'name' => $key, + 'value' => $value, + ]; + } + } + else { + $result[] = [ + 'name' => $config_key, + 'value' => $config, + ]; + } + + return $result; + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LandingPage/QueryLandingPages.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LandingPage/QueryLandingPages.php new file mode 100644 index 0000000..99c9ed5 --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LandingPage/QueryLandingPages.php @@ -0,0 +1,107 @@ +get('entity_type.manager') + ); + } + + /** + * Articles constructor. + * + * @param array $configuration + * The plugin configuration. + * @param string $pluginId + * The plugin id. + * @param mixed $pluginDefinition + * The plugin definition. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * Undocumented function. + * + * @codeCoverageIgnore + */ + public function __construct( + array $configuration, + $pluginId, + $pluginDefinition, + EntityTypeManagerInterface $entityTypeManager + ) { + parent::__construct($configuration, $pluginId, $pluginDefinition); + $this->entityTypeManager = $entityTypeManager; + } + + /** + * Undocumented function. + */ + public function resolve($offset, $limit, RefinableCacheableDependencyInterface $metadata) { + if ($limit > static::MAX_LIMIT) { + throw new UserError(sprintf('Exceeded maximum query limit: %s.', static::MAX_LIMIT)); + } + + $storage = $this->entityTypeManager->getStorage('node'); + $entityType = $storage->getEntityType(); + $query = $storage->getQuery() + ->currentRevision() + ->accessCheck(); + + $query->condition($entityType->getKey('bundle'), 'landing_page'); + $query->range($offset, $limit); + + $metadata->addCacheTags($entityType->getListCacheTags()); + $metadata->addCacheContexts($entityType->getListCacheContexts()); + + return new QueryConnection($query); + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/BlockEntityReference.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/BlockEntityReference.php new file mode 100644 index 0000000..c5696ab --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/BlockEntityReference.php @@ -0,0 +1,195 @@ +get('entity_type.manager'), + $container->get('entity.repository'), + $container->get('graphql.buffer.entity') + ); + } + + /** + * EntityLoad constructor. + * + * @param array $configuration + * The plugin configuration array. + * @param string $pluginId + * The plugin id. + * @param array $pluginDefinition + * The plugin definition array. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager service. + * @param \Drupal\Core\Entity\EntityRepositoryInterface $entityRepository + * The entity repository service. + * @param \Drupal\graphql\GraphQL\Buffers\EntityBuffer $entityBuffer + * The entity buffer service. + * + * @codeCoverageIgnore + */ + public function __construct( + array $configuration, + $pluginId, + array $pluginDefinition, + EntityTypeManagerInterface $entityTypeManager, + EntityRepositoryInterface $entityRepository, + EntityBuffer $entityBuffer + ) { + parent::__construct($configuration, $pluginId, $pluginDefinition); + $this->entityTypeManager = $entityTypeManager; + $this->entityRepository = $entityRepository; + $this->entityBuffer = $entityBuffer; + } + + /** + * Undocumented function. + */ + public function resolve(EntityInterface $entity, $field, ?string $language, ?array $bundles, ?bool $access, ?AccountInterface $accessUser, ?string $accessOperation, FieldContext $context) { + if (!$entity instanceof BlockContent || !$entity->$field) { + return NULL; + } + + $definition = $entity->getFieldDefinition($field); + $type = $definition->getSetting('target_type'); + $values = $entity->get($field); + if ($values instanceof EntityReferenceFieldItemListInterface) { + $ids = array_map(function ($value) { + return $value['target_id']; + }, $values->getValue()); + + $resolver = $this->entityBuffer->add($type, $ids); + return new Deferred(function () use ($type, $language, $bundles, $access, $accessUser, $accessOperation, $resolver, $context) { + $entities = $resolver() ?: []; + $entities = array_filter($entities, function (EntityInterface $entity) use ($language, $bundles, $access, $accessOperation, $accessUser, $context) { + if (isset($bundles) && !in_array($entity->bundle(), $bundles)) { + return FALSE; + } + + // Get the correct translation. + if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) { + $entity = $entity->getTranslation($language); + $entity->addCacheContexts(["static:language:{$language}"]); + } + + // Check if the passed user (or current user if none is passed) has + // access to the entity, if not return NULL. + if ($access) { + /** @var \Drupal\Core\Access\AccessResultInterface $accessResult */ + $accessResult = $entity->access($accessOperation, $accessUser, TRUE); + $context->addCacheableDependency($accessResult); + if (!$accessResult->isAllowed()) { + return FALSE; + } + } + + return TRUE; + }); + + if (empty($entities)) { + $type = $this->entityTypeManager->getDefinition($type); + /** @var \Drupal\Core\Entity\EntityTypeInterface $type */ + $tags = $type->getListCacheTags(); + $context->addCacheTags($tags); + return NULL; + } + + return $entities; + }); + + } + + return NULL; + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/FormattedText.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/FormattedText.php new file mode 100644 index 0000000..ce1dda1 --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/FormattedText.php @@ -0,0 +1,40 @@ +$field)) { + return $entity->$field->processed; + } + return NULL; + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/PlainText.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/PlainText.php new file mode 100644 index 0000000..9ca96ff --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Blocks/Fields/PlainText.php @@ -0,0 +1,40 @@ +$field)) { + return $entity->$field->value; + } + return NULL; + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentRegion.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentRegion.php new file mode 100644 index 0000000..f82104c --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentRegion.php @@ -0,0 +1,34 @@ +getRegion(); + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentType.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentType.php new file mode 100644 index 0000000..f540f11 --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentType.php @@ -0,0 +1,34 @@ +getPlugin()->getConfiguration()['type']; + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentUuid.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentUuid.php new file mode 100644 index 0000000..0842a3d --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/ComponentUuid.php @@ -0,0 +1,34 @@ +getPlugin()->getConfiguration()['uuid']; + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/Components.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/Components.php new file mode 100644 index 0000000..c010baf --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Components/Components.php @@ -0,0 +1,37 @@ +getComponents(); + foreach ($components as $component) { + yield $component; + } + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/SectionField.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/SectionField.php new file mode 100644 index 0000000..d75d079 --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/SectionField.php @@ -0,0 +1,42 @@ +getLayoutSettings()[$field])) { + return $section->getLayoutSettings()[$field]; + } + else { + return NULL; + } + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/SectionId.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/SectionId.php new file mode 100644 index 0000000..c488d8e --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/SectionId.php @@ -0,0 +1,34 @@ +getLayoutId(); + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/Sections.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/Sections.php new file mode 100644 index 0000000..a77a034 --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/LayoutBuilder/Sections/Sections.php @@ -0,0 +1,46 @@ +hasField('layout_builder__layout')) { + $layout = $entity->get('layout_builder__layout'); + $sections = $layout->getIterator(); + + foreach ($sections as $item) { + $section = $item->section; + yield $section; + } + } + else { + return NULL; + } + + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/SearchApi/QuerySearchApiSearch.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/SearchApi/QuerySearchApiSearch.php new file mode 100644 index 0000000..9422b27 --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/DataProducer/SearchApi/QuerySearchApiSearch.php @@ -0,0 +1,322 @@ +get('entity_type.manager'), + $container->get('logger.factory') + ); + } + + /** + * Articles constructor. + * + * @param array $configuration + * The plugin configuration. + * @param string $pluginId + * The plugin id. + * @param mixed $pluginDefinition + * The plugin definition. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * Undocumented function. + * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger + * Undocumented function. + * + * @codeCoverageIgnore + */ + public function __construct( + array $configuration, + $pluginId, + $pluginDefinition, + EntityTypeManagerInterface $entityTypeManager, + LoggerChannelFactoryInterface $logger + ) { + parent::__construct($configuration, $pluginId, $pluginDefinition); + $this->entityTypeManager = $entityTypeManager; + $this->logger = $logger; + } + + /** + * Undocumented function. + */ + public function resolve(string $index_id, $range, $fulltext, $conditions, $condition_group, $sort, $languages, $solr_params) { + // Load up the index passed in argument. + $this->index = $this->entityTypeManager->getStorage('search_api_index')->load($index_id); + + // Prepare the query with our arguments. + $this->prepareSearchQuery($range, $fulltext, $conditions, $condition_group, $sort, $languages, $solr_params); + + // Execute search. + try { + $results = $this->query->execute(); + } + // Handle error, check exception type -> SearchApiException ? + catch (\Exception $exception) { + $this->logger->get('graphql')->error($exception->getMessage()); + } + + // Load all entities at once, for better performance. + $results->preLoadResultItems(); + $result_entities = array_map(static function (ItemInterface $item) { + return $item->getOriginalObject()->getValue(); + }, $results->getResultItems()); + + // Initialise response array. + $search_response = []; + + // Get search response from results. + $search_response['items'] = $result_entities; + + // Add the result count to the response. + $search_response['total'] = $results->getResultCount(); + + yield $search_response; + } + + /** + * Prepares the Search API query by adding all possible options. + * + * Options include conditions, language, fulltext, range, sort and facets. + * + * @args + * The arguments containing all the parameters to be loaded to the query. + */ + private function prepareSearchQuery($range, $fulltext, $conditions, $condition_group, $sort, $languages, $solr_params) { + + // Prepare a query for the respective Search API index. + $this->query = $this->index->query(); + + // Adding query conditions if they exist. + if ($conditions) { + $this->addConditions($conditions); + } + // Adding query group conditions if they exist. + if ($condition_group) { + $this->addConditionGroup($condition_group); + } + // Adding Solr specific parameters if they exist. + if ($solr_params) { + $this->addSolrParams($solr_params); + } + // Restrict the search to specific languages. + if ($languages) { + $this->query->setLanguages($languages); + } + // Set fulltext search parameters in the query. + if ($fulltext) { + $this->setFulltextFields($fulltext); + } + // Adding range parameters to the query (e.g for pagination). + if ($range) { + $this->query->range($range['offset'], $range['limit']); + } + // Adding sort parameters to the query. + if ($sort) { + foreach ($sort as $sort_item) { + $this->query->sort($sort_item['field'], $sort_item['value']); + } + } + + } + + /** + * Adds conditions to the Search API query. + * + * @conditions + * The conditions to be added. + */ + private function addConditions($conditions) { + // Loop through conditions to add them into the query. + foreach ($conditions as $condition) { + if (empty($condition['operator'])) { + $condition['operator'] = '='; + } + if ($condition['value'] == 'NULL') { + $condition['value'] = NULL; + } + // Set the condition in the query. + $this->query->addCondition($condition['name'], $condition['value'], $condition['operator']); + } + + } + + /** + * Adds a condition group to the Search API query. + * + * @condition_group + * The conditions to be added. + */ + private function addConditionGroup($condition_group) { + // Loop through the groups in the args. + foreach ($condition_group['groups'] as $group) { + + // Set default conjunction and tags. + $group_conjunction = 'AND'; + $group_tags = []; + + // Set conjunction from args. + if (isset($group['conjunction'])) { + + $group_conjunction = $group['conjunction']; + } + if (isset($group['tags'])) { + $group_tags = $group['tags']; + } + + // Create a single condition group. + $condition_group = $this->query->createConditionGroup($group_conjunction, $group_tags); + + // Loop through all conditions and add them to the Group. + foreach ($group['conditions'] as $condition) { + + $condition_group->addCondition($condition['name'], $condition['value'], $condition['operator']); + } + + // Merge the single groups to the condition group. + $this->query->addConditionGroup($condition_group); + } + + } + + /** + * Adds direct Solr parameters to the Search API query. + * + * @params + * The conditions to be added. + */ + private function addSolrParams($params) { + // Loop through conditions to add them into the query. + foreach ($params as $param) { + // Set the condition in the query. + $this->query->setOption('solr_param_' . $param['parameter'], $param['value']); + } + + } + + /** + * Sets fulltext fields in the Search API query. + * + * @fulltext + * Parameters containing fulltext keywords to be used as well as optional + * fields. + */ + private function setFulltextFields($fulltext) { + // Check if keys is an array and if so set a conjunction. + if (is_array($fulltext['keys'])) { + // If no conjunction was specified use OR as default. + if (!empty($fulltext['conjunction'])) { + $fulltext['keys']['#conjunction'] = $fulltext['conjunction']; + } + else { + $fulltext['keys']['#conjunction'] = 'OR'; + } + } + + // Set the keys in the query. + $this->query->keys($fulltext['keys']); + + // Set the optional fulltext fields if specified. + if (!empty($fulltext['fields'])) { + $this->query->setFulltextFields($fulltext['fields']); + } + + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/Schema/ManatiSchema.php b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/Schema/ManatiSchema.php new file mode 100644 index 0000000..f6f3637 --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Plugin/GraphQL/Schema/ManatiSchema.php @@ -0,0 +1,437 @@ +addQueryFields($registry, $builder); + // $this->addSearchFields($registry, $builder); + $this->addLandingPageFields($registry, $builder); + $this->addTermFields($registry, $builder); + $this->addArticleFields($registry, $builder); + $this->addSectionFields($registry, $builder); + $this->addComponentFields($registry, $builder); + $this->addLayoutBuilderBlockTypeResolver($registry); + $this->addMediaBlockTypeResolver($registry); + $this->addNodeInterfaceTypeResolver($registry); + $this->addBasicBlockFields($registry, $builder); + $this->addCardFields($registry, $builder); + $this->addMediaBlockImageFields($registry, $builder); + $this->addFileFields($registry, $builder); + // $this->addParagraphFields($registry, $builder); + // $this->addMediaFileFields($registry, $builder); + // Re-usable connection type fields. + $this->addConnectionFields('LandingPageConnection', $registry, $builder); + + return $registry; + } + + /** + * Undocumented function. + */ + protected function addQueryFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('Query', 'landingPage', + $builder->produce('entity_load') + ->map('type', $builder->fromValue('node')) + ->map('bundles', $builder->fromValue(['landing_page'])) + ->map('id', $builder->fromArgument('id')) + ); + + $registry->addFieldResolver('Query', 'landingPages', + $builder->produce('query_landing_pages') + ->map('offset', $builder->fromArgument('offset')) + ->map('limit', $builder->fromArgument('limit')) + ); + + $registry->addFieldResolver('Query', 'terms', + $builder->produce('taxonomy_load_tree') + ->map('vid', $builder->fromArgument('vocabulary')) + ->map('parent', $builder->fromValue(0)) + ->map('max_depth', $builder->fromValue(1)) + ); + + $registry->addFieldResolver('Query', 'drupalConfig', + $builder->produce('query_drupal_config') + ->map('config_file', $builder->fromArgument('configFile')) + ->map('config_key', $builder->fromArgument('configKey')) + ); + + $registry->addFieldResolver('Query', 'search', + $builder->produce('query_search_api_search') + ->map('index_id', $builder->fromValue('main_index')) + ->map('range', $builder->fromArgument('range')) + ->map('sort', $builder->fromArgument('sort')) + ->map('fulltext', $builder->fromArgument('fulltext')) + ->map('conditions', $builder->fromArgument('conditions')) + ->map('languages', $builder->fromArgument('languages')) + ->map('solr_params', $builder->fromArgument('solrParams')) + ->map('condition_group', $builder->fromArgument('conditionGroup')) + ); + + } + + /** + * Undocumented function. + */ + protected function addLandingPageFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('LandingPage', 'id', + $builder->produce('entity_id') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('LandingPage', 'title', + $builder->compose( + $builder->produce('entity_label') + ->map('entity', $builder->fromParent()) + ) + ); + + $registry->addFieldResolver('LandingPage', 'type', + $builder->compose( + $builder->produce('entity_bundle') + ->map('entity', $builder->fromParent()) + ) + ); + + $registry->addFieldResolver('LandingPage', 'sections', + $builder->compose( + $builder->produce('layout_sections') + ->map('entity', $builder->fromParent()) + ) + ); + + } + + /** + * Undocumented function. + */ + protected function addTermFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('Term', 'id', + $builder->produce('entity_id') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('Term', 'name', + $builder->compose( + $builder->produce('entity_label') + ->map('entity', $builder->fromParent()) + ) + ); + + $registry->addFieldResolver('Term', 'children', + $builder->compose( + $builder->produce('taxonomy_load_tree') + ->map('vid', $builder->produce('entity_bundle') + ->map('entity', $builder->fromParent())) + ->map('parent', $builder->produce('entity_id') + ->map('entity', $builder->fromParent())) + ->map('max_depth', $builder->fromValue(1)) + ) + ); + + } + + /** + * Undocumented function. + */ + protected function addArticleFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('Article', 'id', + $builder->produce('entity_id') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('Article', 'title', + $builder->compose( + $builder->produce('entity_label') + ->map('entity', $builder->fromParent()) + ) + ); + + $registry->addFieldResolver('Article', 'type', + $builder->compose( + $builder->produce('entity_bundle') + ->map('entity', $builder->fromParent()) + ) + ); + + } + + /** + * Undocumented function. + */ + protected function addSectionFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('Section', 'section_id', + $builder->produce('section_id') + ->map('section', $builder->fromParent()) + ); + + $registry->addFieldResolver('Section', 'variant', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('variant')) + ); + + $registry->addFieldResolver('Section', 'background', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('background')) + ); + + $registry->addFieldResolver('Section', 'column_proportions', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('column_proportions')) + ); + + $registry->addFieldResolver('Section', 'spacing_top', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('spacing_top')) + ); + + $registry->addFieldResolver('Section', 'spacing_bottom', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('spacing_bottom')) + ); + + $registry->addFieldResolver('Section', 'spacing_columns', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('spacing_columns')) + ); + + $registry->addFieldResolver('Section', 'equal_height', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('equal_height')) + ); + + $registry->addFieldResolver('Section', 'side_spacing', + $builder->produce('section_field') + ->map('section', $builder->fromParent()) + ->map('field', $builder->fromValue('side_spacing')) + ); + + $registry->addFieldResolver('Section', 'components', + $builder->produce('section_components') + ->map('section', $builder->fromParent()) + ); + } + + /** + * Undocumented function. + */ + protected function addComponentFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('Component', 'region', + $builder->produce('component_region') + ->map('component', $builder->fromParent()) + ); + + $registry->addFieldResolver('Component', 'type', + $builder->produce('component_type') + ->map('component', $builder->fromParent()) + ); + + $registry->addFieldResolver('Component', 'uuid', + $builder->produce('component_uuid') + ->map('component', $builder->fromParent()) + ); + + $registry->addFieldResolver('Component', 'block', + $builder->produce('entity_load_by_uuid') + ->map('type', $builder->fromValue('block_content')) + ->map('bundle', $builder->produce('component_type') + ->map('component', $builder->fromParent())) + ->map('uuid', $builder->produce('component_uuid') + ->map('component', $builder->fromParent())) + + ); + } + + /** + * Undocumented function. + */ + protected function addNodeInterfaceTypeResolver(ResolverRegistry $registry) { + // Tell GraphQL how to resolve the NodeInterface interface. + $registry->addTypeResolver('NodeInterface', function ($entity) { + if ($entity instanceof NodeInterface) { + switch ($entity->bundle()) { + case 'landing_page': + return 'LandingPage'; + + case 'article': + return 'Article'; + } + + } + throw new Error('Could not resolve content type.'); + }); + } + + /** + * Undocumented function. + */ + protected function addLayoutBuilderBlockTypeResolver(ResolverRegistry $registry) { + // Tell GraphQL how to resolve the LayoutBuilderBlock interface. + $registry->addTypeResolver('LayoutBuilderBlock', function ($entity) { + if ($entity instanceof BlockContentInterface) { + switch ($entity->bundle()) { + case 'basic_block': + return 'BasicBlock'; + + case 'card': + return 'Card'; + } + + } + throw new Error('Could not resolve content type.'); + }); + } + + /** + * Undocumented function. + */ + protected function addMediaBlockTypeResolver(ResolverRegistry $registry) { + // Tell GraphQL how to resolve the MediaBlock interface. + $registry->addTypeResolver('MediaBlock', function ($entity) { + if ($entity instanceof MediaInterface) { + switch ($entity->bundle()) { + case 'image': + return 'MediaBlockImage'; + + case 'file': + return 'MediaBlockFile'; + } + + } + throw new Error('Could not resolve content type.'); + }); + } + + /** + * Undocumented function. + */ + protected function addBasicBlockFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('BasicBlock', 'id', + $builder->produce('entity_id') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('BasicBlock', 'label', + $builder->produce('entity_label') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('BasicBlock', 'field_title', + $builder->produce('block_plain_text') + ->map('entity', $builder->fromParent()) + ->map('field', $builder->fromValue('field_title')) + ); + + $registry->addFieldResolver('BasicBlock', 'body', + $builder->produce('block_formatted_text') + ->map('entity', $builder->fromParent()) + ->map('field', $builder->fromValue('body')) + ); + } + + /** + * Undocumented function. + */ + protected function addCardFields(ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver('Card', 'label', + $builder->produce('entity_label') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('Card', 'id', + $builder->produce('entity_id') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('Card', 'body', + $builder->produce('block_formatted_text') + ->map('entity', $builder->fromParent()) + ->map('field', $builder->fromValue('body')) + ); + + $registry->addFieldResolver('Card', 'field_image', + $builder->produce('block_entity_reference') + ->map('entity', $builder->fromParent()) + ->map('field', $builder->fromValue('field_image')) + ); + } + + /** + * Undocumented function. + */ + protected function addMediaBlockImageFields(ResolverRegistry $registry, ResolverBuilder $builder) { + + $registry->addFieldResolver('MediaBlockImage', 'id', + $builder->produce('entity_id') + ->map('entity', $builder->fromParent()) + ); + + $registry->addFieldResolver('MediaBlockImage', 'file', + $builder->produce('entity_reference') + ->map('entity', $builder->fromParent()) + ->map('field', $builder->fromValue('field_media_image')) + ); + + } + + /** + * Undocumented function. + */ + protected function addFileFields(ResolverRegistry $registry, ResolverBuilder $builder) { + + $registry->addFieldResolver('File', 'url', + $builder->produce('image_url') + ->map('entity', $builder->fromParent()) + ); + + } + + /** + * Undocumented function. + */ + protected function addConnectionFields($type, ResolverRegistry $registry, ResolverBuilder $builder) { + $registry->addFieldResolver($type, 'total', + $builder->callback(function (QueryConnection $connection) { + return $connection->total(); + }) + ); + + $registry->addFieldResolver($type, 'items', + $builder->callback(function (QueryConnection $connection) { + return $connection->items(); + }) + ); + } + +} diff --git a/drupal/modules/custom/manati_graphql/src/Wrappers/QueryConnection.php b/drupal/modules/custom/manati_graphql/src/Wrappers/QueryConnection.php new file mode 100644 index 0000000..bcf335b --- /dev/null +++ b/drupal/modules/custom/manati_graphql/src/Wrappers/QueryConnection.php @@ -0,0 +1,52 @@ +query = $query; + } + + /** + * Undocumented function. + */ + public function total() { + $query = clone $this->query; + $query->range(NULL, NULL)->count(); + return $query->execute(); + } + + /** + * Undocumented function. + */ + public function items() { + $result = $this->query->execute(); + if (empty($result)) { + return []; + } + + $buffer = \Drupal::service('graphql.buffer.entity'); + $callback = $buffer->add($this->query->getEntityTypeId(), array_values($result)); + return new Deferred(function () use ($callback) { + return $callback(); + }); + } + +} diff --git a/drupal/modules/custom/manati_landing_pages/manati_landing_pages.module b/drupal/modules/custom/manati_landing_pages/manati_landing_pages.module index 1a058bc..cc3df9c 100644 --- a/drupal/modules/custom/manati_landing_pages/manati_landing_pages.module +++ b/drupal/modules/custom/manati_landing_pages/manati_landing_pages.module @@ -8,44 +8,3 @@ * This file is no longer required in Drupal 8. * @see https://www.drupal.org/node/2217931 */ - -use Drupal\Core\Entity\EntityInterface; - -/** - * Implements hook_form_alter(). - */ -function manati_landing_pages_form_alter(&$form, &$form_state, $form_id) { - $forms = ['node_landing_page_form', 'node_landing_page_edit_form']; - if (in_array($form_id, $forms)) { - // Hide field_blocks field. - $form['field_blocks']['#access'] = FALSE; - } -} - -/** - * Implements hook_ENTITY_TYPE_insert(). - */ -function manati_landing_pages_node_update(EntityInterface $node) { - if ($node->bundle() === 'landing_page') { - $block_ids = []; - foreach ($node->layout_builder__layout->getSections() as $section) { - foreach ($section->getComponents() as $component) { - $block = \Drupal::entityTypeManager()->getStorage('block_content')->loadRevision($component->get('configuration')['block_revision_id']); - $block_ids[] = [ - 'target_id' => $block->id(), - ]; - } - } - $node->field_blocks = $block_ids; - drupal_register_shutdown_function('_manati_landing_pages_post_update', $node); - } -} - -/** - * Helper function for save the node. - */ -function _manati_landing_pages_post_update($node) { - if ($node) { - $node->save(); - } -}