BaseDynamicChannelFormula::getChannelIdentifier()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 18
ccs 0
cts 8
cp 0
rs 9.9666
cc 3
nc 4
nop 0
crap 12
1
<?php
2
3
namespace MallardDuck\DynamicEcho\Channels;
4
5
use Illuminate\Broadcasting\Channel;
6
use Illuminate\Support\Str;
7
use RuntimeException;
8
9
/**
10
 * Trait UsesDynamicChannelFormula
11
 *
12
 * @implements HasDynamicChannelFormula
13
 * @package MallardDuck\DynamicEcho\Channels
14
 */
15
trait BaseDynamicChannelFormula
16
{
17
    protected static ?AbstractChannelParameters $dynamicChannel = null;
18
19
    public static function getChannelParametersClassname(): string
20
    {
21
        throw new \BadMethodCallException("This method should be redefined by the base class.");
22
    }
23
24
    private static function getChannelParametersClass(): AbstractChannelParameters
25
    {
26
        if (null === self::$dynamicChannel) {
27
            self::$dynamicChannel = self::getChannelParametersClassname()::getInstance();
28
        }
29
30
        return self::$dynamicChannel;
31
    }
32
33
    /**
34
     * @example:
35
     *         'App.Models.Game.{gameID}.User.{userID}'
36
     *
37
     * @return string
38
     */
39
    public static function getChannelAuthName(): string
40
    {
41
        return self::getChannelParametersClass()->channelAuthName;
42
    }
43
44
    /**
45
     * @example:
46
     *         'App.Models.Game.42.User.1'
47
     *
48
     * @return string
49
     * @throws RuntimeException
50
     */
51
    public function getChannelIdentifier(): string
52
    {
53
        $bindings = $this->getChannelIdentifierBindings();
54
        $identifierFormula = self::getChannelAuthName();
55
56
57
        foreach ($bindings as $binding => $value) {
58
            $identifierFormula = Str::replaceFirst("{" . $binding . "}", $value, $identifierFormula);
59
        }
60
61
        if (Str::contains($identifierFormula, ["{", "}"])) {
62
            throw new RuntimeException(sprintf(
63
                "Fatal Error: Channel identifier [%s] bindings not properly replaced. Still contains curly braces.",
64
                $identifierFormula
65
            ));
66
        }
67
68
        return $identifierFormula;
69
    }
70
71
    /**
72
     * Rewrites the identifier for JS channel listener.
73
     *
74
     * Essentially replaces the dynamic bindings with "${" instead of "{".
75
     *
76
     * @example:
77
     *         'App.Models.Game.${gameID}.User.${userID}'
78
     *
79
     * @return string
80
     */
81
    public static function getJSChannelIdentifier(): string
82
    {
83
        return str_replace('{', '${', self::getChannelAuthName());
84
    }
85
86
    /**
87
     * @return array
88
     *
89
     * @example:
90
     * [
91
     *     'gameID' => $this->gameId
92
     *     'userID' => $this->userId
93
     * ]
94
     */
95
    public function getChannelIdentifierBindings(): array
96
    {
97
        $selfEvent = $this;
98
        $callback = self::getChannelParametersClass()->eventChannelIdentifierBindingCallback;
99
100
        return $callback($selfEvent);
101
    }
102
103
    /**
104
     * A class string for the type of event channel to use.
105
     *
106
     * @example Options as follows:
107
     *  @see \Illuminate\Broadcasting\Channel
108
     *  @see \Illuminate\Broadcasting\PrivateChannel
109
     *
110
     * @return string
111
     */
112
    public function getChannelType(): string
113
    {
114
        return self::getChannelParametersClass()->channelType;
115
    }
116
117
    /**
118
     * This method takes the Formula class and builds the channel.
119
     *
120
     * @return Channel
121
     */
122
    public function buildChannelFormula(): Channel
123
    {
124
        $channelType = $this->getChannelType();
125
        $channelIdentifier = $this->getChannelIdentifier();
126
127
        return new $channelType($channelIdentifier);
128
    }
129
130
    public function broadcastOn(): Channel
131
    {
132
        return $this->buildChannelFormula();
133
    }
134
}
135