xref: /template/strap/ComboStrap/HttpResponse.php (revision c3437056399326d621a01da73b649707fbb0ae69)
1*c3437056SNickeau<?php
2*c3437056SNickeau
3*c3437056SNickeau
4*c3437056SNickeaunamespace ComboStrap;
5*c3437056SNickeau
6*c3437056SNickeau
7*c3437056SNickeauuse TestRequest;
8*c3437056SNickeau
9*c3437056SNickeauclass HttpResponse
10*c3437056SNickeau{
11*c3437056SNickeau    public const EXIT_KEY = 'exit';
12*c3437056SNickeau
13*c3437056SNickeau
14*c3437056SNickeau    const STATUS_NOT_FOUND = 404;
15*c3437056SNickeau    public const STATUS_ALL_GOOD = 200;
16*c3437056SNickeau    const STATUS_NOT_MODIFIED = 304;
17*c3437056SNickeau    const STATUS_PERMANENT_REDIRECT = 301;
18*c3437056SNickeau    public const STATUS_DOES_NOT_EXIST = 404;
19*c3437056SNickeau    public const STATUS_UNSUPPORTED_MEDIA_TYPE = 415;
20*c3437056SNickeau    public const STATUS_BAD_REQUEST = 400;
21*c3437056SNickeau    public const STATUS_INTERNAL_ERROR = 500;
22*c3437056SNickeau    public const STATUS_NOT_AUTHORIZED = 401;
23*c3437056SNickeau    const MESSAGE_ATTRIBUTE = "message";
24*c3437056SNickeau
25*c3437056SNickeau    /**
26*c3437056SNickeau     * @var int
27*c3437056SNickeau     */
28*c3437056SNickeau    private $status;
29*c3437056SNickeau
30*c3437056SNickeau    private $canonical = "support";
31*c3437056SNickeau    /**
32*c3437056SNickeau     * @var \Doku_Event
33*c3437056SNickeau     */
34*c3437056SNickeau    private $event;
35*c3437056SNickeau    /**
36*c3437056SNickeau     * @var array
37*c3437056SNickeau     */
38*c3437056SNickeau    private $headers = [];
39*c3437056SNickeau    private $msg;
40*c3437056SNickeau
41*c3437056SNickeau
42*c3437056SNickeau    /**
43*c3437056SNickeau     * Error constructor.
44*c3437056SNickeau     */
45*c3437056SNickeau    public function __construct($status, $msg)
46*c3437056SNickeau    {
47*c3437056SNickeau        $this->status = $status;
48*c3437056SNickeau        $this->msg = $msg;
49*c3437056SNickeau    }
50*c3437056SNickeau
51*c3437056SNickeau    public static function create(int $status, string $msg = null): HttpResponse
52*c3437056SNickeau    {
53*c3437056SNickeau        return new HttpResponse($status, $msg);
54*c3437056SNickeau    }
55*c3437056SNickeau
56*c3437056SNickeau
57*c3437056SNickeau    public function setEvent(\Doku_Event $event): HttpResponse
58*c3437056SNickeau    {
59*c3437056SNickeau        $this->event = $event;
60*c3437056SNickeau        return $this;
61*c3437056SNickeau    }
62*c3437056SNickeau
63*c3437056SNickeau    public function send($payload = null, $contentType = null)
64*c3437056SNickeau    {
65*c3437056SNickeau
66*c3437056SNickeau        if ($contentType != null) {
67*c3437056SNickeau            Http::setMime($contentType);
68*c3437056SNickeau        } else {
69*c3437056SNickeau            Http::setMime(Mime::PLAIN_TEXT);
70*c3437056SNickeau        }
71*c3437056SNickeau
72*c3437056SNickeau        // header should before the status
73*c3437056SNickeau        // because for instance a `"Location` header changes the status to 302
74*c3437056SNickeau        foreach ($this->headers as $header) {
75*c3437056SNickeau            header($header);
76*c3437056SNickeau        }
77*c3437056SNickeau
78*c3437056SNickeau        if ($this->status !== null) {
79*c3437056SNickeau            Http::setStatus($this->status);
80*c3437056SNickeau        } else {
81*c3437056SNickeau            $status = Http::getStatus();
82*c3437056SNickeau            if ($status === null) {
83*c3437056SNickeau                Http::setStatus(self::STATUS_INTERNAL_ERROR);
84*c3437056SNickeau                LogUtility::log2file("No status was set for this soft exit, the default was set instead", LogUtility::LVL_MSG_ERROR, $this->canonical);
85*c3437056SNickeau            }
86*c3437056SNickeau        }
87*c3437056SNickeau
88*c3437056SNickeau
89*c3437056SNickeau        /**
90*c3437056SNickeau         * Payload
91*c3437056SNickeau         */
92*c3437056SNickeau        if ($payload !== null) {
93*c3437056SNickeau            echo $payload;
94*c3437056SNickeau        }
95*c3437056SNickeau
96*c3437056SNickeau        /**
97*c3437056SNickeau         * Exit
98*c3437056SNickeau         */
99*c3437056SNickeau        if (!PluginUtility::isTest()) {
100*c3437056SNickeau            if (Http::getStatus() !== self::STATUS_ALL_GOOD) {
101*c3437056SNickeau                LogUtility::log2file($this->msg, LogUtility::LVL_MSG_ERROR, $this->canonical);
102*c3437056SNickeau            }
103*c3437056SNickeau            exit;
104*c3437056SNickeau        } else {
105*c3437056SNickeau
106*c3437056SNickeau            /**
107*c3437056SNickeau             * Stop the propagation and prevent the default
108*c3437056SNickeau             */
109*c3437056SNickeau            if ($this->event !== null) {
110*c3437056SNickeau                $this->event->stopPropagation();
111*c3437056SNickeau                $this->event->preventDefault();
112*c3437056SNickeau            }
113*c3437056SNickeau
114*c3437056SNickeau            /**
115*c3437056SNickeau             * Add test info into the request
116*c3437056SNickeau             */
117*c3437056SNickeau            $testRequest = TestRequest::getRunning();
118*c3437056SNickeau
119*c3437056SNickeau            if ($testRequest !== null) {
120*c3437056SNickeau                $testRequest->addData(self::EXIT_KEY, $payload);
121*c3437056SNickeau            }
122*c3437056SNickeau
123*c3437056SNickeau            /**
124*c3437056SNickeau             * Output buffer
125*c3437056SNickeau             * Stop the buffer
126*c3437056SNickeau             * Test request starts a buffer at {@link TestRequest::execute()},
127*c3437056SNickeau             * it will capture the body until this point
128*c3437056SNickeau             */
129*c3437056SNickeau            ob_end_clean();
130*c3437056SNickeau            /**
131*c3437056SNickeau             * To avoid phpunit warning `Test code or tested code did not (only) close its own output buffers`
132*c3437056SNickeau             * and
133*c3437056SNickeau             * Send the output to the void
134*c3437056SNickeau             */
135*c3437056SNickeau            ob_start(function ($value) {
136*c3437056SNickeau            });
137*c3437056SNickeau
138*c3437056SNickeau        }
139*c3437056SNickeau    }
140*c3437056SNickeau
141*c3437056SNickeau    public function setCanonical($canonical): HttpResponse
142*c3437056SNickeau    {
143*c3437056SNickeau        $this->canonical = $canonical;
144*c3437056SNickeau        return $this;
145*c3437056SNickeau    }
146*c3437056SNickeau
147*c3437056SNickeau
148*c3437056SNickeau    public function addHeader(string $header): HttpResponse
149*c3437056SNickeau    {
150*c3437056SNickeau        $this->headers[] = $header;
151*c3437056SNickeau        return $this;
152*c3437056SNickeau    }
153*c3437056SNickeau
154*c3437056SNickeau    /**
155*c3437056SNickeau     * @param string|array $messages
156*c3437056SNickeau     */
157*c3437056SNickeau    public function sendMessage($messages)
158*c3437056SNickeau    {
159*c3437056SNickeau        if (is_array($messages) && sizeof($messages) == 0) {
160*c3437056SNickeau            $messages = ["No information, no errors"];
161*c3437056SNickeau        }
162*c3437056SNickeau        $message = json_encode(["message" => $messages]);
163*c3437056SNickeau        $this->send($message, Mime::JSON);
164*c3437056SNickeau
165*c3437056SNickeau    }
166*c3437056SNickeau
167*c3437056SNickeau}
168