Completed
Pull Request — master (#23)
by Simon
08:01
created

AMQPConnectionFactory::parseUrl()   C

Complexity

Conditions 12
Paths 66

Size

Total Lines 38
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 21
nc 66
nop 1
dl 0
loc 38
rs 6.9666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace OldSound\RabbitMqBundle\RabbitMq;
4
5
use OldSound\RabbitMqBundle\Provider\ConnectionParametersProviderInterface;
6
use PhpAmqpLib\Connection\AbstractConnection;
7
use PhpAmqpLib\Connection\AMQPSocketConnection;
8
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
9
10
class AMQPConnectionFactory
11
{
12
    /** @var \ReflectionClass */
13
    private $class;
14
15
    /** @var array */
16
    private $parameters = array(
17
        'url'                => '',
18
        'host'               => 'localhost',
19
        'port'               => 5672,
20
        'user'               => 'guest',
21
        'password'           => 'guest',
22
        'vhost'              => '/',
23
        'connection_timeout' => 3,
24
        'read_write_timeout' => 3,
25
        'ssl_context'        => null,
26
        'keepalive'          => false,
27
        'heartbeat'          => 0,
28
    );
29
30
    /**
31
     * Constructor
32
     *
33
     * @param string                                $class              FQCN of AMQPConnection class to instantiate.
34
     * @param array                                 $parameters         Map containing parameters resolved by
35
     *                                                                  Extension.
36
     * @param ConnectionParametersProviderInterface $parametersProvider Optional service providing/overriding
37
     *                                                                  connection parameters.
38
     */
39
    public function __construct(
40
        $class,
41
        array $parameters,
42
        ConnectionParametersProviderInterface $parametersProvider = null
43
    ) {
44
        $this->class = $class;
0 ignored issues
show
Documentation Bug introduced by
It seems like $class of type string is incompatible with the declared type ReflectionClass of property $class.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
45
        $this->parameters = array_merge($this->parameters, $parameters);
46
        $this->parameters = $this->parseUrl($this->parameters);
47
        if (is_array($this->parameters['ssl_context'])) {
48
            $this->parameters['ssl_context'] = ! empty($this->parameters['ssl_context'])
49
                ? stream_context_create(array('ssl' => $this->parameters['ssl_context']))
50
                : null;
51
        }
52
        if ($parametersProvider) {
53
            $this->parameters = array_merge($this->parameters, $parametersProvider->getConnectionParameters());
54
        }
55
    }
56
57
    /**
58
     * Creates the appropriate connection using current parameters.
59
     *
60
     * @return AbstractConnection
61
     */
62
    public function createConnection()
63
    {
64
        $ref = new \ReflectionClass($this->class);
65
66
        if (isset($this->parameters['constructor_args']) && is_array($this->parameters['constructor_args'])) {
67
            return $ref->newInstanceArgs($this->parameters['constructor_args']);
68
        }
69
70
        if ($this->class == 'PhpAmqpLib\Connection\AMQPSocketConnection' || is_subclass_of($this->class, 'PhpAmqpLib\Connection\AMQPSocketConnection')) {
71
            return $ref->newInstanceArgs([
72
                    $this->parameters['host'],
73
                    $this->parameters['port'],
74
                    $this->parameters['user'],
75
                    $this->parameters['password'],
76
                    $this->parameters['vhost'],
77
                    false,      // insist
78
                    'AMQPLAIN', // login_method
79
                    null,       // login_response
80
                    'en_US',    // locale
81
                    isset($this->parameters['read_timeout']) ? $this->parameters['read_timeout'] : $this->parameters['read_write_timeout'],
82
                    $this->parameters['keepalive'],
83
                    isset($this->parameters['write_timeout']) ? $this->parameters['write_timeout'] : $this->parameters['read_write_timeout'],
84
                    $this->parameters['heartbeat']
85
                ]
86
            );
87
        } else {
88
            return $ref->newInstanceArgs([
89
                $this->parameters['host'],
90
                $this->parameters['port'],
91
                $this->parameters['user'],
92
                $this->parameters['password'],
93
                $this->parameters['vhost'],
94
                false,      // insist
95
                'AMQPLAIN', // login_method
96
                null,       // login_response
97
                'en_US',    // locale
98
                $this->parameters['connection_timeout'],
99
                $this->parameters['read_write_timeout'],
100
                $this->parameters['ssl_context'],
101
                $this->parameters['keepalive'],
102
                $this->parameters['heartbeat']
103
            ]);
104
        }
105
    }
106
107
    /**
108
     * Parses connection parameters from URL parameter.
109
     *
110
     * @param array $parameters
111
     *
112
     * @return array
113
     */
114
    private function parseUrl(array $parameters)
115
    {
116
        if (!$parameters['url']) {
117
            return $parameters;
118
        }
119
120
        $url = parse_url($parameters['url']);
121
122
        if ($url === false || !isset($url['scheme']) || $url['scheme'] !== 'amqp' || $url['scheme'] !== 'amqps') {
123
            throw new InvalidConfigurationException('Malformed parameter "url".');
124
        }
125
126
        // See https://www.rabbitmq.com/uri-spec.html
127
        if (isset($url['host'])) {
128
            $parameters['host'] = urldecode($url['host']);
129
        }
130
        if (isset($url['port'])) {
131
            $parameters['port'] = (int)$url['port'];
132
        }
133
        if (isset($url['user'])) {
134
            $parameters['user'] = urldecode($url['user']);
135
        }
136
        if (isset($url['pass'])) {
137
            $parameters['password'] = urldecode($url['pass']);
138
        }
139
        if (isset($url['path'])) {
140
            $parameters['vhost'] = urldecode(ltrim($url['path'], '/'));
141
        }
142
143
        if (isset($url['query'])) {
144
            $query = array();
145
            parse_str($url['query'], $query);
146
            $parameters = array_merge($parameters, $query);
147
        }
148
149
        unset($parameters['url']);
150
151
        return $parameters;
152
    }
153
}
154