Client::get()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 6
c 2
b 0
f 0
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
/**
4
 * @author Marwan Al-Soltany <[email protected]>
5
 * @copyright Marwan Al-Soltany 2020
6
 * For the full copyright and license information, please view
7
 * the LICENSE file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace MAKS\AmqpAgent;
13
14
use MAKS\AmqpAgent\Config;
15
use MAKS\AmqpAgent\Worker\Publisher;
16
use MAKS\AmqpAgent\Worker\Consumer;
17
use MAKS\AmqpAgent\RPC\ClientEndpoint;
18
use MAKS\AmqpAgent\RPC\ServerEndpoint;
19
use MAKS\AmqpAgent\Helper\ArrayProxy;
20
use MAKS\AmqpAgent\Helper\Serializer;
21
use MAKS\AmqpAgent\Helper\Logger;
22
use MAKS\AmqpAgent\Exception\AmqpAgentException;
23
24
/**
25
 * A class returns everything AMQP Agent has to offer. A simple service container so to say.
26
 *
27
 * Example:
28
 * ```
29
 * $config = new Config('path/to/some/config-file.php');
30
 * $client = new Client($config);
31
 * $publisher = $client->getPublisher(); // or $client->get('publisher');
32
 * $consumer = $client->getConsumer(); // or $client->get('consumer');
33
 * ```
34
 *
35
 * @since 1.0.0
36
 * @api
37
 */
