<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

declare (strict_types=1);

namespace buwang\base;

use buwang\traits\JsonTrait;
use buwang\traits\JwtTrait;
use buwang\traits\JumpTrait;
use think\App;
use think\exception\ValidateException;
use think\Validate;

/**
 * 控制器基础类
 */
abstract class BaseController
{
    use JsonTrait;
    use JumpTrait;
    use JwtTrait;

    /**
     * @var string 用户类型
     */
    protected $scopes = '';
    /**
     * @var bool 是否登录
     */
    protected $isUserLogin = false;
    /**
     * @var array 用户信息
     */
    protected $user = [];

    /**
     * @var string token
     */
    protected $token = '';

    /**
     * Request实例
     * @var \think\Request
     */
    protected $request = null;

    /**
     * 应用实例
     * @var \think\App
     */
    protected $app = null;

    /**
     * 是否批量验证
     * @var bool
     */
    protected $batchValidate = false;

    /**
     * 控制器中间件
     * @var array
     */
    protected $middleware = [];
    /**
     * @var array 应用下自动加载 vendor
     */
    public static $vendorLoaded = [];

    /**
     * 构造方法
     * BaseController constructor.
     */
    public function __construct()
    {
        header("Content-type:text/html;charset=utf-8");
        //如下先判断是因为 PluginBaseController也继承了此基类,会重写__construct,先执行了
        if(!$this->app) $this->app = app();
        if(!$this->request) $this->request = isset(app()->bwRequest) ? app('bwRequest') : $this->app->request;
        if(!$this->isUserLogin) $this->isUserLogin = isset(app()->bwRequest) ? $this->request->isUserLogin() : false;
        if(!$this->user) $this->user = isset(app()->bwRequest) ? $this->request->userInfo() : [];//token携带者信息
        if(!$this->token) $this->token = isset(app()->bwRequest) ? $this->request->token() : '';
        if(!$this->scopes) $this->scopes = isset(app()->bwRequest) ? $this->request->scopes() : '';
        $appPath = app('http')->getName();
        if (empty(self::$vendorLoaded[$appPath])) {
            $pluginVendorAutoLoadFile = app_path() .'vendor'.DS.'autoload.php';
            if (file_exists($pluginVendorAutoLoadFile)) {
                require_once $pluginVendorAutoLoadFile;
            }
            self::$vendorLoaded[$appPath] = true;
        }
        // 控制器初始化
        $this->initialize();
    }

    // 初始化
    protected function initialize()
    {
    }

    /**
     * 验证数据
     * @access protected
     * @param array $data 数据
     * @param string|array $validate 验证器名或者验证规则数组
     * @param array $message 提示信息
     * @param bool $batch 是否批量验证
     * @return array|string|true
     * @throws ValidateException
     */
    protected function validate(array $data, $validate, array $message = [], bool $batch = false)
    {
        if (is_array($validate)) {
            $v = new Validate();
            $v->rule($validate);
        } else {
            if (strpos($validate, '.')) {
                // 支持场景
                list($validate, $scene) = explode('.', $validate);
            }
            $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
            $v = new $class();
            if (!empty($scene)) {
                $v->scene($scene);
            }
        }
        $v->message($message);
        // 是否批量验证
        if ($batch || $this->batchValidate) {
            $v->batch(true);
        }

        return $v->failException(true)->check($data);
    }

    /**
     * 获取用户类型
     * @return mixed
     */
    public function getScopes()
    {
        return $this->scopes;
    }
}