Response.php

<?php

namespace Lia\Http;

/**
 * Mutable object to represent a web response
 */
class Response {

    
    /**
     * The request being responded to.
     */
    public \Lia\Http\Request $request;

    /**
     * The body to send
     */
    public string $body = '';

    /**
     * A theme in your app, or from an app you depend on. 
     * Or a built-in theme:
     * - raw: send body, default.
     * - html_page: wrap content in valid html with doctype, head, body, with automatic css & js inclusion.
     * - json (placeholder for apps and routes that optionally return json)
     */
    public string $theme_name;
    /**
     * Array of headers, where each header is an array arglist to past to `header()`
     *
     * Headers can also just be sent directly
     *
     * Example:
     * [
     *   ['Location: /url/', true, 302],
     * ]
     * or 
     * [
     *   ['Last-Modified: Sun, 10 Dec 2023 04:02:06', true, 304],
     *   ['Content-type: text/json');
     *   ['Content-Length: 502');
     *   ['Cache-Control: max-age=2592000'); // 2592000 is 30 days
     * ]
     *
     * @param $headers array<int index, array header> & header is an array of args to pass to `header()`
     */
    public array $headers = [];

    /**
     * Whether to send content or not. Mark false if you're sending headers to load-from-cache
     */
    public bool $send_body = true;

    public function __construct(\Lia\Http\Request $request){
        $this->request = $request;
    }

    /**
     * Add a header.
     *
     * @param $header array args you'd pass to `header()`
     */
    public function addHeader(array $header){
        $this->headers[] = $header;
    }
    

    /**
     * Add a header to redirect to url with 302 status code for temporary redirect.
     * @param $url string
     */
    public function redirect_temporary(string $url){
        $this->addHeader(['Location: '.$url, true, 302]);
    }

    /**
     * Add a header to redirect to url with 301 status code for Moved Permanently
     * @param $url string
     */
    public function redirect_permantent(string $url){
        $this->addHeader(['Location: '.$url, true, 301]);
    }

    /**
     * Add multiple headers.
     *
     * @param $headers array<int index, array header> & header is an array of args to pass to `header()`
     */
    public function addHeaders($headers){
        $this->headers = array_merge($this->headers, $headers);
    }

    /**
     * Send headers by calling `header()`
     * To override the call to `header()` implement a function `\Lia\Http\header(...)` which takes the same args.
     */
    public function sendHeaders(){
        foreach ($this->headers as $headerArgsArray){
            header(...$headerArgsArray);
        }
    }

    /**
     * Send headers & body.
     *
     * If $this->send_body is set false, body will not be sent.
     */
    public function send(){
        $this->sendHeaders();
        if ($this->send_body)echo $this->body;
    }

    /** Add the header: HTTP/1.1 404 Not Found */
    public function PageNotFound(){
        $this->addHeader(["HTTP/1.1 404 Not Found", true, 404]);

        // Note from php docs:
        // This example illustrates the "HTTP/" special case
        // Better alternatives in typical use cases include:
        // 1. header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
        //    (to override http status messages for clients that are still using HTTP/1.0)
        // 2. http_response_code(404); (to use the default message)
    }

    /** Add the header: HTTP/1.1 500 Internal Server Error */
    public function InternalServerError(){
        $this->addHeader(["HTTP/1.1 500 Internal Server Error ", true, 500]);

        // Note from php docs:
        // This example illustrates the "HTTP/" special case
        // Better alternatives in typical use cases include:
        // 1. header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");
        //    (to override http status messages for clients that are still using HTTP/1.0)
        // 2. http_response_code(404); (to use the default message)
    }
}