View.php

<?php

namespace Lia\Compo;

class View extends \Lia\Compo {

    protected $views = [];


    protected $conflictMode = 'throw';

    public function onReady(){
        $lia = $this->lia;
        if ($lia->hasApi('lia:config.default')){
            //@TODO cover onPreStart in View tests
            $lia->api('lia:config.default', 'lia:view.conflictMode', 'throw');
        }

        $this->lia->addApi('lia:view.setConflictMode',[$this, 'setConflictMode']);
        $this->lia->addApiMethod('lia:view.setConflictMode', 'setViewConflictMode');

        $this->lia->addApi('lia:view.addCallable',[$this, 'addCallable']);
        $this->lia->addApiMethod('lia:view.addCallable', 'addViewCallable');

        $this->lia->addApi('lia:view.add',[$this, 'addViewHandler']);
        $this->lia->addApiMethod('lia:view.add', 'addView');

        $this->lia->addApi('lia:view.get',[$this,'view']);
        $this->lia->addApiMethod('lia:view.get', 'view');
    }

    public function setConflictMode($conflictMode){
        $this->conflictMode = $conflictMode;
    }
    public function addCallable($viewName, $callable, $args=[]){
        $class = '\\Lia\\Obj\\ViewCallable';
        $this->lia->api('lia:view.add', $class, $callable, $viewName, $args);
    }

    //@TODO Different naming for 'add'. Maybe 'addView' 'addViewClass', 'addViewData', 'addViewHandler', or just 'addHandler'
    public function addViewHandler($class, $dir, $viewName, $args=[]){
        $vnCopy = $viewName;
        \Lia\Utility\NS::parseNamespace($vnCopy,$namespace,$fqn);

        if (\Lia\Utility\NS::has($this->views, $viewName)&&$namespace!==false){
            $cm = $this->conflictMode;
            if ($cm=='ignore')return;
            else if ($cm!='overwrite'){
                throw new \Lia\Exception\Base("View '$viewName' is already set.");
            }
        }

        $viewData = [
                'class'=>$class,
                'dir'=>$dir,
                'name'=>$vnCopy,
                'namespace'=>$namespace,
                'args'=>$args,
            ];
        \Lia\Utility\NS::set($this->views, $viewName, $viewData);
    }


    /**
     *
     */
    public function view($name, $args=[]){
        $viewData = \Lia\Utility\NS::get($this->views, $name, $namespace);
        if ($viewData == null){
            throw new \Lia\Exception\Base("View '${name}' does not exist.");
        } 

        if ($viewData==null){
            $message="";
            $ext = strtolower(pathinfo($name,PATHINFO_EXTENSION));
            if ($ext=='php'||$ext=='html'){
                $message = "Do not include the file extension when calling view()";
            }
            throw new \Lia\Exception\Base(". {$message}");
        }
        $cn = $viewData['class'];
        $dir = $viewData['dir'];
        $name = $viewData['name'];
        $setupArgs = $viewData['args'];
        $globalArgs = $this->lia->api('lia:globalparams.getAll');
        $viewData['globalArgs'] = $globalArgs;

        if (in_array('Lia\\Obj\\IView',class_implements($cn,true))){
            $allArgs = array_merge($globalArgs,$setupArgs,$args);
            $view = new $cn($name, $dir, $allArgs);
        } else {
            $viewData['given_args'] = $args;
            $view = new $cn($viewData);
        }
        return $view;
    }
}