<?php

use think\App;
use think\facade\Hook;
use think\facade\Config;
use think\Loader;
use think\facade\Cache;
use think\facade\Route;

// 插件目录
$appPath = (new App())->getAppPath();
$addons_path = dirname($appPath) . DIRECTORY_SEPARATOR . 'addons' . DIRECTORY_SEPARATOR;
Env::set('addons_path', $addons_path);
// 定义路由
//两种路由方式
//addons/addon/controller/action 将直接执行插件方法
Route::any('addons/:addon/:controller/:action', "\\think\\addons\\Route@execute");
//addons/addon-controller-action 通过模块中的插件代理，通过反射来执行。这种方式，会先执行模块中的父类方法，比如说权限验证。同时该方式可以加载模块中的父模板及使用include标签加载的模板文件。
Route::any('addons/:addon-:controller-:action', "Addons/agent");

// 如果插件目录不存在则创建
//if (!is_dir($addons_path)) {
//    @mkdir($addons_path, 0777, true);
//}

// 注册类的根命名空间
Loader::addNamespace('addons', $addons_path);

// 闭包初始化行为
Hook::add('app_init', function () {
    //从配置中加载钩子
    $addonsConfig = __ROOT__ . 'config/addons.php';
    if (is_file($addonsConfig)) {
        $config = include $addonsConfig;
        Hook::import($config['hooks'], false);
        //如果在插件中有定义appInit，则直接执行
        if (isset($config['hooks']['appInit'])) {
            foreach ($config['hooks']['appInit'] as $k => $v) {
                Hook::exec([$v,'appInit']);
            }
        }
    }
});

/**
 * 处理插件钩子
 * @param string $hook 钩子名称
 * @param mixed $params 传入参数
 * @return void
 */
function hook($hook, $params = [])
{
    $hook = lcfirst(Loader::parseName($hook, 1));
    $result = Hook::listen($hook, $params);
    if (is_array($result)) {
        foreach ($result as &$item) {
            if ($item instanceof \think\response\Json) {
                return $item = $item->getContent();
            }
        }
        $result = join(PHP_EOL, $result);
    }
    return $result;
}

/**
 * 获取插件类的类名
 * @param $name 插件名
 * @param string $type 返回命名空间类型
 * @param string $class 当前类名
 * @return string
 */
function get_addon_class($name, $type = 'hook', $class = null)
{
    $name = Loader::parseName($name);  //驼峰转下划线
    // 处理多级控制器情况
    if (!is_null($class) && strpos($class, '.')) {
        $class = explode('.', $class);
        foreach ($class as $key => $cls) {
            $class[$key] = Loader::parseName($cls, 1);
        }
        $class = implode('\\', $class);
    } else {

        $class = Loader::parseName(is_null($class) ? $name : $class, 1);
    }
    switch ($type) {
        case 'controller':
            $namespace = "\\addons\\" . $name . "\\controller\\" . $class;
            break;
        default:
            $namespace = "\\addons\\" . $name . "\\" . $class;
    }

    return class_exists($namespace) ? $namespace : '';
}

/**
 * 获取插件类的配置文件数组
 * @param string $name 插件名
 * @return array
 */
function get_addon_config($name)
{
    $class = get_addon_class($name);
    if (class_exists($class)) {
        $addon = new $class();
        return $addon->getConfig();
    } else {
        return [];
    }
}

/**
 * 插件显示内容里生成访问插件的url
 * @param string $url 地址 格式：插件名/控制器/方法
 * @param array $param ,参数
 * @param bool|string $suffix 生成的URL后缀
 * @param bool|string $domain 域名
 * @return bool|string
 */
function addon_url($url, $param = [], $suffix = true, $domain = false)
{
    $parse_param = parse_url(ltrim($url, '/'));

    /* 解析URL带的参数 */
    if (isset($parse_param['query'])) {
        parse_str($parse_param['query'], $query);
        $param = array_merge($query, $param);
    }
    return url("@addons/".$parse_param['path'], $param, $suffix, $domain);
}