Completed
Branch master (09022f)
by Gareth
05:56 queued 03:06
created

HttpPlayback::setHttpClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
3
namespace garethp\ews\HttpPlayback;
4
5
use GuzzleHttp\HandlerStack;
6
use GuzzleHttp\Middleware;
7
use GuzzleHttp\Handler\MockHandler;
8
use GuzzleHttp\Psr7\Response;
9
use GuzzleHttp\Client;
10
11
class HttpPlayback
12
{
13
    protected $mode = 'live';
14
15
    protected $callList = [];
16
17
    protected $recordLocation;
18
19
    protected $recordFileName = 'saveState.json';
20
21
    private $shutdownRegistered = false;
22
23
    private static $instances = [ ];
24
25
    /**
26
     * @var Client
27
     */
28
    private $client;
29
30 29
    public static function getInstance($options = [ ])
31
    {
32 29
        foreach (self::$instances as $instance) {
33 29
            if ($instance['options'] == $options) {
34 29
                return $instance['instance'];
35
            }
36
        }
37
38 26
        $instance = new static();
39 26
        $instance->setPlaybackOptions($options);
40 26
        self::$instances[] = [
41 26
            'instance' => $instance,
42 26
            'options' => $options
43
        ];
44
45 26
        return $instance;
46
    }
47
48 27
    public function setPlaybackOptions($options = [])
49
    {
50 27
        $options = array_replace_recursive(['mode' => null, 'recordLocation' => null, 'recordFileName' => null], $options);
51
52 27
        if ($options['mode'] !== null) {
53 26
            $this->mode = $options['mode'];
54
        }
55
56 27
        if ($options['recordLocation'] !== null) {
57 1
            $this->recordLocation = $options['recordLocation'];
58
        }
59
60 27
        if ($options['recordFileName'] !== null) {
61 26
            $this->recordFileName = $options['recordFileName'];
62
        }
63
    }
64
65
    /**
66
     * Get the client for making calls
67
     *
68
     * @return Client
69
     */
70 22
    public function getHttpClient()
71
    {
72 22
        if ($this->client == null) {
73 22
            $handler = HandlerStack::create();
74
75 22
            if ($this->mode == 'record') {
76
                $history = Middleware::history($this->callList);
77
                $handler->push($history);
78 22
            } elseif ($this->mode == 'playback') {
79 22
                $recordings = $this->getRecordings();
80
81 22
                $playList = $recordings;
82 22
                $mockedResponses = [];
83 22
                foreach ($playList as $item) {
84 22
                    $mockedResponses[] = new Response($item['statusCode'], $item['headers'], $item['body']);
85
                }
86
87 22
                $mockHandler = new MockHandler($mockedResponses);
88 22
                $handler = HandlerStack::create($mockHandler);
89
            }
90
91 22
            $this->client = new Client(['handler' => $handler]);
92
93 22
            if (!$this->shutdownRegistered) {
94 22
                register_shutdown_function(array($this, 'endRecord'));
95 22
                $this->shutdownRegistered = true;
96
            }
97
        }
98
99 22
        return $this->client;
100
    }
101
102
    /**
103
     * Sets the client
104
     *
105
     * @param Client $client
106
     * @return $this
107
     */
108
    public function setHttpClient($client)
109
    {
110
        $this->client = $client;
111
112
        return $this;
113
    }
114
115 23
    public function getRecordLocation()
116
    {
117 23
        if (!$this->recordLocation) {
118 22
            $dir = __DIR__;
119 22
            $dirPos = strrpos($dir, "src/API");
120 22
            $dir = substr($dir, 0, $dirPos);
121
122 22
            $this->recordLocation = $dir . 'Resources/recordings/';
123
        }
124
125 23
        return $this->recordLocation;
126
    }
127
128 23
    public function getRecordFilePath()
129
    {
130 23
        $path = $this->getRecordLocation() . $this->recordFileName;
131 23
        $path = str_replace("\\", "/", $path);
132 23
        return $path;
133
    }
134
135 22
    public function getRecordings()
136
    {
137 22
        $saveLocation = $this->getRecordFilePath();
138 22
        $records = json_decode(file_get_contents($saveLocation), true);
139
140 22
        return $records;
141
    }
142
143 1
    public function endRecord()
144
    {
145 1
        if ($this->mode != 'record') {
146 1
            return;
147
        }
148
149 1
        $saveList = [];
150 1
        foreach ($this->callList as $item) {
151
            /** @var Response $response */
152
            $response = $item['response'];
153
            $saveList[] = [
154
                'statusCode' => $response->getStatusCode(),
155
                'headers' => $response->getHeaders(),
156 1
                'body' => $response->getBody()->__toString()
157
            ];
158
        }
159
160 1
        $saveLocation = $this->getRecordFilePath();
161 1
        $folder = pathinfo($saveLocation)['dirname'];
162 1
        if (!is_dir($folder)) {
163 1
            mkdir($folder, 0777, true);
164
        }
165
166 1
        file_put_contents($saveLocation, json_encode($saveList));
167
    }
168
}
169