• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

contributte / redis / 6689966258

16 Oct 2023 06:35AM UTC coverage: 58.621% (+5.8%) from 52.838%
6689966258

push

github

f3l1x
Fix strict comparison, add tests

1 of 1 new or added line in 1 file covered. (100.0%)

136 of 232 relevant lines covered (58.62%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.74
/src/DI/RedisExtension.php
1
<?php declare(strict_types = 1);
2

3
namespace Contributte\Redis\DI;
4

5
use Contributte\Redis\Caching\RedisJournal;
6
use Contributte\Redis\Caching\RedisStorage;
7
use Contributte\Redis\Exception\Logic\InvalidStateException;
8
use Contributte\Redis\Tracy\RedisPanel;
9
use Nette\Caching\IStorage;
10
use Nette\DI\CompilerExtension;
11
use Nette\DI\Definitions\ServiceDefinition;
12
use Nette\Http\Session;
13
use Nette\PhpGenerator\ClassType;
14
use Nette\Schema\Expect;
15
use Nette\Schema\Schema;
16
use Predis\Client;
17
use Predis\ClientInterface;
18
use Predis\Session\Handler;
19
use RuntimeException;
20
use stdClass;
21

22
/**
23
 * @property-read stdClass $config
24
 */
25
final class RedisExtension extends CompilerExtension
26
{
27

28
        public function getConfigSchema(): Schema
29
        {
30
                return Expect::structure([
1✔
31
                        'debug' => Expect::bool(false),
1✔
32
                        'serializer' => Expect::anyOf(Expect::string()),
1✔
33
                        'connection' => Expect::arrayOf(Expect::structure([
1✔
34
                                'uri' => Expect::anyOf(Expect::string(), Expect::listOf(Expect::string()))->default('tcp://127.0.0.1:6379')->dynamic(),
1✔
35
                                'options' => Expect::array(),
1✔
36
                                'storageClass' => Expect::string()->default(RedisStorage::class),
1✔
37
                                'storage' => Expect::bool(false),
1✔
38
                                'sessions' => Expect::anyOf(
1✔
39
                                        Expect::bool(),
1✔
40
                                        Expect::array()
1✔
41
                                )->default(false),
1✔
42
                        ])),
43
                        'clientFactory' => Expect::string(Client::class),
1✔
44
                ]);
45
        }
46

47
        public function loadConfiguration(): void
48
        {
49
                $builder = $this->getContainerBuilder();
1✔
50
                $config = $this->config;
1✔
51

52
                $connections = [];
1✔
53

54
                foreach ($config->connection as $name => $connection) {
1✔
55
                        $autowired = $name === 'default';
1✔
56

57
                        $client = $builder->addDefinition($this->prefix('connection.' . $name . '.client'))
1✔
58
                                ->setType(ClientInterface::class)
1✔
59
                                ->setFactory($config->clientFactory, [$connection->uri, $connection->options])
1✔
60
                                ->setAutowired($autowired);
1✔
61

62
                        $connections[] = [
1✔
63
                                'name' => $name,
1✔
64
                                'client' => $client,
1✔
65
                                'uri' => $connection->uri,
1✔
66
                                'options' => $connection->options,
1✔
67
                        ];
68
                }
69

70
                if ($config->debug && $config->connection !== []) {
1✔
71
                        $builder->addDefinition($this->prefix('panel'))
×
72
                                ->setFactory(RedisPanel::class, [$connections]);
×
73
                }
74
        }
1✔
75

76
        public function beforeCompile(): void
77
        {
78
                $this->beforeCompileStorage();
1✔
79
                $this->beforeCompileSession();
1✔
80
        }
1✔
81

82
        public function beforeCompileStorage(): void
83
        {
84
                $builder = $this->getContainerBuilder();
1✔
85
                $config = $this->config;
1✔
86
                $storages = 0;
1✔
87

88
                foreach ($config->connection as $name => $connection) {
1✔
89
                        $autowired = $name === 'default';
1✔
90

91
                        // Skip if replacing storage is disabled
92
                        if (!$connection->storage) {
1✔
93
                                continue;
1✔
94
                        }
95

96
                        // Validate needed services
97
                        if ($builder->getByType(IStorage::class) === null) {
1✔
98
                                throw new RuntimeException(sprintf('Please install nette/caching package. %s is required', IStorage::class));
×
99
                        }
100

101
                        if ($storages === 0) {
1✔
102
                                $builder->getDefinitionByType(IStorage::class)
1✔
103
                                        ->setAutowired(false);
1✔
104
                        }
105

106
                        $builder->addDefinition($this->prefix('connection.' . $name . '.journal'))
1✔
107
                                ->setFactory(RedisJournal::class)
1✔
108
                                ->setAutowired(false);
1✔
109

110
                        $builder->addDefinition($this->prefix('connection.' . $name . '.storage'))
1✔
111
                                ->setFactory($connection->storageClass)
1✔
112
                                ->setArguments([
1✔
113
                                        'client' => $builder->getDefinition($this->prefix('connection.' . $name . '.client')),
1✔
114
                                        'journal' => $builder->getDefinition($this->prefix('connection.' . $name . '.journal')),
1✔
115
                                        'serializer' => $config->serializer,
1✔
116
                                ])
117
                                ->setAutowired($autowired);
1✔
118

119
                        $storages++;
1✔
120
                }
121
        }
1✔
122

123
        public function beforeCompileSession(): void
124
        {
125
                $builder = $this->getContainerBuilder();
1✔
126
                $config = $this->config;
1✔
127

128
                $sessionHandlingConnection = null;
1✔
129

130
                foreach ($config->connection as $name => $connection) {
1✔
131
                        // Skip if replacing session is disabled
132
                        if ($connection->sessions === false) {
1✔
133
                                continue;
1✔
134
                        }
135

136
                        if ($sessionHandlingConnection === null) {
×
137
                                $sessionHandlingConnection = $name;
×
138
                        } else {
139
                                throw new InvalidStateException(sprintf(
×
140
                                        'Connections "%s" and "%s" both try to register session handler. Only one of them could have session handler enabled.',
×
141
                                        $sessionHandlingConnection,
142
                                        $name
143
                                ));
144
                        }
145

146
                        // Validate needed services
147
                        if ($builder->getByType(Session::class) === null) {
×
148
                                throw new RuntimeException(sprintf('Please install nette/http package. %s is required', Session::class));
×
149
                        }
150

151
                        // Validate session config
152
                        if ($connection->sessions === true) {
×
153
                                $sessionConfig = [
×
154
                                        'ttl' => null,
155
                                ];
156
                        } else {
157
                                $sessionConfig = (array) $connection->sessions;
×
158
                        }
159

160
                        $sessionHandler = $builder->addDefinition($this->prefix('connection.' . $name . 'sessionHandler'))
×
161
                                ->setType(Handler::class)
×
162
                                ->setArguments([$this->prefix('@connection.' . $name . '.client'), ['gc_maxlifetime' => $sessionConfig['ttl'] ?? null]]);
×
163

164
                        $session = $builder->getDefinitionByType(Session::class);
×
165
                        assert($session instanceof ServiceDefinition);
×
166
                        $session->addSetup('setHandler', [$sessionHandler]);
×
167
                }
168
        }
1✔
169

170
        public function afterCompile(ClassType $class): void
1✔
171
        {
172
                $config = $this->config;
1✔
173

174
                if ($config->debug && $config->connection !== []) {
1✔
175
                        $initialize = $class->getMethod('initialize');
×
176
                        $initialize->addBody('$this->getService(?)->addPanel($this->getService(?));', ['tracy.bar', $this->prefix('panel')]);
×
177
                }
178
        }
1✔
179

180
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc