ScaleEngineRequestVisitor   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
c 1
b 0
f 0
lcom 1
cbo 2
dl 0
loc 83
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A visit() 0 6 2
A after() 0 14 3
A _getSignature() 0 6 1
1
<?php
2
namespace FloSports\ScaleEngine\Visitor;
3
4
use Guzzle\Http\Message\RequestInterface;
5
use Guzzle\Service\Command\CommandInterface;
6
use Guzzle\Service\Command\LocationVisitor\Request\AbstractRequestVisitor;
7
use Guzzle\Service\Description\Parameter;
8
use SplObjectStorage;
9
10
/**
11
 * Visitor used to apply a parameter to an array that will be signed and
12
 * serialized as a POST field named json in the response in accordance with
13
 * ScaleEngine's API format.
14
 */
15
class ScaleEngineRequestVisitor extends AbstractRequestVisitor
16
{
17
    /** @type \SplObjectStorage Data object for persisting JSON data. */
18
    private $_storage;
19
20
    /** @type string The API secret used to sign requests. */
21
    private $_apiSecret;
22
23
    /**
24
     * Create the visitor, initializing the SPL Object Storage.
25
     *
26
     * @param string $apiSecret The API secret used to sign requests.
27
     */
28
    public function __construct($apiSecret)
29
    {
30
        $this->_storage = new SplObjectStorage();
31
        $this->_apiSecret = $apiSecret;
32
    }
33
34
    /**
35
     * Handle a single parameter for a command.
36
     *
37
     * Each command has it's own storage inside the SPL Object Storage.  This
38
     * adds the parameter/value to the storage for that command, after
39
     * processing any filters, etc. for the parameter.
40
     *
41
     * @param CommandInterface $command The command the parameter is for.
42
     * @param RequestInterface $request The HTTP request being prepared.
43
     *     Unused.
44
     * @param Parameter $param The parameter definition being set.
45
     * @param mixed $value The value the parameter is being set to.
46
     * @return void
47
     */
48
    public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
49
    {
50
        $data = isset($this->_storage[$command]) ? $this->_storage[$command] : [];
51
        $data[$param->getWireName()] = $this->prepareValue($value, $param);
52
        $this->_storage[$command] = $data;
53
    }
54
55
    /**
56
     * Finalizes the data for a request and sets it in the response.
57
     *
58
     * ScaleEngine requires a signature of the request to be added to the
59
     * request.  The data is then JSON-encoded and shoved into a POST field
60
     * named `json`.
61
     *
62
     * @param CommandInterface $command The command being sent.
63
     * @param RequestInterface $request The HTTP request being prepared.  Will
64
     *     be modified with the serialized data added as a POST field.
65
     * @return void
66
     */
67
    public function after(CommandInterface $command, RequestInterface $request)
68
    {
69
        if (!isset($this->_storage[$command])) {
70
            return;
71
        }
72
73
        $data = $this->_storage[$command];
74
        unset($this->_storage[$command]);
75
76
        $data['timestamp'] = isset($data['timestamp']) ? $data['timestamp'] : time();
77
        $data['signature'] = $this->_getSignature($data);
78
79
        $request->setPostField('json', json_encode($data));
80
    }
81
82
    /**
83
     * Gets the signature of the data using ScaleEngine's algorithm.
84
     *
85
     * This is a potentially fragile method as it could break if `json_encode`
86
     * changes.
87
     *
88
     * @param array $data The data from the request to sign.
89
     * @return string The base64-encoded signature of the data.
90
     */
91
    private function _getSignature(array $data)
92
    {
93
        $json = json_encode($data);
94
95
        return base64_encode(hash_hmac('sha256', $json, $this->_apiSecret, true));
96
    }
97
}
98