3
3
4
4
namespace PTS \SymfonyDiLoader ;
5
5
6
- use Symfony \Component \DependencyInjection \ Container ;
6
+ use Symfony \Component \Config \ FileLocator ;
7
7
use Symfony \Component \DependencyInjection \ContainerBuilder ;
8
8
use Symfony \Component \DependencyInjection \ContainerInterface ;
9
9
use Symfony \Component \DependencyInjection \Dumper \PhpDumper ;
10
10
use Symfony \Component \DependencyInjection \Exception \EnvParameterException ;
11
+ use Symfony \Component \DependencyInjection \Loader \YamlFileLoader ;
11
12
12
13
class LoaderContainer implements LoaderContainerInterface
13
14
{
14
- /** @var array */
15
- protected $ configFiles = [];
16
-
17
- /** @var FactoryContainer */
18
- protected $ factory ;
19
- /** @var ContainerInterface */
20
- protected $ container ;
21
-
22
- /** @var string */
23
- protected $ cacheFile ;
24
- /** @var bool */
25
- protected $ checkExpired = true ;
26
-
27
- /** @var string */
28
- protected $ classContainer = 'AppContainer ' ;
29
-
30
-
31
- public function __construct (array $ configFiles , string $ cacheFile , FactoryContainer $ factory )
32
- {
33
- $ this ->configFiles = $ configFiles ;
34
- $ this ->cacheFile = $ cacheFile ;
35
- $ this ->factory = $ factory ;
36
- }
37
-
38
- public function setCheckExpired ($ checkExpired = true ): self
15
+ /** @var array */
16
+ protected $ configFiles = [];
17
+
18
+ /** @var FactoryContainer */
19
+ protected $ factory ;
20
+ /** @var ContainerInterface */
21
+ protected $ container ;
22
+ /** @var CacheWatcher */
23
+ protected $ cacheWatcher ;
24
+
25
+ /** @var string */
26
+ protected $ cacheFile ;
27
+ /** @var bool */
28
+ protected $ checkExpired = true ;
29
+
30
+ /** @var string */
31
+ protected $ classContainer = 'AppContainer ' ;
32
+
33
+ /**
34
+ * @param string[] $configFiles
35
+ * @param string $cacheFile
36
+ * @param FactoryContainer|null $factory
37
+ */
38
+ public function __construct (array $ configFiles , string $ cacheFile , FactoryContainer $ factory = null )
39
+ {
40
+ $ this ->configFiles = $ configFiles ;
41
+ $ this ->cacheFile = $ cacheFile ;
42
+ $ this ->factory = $ factory ?? new FactoryContainer (YamlFileLoader::class, new FileLocator );
43
+ $ this ->cacheWatcher = new CacheWatcher ;
44
+ }
45
+
46
+ public function setCheckExpired (bool $ checkExpired = true ): self
39
47
{
40
48
$ this ->checkExpired = $ checkExpired ;
41
49
return $ this ;
@@ -48,40 +56,44 @@ public function setCheckExpired($checkExpired = true): self
48
56
public function getContainer (): ContainerInterface
49
57
{
50
58
if ($ this ->container === null ) {
51
- $ container = $ this ->createContainer ();
52
- $ this ->setContainer ($ container );
59
+ $ container = $ this ->tryGetContainerFromCache ($ this ->cacheFile , $ this ->configFiles );
60
+ $ container = $ container ?? $ this ->createContainer ($ this ->configFiles , $ this ->cacheFile , $ this ->classContainer );
61
+ $ this ->container = $ container ;
53
62
}
54
63
55
64
return $ this ->container ;
56
65
}
57
66
58
- public function setContainer (ContainerInterface $ container ): self
67
+ /**
68
+ * @param string[] $configs
69
+ * @param string $cacheFile
70
+ * @param string $class
71
+ *
72
+ * @return ContainerInterface
73
+ * @throws \Exception
74
+ */
75
+ protected function createContainer (array $ configs , string $ cacheFile , string $ class ): ContainerInterface
59
76
{
60
- $ this ->container = $ container ;
61
- return $ this ;
62
- }
63
-
64
- protected function getFactory (): FactoryContainer
65
- {
66
- return $ this ->factory ;
67
- }
68
-
69
- /**
70
- * @return ContainerInterface
71
- * @throws \Exception
72
- */
73
- protected function createContainer (): ContainerInterface
74
- {
75
- $ appContainer = $ this ->getContainerFromCache ($ this ->cacheFile , $ this ->configFiles );
76
-
77
- if (!($ appContainer instanceof ContainerInterface)) {
78
- $ appContainer = $ this ->getFactory ()->create ($ this ->configFiles );
79
- $ this ->dump ($ this ->cacheFile , $ this ->classContainer , $ appContainer );
80
- }
77
+ $ appContainer = $ this ->factory ->create ($ configs );
78
+ $ this ->dump ($ cacheFile , $ class , $ appContainer );
79
+ $ this ->dumpMeta ($ cacheFile . '.meta ' , $ configs );
81
80
82
81
return $ appContainer ;
83
82
}
84
83
84
+ /**
85
+ * @param string $filePath
86
+ * @param string[] $configFiles
87
+ */
88
+ protected function dumpMeta (string $ filePath , array $ configFiles ): void
89
+ {
90
+ try {
91
+ file_put_contents ($ filePath , serialize ($ configFiles ));
92
+ } catch (\Throwable $ throwable ) {
93
+ throw new \RuntimeException ('Can`t dump meta for DI container ' , 0 , $ throwable );
94
+ }
95
+ }
96
+
85
97
/**
86
98
* @param string $filePath
87
99
* @param string $className
@@ -91,43 +103,39 @@ protected function createContainer(): ContainerInterface
91
103
*/
92
104
protected function dump (string $ filePath , string $ className , ContainerBuilder $ container ): void
93
105
{
94
- $ container ->compile (true );
95
106
$ dumper = new PhpDumper ($ container );
96
- file_put_contents ($ filePath , $ dumper ->dump ([
97
- 'class ' => $ className ,
98
- ]));
107
+
108
+ try {
109
+ file_put_contents ($ filePath , $ dumper ->dump ([
110
+ 'class ' => $ className ,
111
+ ]));
112
+ } catch (\Throwable $ throwable ) {
113
+ throw new \RuntimeException ('Can`t dump cache for DI container ' , 0 , $ throwable );
114
+ }
99
115
}
100
116
101
- protected function getContainerFromCache ($ fileCache , $ configs ): ?Container
117
+ /**
118
+ * @param string $fileCache
119
+ * @param string[] $configs
120
+ *
121
+ * @return null|ContainerInterface
122
+ */
123
+ protected function tryGetContainerFromCache (string $ fileCache , array $ configs ): ?ContainerInterface
102
124
{
103
125
if (!file_exists ($ fileCache )) {
104
126
return null ;
105
127
}
106
128
107
- if ($ this ->checkExpired && $ this ->isExpired ($ fileCache , $ configs )) {
129
+ if ($ this ->checkExpired && ! $ this ->getWatcher ()-> isActualCache ($ fileCache , $ configs )) {
108
130
return null ;
109
131
}
110
132
111
133
require_once $ fileCache ;
112
134
return new $ this ->classContainer ;
113
135
}
114
136
115
- /**
116
- * @param string $containerPath
117
- * @param string[] $configs
118
- *
119
- * @return bool
120
- */
121
- protected function isExpired (string $ containerPath , array $ configs ): bool
122
- {
123
- $ cacheTime = filemtime ($ containerPath );
124
-
125
- foreach ($ configs as $ config ) {
126
- if ($ cacheTime < filemtime ($ config )) {
127
- return true ;
128
- }
129
- }
130
-
131
- return false ;
132
- }
137
+ protected function getWatcher (): CacheWatcher
138
+ {
139
+ return $ this ->cacheWatcher ;
140
+ }
133
141
}
0 commit comments