@amazeelabs/silverback-gatsby 3.7.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/drupal/silverback_gatsby/.prettierignore +1 -0
  3. package/drupal/silverback_gatsby/CHANGELOG.md +1216 -0
  4. package/drupal/silverback_gatsby/README.md +297 -0
  5. package/drupal/silverback_gatsby/composer.json +15 -0
  6. package/drupal/silverback_gatsby/directives.gql +63 -0
  7. package/drupal/silverback_gatsby/directives.graphql +62 -0
  8. package/drupal/silverback_gatsby/drush.services.yml +9 -0
  9. package/drupal/silverback_gatsby/graphql/entity.directive.graphqls +2 -0
  10. package/drupal/silverback_gatsby/graphql/menu.directive.graphqls +17 -0
  11. package/drupal/silverback_gatsby/graphql/silverback_gatsby.base.graphqls +25 -0
  12. package/drupal/silverback_gatsby/graphql/silverback_gatsby.extension.graphqls +10 -0
  13. package/drupal/silverback_gatsby/graphql/stringTranslation.directive.graphqls +4 -0
  14. package/drupal/silverback_gatsby/graphql/translatableString.directive.graphqls +2 -0
  15. package/drupal/silverback_gatsby/modules/silverback_gatsby_example/directives.gql +6 -0
  16. package/drupal/silverback_gatsby/modules/silverback_gatsby_example/graphql/.graphqlrc.json +4 -0
  17. package/drupal/silverback_gatsby/modules/silverback_gatsby_example/graphql/silverback_gatsby_example.graphqls +39 -0
  18. package/drupal/silverback_gatsby/modules/silverback_gatsby_example/silverback_gatsby_example.info.yml +7 -0
  19. package/drupal/silverback_gatsby/modules/silverback_gatsby_example/silverback_gatsby_example.module +16 -0
  20. package/drupal/silverback_gatsby/modules/silverback_gatsby_example/src/Directives.php +24 -0
  21. package/drupal/silverback_gatsby/silverback_gatsby.info.yml +8 -0
  22. package/drupal/silverback_gatsby/silverback_gatsby.install +180 -0
  23. package/drupal/silverback_gatsby/silverback_gatsby.links.task.yml +6 -0
  24. package/drupal/silverback_gatsby/silverback_gatsby.module +119 -0
  25. package/drupal/silverback_gatsby/silverback_gatsby.permissions.yml +8 -0
  26. package/drupal/silverback_gatsby/silverback_gatsby.post_update.php +15 -0
  27. package/drupal/silverback_gatsby/silverback_gatsby.routing.yml +28 -0
  28. package/drupal/silverback_gatsby/silverback_gatsby.services.yml +50 -0
  29. package/drupal/silverback_gatsby/src/Annotation/GatsbyFeed.php +41 -0
  30. package/drupal/silverback_gatsby/src/Commands/SilverbackGatsbyCommands.php +102 -0
  31. package/drupal/silverback_gatsby/src/Controller/BuildController.php +45 -0
  32. package/drupal/silverback_gatsby/src/Controller/PublisherController.php +34 -0
  33. package/drupal/silverback_gatsby/src/Directives.php +51 -0
  34. package/drupal/silverback_gatsby/src/GatsbyBuildTrigger.php +230 -0
  35. package/drupal/silverback_gatsby/src/GatsbyBuildTriggerInterface.php +52 -0
  36. package/drupal/silverback_gatsby/src/GatsbyUpdate.php +38 -0
  37. package/drupal/silverback_gatsby/src/GatsbyUpdateHandler.php +181 -0
  38. package/drupal/silverback_gatsby/src/GatsbyUpdateTracker.php +98 -0
  39. package/drupal/silverback_gatsby/src/GatsbyUpdateTrackerInterface.php +59 -0
  40. package/drupal/silverback_gatsby/src/GatsbyUpdateTrigger.php +69 -0
  41. package/drupal/silverback_gatsby/src/GatsbyUpdateTriggerInterface.php +22 -0
  42. package/drupal/silverback_gatsby/src/GraphQL/Build.php +235 -0
  43. package/drupal/silverback_gatsby/src/GraphQL/ComposableSchema.php +73 -0
  44. package/drupal/silverback_gatsby/src/LocaleStorageDecorator.php +181 -0
  45. package/drupal/silverback_gatsby/src/MenuTreeStorageDecorator.php +139 -0
  46. package/drupal/silverback_gatsby/src/Plugin/FeedBase.php +121 -0
  47. package/drupal/silverback_gatsby/src/Plugin/FeedInterface.php +132 -0
  48. package/drupal/silverback_gatsby/src/Plugin/FeedPluginManager.php +39 -0
  49. package/drupal/silverback_gatsby/src/Plugin/Gatsby/Feed/EntityFeed.php +252 -0
  50. package/drupal/silverback_gatsby/src/Plugin/Gatsby/Feed/MenuFeed.php +292 -0
  51. package/drupal/silverback_gatsby/src/Plugin/Gatsby/Feed/StringTranslationFeed.php +171 -0
  52. package/drupal/silverback_gatsby/src/Plugin/Gatsby/Feed/TranslatableStringFeed.php +128 -0
  53. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/CurrentUserEntity.php +43 -0
  54. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/EntityQueryBase.php +40 -0
  55. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/FetchEntity.php +371 -0
  56. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/FetchString.php +64 -0
  57. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/FetchTranslatableString.php +74 -0
  58. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/FocalPoint.php +47 -0
  59. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/GatsbyBuildId.php +36 -0
  60. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/GatsbyExtractId.php +28 -0
  61. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/GatsbyExtractLangcode.php +28 -0
  62. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/ImageProps.php +149 -0
  63. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/ListEntities.php +88 -0
  64. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/ListStrings.php +87 -0
  65. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/StringId.php +37 -0
  66. package/drupal/silverback_gatsby/src/Plugin/GraphQL/DataProducer/StringTranslations.php +94 -0
  67. package/drupal/silverback_gatsby/src/Plugin/GraphQL/Directive/EntityFetch.php +51 -0
  68. package/drupal/silverback_gatsby/src/Plugin/GraphQL/Directive/EntityTranslationsWithDefault.php +30 -0
  69. package/drupal/silverback_gatsby/src/Plugin/GraphQL/Directive/FocalPoint.php +27 -0
  70. package/drupal/silverback_gatsby/src/Plugin/GraphQL/Directive/ImageProps.php +27 -0
  71. package/drupal/silverback_gatsby/src/Plugin/GraphQL/Directive/MenuLangcode.php +27 -0
  72. package/drupal/silverback_gatsby/src/Plugin/GraphQL/Directive/MenuTranslations.php +36 -0
  73. package/drupal/silverback_gatsby/src/Plugin/GraphQL/Directive/SilverbackGatsbyEntityId.php +39 -0
  74. package/drupal/silverback_gatsby/src/Plugin/GraphQL/SchemaExtension/SilverbackGatsbySchemaExtension.php +384 -0
  75. package/drupal/silverback_gatsby/src/SilverbackGatsbyServiceProvider.php +43 -0
  76. package/drupal/silverback_gatsby/src/SilverbackGatsbySessionConfiguration.php +30 -0
  77. package/drupal/silverback_gatsby/src/SilverbackReverseProxyMiddleware.php +49 -0
  78. package/drupal/silverback_gatsby/tests/queries/create-page-fields.gql +12 -0
  79. package/drupal/silverback_gatsby/tests/queries/current-user.gql +6 -0
  80. package/drupal/silverback_gatsby/tests/queries/feed_info.gql +12 -0
  81. package/drupal/silverback_gatsby/tests/queries/load-entity.gql +5 -0
  82. package/drupal/silverback_gatsby/tests/queries/menus.gql +31 -0
  83. package/drupal/silverback_gatsby/tests/queries/multilingual-menus.gql +11 -0
  84. package/drupal/silverback_gatsby/tests/queries/revisionable-translatable.gql +15 -0
  85. package/drupal/silverback_gatsby/tests/queries/revisionable.gql +8 -0
  86. package/drupal/silverback_gatsby/tests/queries/translatable.gql +14 -0
  87. package/drupal/silverback_gatsby/tests/queries/untranslatable.gql +10 -0
  88. package/drupal/silverback_gatsby/tests/schema/.graphqlrc.json +4 -0
  89. package/drupal/silverback_gatsby/tests/schema/translatable-strings.graphql +7 -0
  90. package/drupal/silverback_gatsby/tests/src/Kernel/CurrentUserTest.php +37 -0
  91. package/drupal/silverback_gatsby/tests/src/Kernel/EntityFeedTest.php +490 -0
  92. package/drupal/silverback_gatsby/tests/src/Kernel/EntityFeedTestBase.php +178 -0
  93. package/drupal/silverback_gatsby/tests/src/Kernel/GatsbyBuildTriggerTest.php +155 -0
  94. package/drupal/silverback_gatsby/tests/src/Kernel/GatsbyFeedInfoTest.php +319 -0
  95. package/drupal/silverback_gatsby/tests/src/Kernel/GatsbyUpdateHandlerTest.php +131 -0
  96. package/drupal/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTrackerTest.php +196 -0
  97. package/drupal/silverback_gatsby/tests/src/Kernel/GatsbyUpdateTriggerTest.php +177 -0
  98. package/drupal/silverback_gatsby/tests/src/Kernel/MenuFeedTest.php +192 -0
  99. package/drupal/silverback_gatsby/tests/src/Kernel/TranslatableStringFeedTest.php +210 -0
  100. package/drupal/silverback_gatsby/tests/src/Traits/NotificationCheckTrait.php +43 -0
  101. package/package.json +15 -0
