55use Drupal \Core \DependencyInjection \DependencySerializationTrait ;
66use Drupal \Core \Entity \EntityTypeManagerInterface ;
77use Drupal \Core \Plugin \ContainerFactoryPluginInterface ;
8+ use Drupal \Core \Render \RenderContext ;
9+ use Drupal \Core \Render \RendererInterface ;
810use Drupal \Core \StringTranslation \StringTranslationTrait ;
911use Drupal \graphql \GraphQL \Execution \ResolveContext ;
1012use Drupal \graphql_core \GraphQL \EntityCrudOutputWrapper ;
@@ -23,6 +25,13 @@ abstract class UpdateEntityBase extends MutationPluginBase implements ContainerF
2325 */
2426 protected $ entityTypeManager ;
2527
28+ /**
29+ * The renderer service.
30+ *
31+ * @var \Drupal\Core\Render\RendererInterface
32+ */
33+ protected $ renderer ;
34+
2635 /**
2736 * {@inheritdoc}
2837 */
@@ -31,7 +40,8 @@ public static function create(ContainerInterface $container, array $configuratio
3140 $ configuration ,
3241 $ pluginId ,
3342 $ pluginDefinition ,
34- $ container ->get ('entity_type.manager ' )
43+ $ container ->get ('entity_type.manager ' ),
44+ $ container ->get ('renderer ' )
3545 );
3646 }
3747
@@ -46,64 +56,74 @@ public static function create(ContainerInterface $container, array $configuratio
4656 * The plugin definition.
4757 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
4858 * The entity type manager service.
59+ * @param \Drupal\Core\Render\RendererInterface $renderer
60+ * The renderer service.
4961 */
50- public function __construct (array $ configuration , $ pluginId , $ pluginDefinition , EntityTypeManagerInterface $ entityTypeManager ) {
62+ public function __construct (array $ configuration , $ pluginId , $ pluginDefinition , EntityTypeManagerInterface $ entityTypeManager, RendererInterface $ renderer ) {
5163 parent ::__construct ($ configuration , $ pluginId , $ pluginDefinition );
5264 $ this ->entityTypeManager = $ entityTypeManager ;
65+ $ this ->renderer = $ renderer ;
5366 }
5467
5568 /**
5669 * {@inheritdoc}
5770 */
5871 public function resolve ($ value , array $ args , ResolveContext $ context , ResolveInfo $ info ) {
59- $ entityTypeId = $ this ->pluginDefinition ['entity_type ' ];
60- $ bundleName = $ this ->pluginDefinition ['entity_bundle ' ];
61- $ storage = $ this ->entityTypeManager ->getStorage ($ entityTypeId );
62-
63- /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
64- if (!$ entity = $ storage ->load ($ args ['id ' ])) {
65- return new EntityCrudOutputWrapper (NULL , NULL , [
66- $ this ->t ('The requested @bundle could not be loaded. ' , ['@bundle ' => $ bundleName ]),
67- ]);
68- }
69-
70- if (!$ entity ->bundle () === $ bundleName ) {
71- return new EntityCrudOutputWrapper (NULL , NULL , [
72- $ this ->t ('The requested entity is not of the expected type @bundle. ' , ['@bundle ' => $ bundleName ]),
73- ]);
74- }
75-
76- if (!$ entity ->access ('update ' )) {
77- return new EntityCrudOutputWrapper (NULL , NULL , [
78- $ this ->t ('You do not have the necessary permissions to update this @bundle. ' , ['@bundle ' => $ bundleName ]),
79- ]);
80- }
81-
82- // The raw input needs to be converted to use the proper field and property
83- // keys because we usually convert them to camel case when adding them to
84- // the schema. Allow the other implementations to control this easily.
85- $ input = $ this ->extractEntityInput ($ value , $ args , $ context , $ info );
86-
87- try {
88- foreach ($ input as $ key => $ value ) {
89- $ entity ->get ($ key )->setValue ($ value );
72+ // There are cases where the Drupal entity API calls emit the cache metadata
73+ // in the current render context. In such cases
74+ // EarlyRenderingControllerWrapperSubscriber throws the leaked cache
75+ // metadata exception. To avoid this, wrap the execution in its own render
76+ // context.
77+ return $ this ->renderer ->executeInRenderContext (new RenderContext (), function () use ($ value , $ args , $ context , $ info ) {
78+ $ entityTypeId = $ this ->pluginDefinition ['entity_type ' ];
79+ $ bundleName = $ this ->pluginDefinition ['entity_bundle ' ];
80+ $ storage = $ this ->entityTypeManager ->getStorage ($ entityTypeId );
81+
82+ /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
83+ if (!$ entity = $ storage ->load ($ args ['id ' ])) {
84+ return new EntityCrudOutputWrapper (NULL , NULL , [
85+ $ this ->t ('The requested @bundle could not be loaded. ' , ['@bundle ' => $ bundleName ]),
86+ ]);
9087 }
91- }
92- catch (\InvalidArgumentException $ exception ) {
93- return new EntityCrudOutputWrapper (NULL , NULL , [
94- $ this ->t ('The entity update failed with exception: @exception. ' , ['@exception ' => $ exception ->getMessage ()]),
95- ]);
96- }
97-
98- if (($ violations = $ entity ->validate ()) && $ violations ->count ()) {
99- return new EntityCrudOutputWrapper (NULL , $ violations );
100- }
101-
102- if (($ status = $ entity ->save ()) && $ status === SAVED_UPDATED ) {
103- return new EntityCrudOutputWrapper ($ entity );
104- }
105-
106- return NULL ;
88+
89+ if (!$ entity ->bundle () === $ bundleName ) {
90+ return new EntityCrudOutputWrapper (NULL , NULL , [
91+ $ this ->t ('The requested entity is not of the expected type @bundle. ' , ['@bundle ' => $ bundleName ]),
92+ ]);
93+ }
94+
95+ if (!$ entity ->access ('update ' )) {
96+ return new EntityCrudOutputWrapper (NULL , NULL , [
97+ $ this ->t ('You do not have the necessary permissions to update this @bundle. ' , ['@bundle ' => $ bundleName ]),
98+ ]);
99+ }
100+
101+ // The raw input needs to be converted to use the proper field and property
102+ // keys because we usually convert them to camel case when adding them to
103+ // the schema. Allow the other implementations to control this easily.
104+ $ input = $ this ->extractEntityInput ($ value , $ args , $ context , $ info );
105+
106+ try {
107+ foreach ($ input as $ key => $ value ) {
108+ $ entity ->get ($ key )->setValue ($ value );
109+ }
110+ }
111+ catch (\InvalidArgumentException $ exception ) {
112+ return new EntityCrudOutputWrapper (NULL , NULL , [
113+ $ this ->t ('The entity update failed with exception: @exception. ' , ['@exception ' => $ exception ->getMessage ()]),
114+ ]);
115+ }
116+
117+ if (($ violations = $ entity ->validate ()) && $ violations ->count ()) {
118+ return new EntityCrudOutputWrapper (NULL , $ violations );
119+ }
120+
121+ if (($ status = $ entity ->save ()) && $ status === SAVED_UPDATED ) {
122+ return new EntityCrudOutputWrapper ($ entity );
123+ }
124+
125+ return NULL ;
126+ });
107127 }
108128
109129 /**
0 commit comments