38
class Client
39
{
40
    /**
41
     * An instance of the configuration object.
42
     * @var Config
43
     */
44
    protected $config;
45
46
    /**
47
     * An instance of the Publisher class.
48
     * @var Publisher
49
     */
50
    protected $publisher;
51
52
    /**
53
     * An instance of the Consumer class.
54
     * @var Consumer
55
     */
56
    protected $consumer;
57
58
    /**
59
     * An instance of the RPC Client class.
60
     * @var ClientEndpoint
61
     */
62
    protected $clientEndpoint;
63
64
    /**
65
     * An instance of the RPC Server class.
66
     * @var ServerEndpoint
67
     */
68
    protected $serverEndpoint;
69
70
    /**
71
     * An instance of the Serializer class.
72
     * @var Serializer
73
     */
74
    protected $serializer;
75
76
    /**
77
     * An instance of the Logger class.
78
     * @var Logger
79
     */
80
    protected $logger;
81
82
83
    /**
84
     * Client object constructor.
85
     * @param Config|string $config An instance of the Config class or a path to a config file.
86
     * @throws AmqpAgentException
87
     */
88 11
    public function __construct($config)
89
    {
90 11
        if ($config instanceof Config) {
91 11
            $this->config = $config;
92 2
        } elseif (is_string($config) && strlen(trim($config)) > 0) {
93 1
            $this->config = new Config($config);
94
        } else {
95 1
            throw new AmqpAgentException(
96 1
                'A Config instance or a valid path to a config file must be specified.'
97
            );
98
        }
99 11
    }
100
101
    /**
102
     * Gets a class member via public property access notation.
103
     * @param string $member Property name.
104
     * @return mixed
105
     * @throws AmqpAgentException
106
     */
107 7
    public function __get(string $member)
108
    {
109
        // using $this->get() to reuse the logic in get() method.
110 7
        return $this->get($member);
111
    }
112
113
114
    /**
115
     * Returns an instance of a class by its name (lowercase, UPPERCASE, PascalCase, camelCase, dot.case, kebab-case, or snake_case representation of class name).
116
     * @param string $member Member name. Check out `self::gettable()` for available members.
117
     * @return Config|Publisher|Consumer|Serializer|Logger
118
     * @throws AmqpAgentException
119
     */
120 8
    public function get(string $member)
121
    {
122 8
        $method = __FUNCTION__ . preg_replace('/[\.\-_]+/', '', ucwords(strtolower($member), '.-_'));
123
124 8
        if (method_exists($this, $method)) {
125 7
            return $this->{$method}();
126
        }
127
128 1
        $available = ArrayProxy::castArrayToString($this->gettable());
129 1
        throw new AmqpAgentException(
130 1
            "The requested member with the name \"{$member}\" does not exist! Available members are: {$available}."
131
        );
132
    }
133
134
135
    /**
136
     * Returns an array of available members that can be obtained via `self::get()`.
137
     * @since 1.2.1
138
     * @return array
139
     */
140 2
    public static function gettable(): array
141
    {
142 2
        $methods = get_class_methods(static::class);
143 2
        $gettable = [];
144 2
        $separator = ('.-_')[rand(0, 2)];
145
146 2
        foreach ($methods as $method) {
147 2
            if (preg_match('/get[A-Z][a-z]+/', $method)) {
148 2
                $gettable[] = strtolower(
149 2
                    preg_replace(
150 2
                        ['/get/', '/([a-z])([A-Z])/'],
151 2
                        ['', '$1' . $separator . '$2'],
152 2
                        $method
153
                    )
154
                );
155
            }
156
        }
157
158 2
        return $gettable;
159
    }
160
161
162
    /**
163
     * Returns an instance of the Publisher class.
164
     * @return Publisher
165
     * @api
166
     */
167 1
    public function getPublisher(): Publisher
168
    {
169 1
        if (!isset($this->publisher)) {
170 1
            $this->publisher = new Publisher(
171 1
                $this->config->connectionOptions,
172 1
                $this->config->channelOptions,
173 1
                $this->config->queueOptions,
174 1
                $this->config->exchangeOptions,
175 1
                $this->config->bindOptions,
176 1
                $this->config->messageOptions,
177 1
                $this->config->publishOptions
178
            );
179
        }
180
181 1
        return $this->publisher;
182
    }
183
184
    /**
185
     * Returns an instance of the Consumer class.
186
     * @return Consumer
187
     */
188 1
    public function getConsumer(): Consumer
189
    {
190 1
        if (!isset($this->consumer)) {
191 1
            $this->consumer = new Consumer(
192 1
                $this->config->connectionOptions,
193 1
                $this->config->channelOptions,
194 1
                $this->config->queueOptions,
195 1
                $this->config->qosOptions,
196 1
                $this->config->waitOptions,
197 1
                $this->config->consumeOptions
198
            );
199
        }
200
201 1
        return $this->consumer;
202
    }
203
204
    /**
205
     * Returns an instance of the RPC Client class.
206
     * @return ClientEndpoint
207
     */
208 1
    public function getClientEndpoint(): ClientEndpoint
209
    {
210 1
        if (!isset($this->clientEndpoint)) {
211 1
            $this->clientEndpoint = new ClientEndpoint(
212 1
                $this->config->rpcConnectionOptions,
213 1
                $this->config->rpcQueueName
214
            );
215
        }
216
217 1
        return $this->clientEndpoint;
218
    }
219
220
    /**
221
     * Returns an instance of the RPC Server class.
222
     * @return ServerEndpoint
223
     */
224 1
    public function getServerEndpoint(): ServerEndpoint
225
    {
226 1
        if (!isset($this->serverEndpoint)) {
227 1
            $this->serverEndpoint = new ServerEndpoint(
228 1
                $this->config->rpcConnectionOptions,
229 1
                $this->config->rpcQueueName
230
            );
231
        }
232
233 1
        return $this->serverEndpoint;
234
    }
235
236
    /**
237
     * Returns an instance of the Serializer class.
238
     * @return Serializer
239
     */
240 1
    public function getSerializer(): Serializer
241
    {
242 1
        if (!isset($this->serializer)) {
243 1
            $this->serializer = new Serializer();
244
        }
245
246 1
        return $this->serializer;
247
    }
248
249
    /**
250
     * Returns an instance of the Logger class.
251
     * Filename and directory must be set through setters.
252
     * @return Logger
253
     */
254 2
    public function getLogger(): Logger
255
    {
256 2
        if (!isset($this->logger)) {
257 2
            $this->logger = new Logger(null, null);
258
        }
259
260 2
        return $this->logger;
261
    }
262
263
    /**
264
     * Returns the currently used config object.
265
     * @return Config
266
     */
267 1
    public function getConfig(): Config
268
    {
269 1
        return $this->config;
270
    }
271
}
272