AcquiaNetworkClient::factory()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 14
cts 14
cp 1
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 14
nc 4
nop 1
crap 3
1
<?php
2
3
namespace Acquia\Network;
4
5
use Acquia\Common\Services;
6
use Acquia\Common\Version;
7
use Acquia\Network\Subscription;
8
use Acquia\Rest\ServiceManagerAware;
9
use fXmlRpc\Exception\ResponseException;
10
use Guzzle\Common\Collection;
11
use Guzzle\Service\Client;
12
13
class AcquiaNetworkClient extends Client implements ServiceManagerAware
14
{
15
    const NONCE_LENGTH = 55;
16
17
    /**
18
     * @var string
19
     */
20
    protected $networkId;
21
22
    /**
23
     * @var string
24
     */
25
    protected $networkKey;
26
27
    /**
28
     * @var string
29
     */
30
    protected $serverAddress;
31
32
    /**
33
     * @var string
34
     */
35
    protected $httpHost;
36
37
    /**
38
     * @var bool
39
     */
40
    protected $https;
41
42
    /**
43
     * {@inheritdoc}
44
     *
45
     * @return \Acquia\Network\AcquiaNetworkClient
46
     */
47 39
    public static function factory($config = array())
0 ignored issues
show
Coding Style introduced by
factory uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
48
    {
49
50
        $defaults = array(
51 39
            'base_url'       => 'https://rpc.acquia.com',
52 39
            'server_address' => isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '',
53 39
            'http_host'      => isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '',
54 39
            'https'          => false,
55 39
            'network_id'     => '',
56 39
            'network_key'    => '',
57 39
        );
58
59
        // Instantiate the Acquia Search plugin.
60 39
        $config = Collection::fromConfig($config, $defaults);
61 39
        return new static(
62 39
            $config->get('base_url'),
63 39
            $config->get('network_id'),
64 39
            $config->get('network_key'),
65
            $config
66 39
        );
67
    }
68
69
    /**
70
     * @param string $networkUri
71
     * @param string $networkId
72
     * @param string $networkKey
73
     * @param mixed $config
74
     */
75 39
    public function __construct($networkUri, $networkId, $networkKey, $config = null)
76
    {
77 39
        $this->networkId = $networkId;
78 39
        $this->networkKey = $networkKey;
79 39
        $this->serverAddress = $config->get('server_address');
80 39
        $this->httpHost = $config->get('http_host');
81 39
        $this->https = $config->get('https');
82
83 39
        parent::__construct($networkUri, $config);
84 39
    }
85
86
    /**
87
     * @return string
88
     */
89 3
    public function getNetworkId()
90
    {
91 3
        return $this->networkId;
92
    }
93
94
    /**
95
     * @return string
96
     */
97 13
    public function getNetworkKey()
98
    {
99 13
        return $this->networkKey;
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105 3
    public function getBuilderParams()
106
    {
107
        return array(
108 3
            'base_url'    => $this->getConfig('base_url'),
0 ignored issues
show
Documentation introduced by
'base_url' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
109 3
            'network_id'  => $this->networkId,
110 3
            'network_key' => $this->networkKey,
111 3
        );
112
    }
113
114
    /**
115
     * Returns default paramaters for request. Not every call requires these.
116
     *
117
     * @return array
118
     */
119 21
    protected function defaultRequestParams()
120
    {
121
        $params = array(
122 21
            'authenticator' => $this->buildAuthenticator(),
123 21
            'ssl'           => $this->https === true ? 1 : 0,
124 21
            'ip'            => $this->serverAddress,
125 21
            'host'          => $this->httpHost,
126 21
        );
127 21
        return $params;
128
    }
129
130
    /**
131
     * @param string $method
132
     * @param array $params
133
     *
134
     * @return array
135
     *
136
     * @throws \fXmlRpc\Exception\ResponseException
137
     */
138 27
    protected function call($method, array $params)
139
    {
140 27
        $uri = $this->getConfig('base_url') . '/xmlrpc.php';
0 ignored issues
show
Documentation introduced by
'base_url' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
141 27
        $bridge = new \fXmlRpc\Transport\GuzzleBridge($this);
142 27
        $client = new \fXmlRpc\Client($uri, $bridge);
143
144
        // We have to nest the params in an array otherwise we get a "Wrong
145
        // number of method parameters" error.
146 27
        return $client->call($method, array($params));
147
    }
148
149
    /**
150
     * @param string &$errstr
151
     *
152
     * @return bool
153
     */
154 6
    public function validateCredentials(&$errstr = null)
155
    {
156
        try {
157 6
            $errstr = '';
158 6
            $params = $this->defaultRequestParams();
159 6
            $this->call('acquia.agent.validate', $params);
160 3
            return true;
161 3
        } catch (ResponseException $e) {
162 3
            $errstr = $e->getMessage();
163 3
            return false;
164
        }
165
    }
166
167
    /**
168
     * @return string
169
     *
170
     * @throws \UnexpectedValueException
171
     * @throws \OutOfBoundsException
172
     */
173 9
    public function getSubscriptionName()
174
    {
175 9
        if (empty($this->networkId)) {
176 3
            throw new \UnexpectedValueException('Acquia Network identifier required');
177
        }
178
179 6
        $params = $this->defaultRequestParams();
180 6
        $params['body'] = array(
181 6
            'identifier' => $this->networkId,
182
        );
183
184 6
        $response = $this->call('acquia.agent.subscription.name', $params);
185 6
        if (!isset($response['body']['subscription']['site_name'])) {
186 3
            throw new \OutOfBoundsException('Invalid response returned from server.');
187
        }
188
189 3
        return $response['body']['subscription']['site_name'];
190
    }
191
192
    /**
193
     * @param string $email
194
     *
195
     * @return array
196
     *
197
     * @throws \fXmlRpc\Exception\ResponseException
198
     */
199 3
    public function getCommunicationSettings($email)
200
    {
201
        // Build a light authenticator.
202 3
        $signature = new Signature('x');
203 3
        $signature->getNoncer()->setLength(self::NONCE_LENGTH);
204
        $authentiator = array(
205 3
            'time' => $signature->getRequestTime(),
206 3
            'hash' => $signature->generate(),
207 3
            'nonce' => $signature->getNonce(),
208 3
        );
209
        $params = array(
210 3
            'authenticator' => $authentiator,
211 3
            'body' => array('email' => $email),
212 3
        );
213
214 3
        return $this->call('acquia.agent.communication.settings', $params);
215
    }
216
217
    /**
218
     * @param $email
219
     * @param $password
220
     *
221
     * @throws \fXmlRpc\Exception\ResponseException
222
     */
223 3
    public function getSubscriptionCredentials($email, $password)
224
    {
225
        // Build a light authenticator.
226 3
        $signature = new Signature($password);
227 3
        $signature->getNoncer()->setLength(self::NONCE_LENGTH);
228
        $authentiator = array(
229 3
            'time' => $signature->getRequestTime(),
230 3
            'hash' => $signature->generate(),
231 3
            'nonce' => $signature->getNonce(),
232 3
        );
233
        $params = array(
234 3
            'authenticator' => $authentiator,
235 3
            'body' => array('email' => $email),
236 3
        );
237
238 3
        $response = $this->call('acquia.agent.subscription.credentials', $params);
239
        // @todo catch error and/or check response is_error
240
        // @todo set this key/id
241 3
        return $response;
242
    }
243
244
    /*
245
     * @params array
246
     *   Parameters to have signed.
247
     *
248
     * @return string
249
     */
250 21
    protected function buildAuthenticator($params = array())
251
    {
252 21
        $signature = new Signature($this->networkKey);
253 21
        $signature->getNoncer()->setLength(self::NONCE_LENGTH);
254
255
        $authenticator = array(
256 21
            'identifier' => $this->networkId,
257 21
            'time' => $signature->getRequestTime(),
258 21
            'hash' => $signature->generate($params),
259 21
            'nonce' => $signature->getNonce(),
260 21
        );
261
262 21
        return $authenticator;
263
    }
264
265
    /**
266
     * @param array $options
267
     *   - search_version: An array of search module versions keyed by name.
268
     *   - no_heartbeat: Pass 1 to not send a heartbeat.
269
     *
270
     * @return \Acquia\Network\Subscription
271
     */
272 9
    public function getSubscription(array $options = array())
273
    {
274 9
        $params = $this->defaultRequestParams();
275 9
        $params['body'] = $options;
276
277 9
        $response = $this->call('acquia.agent.subscription', $params);
278 9
        return Subscription::loadFromResponse($this->networkId, $this->networkKey, $response);
0 ignored issues
show
Documentation introduced by
$response is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
279
    }
280
281
    /**
282
     * @param int $services
283
     *
284
     * @return \Acquia\Network\Subscription
285
     */
286 3
    public function checkSubscription($services = 0)
287
    {
288 3
        $options = array();
289
290 3
        if ($services & Services::ACQUIA_SEARCH) {
291
            $options = array(
292 3
                'search_version' => array('acquia/acquia-search-sdk' => Version::RELEASE)
293 3
            );
294 3
        }
295
296 3
        return $this->getSubscription($options);
297
    }
298
299
    /**
300
     * @return boolean
301
     */
302 6
    public function subscriptionActive()
303
    {
304 6
        $subscription = $this->getSubscription(array('no_heartbeat' => 1));
305 6
        return $subscription->isActive();
306
    }
307
}
308