77use Contributte \Redis \Tracy \RedisPanel ;
88use Nette \Caching \IStorage ;
99use Nette \DI \CompilerExtension ;
10+ use Nette \DI \Definitions \ServiceDefinition ;
1011use Nette \Http \Session ;
1112use Nette \PhpGenerator \ClassType ;
12- use Nette \Utils \Validators ;
13+ use Nette \Schema \Expect ;
14+ use Nette \Schema \Schema ;
1315use Predis \Client ;
1416use Predis \Session \Handler ;
1517use RuntimeException ;
18+ use stdClass ;
1619
20+ /**
21+ * @property-read stdClass $config
22+ */
1723final class RedisExtension extends CompilerExtension
1824{
1925
20- /** @var mixed[] */
21- private $ defaults = [
22- 'debug ' => false ,
23- 'connection ' => [],
24- ];
25-
26- /** @var mixed[] */
27- private $ connectionDefaults = [
28- 'uri ' => 'tcp://127.0.0.1:6379 ' ,
29- 'options ' => [],
30- 'storage ' => false ,
31- 'sessions ' => false ,
32- ];
33-
34- /** @var mixed[] */
35- private $ sessionDefaults = [
36- 'ttl ' => null ,
37- ];
26+ public function getConfigSchema (): Schema
27+ {
28+ return Expect::structure ([
29+ 'debug ' => Expect::bool (false ),
30+ 'connection ' => Expect::arrayOf (Expect::structure ([
31+ 'uri ' => Expect::string ('tcp://127.0.0.1:6379 ' ),
32+ 'options ' => Expect::array (),
33+ 'storage ' => Expect::bool (false ),
34+ 'sessions ' => Expect::anyOf (
35+ Expect::bool (),
36+ Expect::array ()
37+ )->default (false ),
38+ ])),
39+ ]);
40+ }
3841
3942 public function loadConfiguration (): void
4043 {
4144 $ builder = $ this ->getContainerBuilder ();
42- $ config = $ this ->validateConfig ($ this ->defaults );
43-
44- if (!isset ($ config ['connection ' ]['default ' ])) {
45- throw new InvalidStateException (sprintf ('%s.connection.default is required. ' , $ this ->name ));
46- }
45+ $ config = $ this ->config ;
4746
4847 $ connections = [];
4948
50- foreach ($ config ['connection ' ] as $ name => $ connection ) {
51- $ connection = $ this ->validateConfig ($ this ->connectionDefaults , $ connection , $ this ->prefix ('connection. ' . $ name ));
52-
49+ foreach ($ config ->connection as $ name => $ connection ) {
5350 $ client = $ builder ->addDefinition ($ this ->prefix ('connection. ' . $ name . '.client ' ))
5451 ->setType (Client::class)
55- ->setArguments ([$ connection[ ' uri ' ] , $ connection[ ' options ' ] ]);
52+ ->setArguments ([$ connection-> uri , $ connection-> options ]);
5653
5754 if ($ name !== 'default ' ) {
5855 $ client ->setAutowired (false );
@@ -66,7 +63,7 @@ public function loadConfiguration(): void
6663 ];
6764 }
6865
69- if ($ config[ ' debug ' ] === true ) {
66+ if ($ config-> debug && $ config -> connection !== [] ) {
7067 $ builder ->addDefinition ($ this ->prefix ('panel ' ))
7168 ->setFactory (RedisPanel::class, [$ connections ]);
7269 }
@@ -81,13 +78,13 @@ public function beforeCompile(): void
8178 public function beforeCompileStorage (): void
8279 {
8380 $ builder = $ this ->getContainerBuilder ();
84- $ config = $ this ->validateConfig ($ this ->defaults );
85-
86- foreach ($ config ['connection ' ] as $ name => $ connection ) {
87- $ connection = $ this ->validateConfig ($ this ->connectionDefaults , $ connection , $ this ->prefix ('connection. ' . $ name ));
81+ $ config = $ this ->config ;
8882
83+ foreach ($ config ->connection as $ name => $ connection ) {
8984 // Skip if replacing storage is disabled
90- if ($ connection ['storage ' ] === false ) continue ;
85+ if (!$ connection ->storage ) {
86+ continue ;
87+ }
9188
9289 // Validate needed services
9390 if ($ builder ->getByType (IStorage::class) === null ) {
@@ -98,23 +95,22 @@ public function beforeCompileStorage(): void
9895 ->setAutowired (false );
9996
10097 $ builder ->addDefinition ($ this ->prefix ('connection. ' . $ name . 'storage ' ))
101- ->setFactory (RedisStorage::class)
102- ->setAutowired (true );
98+ ->setFactory (RedisStorage::class);
10399 }
104100 }
105101
106102 public function beforeCompileSession (): void
107103 {
108104 $ builder = $ this ->getContainerBuilder ();
109- $ config = $ this ->validateConfig ( $ this -> defaults ) ;
105+ $ config = $ this ->config ;
110106
111107 $ sessionHandlingConnection = null ;
112108
113- foreach ($ config ['connection ' ] as $ name => $ connection ) {
114- $ connection = $ this ->validateConfig ($ this ->connectionDefaults , $ connection , $ this ->prefix ('connection. ' . $ name ));
115-
109+ foreach ($ config ->connection as $ name => $ connection ) {
116110 // Skip if replacing session is disabled
117- if ($ connection ['sessions ' ] === false ) continue ;
111+ if ($ connection ->sessions === false ) {
112+ continue ;
113+ }
118114
119115 if ($ sessionHandlingConnection === null ) {
120116 $ sessionHandlingConnection = $ name ;
@@ -126,35 +122,35 @@ public function beforeCompileSession(): void
126122 ));
127123 }
128124
129- // Validate given config
130- Validators::assert ($ connection ['sessions ' ], 'bool|array ' );
131-
132125 // Validate needed services
133126 if ($ builder ->getByType (Session::class) === null ) {
134127 throw new RuntimeException (sprintf ('Please install nette/http package. %s is required ' , Session::class));
135128 }
136129
137130 // Validate session config
138- if ($ connection ['sessions ' ] === true ) {
139- $ sessionConfig = $ this ->sessionDefaults ;
131+ if ($ connection ->sessions === true ) {
132+ $ sessionConfig = [
133+ 'ttl ' => null ,
134+ ];
140135 } else {
141- $ sessionConfig = $ this -> validateConfig ( $ this -> sessionDefaults , $ connection[ ' sessions ' ], $ this -> prefix ( ' connection. ' . $ name . ' sessions ' )) ;
136+ $ sessionConfig = ( array ) $ connection-> sessions ;
142137 }
143138
144139 $ sessionHandler = $ builder ->addDefinition ($ this ->prefix ('connection. ' . $ name . 'sessionHandler ' ))
145140 ->setType (Handler::class)
146- ->setArguments ([$ this ->prefix ('@connection. ' . $ name . '.client ' ), ['gc_maxlifetime ' => $ sessionConfig ['ttl ' ]]]);
141+ ->setArguments ([$ this ->prefix ('@connection. ' . $ name . '.client ' ), ['gc_maxlifetime ' => $ sessionConfig ['ttl ' ] ?? null ]]);
147142
148- $ builder ->getDefinitionByType (Session::class)
149- ->addSetup ('setHandler ' , [$ sessionHandler ]);
143+ $ session = $ builder ->getDefinitionByType (Session::class);
144+ assert ($ session instanceof ServiceDefinition);
145+ $ session ->addSetup ('setHandler ' , [$ sessionHandler ]);
150146 }
151147 }
152148
153149 public function afterCompile (ClassType $ class ): void
154150 {
155- $ config = $ this ->validateConfig ( $ this -> defaults ) ;
151+ $ config = $ this ->config ;
156152
157- if ($ config[ ' debug ' ] === true ) {
153+ if ($ config-> debug && $ config -> connection !== [] ) {
158154 $ initialize = $ class ->getMethod ('initialize ' );
159155 $ initialize ->addBody ('$this->getService(?)->addPanel($this->getService(?)); ' , ['tracy.bar ' , $ this ->prefix ('panel ' )]);
160156 }
0 commit comments