View.php

<?php

namespace Lia\Compo;

class View extends \Lia\Compo {

    protected $views = [];

/**
 * - document the use of a view that does NOT implement Lia\IView
 * - implement & document adding a view by simple file path
 * 
 * @export(TODO.ViewComponent)
 */
    
    protected $conflictMode = 'throw';
    
    public function onPreStart(){
        $lia = $this->lia;
        if ($lia->hasApi('lia.conf')){
            //@TODO cover onPreStart in View tests
            $lia->api('lia.conf', 'default', 'views.conflict', 'throw');
        }
    }

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

    public function apiAdd_lia_view_addView($class, $dir, $viewName, $args=[]){
        if (isset($this->views[$viewName])){
            $cm = $this->conflictMode;
            if ($cm=='ignore')return;
            else if ($cm=='overwrite'){}
            else {
                throw new \Lia\Exception\Base("View '{$viewName}' cannot be added, because a view already exists with that name.\n     The existing view's target class is '{$class}' and it's target dir is '{$dir}'\n");                
            }
        }

        
        $this->views[$viewName] =
            [
                'class'=>$class,
                'dir'=>$dir,
                'name'=>$viewName,
                'args'=>$args,
            ];
    }

    public function api_lia_view_view($name, $args=[]){
        $viewData = $this->views[$name] ?? null;
        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("View '{$name}' has not been added. {$message}");
        }
        $cn = $viewData['class'];
        $dir = $viewData['dir'];
        $name = $viewData['name'];
        $setupArgs = $viewData['args'];
        $globalArgs = $this->lia->api('lia.globalparams', 'get');
        $viewData['globalArgs'] = $globalArgs;

        if (in_array('Lia\\Obj\\IView',class_implements($cn,true))){
            // echo 'did the correct view thing';
            // @TODO add a more elegant, prefix-based merging-method for conflicts
            $allArgs = array_merge($globalArgs,$setupArgs,$args);
            // var_dump(array_keys($allArgs));
            $view = new $cn($name, $dir, $allArgs);
        } else {
            $viewData['given_args'] = $args;
            $view = new $cn($viewData);
        }
        return $view;
    }
}