99use OpenClassrooms \ServiceProxy \Helper \TypesExtractor ;
1010use OpenClassrooms \ServiceProxy \Interceptor \Config \CacheInterceptorConfig ;
1111use OpenClassrooms \ServiceProxy \Interceptor \Contract \AbstractInterceptor ;
12- use OpenClassrooms \ServiceProxy \Interceptor \Contract \Cache \AutoTaggable ;
1312use OpenClassrooms \ServiceProxy \Interceptor \Contract \PrefixInterceptor ;
1413use OpenClassrooms \ServiceProxy \Interceptor \Contract \SuffixInterceptor ;
1514use OpenClassrooms \ServiceProxy \Interceptor \Exception \InternalCodeRetrievalException ;
1615use OpenClassrooms \ServiceProxy \Model \Request \Instance ;
1716use OpenClassrooms \ServiceProxy \Model \Response \Response ;
18- use OpenClassrooms \ServiceProxy \Util \Expression ;
1917use Symfony \Component \PropertyInfo \Type ;
2018
2119final class CacheInterceptor extends AbstractInterceptor implements SuffixInterceptor, PrefixInterceptor
2220{
21+ use CacheTagsTrait;
22+
2323 private const DEFAULT_POOL_NAME = 'default ' ;
2424
2525 /**
@@ -46,16 +46,18 @@ public function __construct(
4646 /**
4747 * @return array<int, string>
4848 */
49- public static function getHits (?string $ poolName = self :: DEFAULT_POOL_NAME ): array
49+ public static function getHits (?string $ poolName = null ): array
5050 {
51+ $ poolName ??= self ::DEFAULT_POOL_NAME ;
5152 return self ::$ hits [$ poolName ] ?? [];
5253 }
5354
5455 /**
5556 * @return array<int, string>
5657 */
57- public static function getMisses (?string $ poolName = self :: DEFAULT_POOL_NAME ): array
58+ public static function getMisses (?string $ poolName = null ): array
5859 {
60+ $ poolName ??= self ::DEFAULT_POOL_NAME ;
5961 return self ::$ misses [$ poolName ] ?? [];
6062 }
6163
@@ -103,18 +105,19 @@ public function prefix(Instance $instance): Response
103105
104106 self ::$ hits [$ pool ] = self ::$ hits [$ pool ] ?? [];
105107 self ::$ hits [$ pool ][] = $ cacheKey ;
106-
108+ $ data = $ data ->get ();
109+ $ tags = $ this ->getTags ($ instance , $ attribute , $ data );
107110 foreach ($ missedPools as $ missedPool ) {
108111 $ handler ->save (
109112 $ missedPool ,
110113 $ cacheKey ,
111- $ data-> get () ,
114+ $ data ,
112115 $ attribute ->ttl ?? $ this ->config ->defaultTtl ,
113- $ this -> getTags ( $ instance , $ attribute , $ data )
116+ $ tags
114117 );
115118 }
116119
117- return new Response ($ data-> get () , true );
120+ return new Response ($ data , true );
118121 }
119122
120123 return new Response (null , false );
@@ -272,107 +275,6 @@ private function getInnerCode(\ReflectionMethod|\ReflectionClass $reflection): s
272275 return $ code ;
273276 }
274277
275- /**
276- * @return array<int, string>
277- */
278- private function getTags (Instance $ instance , Cache $ attribute , mixed $ response = null ): array
279- {
280- $ parameters = $ instance ->getMethod ()
281- ->getParameters ();
282-
283- $ tags = array_map (
284- static fn (string $ expression ) => Expression::evaluateToString ($ expression , $ parameters ),
285- $ attribute ->tags
286- );
287-
288- if ($ response !== null ) {
289- $ tags = array_values (array_filter ([
290- ...$ tags ,
291- ...$ this ->guessObjectsTags (
292- $ response ,
293- $ this ->config ->autoTagsExcludedClasses
294- ),
295- ]));
296- }
297-
298- return $ tags ;
299- }
300-
301- /**
302- * @param array<class-string> $excludedClasses
303- * @param array<string, string> $registeredTags
304- *
305- * @return array<string, string>
306- */
307- private function guessObjectsTags (mixed $ object , array $ excludedClasses = [], array $ registeredTags = []): array
308- {
309- if (!\is_object ($ object ) && !is_iterable ($ object )) {
310- return $ registeredTags ;
311- }
312-
313- foreach ($ excludedClasses as $ excludedClass ) {
314- if ($ object instanceof $ excludedClass ) {
315- return $ registeredTags ;
316- }
317- }
318-
319- if (is_iterable ($ object )) {
320- foreach ($ object as $ item ) {
321- $ registeredTags = $ this ->guessObjectsTags ($ item , $ excludedClasses , $ registeredTags );
322- }
323-
324- return $ registeredTags ;
325- }
326-
327- if (!$ object instanceof AutoTaggable) {
328- return $ registeredTags ;
329- }
330-
331- $ tag = $ this ->buildTag ($ object );
332-
333- if (isset ($ registeredTags [$ tag ])) {
334- return $ registeredTags ;
335- }
336-
337- $ registeredTags [$ tag ] = $ tag ;
338-
339- $ ref = new \ReflectionClass ($ object );
340-
341- foreach ($ ref ->getProperties () as $ propRef ) {
342- $ subObject = $ this ->getPropertyValue ($ ref , $ object , $ propRef ->getName ());
343-
344- $ registeredTags = $ this ->guessObjectsTags ($ subObject , $ excludedClasses , $ registeredTags );
345- }
346-
347- return $ registeredTags ;
348- }
349-
350- private function buildTag (AutoTaggable $ object ): string
351- {
352- return str_replace ('\\' , '. ' , \get_class ($ object )) . '. ' . $ object ->getId ();
353- }
354-
355- /**
356- * @param \ReflectionClass<object> $ref
357- */
358- private function getPropertyValue (\ReflectionClass $ ref , object $ object , string $ propertyName ): mixed
359- {
360- $ getter = 'get ' . ucfirst ($ propertyName );
361- $ refMethod = $ ref ->hasMethod ($ getter ) ? $ ref ->getMethod ($ getter ) : null ;
362- if ($ refMethod !== null && $ refMethod ->isPublic () && \count ($ refMethod ->getParameters ()) === 0 ) {
363- return $ refMethod ->invoke ($ object );
364- }
365-
366- $ propRef = $ ref ->getProperty ($ propertyName );
367- if (!$ propRef ->isInitialized ($ object )) {
368- return null ;
369- }
370-
371- $ propRef ->setAccessible (true );
372-
373- return $ propRef ->getValue ($ object );
374- }
375-
376278 /**
377279 * @param array<string, mixed> $parameters
378280 */
0 commit comments