<?php
/**
 * +------------------------------------------------------------
 * | 后台插件管理类
 * +------------------------------------------------------------
 * | @author: bsh (844783437@qq.com)
 * | @create_time: 2018年10月13日15:48:47
 * +------------------------------------------------------------
 * | @copyright: CIM信息聚合系统 (https://cimxx.com)
 * +------------------------------------------------------------
 * | @last_modified_by: bsh
 * | @last_modified_time: 2018年10月13日15:48:56
 * +------------------------------------------------------------
 * |
 * +------------------------------------------------------------
 */

namespace app\cim\controller;

use app\common\controller\Init;

use think\facade\Env;

define('ADDONS_DIR', Env::get('root_path') . 'addons' . DIRECTORY_SEPARATOR);
define('STATIC_DIR', Env::get('root_path') . 'public' . DIRECTORY_SEPARATOR);

class Addons extends Init
{

    public function initialize()
    {
        parent::initialize();
        if (empty(session('admin'))) die(json_encode(['code' => 1000, 'msg' => '请登录...']));
    }

    /**
     * 插件列表
     */
    public function index()
    {
        if (!file_exists(ADDONS_DIR)) return json(['code' => 84001, 'msg' => '插件目录不存在']);
        $dir = get_dir(ADDONS_DIR);
        if (empty($dir)) {
            $list = [];
        } else {
            $list = array_column(model('app\common\model\Addons')->where('name', 'in', $dir)->select()->toArray(), null, 'name');
            $uninstall = array_diff($dir, array_column($list, 'name'));
            if (!empty($uninstall)) {
                foreach ($uninstall as $k => $v) {
                    $class = "addons\\{$v}\\" . ucfirst($v);
                    if (class_exists($class)) {
                        $obj = new $class;
                        if (isset($obj->info)) {
                            $list[$v] = $obj->info;
                            $class = get_addon_class($v, 'controller', 'admin');
                            $list[$v]['admin'] = 0;
                        }
                    }
                    if (file_exists(ADDONS_DIR . $v . DIRECTORY_SEPARATOR . $v . '.png') && !file_exists(STATIC_DIR . $v . DIRECTORY_SEPARATOR . $v . '.png')) {
                        if (!file_exists(STATIC_DIR . $v . DIRECTORY_SEPARATOR)) @mkdir(STATIC_DIR . $v . DIRECTORY_SEPARATOR, 1);
                        @copy(ADDONS_DIR . $v . DIRECTORY_SEPARATOR . $v . '.png', STATIC_DIR . $v . DIRECTORY_SEPARATOR . $v . '.png');
                    }
                }
            }
            foreach ($list as $k => $v) {
                $list[$k]['icon'] = $this->request->domain() . "/{$k}/{$k}.png";
                $v['admin'] && $list[$k]['admin_url'] = $this->request->domain() . "/addons/{$v['name']}/admin/index";
            }
        }
        return json(['code' => 1, 'msg' => '加载成功', 'data' => array_values($list)]);
    }

    /**
     * 安装插件
     */
    public function install($name = '')
    {
        $dir = ADDONS_DIR . $name . DIRECTORY_SEPARATOR;
        if (!$name || !is_dir($dir)) return json(['code' => 84002, 'msg' => '指定插件不存在']);
        try {
            if (db('addons')->where('name', '=', $name)->count()) return json(['code' => 84003, 'msg' => '插件已安装']);
            $class = get_addon_class($name);
            $addons = new $class ();
            if (method_exists($addons, 'install')) $addons->install();
            if (is_file($dir . 'install.sql')) $this->sql($dir . 'install.sql');
            if (is_dir($dir . 'static')) copydir($dir . 'static', \think\facade\Env::get('root_path') . 'public' . DIRECTORY_SEPARATOR . $name);

            $info = $addons->info;
            $addonsModel = model('app\common\model\Addons');
            if (file_exists(ADDONS_DIR . $name . DIRECTORY_SEPARATOR . 'config.php')) {
                $addon_config = include(ADDONS_DIR . $name . DIRECTORY_SEPARATOR . 'config.php');
                if (!empty($addon_config)) $info['setting'] = $addon_config;
            }
            $class = get_addon_class($name, 'controller', 'admin');
            $info['admin'] = (class_exists($class) && method_exists($class, 'index')) ? 1 : 0;
            if ($addonsModel->allowField(true)->save($info)) {
                return json(['code' => 1, 'msg' => '插件安装成功']);
            } else {
                return json(['code' => 84004, 'msg' => '写入插件数据失败']);
            }
        } catch (\Exception $e) {
            return json(['code' => 84005, 'msg' => $e->getMessage()]);
        }
    }

    /**
     *  卸载插件
     */
    public function uninstall($id = 0)
    {
        $addon = db('addons')->where('id', '=', $id)->find();
        if (empty($addon) || !is_dir($dir = ADDONS_DIR . $addon['name'] . DIRECTORY_SEPARATOR)) return json(['code' => 84002, 'msg' => '指定插件不存在']);
        $static_dir = \think\facade\Env::get('root_path') . 'public' . DIRECTORY_SEPARATOR . $addon['name'];
        try {
            $class = get_addon_class($addon['name']);
            $addons = new $class();
            if (method_exists($addons, 'uninstall')) $addons->uninstall();
            if (is_file($dir . 'uninstall.sql')) $this->sql($dir . 'uninstall.sql');
            if (is_dir($static_dir)) clear_file($static_dir);
            db('addons')->where('id', '=', $id)->delete();
            return json(['code' => 1, 'msg' => '插件卸载成功']);
        } catch (\Exception $e) {
            return json(['cide' => 84006, 'msg' => $e->getMessage()]);
        }
    }

    /**
     * 执行sql文件
     */
    public function sql($sql_path)
    {
        if (is_file($sql_path)) {
            try {
                $sql = file($sql_path);
                foreach ($sql as $k => $v) $sql[$k] = trim($v);
                $sql = explode(';', join('', $sql));
                foreach ($sql as $k => $v) {
                    if (!empty($v)) \think\Db::execute($v);
                }
            } catch (\Exception $e) {
                throw new \Exception($e->getMessage());
            }
        }
        return true;
    }

}