diff --git a/src/Plugin/GraphQL/DataProducer/WebformRenderElement.php b/src/Plugin/GraphQL/DataProducer/WebformRenderElement.php new file mode 100644 index 0000000000000000000000000000000000000000..ab4a17109350b75b8113b99f8421f3ccae4bb410 --- /dev/null +++ b/src/Plugin/GraphQL/DataProducer/WebformRenderElement.php @@ -0,0 +1,83 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\graphql_webform\Plugin\GraphQL\DataProducer; + +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Render\RendererInterface; +use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Renders a Webform element. + * + * @DataProducer( + * id = "webform_render_element", + * name = @Translation("Webform render element"), + * description = @Translation("Renders the Webform element."), + * produces = @ContextDefinition("any", + * label = @Translation("Rendered Webform element"), + * ), + * consumes = { + * "element" = @ContextDefinition("any", + * label = @Translation("Webform element as a render array"), + * ) + * } + * ) + */ +class WebformRenderElement extends DataProducerPluginBase implements ContainerFactoryPluginInterface { + + /** + * Constructs a new WebformRenderElement data producer. + * + * @param array $configuration + * The plugin configuration. + * @param string $pluginId + * The plugin ID. + * @param mixed $pluginDefinition + * The plugin definition. + * @param \Drupal\Core\Render\RendererInterface $renderer + * The renderer. + */ + public function __construct( + array $configuration, + $pluginId, + $pluginDefinition, + protected RendererInterface $renderer, + ) { + parent::__construct($configuration, $pluginId, $pluginDefinition); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('renderer') + ); + } + + /** + * Renders the Webform element. + * + * @param array $element + * The Webform element as a render array. + * + * @return string + * The rendered Webform element. + */ + public function resolve(array $element): string { + // The Webform module is wrapping its elements in the 'form_element' theme + // wrapper since it is designed to show its forms in the Drupal theming + // layer. Remove the wrapper to render the element as a standalone element. + if (!empty($element['#theme_wrappers'])) { + $element['#theme_wrappers'] = array_diff($element['#theme_wrappers'], ['form_element']); + } + return (string) $this->renderer->renderPlain($element); + } + +} diff --git a/src/Plugin/GraphQL/SchemaExtension/WebformExtension.php b/src/Plugin/GraphQL/SchemaExtension/WebformExtension.php index 0bea7251427f75c934c21dde2938257f74845849..1de7bb2feb85dea4c8d381a14b4b46085e45d126 100644 --- a/src/Plugin/GraphQL/SchemaExtension/WebformExtension.php +++ b/src/Plugin/GraphQL/SchemaExtension/WebformExtension.php @@ -206,6 +206,12 @@ class WebformExtension extends SdlSchemaExtensionPluginBase { fn (array $value) => (WebformElementDisplayOn::tryFrom($value['#display_on'] ?? '') ?? WebformElementDisplayOn::DISPLAY_ON_FORM)->name )); + // WebformElementProcessedText markup. + $registry->addFieldResolver('WebformElementProcessedText', 'markup', $builder + ->produce('webform_render_element') + ->map('element', $builder->fromParent()) + ); + // Expose information about elements that accept multiple values. $registry->addFieldResolver('WebformElementMultipleValuesBase', 'multipleValues', $builder ->produce('webform_element_multiple_values') diff --git a/tests/modules/graphql_webform_test/config/install/webform.webform.graphql_webform_test_form.yml b/tests/modules/graphql_webform_test/config/install/webform.webform.graphql_webform_test_form.yml index 35310f6680e27de96f94c19e5d50f2b79a1097b9..a12d2aeab8c7a10008af7a5213b55fce53b07074 100644 --- a/tests/modules/graphql_webform_test/config/install/webform.webform.graphql_webform_test_form.yml +++ b/tests/modules/graphql_webform_test/config/install/webform.webform.graphql_webform_test_form.yml @@ -126,6 +126,11 @@ elements: |- '#multiple__min_items': 2 '#multiple__add_more_button_label': 'I want more' '#multiple__add_more_items': 2 + processed_text: + '#type': processed_text + '#display_on': both + '#text': '<p><strong><em>Processed text</em></strong></p>' + '#format': basic_html actions: '#type': webform_actions '#title': 'Submit button(s)' diff --git a/tests/queries/markup.gql b/tests/queries/markup.gql index a1a50d2c63be6bebe37b9d93e3e303d706007d72..27af61eae67f30cca31f1903157b3149bc597edc 100644 --- a/tests/queries/markup.gql +++ b/tests/queries/markup.gql @@ -1,6 +1,5 @@ -fragment webformElementMarkup on WebformElementWebformMarkup { +fragment webformElementMarkup on WebformElementMarkupBase { __typename - key markup displayOn } diff --git a/tests/src/Kernel/Element/MarkupTest.php b/tests/src/Kernel/Element/MarkupTest.php index 8e41bc0e6230c3dd3b51a9734f3fd1cf1ebaaac1..77ec7ac012e740936b6d7e17790b94abd2d7fab4 100644 --- a/tests/src/Kernel/Element/MarkupTest.php +++ b/tests/src/Kernel/Element/MarkupTest.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Drupal\Tests\graphql_webform\Kernel\Element; +use Drupal\filter\Entity\FilterFormat; use Drupal\Tests\graphql_webform\Kernel\GraphQLWebformKernelTestBase; /** @@ -13,6 +14,37 @@ use Drupal\Tests\graphql_webform\Kernel\GraphQLWebformKernelTestBase; */ class MarkupTest extends GraphQLWebformKernelTestBase { + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'filter', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + // Create a filter format for testing the processed text. We only allow the + // '<strong>' and '<p>' tags. The markup in the test Webform also contains + // the <em> tag, which should be stripped out in the query result. + FilterFormat::create([ + 'format' => 'basic_html', + 'name' => 'Basic HTML', + 'weight' => 1, + 'filters' => [ + 'filter_html' => [ + 'status' => 1, + 'settings' => [ + 'allowed_html' => '<strong><p>', + ], + ], + ], + ])->save(); + } + /** * Tests custom markup. */ @@ -24,10 +56,15 @@ class MarkupTest extends GraphQLWebformKernelTestBase { 'elements' => [ 5 => [ '__typename' => 'WebformElementWebformMarkup', - 'key' => 'markup', 'markup' => '<strong>Markup</strong>', 'displayOn' => 'DISPLAY_ON_FORM', ], + 14 => [ + '__typename' => 'WebformElementProcessedText', + // The '<em>' tag should be stripped out. + 'markup' => '<p><strong>Processed text</strong></p>', + 'displayOn' => 'DISPLAY_ON_BOTH', + ], ], ], ], $this->defaultCacheMetaData()); diff --git a/tests/src/Kernel/GraphQLWebformKernelTestBase.php b/tests/src/Kernel/GraphQLWebformKernelTestBase.php index 846a4f4198b37c8a85ca322e50985f8ab30fa851..ced2a267054dcb9fd3dd61af2a08834d23911850 100644 --- a/tests/src/Kernel/GraphQLWebformKernelTestBase.php +++ b/tests/src/Kernel/GraphQLWebformKernelTestBase.php @@ -62,6 +62,7 @@ abstract class GraphQLWebformKernelTestBase extends GraphQLTestBase { protected function setUp(): void { parent::setUp(); + $this->installEntitySchema('path_alias'); $this->installSchema('webform', ['webform']); $this->installConfig(['webform', 'graphql_webform_test']);