Completed
Push — response-service ( 6a9516 )
by Yuichi
06:42
created

ResponseService::isJsonResponse()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 4
nc 8
nop 0
crap 4
1
<?php
2
3
namespace CybozuHttp\Service;
4
5
use GuzzleHttp\Exception\ClientException;
6
use GuzzleHttp\Exception\RequestException;
7
use GuzzleHttp\Exception\ServerException;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\ResponseInterface;
10
11
/**
12
 * @author ochi51 <[email protected]>
13
 */
14
class ResponseService
15
{
16
    /**
17
     * @var RequestInterface
18
     */
19
    private $request;
20
21
    /**
22
     * @var ResponseInterface
23
     */
24
    private $response;
25
26
    /**
27
     * ResponseService constructor.
28
     * @param RequestInterface $request
29
     * @param ResponseInterface $response
30
     */
31 63
    public function __construct(RequestInterface $request, ResponseInterface $response)
32
    {
33 63
        $this->request = $request;
34 63
        $this->response = $response;
35 63
    }
36
37
    /**
38
     * @return bool
39
     */
40 61
    public function isJsonResponse(): bool
41
    {
42 61
        $contentType = $this->response->getHeader('Content-Type');
43 61
        $contentType = is_array($contentType) && isset($contentType[0]) ? $contentType[0] : $contentType;
44
45 61
        return is_string($contentType) && strpos($contentType, 'application/json') === 0;
46
    }
47
48
49
    /**
50
     * @throws RequestException
51
     */
52 2
    public function handleDomError(): void
53
    {
54 2
        $body = (string)$this->response->getBody()->getContents();
55 2
        $dom = new \DOMDocument('1.0', 'UTF-8');
56 2
        $dom->preserveWhiteSpace = false;
57 2
        $dom->formatOutput = true;
58 2
        if ($dom->loadHTML($body)) {
59 2
            $title = $dom->getElementsByTagName('title');
60 2
            if (is_object($title)) {
61 2
                $title = $title->item(0)->nodeValue;
62
            }
63 2
            if ($title === 'Error') {
64 2
                $message = $dom->getElementsByTagName('h3')->item(0)->nodeValue;
65 2
                throw $this->createException($message);
66
            }
67 2
            if ($title === 'Unauthorized') {
68 2
                $message = $dom->getElementsByTagName('h2')->item(0)->nodeValue;
69 2
                throw $this->createException($message);
70
            }
71
72 1
            throw $this->createException('Invalid auth.');
73
        }
74
75
        throw new \InvalidArgumentException('Body is not DOM.');
76
    }
77
78
    /**
79
     * @throws RequestException
80
     */
81 4
    public function handleJsonError(): void
82
    {
83
        try {
84 4
            $body = (string)$this->response->getBody()->getContents();
85 4
            $json = \GuzzleHttp\json_decode($body, true);
86 1
        } catch (\InvalidArgumentException $e) {
87 1
            return;
88 1
        } catch (\RuntimeException $e) {
89 1
            return;
90
        }
91
92 4
        $message = $json['message'];
93 4
        if (isset($json['errors']) && is_array($json['errors'])) {
94 1
            $message .= $this->addErrorMessages($json['errors']);
95
        }
96
97 4
        throw $this->createException($message);
98
    }
99
100
    /**
101
     * @param array $errors
102
     * @return string
103
     */
104 1
    private function addErrorMessages(array $errors): string
105
    {
106 1
        $message = ' (';
107 1
        foreach ($errors as $k => $err) {
108 1
            $message .= $k . ' : ';
109 1
            if (is_array($err['messages'])) {
110 1
                foreach ($err['messages'] as $m) {
111 1
                    $message .= $m . ' ';
112
                }
113
            } else {
114 1
                $message .= $err['messages'];
115
            }
116
        }
117 1
        $message .= ')';
118
119 1
        return $message;
120
    }
121
122
    /**
123
     * @param string $message
124
     * @return RequestException
125
     */
126 6
    public function createException($message): RequestException
127
    {
128 6
        $level = (int) floor($this->response->getStatusCode() / 100);
129 6
        $className = RequestException::class;
130
131 6
        if ($level === 4) {
132 4
            $className = ClientException::class;
133 4
        } elseif ($level === 5) {
134 4
            $className = ServerException::class;
135
        }
136
137 6
        return new $className($message, $this->request, $this->response);
138
    }
139
}
140