Completed
Branch dev (b63562)
by Marwan
01:48
created

Client::getServerEndpoint()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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