@@ -9,7 +9,6 @@ use Drupal\restful\Plugin\resource\Decorators\CacheDecoratedResource;
99use Drupal \restful \Plugin \resource \Decorators \CacheDecoratedResourceInterface ;
1010use Drupal \restful \RenderCache \Entity \CacheFragmentController ;
1111use Drupal \restful \RenderCache \RenderCache ;
12- use Drupal \Component \Plugin \Exception \PluginNotFoundException ;
1312use Doctrine \Common \Collections \ArrayCollection ;
1413
1514/**
@@ -77,48 +76,22 @@ function _restful_entity_cache_hashes($entity, $type) {
7776 * Implements hook_entity_update().
7877 */
7978function restful_entity_update ($ entity , $ type ) {
80- $ resource_manager = restful ()->getResourceManager ();
81- foreach (_restful_entity_cache_hashes ($ entity , $ type ) as $ hash ) {
82- if (!$ instance_id = CacheFragmentController::resourceIdFromHash ($ hash )) {
83- continue ;
84- }
85- $ handler = $ resource_manager ->getPlugin ($ instance_id );
86- if (!$ handler instanceof CacheDecoratedResourceInterface) {
87- continue ;
88- }
89- if (!$ handler ->hasSimpleInvalidation ()) {
90- continue ;
91- }
92- // You can get away without the fragments for a clear.
93- $ cache_object = new RenderCache (new ArrayCollection (), $ hash , $ handler ->getCacheController ());
94- // Do a clear with the RenderCache object to also remove the cache fragment
95- // entities.
96- $ cache_object ->clear ();
97- }
79+ $ hashes = &drupal_static ('restful_entity_clear_hashes ' , array ());
80+ $ new_hashes = _restful_entity_cache_hashes ($ entity , $ type );
81+ array_walk ($ new_hashes , '_restful_entity_clear_all_resources ' );
82+ $ hashes += $ new_hashes ;
83+ restful_register_shutdown_function_once ('restful_entity_clear_render_cache ' );
9884}
9985
10086/**
10187 * Implements hook_entity_delete().
10288 */
10389function restful_entity_delete ($ entity , $ type ) {
104- $ resource_manager = restful ()->getResourceManager ();
105- foreach (_restful_entity_cache_hashes ($ entity , $ type ) as $ hash ) {
106- if (!$ instance_id = CacheFragmentController::resourceIdFromHash ($ hash )) {
107- continue ;
108- }
109- $ handler = $ resource_manager ->getPlugin ($ instance_id );
110- if (!$ handler instanceof CacheDecoratedResourceInterface) {
111- continue ;
112- }
113- if (!$ handler ->hasSimpleInvalidation ()) {
114- continue ;
115- }
116- // You can get away without the fragments for a clear.
117- $ cache_object = new RenderCache (new ArrayCollection (), $ hash , $ handler ->getCacheController ());
118- // Do a clear with the RenderCache object to also remove the cache fragment
119- // entities.
120- $ cache_object ->clear ();
121- }
90+ $ hashes = &drupal_static ('restful_entity_clear_hashes ' , array ());
91+ $ new_hashes = _restful_entity_cache_hashes ($ entity , $ type );
92+ array_walk ($ new_hashes , '_restful_entity_clear_all_resources ' );
93+ $ hashes += $ new_hashes ;
94+ restful_register_shutdown_function_once ('restful_entity_clear_render_cache ' );
12295}
12396
12497/**
@@ -131,29 +104,11 @@ function restful_user_update(&$edit, $account, $category) {
131104 ->entityCondition ('entity_type ' , 'cache_fragment ' )
132105 ->propertyCondition ('type ' , 'user_id ' )
133106 ->propertyCondition ('value ' , $ account ->uid );
134- $ resource_manager = restful ()->getResourceManager ();
135- foreach (CacheFragmentController::lookUpHashes ($ query ) as $ hash ) {
136- if (!$ plugin_id = CacheFragmentController::resourceIdFromHash ($ hash )) {
137- continue ;
138- }
139- try {
140- $ handler = $ resource_manager ->getPlugin ($ plugin_id );
141- }
142- catch (PluginNotFoundException $ e ) {
143- continue ;
144- }
145- if (!$ handler instanceof CacheDecoratedResourceInterface) {
146- return ;
147- }
148- if (!$ handler ->hasSimpleInvalidation ()) {
149- return ;
150- }
151- // You can get away without the fragments for a clear.
152- $ cache_object = new RenderCache (new ArrayCollection (), $ hash , $ handler ->getCacheController ());
153- // Do a clear with the RenderCache object to also remove the cache fragment
154- // entities.
155- $ cache_object ->clear ();
156- }
107+ $ hashes = &drupal_static ('restful_entity_clear_hashes ' , array ());
108+ $ new_hashes = CacheFragmentController::lookUpHashes ($ query );
109+ array_walk ($ new_hashes , '_restful_entity_clear_all_resources ' );
110+ $ hashes += $ new_hashes ;
111+ restful_register_shutdown_function_once ('restful_entity_clear_render_cache ' );
157112}
158113
159114/**
@@ -166,19 +121,73 @@ function restful_user_delete($account) {
166121 ->entityCondition ('entity_type ' , 'cache_fragment ' )
167122 ->propertyCondition ('type ' , 'user_id ' )
168123 ->propertyCondition ('value ' , $ account ->uid );
169- $ resource_manager = restful ()->getResourceManager ();
170- foreach (CacheFragmentController::lookUpHashes ($ query ) as $ hash ) {
171- $ handler = $ resource_manager ->getPlugin (CacheFragmentController::resourceIdFromHash ($ hash ));
172- if (!$ handler instanceof CacheDecoratedResourceInterface) {
173- return ;
174- }
175- if (!$ handler ->hasSimpleInvalidation ()) {
176- return ;
124+ $ hashes = &drupal_static ('restful_entity_clear_hashes ' , array ());
125+ $ new_hashes = CacheFragmentController::lookUpHashes ($ query );
126+ array_walk ($ new_hashes , '_restful_entity_clear_all_resources ' );
127+ $ hashes += $ new_hashes ;
128+ restful_register_shutdown_function_once ('restful_entity_clear_render_cache ' );
129+ }
130+
131+ /**
132+ * Helper function to schedule a shutdown once.
133+ *
134+ * @param callable $callback
135+ * The callback.
136+ */
137+ function restful_register_shutdown_function_once ($ callback ) {
138+ $ existing_callbacks = drupal_register_shutdown_function ();
139+ $ added = (bool ) array_filter ($ existing_callbacks , function ($ item ) use ($ callback ) {
140+ return $ item ['callback ' ] == $ callback ;
141+ });
142+ if (!$ added ) {
143+ drupal_register_shutdown_function ($ callback );
144+ }
145+ }
146+
147+ /**
148+ * Clear the cache back ends for the given hash.
149+ *
150+ * @param string $cid
151+ * The cache ID to clear.
152+ */
153+ function _restful_entity_clear_all_resources ($ cid ) {
154+ if (!$ instance_id = CacheFragmentController::resourceIdFromHash ($ cid )) {
155+ return ;
156+ }
157+ $ handler = restful ()
158+ ->getResourceManager ()
159+ ->getPlugin ($ instance_id );
160+ if (!$ handler instanceof CacheDecoratedResourceInterface) {
161+ return ;
162+ }
163+ // Clear the cache bin.
164+ $ handler ->getCacheController ()->clear ($ cid );
165+ }
166+
167+ /**
168+ * Shutdown function that deletes the scheduled fragments and caches on shutdown.
169+ */
170+ function restful_entity_clear_render_cache () {
171+ if ($ hashes = drupal_static ('restful_entity_clear_hashes ' , array ())) {
172+ $ hashes = array_unique ($ hashes );
173+ drupal_static_reset ('restful_entity_clear_hashes ' );
174+ $ resource_manager = restful ()->getResourceManager ();
175+ foreach ($ hashes as $ hash ) {
176+ if (!$ instance_id = CacheFragmentController::resourceIdFromHash ($ hash )) {
177+ continue ;
178+ }
179+ $ handler = $ resource_manager ->getPlugin ($ instance_id );
180+ if (!$ handler instanceof CacheDecoratedResourceInterface) {
181+ continue ;
182+ }
183+ if (!$ handler ->hasSimpleInvalidation ()) {
184+ continue ;
185+ }
186+ // You can get away without the fragments for a clear.
187+ $ cache_object = new RenderCache (new ArrayCollection (), $ hash , $ handler ->getCacheController ());
188+ // Do a clear with the RenderCache object to also remove the cache fragment
189+ // entities.
190+ $ cache_object ->clear ();
177191 }
178- // You can get away without the fragments for a clear.
179- $ cache_object = new RenderCache (NULL , $ hash , $ handler ->getCacheController ());
180- // Do a clear with the RenderCache object to also remove the cache fragment
181- // entities.
182- $ cache_object ->clear ();
183192 }
184193}
0 commit comments