Test Failed
Pull Request — master (#660)
by butschster
09:30
created

BroadcastConfig::compilePattern()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Broadcasting\Config;
6
7
use Spiral\Broadcasting\Exception\InvalidArgumentException;
8
use Spiral\Core\InjectableConfig;
9
10
final class BroadcastConfig extends InjectableConfig
11
{
12
    public const CONFIG = 'broadcasting';
13
14
    protected $config = [
15
        'authorize' => [
16
            'path' => null,
17
            'topics' => [],
18
        ],
19
        'default' => 'null',
20
        'aliases' => [],
21
        'connections' => [],
22
        'driverAliases' => [],
23
    ];
24
    private array $patterns = [];
25
26
    public function __construct(array $config = [])
27
    {
28
        parent::__construct($config);
29
30
        $topics = (array)($config['authorize']['topics'] ?? []);
31
        foreach ($topics as $topic => $callback) {
32
            $this->patterns[$this->compilePattern($topic)] = $callback;
33
        }
34
    }
35
36
    /**
37
     * Get authorization path for broadcasting topics.
38
     */
39
    public function getAuthorizationPath(): ?string
40
    {
41
        return $this->config['authorize']['path'] ?? null;
42
    }
43
44
    /**
45
     * Get broadcast driver aliases
46
     */
47
    public function getAliases(): array
48
    {
49
        return (array)($this->config['aliases'] ?? []);
50
    }
51
52
    /**
53
     * Get default broadcast connection
54
     */
55
    public function getDefaultConnection(): string
56
    {
57
        if (!isset($this->config['default']) || empty($this->config['default'])) {
58
            throw new InvalidArgumentException('Default broadcast connection is not defined.');
59
        }
60
61
        if (!\is_string($this->config['default'])) {
62
            throw new InvalidArgumentException('Default broadcast connection config value must be a string');
63
        }
64
65
        return $this->config['default'];
66
    }
67
68
    public function getConnectionConfig(string $name): array
69
    {
70
        if (!isset($this->config['connections'][$name])) {
71
            throw new InvalidArgumentException(
72
                sprintf('Config for connection `%s` is not defined.', $name)
73
            );
74
        }
75
76
        $config = $this->config['connections'][$name];
77
78
        if (!isset($config['driver'])) {
79
            throw new InvalidArgumentException(
80
                sprintf('Driver for `%s` connection is not defined.', $name)
81
            );
82
        }
83
84
        if (!\is_string($config['driver'])) {
85
            throw new InvalidArgumentException(
86
                \sprintf('Driver value for `%s` connection must be a string', $name)
87
            );
88
        }
89
90
        if (isset($this->config['driverAliases'][$config['driver']])) {
91
            $config['driver'] = $this->config['driverAliases'][$config['driver']];
92
        }
93
94
        return $config;
95
    }
96
97
    public function findTopicCallback(string $topic, array &$matches): ?callable
98
    {
99
        foreach ($this->patterns as $pattern => $callback) {
100
            if (preg_match($pattern, $topic, $matches)) {
101
                return $callback;
102
            }
103
        }
104
105
        return null;
106
    }
107
108
    private function compilePattern(string $topic): string
109
    {
110
        $replaces = [];
111
        if (preg_match_all('/\{(\w+):?(.*?)?\}/', $topic, $matches)) {
112
            $variables = array_combine($matches[1], $matches[2]);
113
            foreach ($variables as $key => $_) {
114
                $replaces['{' . $key . '}'] = '(?P<' . $key . '>[^\/\.]+)';
115
            }
116
        }
117
118
        return '/^' . strtr($topic, $replaces + ['/' => '\\/', '[' => '(?:', ']' => ')?', '.' => '\.']) . '$/iu';
119
    }
120
}
121