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