@@ -0,0 +1,69 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gatsby;
4
+
5
+ use Drupal\Core\Entity\EntityTypeManagerInterface;
6
+ use Drupal\Core\Messenger\MessengerInterface;
7
+ use GuzzleHttp\Client;
8
+
9
+ class GatsbyUpdateTrigger implements GatsbyUpdateTriggerInterface {
10
+
11
+ /**
12
+ * @var \Drupal\silverback_gatsby\GatsbyUpdate[][]
13
+ */
14
+ protected array $updates = [];
15
+
16
+ protected Client $httpClient;
17
+ protected EntityTypeManagerInterface $entityTypeManager;
18
+ protected MessengerInterface $messenger;
19
+
20
+ public function __construct(
21
+ Client $httpClient,
22
+ MessengerInterface $messenger,
23
+ EntityTypeManagerInterface $entityTypeManager
24
+ ) {
25
+ $this->httpClient = $httpClient;
26
+ $this->messenger = $messenger;
27
+ $this->entityTypeManager = $entityTypeManager;
28
+ }
29
+
30
+ protected function getWebhook($server_id) {
31
+ $server = $this->entityTypeManager
32
+ ->getStorage('graphql_server')
33
+ ->load($server_id);
34
+ $schema_id = $server->get('schema');
35
+ if (isset($server->get('schema_configuration')[$schema_id]['update_webhook'])) {
36
+ return $server->get('schema_configuration')[$schema_id]['update_webhook'];
37
+ }
38
+ return NULL;
39
+ }
40
+
41
+ public function trigger(string $server, GatsbyUpdate $update): void {
42
+ // Make sure the shutdown function is registered only once.
43
+ if (!$this->updates) {
44
+ drupal_register_shutdown_function([$this, 'sendUpdates']);
45
+ }
46
+ if ($url = $this->getWebhook($server)) {
47
+ $this->updates[$url][] = $update;
48
+ }
49
+ }
50
+
51
+ public function sendUpdates(): void {
52
+ foreach ($this->updates as $url => $updates) {
53
+ try {
54
+ $this->httpClient->post($url, [
55
+ 'json' => array_map(fn ($update) => [
56
+ 'type' => $update->type,
57
+ 'id' => $update->id,
58
+ ], $updates),
59
+ // It can happen that a request hangs for too long time.
60
+ 'timeout' => 2,
61
+ ]);
62
+ } catch (\Exception $exc) {
63
+ $this->messenger->addError('Could not send build notification to server "' . $url . '".');
64
+ $this->messenger->addError($exc->getMessage());
65
+ }
66
+ }
67
+ }
68
+
69
+ }
@@ -0,0 +1,22 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gatsby;
4
+
5
+ use Drupal\Core\StringTranslation\TranslatableMarkup;
6
+
7
+ interface GatsbyUpdateTriggerInterface {
8
+
9
+ /**
10
+ * Trigger an update for a given server with a type name and entity id.
11
+ *
12
+ * @param string $server
13
+ * The server id.
14
+ * @param \Drupal\silverback_gatsby\GatsbyUpdate $update
15
+ */
16
+ public function trigger(string $server, GatsbyUpdate $update) : void;
17
+
18
+ /**
19
+ * Send out notifications about potential updates to all Gatsby servers.
20
+ */
21
+ public function sendUpdates() : void;
22
+ }
@@ -0,0 +1,235 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gatsby\GraphQL;
4
+
5
+ use Drupal\Component\Plugin\ConfigurableInterface;
6
+ use Drupal\Core\Ajax\AjaxResponse;
7
+ use Drupal\Core\Ajax\HtmlCommand;
8
+ use Drupal\Core\Entity\EntityForm;
9
+ use Drupal\Core\Form\FormStateInterface;
10
+ use Drupal\Core\Form\SubformState;
11
+ use Drupal\Core\Plugin\PluginFormInterface;
12
+ use Drupal\Core\Session\AccountProxyInterface;
13
+ use Drupal\graphql\Plugin\SchemaPluginManager;
14
+ use Drupal\silverback_gatsby\GatsbyBuildTriggerInterface;
15
+ use Symfony\Component\DependencyInjection\ContainerInterface;
16
+
17
+ /**
18
+ * Gatsby build specific configuration of the schema.
19
+ *
20
+ * @package Drupal\silverback_gatsby\GraphQL
21
+ */
22
+ class Build extends EntityForm {
23
+
24
+ /**
25
+ * The schema plugin manager.
26
+ *
27
+ * @var \Drupal\graphql\Plugin\SchemaPluginManager
28
+ */
29
+ protected $schemaManager;
30
+
31
+ /**
32
+ * The Gatsby update trigger.
33
+ *
34
+ * @var \Drupal\silverback_gatsby\GatsbyBuildTriggerInterface
35
+ */
36
+ protected $buildTrigger;
37
+
38
+ /**
39
+ * The current user.
40
+ *
41
+ * @var \Drupal\Core\Session\AccountProxyInterface
42
+ */
43
+ protected $currentUser;
44
+
45
+ /**
46
+ * ServerForm constructor.
47
+ *
48
+ * @param \Drupal\graphql\Plugin\SchemaPluginManager $schemaManager
49
+ * The schema plugin manager.
50
+ *
51
+ * @codeCoverageIgnore
52
+ */
53
+ public function __construct(
54
+ SchemaPluginManager $schemaManager,
55
+ GatsbyBuildTriggerInterface $buildTrigger,
56
+ AccountProxyInterface $currentUser
57
+ ) {
58
+ $this->schemaManager = $schemaManager;
59
+ $this->buildTrigger = $buildTrigger;
60
+ $this->currentUser = $currentUser;
61
+ }
62
+
63
+ /**
64
+ * {@inheritdoc}
65
+ *
66
+ * @codeCoverageIgnore
67
+ */
68
+ public static function create(ContainerInterface $container): self {
69
+ return new static(
70
+ $container->get('plugin.manager.graphql.schema'),
71
+ $container->get('silverback_gatsby.build_trigger'),
72
+ $container->get('current_user')
73
+ );
74
+ }
75
+
76
+ /**
77
+ * {@inheritdoc}
78
+ */
79
+ public function buildForm(
80
+ array $form,
81
+ FormStateInterface $form_state
82
+ ) {
83
+ /** @var \Drupal\graphql\Entity\ServerInterface $server */
84
+ $server = $this->entity;
85
+ $schema = $server->get('schema');
86
+ $enabled = (bool) $this->entity->get('schema_configuration')[$schema]['extensions']['silverback_gatsby'];
87
+ if (!$enabled) {
88
+ $form['message'] = [
89
+ '#type' => 'html_tag',
90
+ '#tag' => 'p',
91
+ '#value' => $this->t('The Gatsby extension is not enabled for this schema.'),
92
+ ];
93
+ return $form;
94
+ }
95
+
96
+ $form = parent::buildForm($form, $form_state);
97
+
98
+ $form['trigger_build'] = [
99
+ '#type' => 'button',
100
+ '#value' => $this->t('Gatsby Build'),
101
+ '#required' => FALSE,
102
+ '#ajax' => [
103
+ 'callback' => [$this, 'gatsbyBuild'],
104
+ ],
105
+ '#suffix' => '<span class="gatsby-build-message"></span>',
106
+ ];
107
+
108
+
109
+ $form['actions']['#access'] = $this->currentUser->hasPermission('administer graphql configuration');
110
+ $form['schema_configuration'] = [
111
+ '#type' => 'container',
112
+ '#access' => $this->currentUser->hasPermission('administer graphql configuration'),
113
+ '#prefix' => '<div id="edit-schema-configuration-plugin-wrapper">',
114
+ '#suffix' => '</div>',
115
+ '#tree' => TRUE,
116
+ ];
117
+
118
+ /** @var \Drupal\graphql\Plugin\SchemaPluginInterface $instance */
119
+ $instance = $schema ? $this->schemaManager->createInstance($schema) : NULL;
120
+ if ($instance instanceof PluginFormInterface && $instance instanceof ConfigurableInterface) {
121
+ $configuration = $server->get('schema_configuration');
122
+ $form['schema_configuration'][$schema] = [
123
+ '#type' => 'fieldset',
124
+ '#title' => $this->t('Build configuration'),
125
+ '#tree' => TRUE,
126
+ ];
127
+
128
+ $buildSettings['build_trigger_on_save'] = [
129
+ '#type' => 'checkbox',
130
+ '#required' => FALSE,
131
+ '#title' => $this->t('Trigger a build on entity save.'),
132
+ '#description' => $this->t('If not checked, make sure to have an alternate build method (cron, manual).'),
133
+ '#default_value' => $configuration[$schema]['build_trigger_on_save'] ?? '',
134
+ ];
135
+ $buildSettings['build_webhook'] = [
136
+ '#type' => 'textfield',
137
+ '#required' => FALSE,
138
+ '#title' => $this->t('Build webhook'),
139
+ '#description' => $this->t('A webhook that will be notified when content changes relevant to this server happen.'),
140
+ '#default_value' => $configuration[$schema]['build_webhook'] ?? '',
141
+ ];
142
+ $buildSettings['update_webhook'] = [
143
+ '#type' => 'textfield',
144
+ '#required' => FALSE,
145
+ '#title' => $this->t('Update webhook'),
146
+ '#description' => $this->t('A webhook to notify clients about realtime data updates.'),
147
+ '#default_value' => $configuration[$schema]['update_webhook'] ?? '',
148
+ ];
149
+ $buildSettings['build_url'] = [
150
+ '#type' => 'url',
151
+ '#required' => FALSE,
152
+ '#title' => $this->t('Build url'),
153
+ '#description' => $this->t('The frontend url that is the result of the build. With the scheme and without a trailing slash (https://www.example.com).'),
154
+ '#default_value' => $configuration[$schema]['build_url'] ?? '',
155
+ ];
156
+ $buildSettings['build_url_netlify_password'] = [
157
+ '#type' => 'textfield',
158
+ '#required' => FALSE,
159
+ '#title' => $this->t('Netlify password for "Build url"'),
160
+ '#description' => $this->t('If "Build url" is hosted on Netlify and is password protected.'),
161
+ '#default_value' => $configuration[$schema]['build_url_netlify_password'] ?? '',
162
+ ];
163
+
164
+ /** @var \Drupal\graphql\Form\ServerForm $formObject */
165
+ $formObject = $form_state->getFormObject();
166
+ /** @var \Drupal\graphql\Entity\Server $server */
167
+ $server = $formObject->getEntity();
168
+
169
+ $buildSettings['user'] = [
170
+ '#type' => 'select',
171
+ '#options' => ['' => $this->t('- None -')],
172
+ '#title' => $this->t('Notification user'),
173
+ '#description' => $this->t('Only changes visible to this user will trigger build updates.'),
174
+ '#default_value' => $configuration[$schema]['user'] ?? '',
175
+ '#states'=> [
176
+ 'required' => [
177
+ ':input[name="schema_configuration[' . $server->schema . '][extensions][silverback_gatsby]"]' => ['checked' => TRUE],
178
+ ],
179
+ ],
180
+ ];
181
+ $users = [];
182
+ /** @var \Drupal\user\UserInterface $user */
183
+ foreach ($this->entityTypeManager->getStorage('user')->loadMultiple() as $user) {
184
+ $users[$user->uuid()] = $user->getAccountName() === '' ? 'Anonymous' : $user->getAccountName();
185
+ }
186
+ natcasesort($users);
187
+ $buildSettings['user']['#options'] += $users;
188
+ $form['schema_configuration'][$schema] += $buildSettings;
189
+ }
190
+ return $form;
191
+ }
192
+
193
+ /**
194
+ * {@inheritdoc}
195
+ */
196
+ public function buildEntity(array $form, FormStateInterface $form_state) {
197
+ $entity = clone $this->entity;
198
+ $entity->schema_configuration[$entity->schema] = array_merge($entity->schema_configuration[$entity->schema], $form_state->getValue('schema_configuration')[$entity->schema]);
199
+ return $entity;
200
+ }
201
+
202
+ /**
203
+ * Gatsby build.
204
+ *
205
+ * @param array $form
206
+ * An associative array containing the structure of the form.
207
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
208
+ * The current state of the form.
209
+ *
210
+ * @return \Drupal\Core\Ajax\AjaxResponse
211
+ * AjaxResponse.
212
+ */
213
+ public function gatsbyBuild(array $form, FormStateInterface $form_state) {
214
+ $response = new AjaxResponse();
215
+ $buildMessage = $this->buildTrigger->triggerLatestBuild($this->entity->id());
216
+ $response->addCommand(new HtmlCommand('.gatsby-build-message', $buildMessage));
217
+ return $response;
218
+ }
219
+
220
+ /**
221
+ * {@inheritdoc}
222
+ *
223
+ * @throws \Drupal\Component\Plugin\Exception\PluginException
224
+ */
225
+ public function save(array $form, FormStateInterface $form_state) {
226
+ $save_result = parent::save($form, $form_state);
227
+ $this->messenger()->addMessage($this->t('Saved the %label server.', [
228
+ '%label' => $this->entity->label(),
229
+ ]));
230
+
231
+ $form_state->setRedirect('entity.graphql_server.collection');
232
+ return $save_result;
233
+ }
234
+
235
+ }
@@ -0,0 +1,73 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gatsby\GraphQL;
4
+
5
+ use Drupal\Component\Plugin\PluginManagerInterface;
6
+ use Drupal\Core\Cache\CacheBackendInterface;
7
+ use Drupal\Core\Entity\EntityTypeManagerInterface;
8
+ use Drupal\Core\Extension\ModuleHandlerInterface;
9
+ use Drupal\Core\Routing\RouteMatchInterface;
10
+ use Drupal\graphql\Plugin\SchemaExtensionPluginManager;
11
+ use Drupal\graphql_directives\DirectivePrinter;
12
+ use Drupal\graphql_directives\Plugin\GraphQL\Schema\DirectableSchema;
13
+ use Symfony\Component\DependencyInjection\ContainerInterface;
14
+
15
+ /**
16
+ * @deprecated Use \Drupal\graphql_directives\Plugin\GraphQL\Schema\DirectableSchema instead.
17
+ *
18
+ * @package Drupal\silverback_gatsby\GraphQL
19
+ */
20
+ class ComposableSchema extends DirectableSchema {
21
+
22
+ protected EntityTypeManagerInterface $entityTypeManager;
23
+ protected RouteMatchInterface $routeMatch;
24
+
25
+ public function __construct(
26
+ array $configuration,
27
+ $pluginId,
28
+ array $pluginDefinition,
29
+ CacheBackendInterface $astCache,
30
+ ModuleHandlerInterface $moduleHandler,
31
+ SchemaExtensionPluginManager $extensionManager,
32
+ ?PluginManagerInterface $directiveManager,
33
+ ?DirectivePrinter $directivePrinter,
34
+ EntityTypeManagerInterface $entityTypeManager,
35
+ RouteMatchInterface $routeMatch,
36
+ array $config
37
+ ) {
38
+ parent::__construct(
39
+ $configuration,
40
+ $pluginId,
41
+ $pluginDefinition,
42
+ $astCache,
43
+ $moduleHandler,
44
+ $extensionManager,
45
+ $directiveManager,
46
+ $directivePrinter,
47
+ $config,
48
+ );
49
+ $this->entityTypeManager = $entityTypeManager;
50
+ $this->routeMatch = $routeMatch;
51
+ }
52
+
53
+ public static function create(
54
+ ContainerInterface $container,
55
+ array $configuration,
56
+ $plugin_id,
57
+ $plugin_definition
58
+ ) {
59
+ return new static(
60
+ $configuration,
61
+ $plugin_id,
62
+ $plugin_definition,
63
+ $container->get('cache.graphql.ast'),
64
+ $container->get('module_handler'),
65
+ $container->get('plugin.manager.graphql.schema_extension'),
66
+ $container->get('graphql_directives.manager'),
67
+ $container->get('graphql_directives.printer'),
68
+ $container->get('entity_type.manager'),
69
+ $container->get('current_route_match'),
70
+ $container->getParameter('graphql.config')
71
+ );
72
+ }
73
+ }
@@ -0,0 +1,181 @@
1
+ <?php
2
+
3
+ namespace Drupal\silverback_gatsby;
4
+
5
+ use Drupal\locale\StringContextInterface;
6
+ use Drupal\locale\StringStorageInterface;
7
+ use Drupal\silverback_gatsby\Plugin\Gatsby\Feed\StringTranslationFeed;
8
+ use Drupal\silverback_gatsby\Plugin\Gatsby\Feed\TranslatableStringFeed;
9
+
10
+ class LocaleStorageDecorator implements StringStorageInterface, StringContextInterface {
11
+
12
+ /**
13
+ * @var \Drupal\locale\StringStorageInterface
14
+ */
15
+ protected StringStorageInterface $subject;
16
+
17
+ /**
18
+ * @var \Drupal\silverback_gatsby\GatsbyUpdateHandler
19
+ */
20
+ protected GatsbyUpdateHandler $updateHandler;
21
+
22
+ /**
23
+ * @param \Drupal\locale\StringStorageInterface $subject
24
+ * The decorated locale storage service.
25
+ */
26
+ public function __construct(
27
+ StringStorageInterface $subject
28
+ ) {
29
+ $this->subject = $subject;
30
+ }
31
+
32
+ /**
33
+ * {@inheritDoc}
34
+ */
35
+ public function getStrings(array $conditions = [], array $options = []) {
36
+ $strings = $this->subject->getStrings($conditions, $options);
37
+ $this->updateStringsStorage($strings);
38
+ return $strings;
39
+ }
40
+
41
+ /**
42
+ * {@inheritDoc}
43
+ */
44
+ public function getTranslations(array $conditions = [], array $options = []) {
45
+ $translations = $this->subject->getTranslations($conditions, $options);
46
+ $this->updateStringsStorage($translations);
47
+ return $translations;
48
+ }
49
+
50
+ /**
51
+ * {@inheritDoc}
52
+ */
53
+ public function getLocations(array $conditions = []) {
54
+ return $this->subject->getLocations($conditions);
55
+ }
56
+
57
+ /**
58
+ * {@inheritDoc}
59
+ */
60
+ public function findString(array $conditions) {
61
+ $string = $this->subject->findString($conditions);
62
+ if (!empty($string)) {
63
+ $string->setStorage($this);
64
+ }
65
+ return $string;
66
+ }
67
+
68
+ /**
69
+ * {@inheritDoc}
70
+ */
71
+ public function findTranslation(array $conditions) {
72
+ $translation = $this->subject->findTranslation($conditions);
73
+ if (!empty($translation)) {
74
+ $translation->setStorage($this);
75
+ }
76
+ return $translation;
77
+ }
78
+
79
+ /**
80
+ * {@inheritDoc}
81
+ */
82
+ public function save($string) {
83
+ $this->subject->save($string);
84
+ $string->setStorage($this);
85
+ // For now, we only track strings which have a context, for performance
86
+ // reasons.
87
+ if (!empty($string->context)) {
88
+ $this->getGatsbyUpdateHandler()->handle(StringTranslationFeed::class, $string);
89
+ $this->getGatsbyUpdateHandler()->handle(TranslatableStringFeed::class, $string);
90
+ }
91
+ return $this;
92
+ }
93
+
94
+ /**
95
+ * {@inheritDoc}
96
+ */
97
+ public function delete($string) {
98
+ // This does not need to trigger a gatsby update handler event since it
99
+ // seems that removing a translation (which means just setting its value to
100
+ // nothing) triggers the save method as well.
101
+ return $this->subject->delete($string);
102
+ }
103
+
104
+ /**
105
+ * {@inheritDoc}
106
+ */
107
+ public function deleteStrings($conditions) {
108
+ return $this->subject->deleteStrings($conditions);
109
+ }
110
+
111
+ /**
112
+ * {@inheritDoc}
113
+ */
114
+ public function deleteTranslations($conditions) {
115
+ return $this->subject->deleteTranslations($conditions);
116
+ }
117
+
118
+ /**
119
+ * {@inheritDoc}
120
+ */
121
+ public function countStrings() {
122
+ return $this->subject->countStrings();
123
+ }
124
+
125
+ /**
126
+ * {@inheritDoc}
127
+ */
128
+ public function countTranslations() {
129
+ return $this->subject->countTranslations();
130
+ }
131
+
132
+ /**
133
+ * {@inheritDoc}
134
+ */
135
+ public function createString($values = []) {
136
+ return $this->subject->createString($values + ['storage' => $this]);
137
+ }
138
+
139
+ /**
140
+ * {@inheritDoc}
141
+ */
142
+ public function createTranslation($values = []) {
143
+ return $this->subject->createTranslation($values + ['storage' => $this]);
144
+ }
145
+
146
+ /**
147
+ * {@inheritDoc}
148
+ */
149
+ public function getContexts(): array {
150
+ if ($this->subject instanceof StringContextInterface) {
151
+ return $this->subject->getContexts();
152
+ }
153
+ return [];
154
+ }
155
+
156
+ /**
157
+ * Get a gatsby update handler service. We need to instantiate this here to
158
+ * prevent a circular dependency issue for entity_type.manager: twig ->
159
+ * twig.extension -> date.formatter -> entity_type.manager ->
160
+ * string_translation -> string_translator.locale.lookup -> locale.storage ->
161
+ * silverback_gatsby.update_handler
162
+ */
163
+ protected function getGatsbyUpdateHandler() {
164
+ if (!isset($this->updateHandler)) {
165
+ $this->updateHandler = \Drupal::getContainer()->get('silverback_gatsby.update_handler');
166
+ }
167
+ return $this->updateHandler;
168
+ }
169
+
170
+ /**
171
+ * Updates the storage reference of a set of strings.
172
+ * @param \Drupal\locale\StringInterface[] $strings
173
+ */
174
+ protected function updateStringsStorage(array $strings) {
175
+ if (!empty($strings)) {
176
+ foreach ($strings as $string) {
177
+ $string->setStorage($this);
178
+ }
179
+ }
180
+ }
181
+ }