<?php

/* ========================================================================
 * $Id: vue.php 12730 2020-07-08 21:01:22Z onez $
 * 
 * Email: www@onez.cn
 * QQ: 6200103
 * HomePage: http://www.onez.cn
 * ========================================================================
 * Copyright 2016-2017 佳蓝科技.
 * 
 * ======================================================================== */

!defined('IN_ONEZ') && exit('Access Denied');
#名称：佳蓝vue专用模板系统
#标识：vue

class onezphp_vue extends onezphp{
  var $rootFile='';
  var $rootPath='';
  var $cssList=array();
  var $jsList=array();
  var $pathList=array();
  function __construct(){
    
  }
  function load($token,$id=0){
    include_once(dirname(__FILE__).'/plugins/'.$token.'.php');
    $clsName="onezphp_vue_plugin_$token";
    return new $clsName($this);
  }
  function tpl(){
    $tpl=$this->get('tpl');
    if($tpl){
      onez($tpl)->init($this);
    }
    return onez($tpl);
  }
  function init($rootFile){
    $this->rootFile=$rootFile;
    $this->rootPath=dirname($rootFile);
    $this->www=basename($this->rootPath);
    if(defined('ONEZ_PRODUCT_PTOKEN')){
      onez(ONEZ_PRODUCT_PTOKEN)->init();
    }
    if(defined('ONEZ_PRODUCT_PTOKENS')){
      foreach(explode(',',ONEZ_PRODUCT_PTOKENS) as $v){
        onez($v)->init();
      }
    }
    $this->checkPost();
    return $this;
  }
  function checkPost(){
    $noVue=onez()->gp('noVue');
    if($noVue){
      return;
    }
    $action=onez()->gp('action');
    $input=@file_get_contents('php://input');
    if($_GET['ui-type']=='frame'){
      $input=array();
      $input['action']='$post';
      $input['req'][]=$_REQUEST;
      print_r($input);exit();
      $input=json_encode($input);
    }
    if($input){
      $A=array();
      $A['status']='success';
      $A['results']=array();
      $post=json_decode($input,1);
      if($post['action']=='$post'){
        if($post['req']){
          foreach($post['req'] as $key=>$req){
            $A['results'][$key]=$this->checkPostItem($req);
          }
        }
      }
      onez()->output($A);
    }
  }
  function checkPostItem($req){
    global $A,$G;
    $A=array();
    $A['status']='success';
    $REQUEST=$this->REQUEST=$_REQUEST;
    $POST=$_POST;
    $_REQUEST=$_POST=array();
    $file=false;
    if(($index=strpos($req['$action'],'?'))!==false){
      parse_str(substr($req['$action'],$index+1),$info);
      $info && $req=array_merge($info,$req);
    }elseif(($index=strpos($req['$action'],'&'))!==false){
      parse_str(substr($req['$action'],$index+1),$info);
      $info && $req=array_merge($info,$req);
    }
    if($req['action']=='$cloud'){
      return $G['this']->onezapi('api',array('key'=>'/cloud/get','post'=>array(
        'name'=>$req['name'],
      )));
    }elseif($req['action']=='$api'){
      $ptoken=$req['ptoken'];
      $funcName=$req['funcName'];
      if(onez()->exists($ptoken)){
        return array(
          'res'=>onez($ptoken)->res(),
        );
      }
      return array('status'=>'error','error'=>'api not exists',);
    }
    if($req['$purl']){
      unset($req['$file']);
    }
    foreach($req as $k=>$v){
      if($k=='$purl'){
        list($ptoken,$pfile)=explode(':',$v);
        $v=substr(onez($ptoken)->path.$pfile,strlen(ONEZ_ROOT));
        $k='$file';
      }
      if($k=='$file'){
        $file=$v;
        if(strpos($file,'./')!==false){
          return $this->error('路径非法');
        }
        if(strpos($file,'/cache')!==false){
          return $this->error('路径非法');
        }
        if($file[0]==='@'){
          $file=ONEZ_CACHE_PATH.substr($file,1);
        }else{
          $file=ONEZ_ROOT.$file;
        }
        if(!file_exists($file)){
          return $this->error('请求文件不存在');
        }
        continue;
      }
      $_REQUEST[$k]=$_POST[$k]=$v;
    }
    $MODE='$post';
    $G['page']=max(1,(int)$_REQUEST['page']);
    ($r=include($file)) && $A=$r;
    $_REQUEST=$REQUEST;
    $_POST=$POST;
    return $A;
  }
  function page($req){
    $A=array();
    $A['status']='error';
    $A['error']=$error;
    return $A;
  }
  function error($error){
    $A=array();
    $A['status']='error';
    $A['error']=$error;
    return $A;
  }
  function ok($result,$goto=''){
    $A=array();
    $A['status']='success';
    $A['message']=$result;
    $A['goto']=$goto;
    return $A;
  }
  function array_merge($a,$b){
    foreach($a as $k=>$v){
      if(is_array($v) && is_array($b[$k]) && array_key_exists($k,$b)){
        $a[$k]=$this->array_merge($v,$b[$k]);
      }
    }
    foreach($b as $k=>$v){
      if(!is_array($v)){
        $a[$k]=$v;
      }
    }
    return $a;
  }
  function css($url){
    $this->cssList[]=$url;
    return $this;
  }
  function js($url){
    $this->jsList[]=$url;
    return $this;
  }
  function addPath(){
    foreach(func_get_args() as $v){
      if(!in_array($v,$this->pathList)){
        $this->pathList[]=$v;
      }
    }
  }
  function cloud($path,$name,$cName){
    include_once(dirname(__FILE__).'/php/lib/build.vue.php');
    $result=array();
    $c=$this->findComponents($path,$name);
    if($c){
      $js=$css=array();
      (new _vue_build($c,'component'))->vue($cName,$js,$css);
      if($js){
        $result['js']=implode("\n",$js);
      }
      if($css[0]){
        $result['css']=implode("\n",$css[0]);
      }
    }
    return $result;
  }
  function findComponents($path,$name,$up=''){
    #公共组件
    $glob=glob($path.'/*');
    if($glob){
      foreach($glob as $v){
        if(!is_dir($v)){
          continue;
        }
        $token=basename($v);
        if($token=='components'){//组件
          $glob2=glob($v.'/*');
          if($glob2){
            foreach($glob2 as $v2){
              if(!is_dir($v2)){
                continue;
              }
              $token2=basename($v2);
              if($name==$up.$token2){
                return $v2;
              }
            }
          }
        }elseif(strpos($v,'/pages')!==false){//页面
          #查找子级组件
          $r=$this->findComponents($v,$name,$up.($token=='pages'?'':$token.'-'));
          if($r!==false){
            return $r;
          }
        }
      }
    }
    return false;
  }
  function build(){
    global $G;
    onez('debug')->showerror();
    include_once(dirname(__FILE__).'/php/lib/build.vue.php');
    $this->components_info=array();
    $this->cloudres=array();
    $js=$css=array();
    $js[]=onez()->read(dirname(__FILE__).'/php/lib/res/build.default.js');
    $this->buildFindComponents($this->path,$js,$css);
    #模板中的组件
    $tpl=$this->get('tpl');
    if($tpl){
      $this->buildFindComponents(onez($tpl)->path,$js,$css);
    }
    #站点组件
    #$this->buildFindComponents($G['this']->path,$js,$css);
    #主目录组件
    #$this->buildFindComponents($G['this']->path.'/www',$js,$css);
    
    if($this->pathList){
      foreach($this->pathList as $v){
        $this->buildFindComponents($v,$js,$css);
      }
    }
    
    
    $path=$this->rootPath;
    #$www=basename($this->rootPath);
    $www=md5($this->rootPath.serialize($this->pathList));
    
    $this->getCloudRes($www,$js,$css);
    unset($this->cloudres['components']);
    if($this->cloudres){
      $r=onez('bs')->onezapi('api',array('key'=>'/cloud/res','post'=>array(
        '_siteid'=>$G['site']['id'],
        'cloudres'=>$this->cloudres,
      )));
      if($r['files']){
        $files=onez('onezip')->unzip(base64_decode($r['files']));
        if($files){
          foreach($files as $k=>$v){
            if(!$v){
              continue;
            }
            $file=ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/'.$k;
            onez()->write($file,$v);
          }
        }
      }
    }
    
    $cacheFileVue=ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components.js';
    onez()->write($cacheFileVue,implode("\n",$js));
    $cacheFileCss=ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components.css';
    onez()->write($cacheFileCss,implode("\n",$css));
    #高级配置信息
    $cacheFileInfo=ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components.php';
    if($this->components_info){
      $codes=array();
      foreach($this->components_info as $k=>$v){
        $codes[]="\$G['$k']=".var_export($v,1).";";
      }
      onez()->write($cacheFileInfo,"<?php\n!defined('IN_ONEZ') && exit('Access Denied');\n".implode("\n",$codes)."\n");
    }else{
      @unlink($cacheFileInfo);
    }
  }
  function getCloudRes($www,&$js,&$css){
    global $G;
    $newComps=array();
    #云资源
    if($this->cloudres['components']){
      foreach($this->cloudres['components'] as $k=>$v){
        $newComps[$k]=ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components/'.$k;
        $cacheFile=ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components/'.$k.'/config.php';
        if(file_exists($cacheFile)){
          $con=include($cacheFile);
          if($con['hash']){
            $this->cloudres['components'][$k]=$con['hash'];
          }
        }
      }
      $r=onez('bs')->onezapi('api',array('key'=>'/cloud/res','post'=>array(
        '_siteid'=>$G['site']['id'],
        'cloudres'=>array(
          'components'=>$this->cloudres['components'],
        ),
      )));
      if($r['files']){
        $files=onez('onezip')->unzip(base64_decode($r['files']));
        if($files){
          foreach($files as $k=>$v){
            if(!$v){
              continue;
            }
            $file=ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/'.$k;
            onez()->write($file,$v);
          }
        }
      }
      $this->cloudres['components']=array();
    }
    if($newComps){
      foreach($newComps as $k=>$v){
        if(!is_dir($v)){
          continue;
        }
        $token=basename($v);
        (new _vue_build($v,'component'))->vue($k,$js,$css);
      }
      if($this->cloudres['components']){
        $this->getCloudRes($www,$js,$css);
      }
    }
  }
  function buildFindComponents($path,&$js,&$css,$up=''){
    #公共组件
    !$this->buildFindComponents_history && $this->buildFindComponents_history=array();
    $glob=glob($path.'/*');
    if($glob){
      foreach($glob as $v){
        if(!is_dir($v)){
          continue;
        }
        $token=basename($v);
        if(file_exists($v.'/'.$token.'.php') && file_exists($v.'/'.$token.'.js')){
          $type='component';
          $index1=strrpos($v,'/pages');
          $index2=strrpos($v,'/components');
          if($index1!==false && $index2===false){
            $type='page';
          }
          if($type=='component'){
            (new _vue_build($v,'component'))->vue($up.$token,$js,$css);
          }else{
            (new _vue_build($v,'page'))->vue('page-'.$up.$token,$js,$css);
          }
        }
        #查找子级组件
        $this->buildFindComponents($v,$js,$css,$up.$token.'-');
      }
    }
  }
  function is_mobile(){
    if(defined('ONEZ_IS_MOBILE')){
      return true;
    }
    $mobile=onez()->gp('_mobile');
    if($mobile){
      return true;
    }
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    //是否在微信浏览器中
    if(strpos($user_agent, 'MicroMessenger')!== false){
      $G['is_weixin']=1;
    }else{
      $G['is_weixin']=0;
    }
    //是否安卓系统
    if(strpos($user_agent, 'iPhone')||strpos($user_agent, 'iPad')){
      $G['is_ios']=1;
    }else{
      $G['is_ios']=0;
    }
    //是否苹果系统
    if(strpos($user_agent, 'Android')){
      $G['is_android']=1;
    }else{
      $G['is_android']=0;
    }
    //是否移动端
    if($G['is_ios']||$G['is_android']){
      $G['is_mobile']=1;
    }else{
      $G['is_mobile']=0;
    }
    return $G['is_mobile']==1;
  }
  function pc($page='index'){
    global $G;
    #$www=basename($this->rootPath);
    $www=md5($this->rootPath.serialize($this->pathList));
    if(!file_exists(ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components.css')||!file_exists(ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components.js')){
      onez('vue')->build();
    }
    $this->css($this->url.'/css/style.css');
    $this->css(ONEZ_CACHE_URL.'/vues/'.$G['this']->token.'/'.$www.'/components.css');
    $this->js($this->url.'/js/vue.min.js');
    $this->js($this->url.'/js/axios.min.js');
    $this->js($this->url.'/js/md5.min.js');
    $this->js(ONEZ_CACHE_URL.'/vues/'.$G['this']->token.'/'.$www.'/components.js');
    
    $this->js($this->url.'/js/vue.onez.js');
    $this->css($this->url.'/css/swiper.min.css');
    $this->js($this->url.'/js/swiper.min.js');
    if($this->is_mobile()){
    }
    if(file_exists(ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components.php')){
      include(ONEZ_CACHE_PATH.'/vues/'.$G['this']->token.'/'.$www.'/components.php');
    }
    #实时消息
    if($G['onez.plugins']['bs.live']){
      onez('bs.live')->pc();
    }
    #字体图标
    if($G['iconfont']){
      $this->css(ONEZ_CACHE_URL.'/vues/'.$G['this']->token.'/'.$www.'/iconfont/onez-iconfont.css');
    }
    include(dirname(__FILE__).'/php/pc.php');
  }
}