@@ -33,6 +33,7 @@ final class CachedIdentifiersExtractor implements IdentifiersExtractorInterface
33
33
private $ cacheItemPool ;
34
34
private $ propertyAccessor ;
35
35
private $ decorated ;
36
+ private $ memoryCache = [];
36
37
37
38
public function __construct (CacheItemPoolInterface $ cacheItemPool , IdentifiersExtractorInterface $ decorated , PropertyAccessorInterface $ propertyAccessor = null )
38
39
{
@@ -46,60 +47,66 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, IdentifiersEx
46
47
*/
47
48
public function getIdentifiersFromItem ($ item ): array
48
49
{
49
- $ identifiers = [];
50
- $ resourceClass = $ this ->getObjectClass ($ item );
51
-
52
- $ cacheKey = self ::CACHE_KEY_PREFIX .md5 ($ resourceClass );
53
-
54
- // This is to avoid setting the cache twice in the case where the related item cache doesn't exist
55
- $ cacheIsHit = false ;
50
+ $ keys = $ this ->getKeys ($ item , function ($ item ) use (&$ identifiers ) {
51
+ return $ identifiers = $ this ->decorated ->getIdentifiersFromItem ($ item );
52
+ });
56
53
57
- try {
58
- $ cacheItem = $ this ->cacheItemPool ->getItem ($ cacheKey );
59
- $ isRelationCached = true ;
60
-
61
- if ($ cacheIsHit = $ cacheItem ->isHit ()) {
62
- foreach ($ cacheItem ->get () as $ propertyName ) {
63
- $ identifiers [$ propertyName ] = $ this ->propertyAccessor ->getValue ($ item , $ propertyName );
54
+ if (null !== $ identifiers ) {
55
+ return $ identifiers ;
56
+ }
64
57
65
- if (! is_object ( $ identifiers[ $ propertyName ])) {
66
- continue ;
67
- }
58
+ $ identifiers = [];
59
+ foreach ( $ keys as $ propertyName ) {
60
+ $ identifiers [ $ propertyName ] = $ this -> propertyAccessor -> getValue ( $ item , $ propertyName );
68
61
69
- $ relatedItem = $ identifiers [$ propertyName ];
70
- $ relatedCacheKey = self ::CACHE_KEY_PREFIX .md5 ($ this ->getObjectClass ($ relatedItem ));
62
+ if (!is_object ($ identifiers [$ propertyName ])) {
63
+ continue ;
64
+ }
71
65
66
+ $ relatedResourceClass = $ this ->getObjectClass ($ identifiers [$ propertyName ]);
67
+ if (!$ relatedIdentifiers = $ this ->memoryCache [$ relatedResourceClass ] ?? false ) {
68
+ $ relatedCacheKey = self ::CACHE_KEY_PREFIX .md5 ($ relatedResourceClass );
69
+ try {
72
70
$ relatedCacheItem = $ this ->cacheItemPool ->getItem ($ relatedCacheKey );
73
-
74
71
if (!$ relatedCacheItem ->isHit ()) {
75
- $ isRelationCached = false ;
76
- break ;
72
+ return $ this ->decorated ->getIdentifiersFromItem ($ item );
77
73
}
74
+ } catch (CacheException $ e ) {
75
+ return $ this ->decorated ->getIdentifiersFromItem ($ item );
76
+ }
77
+
78
+ $ relatedIdentifiers = $ relatedCacheItem ->get ();
79
+ }
78
80
79
- unset($ identifiers [$ propertyName ]);
81
+ $ identifiers [$ propertyName ] = $ this ->propertyAccessor ->getValue ($ identifiers [$ propertyName ], $ relatedIdentifiers [0 ]);
82
+ }
80
83
81
- $ identifiers[ $ propertyName ] = $ this -> propertyAccessor -> getValue ( $ relatedItem , $ relatedCacheItem -> get ()[ 0 ]) ;
82
- }
84
+ return $ identifiers ;
85
+ }
83
86
84
- if (true === $ isRelationCached ) {
85
- return $ identifiers ;
86
- }
87
+ private function getKeys ($ item , callable $ retriever ): array
88
+ {
89
+ $ resourceClass = $ this ->getObjectClass ($ item );
90
+ if (isset ($ this ->memoryCache [$ resourceClass ])) {
91
+ return $ this ->memoryCache [$ resourceClass ];
92
+ }
93
+
94
+ try {
95
+ $ cacheItem = $ this ->cacheItemPool ->getItem (self ::CACHE_KEY_PREFIX .md5 ($ resourceClass ));
96
+ if ($ cacheItem ->isHit ()) {
97
+ return $ this ->memoryCache [$ resourceClass ] = $ cacheItem ->get ();
87
98
}
88
99
} catch (CacheException $ e ) {
89
100
// do nothing
90
101
}
91
102
92
- $ identifiers = $ this -> decorated -> getIdentifiersFromItem ($ item );
103
+ $ keys = array_keys ( $ retriever ($ item) );
93
104
94
- if (isset ($ cacheItem ) && false === $ cacheIsHit ) {
95
- try {
96
- $ cacheItem ->set (array_keys ($ identifiers ));
97
- $ this ->cacheItemPool ->save ($ cacheItem );
98
- } catch (CacheException $ e ) {
99
- // do nothing
100
- }
105
+ if (isset ($ cacheItem )) {
106
+ $ cacheItem ->set ($ keys );
107
+ $ this ->cacheItemPool ->save ($ cacheItem );
101
108
}
102
109
103
- return $ identifiers ;
110
+ return $ this -> memoryCache [ $ resourceClass ] = $ keys ;
104
111
}
105
112
}
0 commit comments