<?php

/* ========================================================================
 * $Id: bs.php 16403 2020-07-09 01:59:03Z onez $
 * 
 * Email: www@onez.cn
 * QQ: 6200103
 * HomePage: http://www.onez.cn
 * ========================================================================
 * Copyright 2016-2017 佳蓝科技.
 * 
 * ======================================================================== */

!defined('IN_ONEZ') && exit('Access Denied');
#名称：佳蓝变数
#标识：bs
class onezphp_bs extends onezphp{
  var $version='v1.0';
  var $onez_api_url='https://open.onez.cn/api/bs.php';
  function __construct(){
    
  }
  function app(){
    global $G;
    return $G['this'];
  }
  function init(){
    $this->data_alias=$this->token;
  }
  function index(){
    global $G;
    if($_SERVER['HTTPS']=='on'){
      header('Content-Security-Policy: upgrade-insecure-requests');
    }
    $_pUrl=onez()->gp('_pUrl');
    if($_pUrl){
      onez('bs.plugins')->urlParse($_pUrl);
    }
    include(dirname(__FILE__).'/www/index.php');
  }
  function sitedata(){
    global $G;
    if($G['site']['id']){
       return onez('data','data'.$G['site']['data'])->noappid();
    }
    return onez('data','site.bs');
  }
  #网站公共引用
  function www_app(){
    global $G,$A;
    $A['title']=$G['bs']['sitename']?$G['bs']['sitename']:'佳蓝智能开发';
    $A['aside']=include(dirname(__FILE__).'/www/menus/menu.aside.php');
    $A['user']=$G['user'];
    $A['menus']=array(
      'left'=>include(dirname(__FILE__).'/www/menus/menu.left.php'),
      'right'=>include(dirname(__FILE__).'/www/menus/menu.right.php'),
    );
  }
  function user_before(){
    global $G;
    $where=$G['this']->where();
    $T=$G['this']->data()->open('users')->record("1$where order by id desc");
    $tables=array();
    foreach($T as $rs){
      $tables[]='user'.$rs['id'];
    }
    $this->tmp_alias=$G['this']->data_alias;
    $G['this']->data_alias='user'.$G['userid'];
    
    $dt=$G['this']->data()->open('member');
    $data_db=$dt->db->info['dbname'];
    $data_table=$dt->db->info['tablepre'].$dt->data_table;
    return array('tables'=>$tables,'tablename'=>"`$data_db`.`$data_table`",'where'=>"namespace in ('".implode("','",$tables)."')");
  }
  function user_after(){
    global $G;
    $G['this']->data_alias=$this->tmp_alias;
    
  }
  #主菜单
  function www_menus(){
    global $G,$A;
  }
  #当前应用需要登录
  function login(){
    global $G;
    $G['userid']=0;
    $cookie=onez('cache')->cookie($this->cname);
    if($cookie){
      list($id)=explode("\t",$cookie);
      if($id){
        $user=onez('db')->open('member')->one("userid='$id'");
        if($user){
          $user['avatar']=$this->avatar($id);
          $G['user']=$user;
          $G['userid']=$user['userid'];
        }
      }
    }
    if(!$G['userid']){
      include_once(dirname(__FILE__)).'/www/login/login.php';
      exit();
    }
  }
  #站点唯一标识
  function sitekey(){
    $siteFile=ONEZ_CACHE_PATH.'/bs.site.php';
    if(!file_exists($siteFile)){
      $siteHash=onez()->post($this->onez_api_url,json_encode(array(
        'action'=>'init',
        't'=>time(),
      )));
      $siteHash && onez()->write($siteFile,$siteHash);
    }
    if(file_exists($siteFile)){
      include($siteFile);
    }
    return $sitekey;
  }
  #与官方接口通信
  function onezapi($action,$args){
    global $G;
    if(!is_array($args)){
      $args=array('key'=>$args);
    }
    $args['userid']=$G['userid'];
    $post=array();
    $post['action']=$action;
    $post['args']=$args;
    $post['sitekey']=$this->sitekey();
    $post['version']=$this->version;
    $d=onez()->post($this->onez_api_url,json_encode($post));
    $json=json_decode($d,1);
    return $json?$json:$d;
  }
  //网站类型
  function siteTypes($key=false){
    global $G;
    $options=array();
    $options['default']='综合';
    $options['weixin']='微信公众号';
    if($key===false){
      return $options;
    }
    return $options[$key];
  }
  //网站状态
  function siteStatus($key=false){
    global $G;
    $options=array();
    $options['running']='运行中';
    $options['stop']='已停止';
    if($key===false){
      return $options;
    }
    return $options[$key];
  }
  //微信账号类型
  function weixinTypes($key=false){
    global $G;
    $options=array();
    $options['weixin']='公众号';
    $options['wxapp']='小程序';
    if($key===false){
      return $options;
    }
    return $options[$key];
  }
  //更新网站
  function siteUpdate(){
    global $G;
    
    $userFile=ONEZ_CACHE_PATH.'/plugins/'.$this->token.'/sites/users/'.$G['userid'].'.php';
    $bs=$this->data()->open('bs')->one("userid='$G[userid]'");
    if(!$bs){
      $item=array();
      $item['userid']=$G['userid'];
      $this->data()->open('bs')->insert($item);
      $bs=$this->data()->open('bs')->one("userid='$G[userid]'");
    }
    if($G['userid']==1 || !defined('IS_ON_ONEZSITE')){
      $bsFile=ONEZ_CACHE_PATH.'/plugins/'.$this->token.'/config.php';
      onez()->write($bsFile,"<?php\n!defined('IN_ONEZ') && exit('Access Denied');\nreturn ".var_export($bs,1).";\n");
    }
    #已安装插件
    $where=$this->where();
    $T=$this->data()->open('plugins')->record("upid='0'$where order by id desc");
    $ids=$plugins=array();
    foreach($T as $rs){
      $ids[]=$rs['index1'];
      $plugins[]=$rs['plugin'];
    }
    $bs['plugins']=$plugins;
    $bs['plugins.ids']=$ids;
    onez()->write($userFile,"<?php\n!defined('IN_ONEZ') && exit('Access Denied');\nreturn ".var_export($bs,1).";\n");
    
    #域名
    $domainFile=ONEZ_CACHE_PATH.'/plugins/'.$this->token.'/sites/domains.php';
    $T=$this->data()->noappid()->open('sites')->record("1 order by id desc");
    $homepage=onez()->homepage();
    $domains=array();
    foreach($T as $rs){
      if($bs['pandomain']){
        $tmp=str_replace('*',dechex($rs['id']+10000),$bs['pandomain']);
        $domains[$tmp]=$rs['id'];
      }
      foreach(explode("\n",$rs['domains']) as $v){
        $v=str_replace(array('http://','http://','/'),'',$v);
        $v=trim($v);
        if($v){
          if(strpos($homepage,$v)===false){
            $domains[$v]=$rs['id'];
          }
        }
      }
      $siteFile=ONEZ_CACHE_PATH.'/plugins/'.$this->token.'/sites/infos/'.$rs['id'].'.php';
      #已安装插件
      $where=$this->where();
      $T2=$this->data()->open('plugins')->record("upid='$rs[id]'$where order by id desc");
      $ids=$plugins=array();
      foreach($T2 as $r){
        $ids[]=$r['index1'];
        $plugins[]=$r['plugin'];
      }
      $rs['plugins']=$plugins;
      $rs['plugins.ids']=$ids;
      onez()->write($siteFile,"<?php\n!defined('IN_ONEZ') && exit('Access Denied');\nreturn ".var_export($rs,1).";\n");
    }
    $domains && onez()->write($domainFile,"<?php\n!defined('IN_ONEZ') && exit('Access Denied');\nreturn ".var_export($domains,1).";\n");
    
  }
  /**
  * 用户资料
  * @param Number $userid
  * @param String $field
  * 
  * @return
  */
  function user($userid,$field=false){
    global $G;
    if(!$this->allUsers[$userid]){
      $user=onez('db')->open('member')->one("userid='$userid'");
      if($user){
        !$user['nickname'] && $user['nickname']=$user['username'];
      }
      $this->allUsers[$userid]=$user;
    }
    if($field!==false){
      return $this->allUsers[$userid][$field];
    }
    return $this->allUsers[$userid];
  }
  function avatarU($userU,$userid=0){
  	$myid = sprintf("%09d", $userid);
  	$dir1 = substr($myid, 0, 3);
  	$dir2 = substr($myid, 3, 2);
  	$dir3 = substr($myid, 5, 2);
    $avatarFile='/avatars/users/'.$userU.'/'.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($myid, -2).'.jpg';
    if(file_exists(ONEZ_CACHE_PATH.$avatarFile)){
      return ONEZ_CACHE_URL.$avatarFile.'?t='.filemtime(ONEZ_CACHE_PATH.$avatarFile);
    }else{
      return str_replace('http://','//',onez('bs')->url).'/images/avatar.png';
    }
  }
  //头像
  function avatar($userid){
    global $G;
  	$myid = sprintf("%09d", $userid);
  	$dir1 = substr($myid, 0, 3);
  	$dir2 = substr($myid, 3, 2);
  	$dir3 = substr($myid, 5, 2);
    $avatarFile='/avatars/'.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($myid, -2).'.jpg';
    if(file_exists(ONEZ_CACHE_PATH.$avatarFile)){
      return ONEZ_CACHE_URL.$avatarFile.'?t='.filemtime(ONEZ_CACHE_PATH.$avatarFile);
    }else{
      $avatar=$this->user($userid,'avatar');
      if($avatar){
        $this->avatar_set($userid,$avatar);
        return ONEZ_CACHE_URL.$avatarFile.'?t='.filemtime(ONEZ_CACHE_PATH.$avatarFile);
      }
      return str_replace('http://','//',$this->url).'/images/avatar.png';
    }
  }
  function avatar_set($userid,$url){
    global $G;
    $usertype=$this->usertype();
  	$myid = sprintf("%09d", $userid);
  	$dir1 = substr($myid, 0, 3);
  	$dir2 = substr($myid, 3, 2);
  	$dir3 = substr($myid, 5, 2);
    $avatarFile='/avatars/'.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($myid, -2).'.jpg';
    
    $opts=array(
       'http'=>array(
         'method'=>'GET',
         'timeout'=>3,
       )
    );
    $context = stream_context_create($opts);
    $data=@file_get_contents($url,false,$context);
    if($data){
      onez()->write(ONEZ_CACHE_PATH.$avatarFile,$data);
    }
    return $this;
  }
  //加载站点
  function loadSite($site,$noPc=false){
    include_once(dirname(__FILE__).'/lib/site.onez.php');
    $Site=new onezphp_bs_site($site);
    $Site->init();
    if($noPc){
      return $Site;
    }
    $Site->pc();
    exit();
  }
  //根据站点信息返回站点
  function toSite($bstoken,$siteId){
    global $G;
    if($bstoken){
      $G['this']=onez($bstoken);
      $G['this']->init();
    }
    if($siteId){
      $T=$G['this']->data()->noappid()->open('sites')->one("id='{$siteId}'");
      if($T){
        include_once(dirname(__FILE__).'/lib/site.onez.php');
        $Site=new onezphp_bs_site($T);
        $Site->init();
      }
    }
  }
  #网站信息
  function site($siteId,$field=false){
    global $G;
    if(!$this->allSites[$siteId]){
      $siteFile=ONEZ_CACHE_PATH.'/plugins/'.$this->token.'/sites/infos/'.$siteId.'.php';
      if(!file_exists($siteFile)){
        $this->siteUpdate();
      }
      $this->allSites[$siteId]=include($siteFile);
    }
    if($field!==false){
      return $this->allSites[$siteId][$field];
    }
    return $this->allSites[$siteId];
  }
  //筛选数据
  function where(){
    global $G;
    return " and userid='$G[userid]'";
  }
  #已安装插件
  function plugins($siteId,$field=false){
    global $G;
    $where=$G['this']->where();
    $T=$G['this']->data()->open('plugins')->record("upid='$siteId'$where order by id desc");
    $ids=array();
    foreach($T as $rs){
      $ids[]=$rs['index1'];
    }
  }
  #安装插件
  function install($base64,$siteId){
    global $G;
    $data=base64_decode($base64);
    $files=onez('onezip')->unzip($data);
    $allFiles=array();
    if($files['plugin.json']){
      $plugin=json_decode($files['plugin.json'],1);
      !$plugin['plugin']['id'] && onez()->error('无效插件');
      #额外压缩包
      if($plugin['zips']){
        foreach($plugin['zips'] as $zipUrl){
          $r=onez('onezip')->unzip(file_get_contents($zipUrl));
          $r && $allFiles=array_merge($allFiles,$r);
        }
      }
      #自动插件
      if($plugin['plugins']){
        foreach($plugin['plugins'] as $ptoken){
          onez($ptoken);
        }
      }
      #自带文件
      foreach($files as $k=>$v){
        if($k!='plugin.json'){
          $allFiles[$k]=$v;
        }
      }
      $where=$G['this']->where();
      $T=$G['this']->data()->open('plugins')->one("upid='$siteId'$where and index1='{$plugin['plugin']['id']}'");
      if(!$T){
        $item=array();
        $item['plugin']=$plugin['plugin'];
        $item['upid']=$siteId;
        $item['userid']=$G['userid'];
        $item['index1']=$plugin['plugin']['id'];
        $G['this']->data()->open('plugins')->insert($item);
      }
    }else{
      onez()->error('未包含有效数据');
    }
    $this->siteUpdate();
    @unlink(ONEZ_CACHE_PATH.'/plugins/bs/sites/infos/'.$siteId.'.build');
  }
  #卸载插件
  function uninstall($plugin,$siteId){
    global $G;
    $where=$G['this']->where();
    $G['this']->data()->open('plugins')->delete("upid='$siteId'$where and index1='$plugin[pluginId]'");
    $this->siteUpdate();
    @unlink(ONEZ_CACHE_PATH.'/plugins/bs/sites/infos/'.$siteId.'.build');
  }
  #匹配卡槽
  function slot($key,&$data){
    global $G;
    if(strpos($key,'./')===false){
      if($G['site']['plugins']){
        foreach($G['site']['plugins'] as $v){
          if($v['token']){
            $ptoken="bs.plugins.$v[token]";
            $file=onez($ptoken)->path.'/comps'.$key.'.php';
            if($file){
              $plugin=onez($ptoken);
              include($file);
            }
          }
        }
      }else{
        $where=$G['this']->where();
        if(!$this->_plugins){
          $this->_plugins=$G['this']->data()->open('plugins')->record("upid='0'$where");
        }
        foreach($this->_plugins as $rs){
          $v=$rs['plugin'];
          if($v['token']){
            $ptoken="bs.plugins.$v[token]";
            $file=onez($ptoken)->path.'/comps'.$key.'.php';
            if($file){
              $plugin=onez($ptoken);
              include($file);
            }
          }
        }
      }
    }
  }
  #某个站点的主页地址
  function homepage(){
    global $G;
    $homepage=onez()->homepage();
    if($G['site']){
      foreach(explode("\n",$G['site']['domains']) as $v){
        $v=str_replace(array('http://','http://','/'),'',$v);
        $v=trim($v);
        if($v){
          if(strpos($homepage,$v)===false){
            return 'http://'.$v;
          }
        }
      }
    }
    return $homepage;
  }
  #使用通配符比较两个字符串
  function stringMatch($source,$pattern) {
    $pattern = preg_quote($pattern,'/');        
    $pattern = str_replace('\*','.*?', $pattern);
    return (bool)preg_match('/^'.$pattern.'$/i',$source);
  }
  /**
  * 触发事件
  * @param undefined $eventName
  * @param undefined $req
  * 
  * @return
  */
  function emit($eventName,$req){
    global $G;
    !$req['to'] && $req['to']='all';
    $req['to']=strtolower($req['to']);
    #php
    if(in_array($req['to'],array('all','php'))){
      if($G['onez.events']){
        foreach($G['onez.events'] as $v){
          if($v['event']==$eventName){
            if(!$req['page'] || $this->stringMatch($v['page'],$req['page'])){
              $request=$req['request'];
              #防止死循环
              $hash=md5("$v[file]\t$eventName");
              if(!$this->emitHistory[$hash]){
                $this->emitHistory[$hash]=time();
                include($v['file']);
              }
            }
          }
        }
      }
    }
    #js
    if(in_array($req['to'],array('all','js'))){
      onez('bs.live')->emit($eventName,$req);
    }
  }
  #输入错误并停止继续执行代码
  function error($text,$type='json'){
    if($type=='json'){
      onez()->error($text);
    }
    $this->header($type);
    
    $this->footer($type);
    exit();
  }
  #输出头部
  function header($type='mobile'){
    global $G;
    $this->ui_type=$type;
    include(dirname(__FILE__).'/ui/'.$type.'/header.php');
  }
  #输出底部
  function footer($type=false){
    global $G;
    if($type===false){
      $type=$this->ui_type;
    }
    include(dirname(__FILE__).'/ui/'.$type.'/footer.php');
  }
  #把一个插件作为站点解析
  function run(){
    global $G;
    foreach(func_get_args() as $k=>$v){
      if($k===0){
        onez('vue')->init(onez($v)->path);
      }
      onez('vue')->addPath(onez($v)->path);
    }
    onez('vue')->css(onez('bootstrap')->url.'/css/bootstrap.min.css');
    onez('vue')->build();
    onez('vue')->pc();
  }
  function is_ios(){
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    return strpos($user_agent, 'iPhone')||strpos($user_agent, 'iPad');
  }
  function is_android(){
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    return strpos($user_agent, 'Android');
  }
  function is_weixin(){
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    return strpos($user_agent, 'MicroMessenger');
  }
  function is_mobile(){
    return $this->is_ios()||$this->is_android()||$this->is_weixin()||$this->is_qq();
  }
  function is_qq(){
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    return strpos($user_agent, 'QQ');
  }
  function is_alipay(){
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    return strpos($user_agent, 'AlipayClient');
  }
  #处理路霸
  function proxy(){
    onez('header')->nolimit();
    $url=onez()->gp('url');
    if(strpos($url,'http')!==0){
      exit('error');
    }
    echo file_get_contents($url);
  }
}