summaryrefslogtreecommitdiff
path: root/src/Http/Response.php
blob: a6b4ab74c179d45c8d2b6c8133f8de0234a7038f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php

namespace Engelsystem\Http;

use Engelsystem\Renderer\Renderer;
use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;

class Response extends SymfonyResponse implements ResponseInterface
{
    use MessageTrait;

    /** @var Renderer */
    protected $renderer;

    /**
     * @param string   $content
     * @param int      $status
     * @param array    $headers
     * @param Renderer $renderer
     */
    public function __construct(
        $content = '',
        int $status = 200,
        array $headers = [],
        Renderer $renderer = null
    ) {
        $this->renderer = $renderer;
        parent::__construct($content, $status, $headers);
    }

    /**
     * Return an instance with the specified status code and, optionally, reason phrase.
     *
     * If no reason phrase is specified, implementations MAY choose to default
     * to the RFC 7231 or IANA recommended reason phrase for the response's
     * status code.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * updated status and reason phrase.
     *
     * @link http://tools.ietf.org/html/rfc7231#section-6
     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
     * @param int    $code         The 3-digit integer result code to set.
     * @param string $reasonPhrase The reason phrase to use with the
     *                             provided status code; if none is provided, implementations MAY
     *                             use the defaults as suggested in the HTTP specification.
     * @return static
     * @throws InvalidArgumentException For invalid status code arguments.
     */
    public function withStatus($code, $reasonPhrase = '')
    {
        $new = clone $this;
        $new->setStatusCode($code, !empty($reasonPhrase) ? $reasonPhrase : null);

        return $new;
    }

    /**
     * Gets the response reason phrase associated with the status code.
     *
     * Because a reason phrase is not a required element in a response
     * status line, the reason phrase value MAY be null. Implementations MAY
     * choose to return the default RFC 7231 recommended reason phrase (or those
     * listed in the IANA HTTP Status Code Registry) for the response's
     * status code.
     *
     * @link http://tools.ietf.org/html/rfc7231#section-6
     * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
     * @return string Reason phrase; must return an empty string if none present.
     */
    public function getReasonPhrase()
    {
        return $this->statusText;
    }

    /**
     * Return an instance with the specified content.
     *
     * This method MUST be implemented in such a way as to retain the
     * immutability of the message, and MUST return an instance that has the
     * updated status and reason phrase.
     *
     * @param mixed $content Content that can be cast to string
     * @return static
     */
    public function withContent($content)
    {
        $new = clone $this;
        $new->setContent($content);

        return $new;
    }

    /**
     * Return an instance with the rendered content.
     *
     * This method retains the immutability of the message and returns
     * an instance with the updated status and headers
     *
     * @param string              $view
     * @param array               $data
     * @param int                 $status
     * @param string[]|string[][] $headers
     * @return Response
     */
    public function withView($view, $data = [], $status = 200, $headers = [])
    {
        if (!$this->renderer instanceof Renderer) {
            throw new InvalidArgumentException('Renderer not defined');
        }

        $new = clone $this;
        $new->setContent($this->renderer->render($view, $data));
        $new->setStatusCode($status, ($status == $this->getStatusCode() ? $this->statusText : null));

        foreach ($headers as $key => $values) {
            $new = $new->withAddedHeader($key, $values);
        }

        return $new;
    }

    /**
     * Return an redirect instance
     *
     * This method retains the immutability of the message and returns
     * an instance with the updated status and headers
     *
     * @param string $path
     * @param int    $status
     * @param array  $headers
     * @return Response
     */
    public function redirectTo($path, $status = 302, $headers = [])
    {
        $response = $this->withStatus($status);
        $response = $response->withHeader('location', $path);

        foreach ($headers as $name => $value) {
            $response = $response->withAddedHeader($name, $value);
        }

        return $response;
    }

    /**
     * Set the renderer to use
     *
     * @param Renderer $renderer
     */
    public function setRenderer(Renderer $renderer)
    {
        $this->renderer = $renderer;
    }
}