Server.php

<?php

namespace Lia\Compo;

class Server extends \Lia\Compo {

    protected $dirs = [];
    protected $debug = false;

    protected $configs = [];
    

    public function onReady(){
        $this->lia->addApi('lia:server.getResponse',[$this, 'getResponse']);
        $this->lia->addApiMethod('lia:server.getResponse', 'getResponse');

        $this->lia->addApi('lia:server.deliver',[$this,'deliver']);
        $this->lia->addApiMethod('lia:server.deliver', 'deliver');
    }
    public function onPackageReady(){
        $this->lia->api('lia:config.default', 'lia:server.bufferResponse', true);
    }


    public function getResponse($url=null, $method=null){

        $this->lia->emit('PreAllPackagesReady');
        $this->lia->emit('AllPackagesReady');

        $request = new \Lia\Obj\Request($url, $method);
        $response = new \Lia\Obj\Response($request);

        $this->lia->emit('RequestStarted', $request, $response);

        $routeList = $this->lia->api('lia:route.get', $request);
        $this->lia->emit('RoutesFound', $routeList);
        $route = $this->getDistinctRoute($routeList);
        if ($route===null){
            throw new \Lia\Exception\Base("No routes were found for this request to ".$request->url());
        }
        $this->lia->emit('RoutesFiltered', $route);

        $response->useTheme = true;
        $target = $route->target();

        ob_start();
        //@TODO add 'route resolvers' to Liaison. Route Resolvers would provide extensibility to the handling of routes.  
        if ($route->isCallable()){
            $response->useTheme = true;
            // ob_start();
            $target($route, $response);
            // $response->content = ob_get_clean();
        } else if ($route->fileExt()=='php'){
            $response->useTheme = true;
            $this->requirePhpFileRoute($route,$response);  
        } else if ($route->isFile()){
            // echo "IS STATIC FILE";exit;
            $response->useTheme = false;
            $staticFile = new \Lia\Utility\StaticFile($route->target());
            $response->addHeaders($staticFile->getHeaders());
            if ($staticFile->userHasFileCached){
                $response->sendContent = false;
            } else {
                $response->content = file_get_contents($route->target());
            }
        } else {
            //error
            throw new \Lia\Exception\Base("We couldn't handle the request...");
        } 
        
        $accidentalOutput = ob_get_clean();

        $this->lia->emit('RouteResolved',$route,$response);
        

        if ($response->useTheme){
            $themeView = $this->lia->api('lia:view.get', 'theme',['response'=>$response, 'content'=>$response->content]);

            $this->lia->emit('ThemeLoaded',$themeView);

            $response->content = ''.$themeView;
        }

        $this->lia->emit('ResponseReady', $response);
        return $response;
    
    }
    public function deliver($url=null, $method=null){
        $response = $this->getResponse($url,$method);
        $response->sendHeaders();
        if ($response->sendContent){
            echo $response->content;
        }


        $this->lia->emit('ResponseSent',$response);

        // $this->closeConnection();
        $this->lia->emit('RequestFinished', $response);
    }
    
    /**
     * Close the connection with client. May not work on all hosts, due to apache/server configuration, I'm pretty sure.
     */
    protected function closeConnection(){
        header("Connection: close");
        ignore_user_abort();
        session_write_close();
        if ($this->lia->api('lia:config.get', 'lia:server.bufferResponse')){
            while (ob_get_level()!=0){
                ob_end_flush();
            }
            flush();
        }
        // sleep(5);
    }
    public function requirePhpFileRoute($route,$response){
        //Use the View class (& probably compo?) to display this file
        $lia = $this->lia;
        $package = $route->package();
        extract($route->paramaters(), EXTR_PREFIX_SAME, 'route');
        extract($lia->getGlobalParamaters(),EXTR_PREFIX_SAME,'global');
        ob_start();
        require($route->target());
        $response->content = ob_get_clean();
    }

    public function getDistinctRoute($routeList){
        usort($routeList,
            function($a, $b){
                $l1 = strlen($a->placeholderPattern());
                $l2 = strlen($b->placeholderPattern());
                if ($l1==$l2)return 0;
                else if ($l1>$l2)return -1;
                else return 1;
            }
        );
        return $routeList[0] ?? null;
    }

}