Completed
Push — master ( e48163...a19c3c )
by Artem
01:18
created

ResponseProcessor::processResponseResult()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
/*
3
 * This file is part of the FreshCentrifugoBundle.
4
 *
5
 * (c) Artem Henvald <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Fresh\CentrifugoBundle\Service;
14
15
use Fresh\CentrifugoBundle\Exception\CentrifugoErrorException;
16
use Fresh\CentrifugoBundle\Exception\CentrifugoException;
17
use Fresh\CentrifugoBundle\Exception\LogicException;
18
use Fresh\CentrifugoBundle\Model\BatchRequest;
19
use Fresh\CentrifugoBundle\Model\CommandInterface;
20
use Fresh\CentrifugoBundle\Model\ResultableCommandInterface;
21
use Symfony\Contracts\HttpClient\ResponseInterface;
22
23
/**
24
 * ResponseProcessor.
25
 *
26
 * @author Artem Henvald <[email protected]>
27
 */
28
class ResponseProcessor
29
{
30
    /** @var CentrifugoChecker */
31
    private $centrifugoChecker;
32
33
    /**
34
     * @param CentrifugoChecker $centrifugoChecker
35
     */
36
    public function __construct(CentrifugoChecker $centrifugoChecker)
37
    {
38
        $this->centrifugoChecker = $centrifugoChecker;
39
    }
40
41
    /**
42
     * @param CommandInterface  $command
43
     * @param ResponseInterface $response
44
     *
45
     * @throws LogicException
46
     *
47
     * @return array|null
48
     */
49
    public function processResponse(CommandInterface $command, ResponseInterface $response): ?array
50
    {
51
        $this->centrifugoChecker->assertValidResponseStatusCode($response);
52
        $this->centrifugoChecker->assertValidResponseHeaders($response);
53
        $this->centrifugoChecker->assertValidResponseContentType($response);
54
55
        $content = $response->getContent();
56
57
        if ($command instanceof BatchRequest) {
58
            $contents = \explode("\n", $content);
59
            $result = [];
60
61
            if (\count($contents) !== $command->getNumberOfCommands()) {
62
                throw new LogicException('Number of command doesn\'t match number of responses');
63
            }
64
65
            $i = 0;
66
            foreach ($command->getCommands() as $innerCommand) {
67
                $result[] = $this->decodeAndProcessResponseResult($innerCommand, $contents[$i]);
68
                ++$i;
69
            }
70
71
            return $result;
72
        }
73
74
        return $this->decodeAndProcessResponseResult($command, $content);
75
    }
76
77
    /**
78
     * @param CommandInterface $command
79
     * @param string           $content
80
     *
81
     * @throws CentrifugoException
82
     * @throws CentrifugoErrorException
83
     *
84
     * @return array|null
85
     */
86
    private function decodeAndProcessResponseResult(CommandInterface $command, string $content): ?array
87
    {
88
        try {
89
            $data = \json_decode($content, true, 512, \JSON_THROW_ON_ERROR);
90
        } catch (\Exception $e) {
91
            throw new CentrifugoException('Centrifugo response payload is not a valid JSON');
92
        }
93
94
        if (isset($data['error'])) {
95
            throw new CentrifugoErrorException($data['error']['message'], $data['error']['code']);
96
        }
97
98
        if ($command instanceof ResultableCommandInterface) {
99
            return $data['result'];
100
        }
101
102
        return null;
103
    }
104
}
105