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