Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.29% covered (success)
89.29%
25 / 28
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Response
89.29% covered (success)
89.29%
25 / 28
66.67% covered (warning)
66.67%
2 / 3
16.31
0.00% covered (danger)
0.00%
0 / 1
 getParsedResponse
83.33% covered (success)
83.33%
15 / 18
0.00% covered (danger)
0.00%
0 / 1
9.37
 collect
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 json
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 * Pop PHP Framework (https://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@noladev.com>
7 * @copyright  Copyright (c) 2009-2025 NOLA Interactive, LLC.
8 * @license    https://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Http\Client;
15
16use Pop\Http\AbstractResponse;
17use Pop\Http\Parser;
18use Pop\Utils\Collection;
19
20/**
21 * HTTP client response class
22 *
23 * @category   Pop
24 * @package    Pop\Http
25 * @author     Nick Sagona, III <dev@noladev.com>
26 * @copyright  Copyright (c) 2009-2025 NOLA Interactive, LLC.
27 * @license    https://www.popphp.org/license     New BSD License
28 * @version    5.3.2
29 */
30class Response extends AbstractResponse
31{
32
33    /**
34     * Get the parsed response
35     *
36     * @return mixed
37     */
38    public function getParsedResponse(): mixed
39    {
40        $parsedResponse         = null;
41        $contentType            = null;
42        $contentEncoding        = null;
43        $contentTypeHeaders     = ['Content-Type', 'Content-type', 'content-type'];
44        $contentEncodingHeaders = ['Content-Encoding', 'Content-encoding', 'content-encoding'];
45
46        if ($this->hasBody()) {
47            $rawResponse = $this->getBody()->getContent();
48            foreach ($contentEncodingHeaders as $contentEncodingHeader) {
49                if ($this->hasHeader($contentEncodingHeader) && (count($this->getHeader($contentEncodingHeader)->getValues()) == 1)) {
50                    $contentEncoding = (string)$this->getHeader($contentEncodingHeader)->getValue(0);
51                    break;
52                }
53            }
54
55            foreach ($contentTypeHeaders as $contentTypeHeader) {
56                if ($this->hasHeader($contentTypeHeader) && (count($this->getHeader($contentTypeHeader)->getValues()) == 1)) {
57                    $contentType    = (string)$this->getHeader($contentTypeHeader)->getValue(0);
58                    $parsedResponse = Parser::parseDataByContentType($rawResponse, $contentType, $contentEncoding);
59                    if ($parsedResponse != $rawResponse) {
60                        break;
61                    }
62                }
63            }
64        }
65
66        return $parsedResponse;
67    }
68
69    /**
70     * Attempt to create a collection object from the response.
71     * Attempts a JSON decode on any content string that returns unparsed.
72     *
73     * @param  bool $forceJson
74     * @return Collection
75     */
76    public function collect(bool $forceJson = true): Collection
77    {
78        $data = ($forceJson) ? $this->json() : $this->getParsedResponse();
79
80        // Fall back to empty array on fail
81        if (!is_array($data)) {
82            $data = [];
83        }
84
85        return new Collection($data);
86    }
87
88    /**
89     * Attempts to JSON-decode any content string that returns unparsed.
90     *
91     * @return array
92     */
93    public function json(): array
94    {
95        $content = $this->getParsedResponse();
96
97        if (is_string($content)) {
98            $json = @json_decode($content, true);
99            if (json_last_error() === JSON_ERROR_NONE) {
100                $content = $json;
101            }
102        }
103
104        return (is_array($content)) ? $content : [];
105    }
106
107}