3
3
* Copyright © Magento, Inc. All rights reserved.
4
4
* See COPYING.txt for license details.
5
5
*/
6
+
6
7
namespace Magento \Config \App \Config \Type ;
7
8
8
9
use Magento \Framework \App \Config \ConfigTypeInterface ;
@@ -23,7 +24,7 @@ class System implements ConfigTypeInterface
23
24
private $ source ;
24
25
25
26
/**
26
- * @var DataObject[]
27
+ * @var DataObject
27
28
*/
28
29
private $ data ;
29
30
@@ -64,6 +65,16 @@ class System implements ConfigTypeInterface
64
65
*/
65
66
private $ configType ;
66
67
68
+ /**
69
+ * Key name for flag which displays whether configuration is cached or not.
70
+ *
71
+ * Once configuration is cached additional flag pushed to cache storage
72
+ * to be able check cache existence without data load.
73
+ *
74
+ * @var string
75
+ */
76
+ private $ cacheExistenceKey ;
77
+
67
78
/**
68
79
* @param \Magento\Framework\App\Config\ConfigSourceInterface $source
69
80
* @param \Magento\Framework\App\Config\Spi\PostProcessorInterface $postProcessor
@@ -92,6 +103,7 @@ public function __construct(
92
103
$ this ->fallback = $ fallback ;
93
104
$ this ->serializer = $ serializer ;
94
105
$ this ->configType = $ configType ;
106
+ $ this ->cacheExistenceKey = $ this ->configType . '_CACHE_EXISTS ' ;
95
107
}
96
108
97
109
/**
@@ -102,23 +114,135 @@ public function get($path = '')
102
114
if ($ path === null ) {
103
115
$ path = '' ;
104
116
}
105
- if (!$ this ->data ) {
106
- $ data = $ this ->cache ->load ($ this ->configType );
107
- if (!$ data ) {
108
- $ data = $ this ->preProcessor ->process ($ this ->source ->get ());
109
- $ this ->data = new DataObject ($ data );
110
- $ data = $ this ->fallback ->process ($ data );
111
- $ this ->data = new DataObject ($ data );
112
- //Placeholder processing need system config - so we need to save intermediate result
113
- $ data = $ this ->postProcessor ->process ($ data );
114
- $ this ->data = new DataObject ($ data );
117
+ if ($ this ->isConfigRead ($ path )) {
118
+ return $ this ->data ->getData ($ path );
119
+ }
120
+
121
+ if (!empty ($ path ) && $ this ->isCacheExists ()) {
122
+ return $ this ->readFromCache ($ path );
123
+ }
124
+
125
+ $ config = $ this ->loadConfig ();
126
+ $ this ->cacheConfig ($ config );
127
+ $ this ->data = new DataObject ($ config );
128
+ return $ this ->data ->getData ($ path );
129
+ }
130
+
131
+ /**
132
+ * Check whether configuration is cached
133
+ *
134
+ * In case configuration cache exists method 'load' returns
135
+ * value equal to $this->cacheExistenceKey
136
+ *
137
+ * @return bool
138
+ */
139
+ private function isCacheExists ()
140
+ {
141
+ return $ this ->cache ->load ($ this ->cacheExistenceKey ) !== false ;
142
+ }
143
+
144
+ /**
145
+ * Explode path by '/'(forward slash) separator
146
+ *
147
+ * In case $path string contains forward slash symbol(/) the $path is exploded and parts array is returned
148
+ * In other case empty array is returned
149
+ *
150
+ * @param string $path
151
+ * @return array
152
+ */
153
+ private function getPathParts ($ path )
154
+ {
155
+ $ pathParts = [];
156
+ if (strpos ($ path , '/ ' ) !== false ) {
157
+ $ pathParts = explode ('/ ' , $ path );
158
+ }
159
+ return $ pathParts ;
160
+ }
161
+
162
+ /**
163
+ * Check whether requested configuration data is read to memory
164
+ *
165
+ * Because of configuration is cached partially each part can be loaded separately
166
+ * Method performs check if corresponding system configuration part is already loaded to memory
167
+ * and value can be retrieved directly without cache look up
168
+ *
169
+ *
170
+ * @param string $path
171
+ * @return bool
172
+ */
173
+ private function isConfigRead ($ path )
174
+ {
175
+ $ pathParts = $ this ->getPathParts ($ path );
176
+ return !empty ($ pathParts ) && isset ($ this ->data [$ pathParts [0 ]][$ pathParts [1 ]]);
177
+ }
178
+
179
+ /**
180
+ * Load configuration from all the sources
181
+ *
182
+ * System configuration is loaded in 3 steps performing consecutive calls to
183
+ * Pre Processor, Fallback Processor, Post Processor accordingly
184
+ *
185
+ * @return array
186
+ */
187
+ private function loadConfig ()
188
+ {
189
+ $ data = $ this ->preProcessor ->process ($ this ->source ->get ());
190
+ $ this ->data = new DataObject ($ data );
191
+ $ data = $ this ->fallback ->process ($ data );
192
+ $ this ->data = new DataObject ($ data );
193
+
194
+ return $ this ->postProcessor ->process ($ data );
195
+ }
196
+
197
+ /**
198
+ *
199
+ * Load configuration and caching it by parts.
200
+ *
201
+ * To be cached configuration is loaded first.
202
+ * Then it is cached by parts to minimize memory usage on load.
203
+ * Additional flag cached as well to give possibility check cache existence without data load.
204
+ *
205
+ * @param array $data
206
+ * @return void
207
+ */
208
+ private function cacheConfig ($ data )
209
+ {
210
+ foreach ($ data as $ scope => $ scopeData ) {
211
+ foreach ($ scopeData as $ key => $ config ) {
115
212
$ this ->cache ->save (
116
- $ this ->serializer ->serialize ($ this -> data -> getData () ),
117
- $ this ->configType ,
213
+ $ this ->serializer ->serialize ($ config ),
214
+ $ this ->configType . ' _ ' . $ scope . $ key ,
118
215
[self ::CACHE_TAG ]
119
216
);
120
- } else {
121
- $ this ->data = new DataObject ($ this ->serializer ->unserialize ($ data ));
217
+ }
218
+ }
219
+ $ this ->cache ->save ($ this ->cacheExistenceKey , $ this ->cacheExistenceKey , [self ::CACHE_TAG ]);
220
+ }
221
+
222
+ /**
223
+ * Read cached configuration
224
+ *
225
+ * Read section of system configuration corresponding to requested $path from cache
226
+ * Configuration stored to internal property right after load to prevent additional
227
+ * requests to cache storage
228
+ *
229
+ * @param string $path
230
+ * @return mixed
231
+ */
232
+ private function readFromCache ($ path )
233
+ {
234
+ if ($ this ->data === null ) {
235
+ $ this ->data = new DataObject ();
236
+ }
237
+
238
+ $ result = null ;
239
+ $ pathParts = $ this ->getPathParts ($ path );
240
+ if (!empty ($ pathParts )) {
241
+ $ result = $ this ->cache ->load ($ this ->configType . '_ ' . $ pathParts [0 ] . $ pathParts [1 ]);
242
+ if ($ result !== false ) {
243
+ $ readData = $ this ->data ->getData ();
244
+ $ readData [$ pathParts [0 ]][$ pathParts [1 ]] = $ this ->serializer ->unserialize ($ result );
245
+ $ this ->data ->setData ($ readData );
122
246
}
123
247
}
124
248
@@ -128,6 +252,10 @@ public function get($path = '')
128
252
/**
129
253
* Clean cache and global variables cache
130
254
*
255
+ * Next items cleared:
256
+ * - Internal property intended to store already loaded configuration data
257
+ * - All records in cache storage tagged with CACHE_TAG
258
+ *
131
259
* @return void
132
260
*/
133
261
public function clean ()
0 commit comments