| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 | <?phpnamespace app\admin\controller;use app\common\controller\Backend;use fast\Http;use think\addons\AddonException;use think\addons\Service;use think\Cache;use think\Config;use think\Db;use think\Exception;/** * 插件管理 * * @icon   fa fa-cube * @remark 可在线安装、卸载、禁用、启用、配置、升级插件,插件升级前请做好备份。 */class Addon extends Backend{    protected $model = null;    protected $noNeedRight = ['get_table_list'];    public function _initialize()    {        parent::_initialize();        if (!$this->auth->isSuperAdmin() && in_array($this->request->action(), ['install', 'uninstall', 'local', 'upgrade', 'authorization', 'testdata'])) {            $this->error(__('Access is allowed only to the super management group'));        }    }    /**     * 插件列表     */    public function index()    {        $addons = get_addon_list();        foreach ($addons as $k => &$v) {            $config = get_addon_config($v['name']);            $v['config'] = $config ? 1 : 0;            $v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);        }        $this->assignconfig(['addons' => $addons, 'api_url' => config('fastadmin.api_url'), 'faversion' => config('fastadmin.version'), 'domain' => request()->host(true)]);        return $this->view->fetch();    }    /**     * 配置     */    public function config($name = null)    {        $name = $name ? $name : $this->request->get("name");        if (!$name) {            $this->error(__('Parameter %s can not be empty', 'name'));        }        if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {            $this->error(__('Addon name incorrect'));        }        $info = get_addon_info($name);        $config = get_addon_fullconfig($name);        if (!$info) {            $this->error(__('Addon not exists'));        }        if ($this->request->isPost()) {            $params = $this->request->post("row/a", [], 'trim');            if ($params) {                foreach ($config as $k => &$v) {                    if (isset($params[$v['name']])) {                        if ($v['type'] == 'array') {                            $params[$v['name']] = is_array($params[$v['name']]) ? $params[$v['name']] : (array)json_decode($params[$v['name']], true);                            $value = $params[$v['name']];                        } else {                            $value = is_array($params[$v['name']]) ? implode(',', $params[$v['name']]) : $params[$v['name']];                        }                        $v['value'] = $value;                    }                }                try {                    $addon = get_addon_instance($name);                    //插件自定义配置实现逻辑                    if (method_exists($addon, 'config')) {                        $addon->config($name, $config);                    } else {                        //更新配置文件                        set_addon_fullconfig($name, $config);                        Service::refresh();                    }                } catch (Exception $e) {                    $this->error(__($e->getMessage()));                }                $this->success();            }            $this->error(__('Parameter %s can not be empty', ''));        }        $tips = [];        $groupList = [];        foreach ($config as $index => &$item) {            //如果有设置分组            if (isset($item['group']) && $item['group']) {                if (!in_array($item['group'], $groupList)) {                    $groupList["custom" . (count($groupList) + 1)] = $item['group'];                }            }            if ($item['name'] == '__tips__') {                $tips = $item;                unset($config[$index]);            }        }        $groupList['other'] = '其它';        $this->view->assign("groupList", $groupList);        $this->view->assign("addon", ['info' => $info, 'config' => $config, 'tips' => $tips]);        $configFile = ADDON_PATH . $name . DS . 'config.html';        $viewFile = is_file($configFile) ? $configFile : '';        return $this->view->fetch($viewFile);    }    /**     * 安装     */    public function install()    {        $name = $this->request->post("name");        $force = (int)$this->request->post("force");        if (!$name) {            $this->error(__('Parameter %s can not be empty', 'name'));        }        if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {            $this->error(__('Addon name incorrect'));        }        $info = [];        try {            $uid = $this->request->post("uid");            $token = $this->request->post("token");            $version = $this->request->post("version");            $faversion = $this->request->post("faversion");            $extend = [                'uid'       => $uid,                'token'     => $token,                'version'   => $version,                'faversion' => $faversion            ];            $info = Service::install($name, $force, $extend);        } catch (AddonException $e) {            $this->result($e->getData(), $e->getCode(), __($e->getMessage()));        } catch (Exception $e) {            $this->error(__($e->getMessage()), $e->getCode());        }        $this->success(__('Install successful'), '', ['addon' => $info]);    }    /**     * 卸载     */    public function uninstall()    {        $name = $this->request->post("name");        $force = (int)$this->request->post("force");        $droptables = (int)$this->request->post("droptables");        if (!$name) {            $this->error(__('Parameter %s can not be empty', 'name'));        }        if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {            $this->error(__('Addon name incorrect'));        }        //只有开启调试且为超级管理员才允许删除相关数据库        $tables = [];        if ($droptables && Config::get("app_debug") && $this->auth->isSuperAdmin()) {            $tables = get_addon_tables($name);        }        try {            Service::uninstall($name, $force);            if ($tables) {                $prefix = Config::get('database.prefix');                //删除插件关联表                foreach ($tables as $index => $table) {                    //忽略非插件标识的表名                    if (!preg_match("/^{$prefix}{$name}/", $table)) {                        continue;                    }                    Db::execute("DROP TABLE IF EXISTS `{$table}`");                }            }        } catch (AddonException $e) {            $this->result($e->getData(), $e->getCode(), __($e->getMessage()));        } catch (Exception $e) {            $this->error(__($e->getMessage()));        }        $this->success(__('Uninstall successful'));    }    /**     * 禁用启用     */    public function state()    {        $name = $this->request->post("name");        $action = $this->request->post("action");        $force = (int)$this->request->post("force");        if (!$name) {            $this->error(__('Parameter %s can not be empty', 'name'));        }        if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {            $this->error(__('Addon name incorrect'));        }        try {            $action = $action == 'enable' ? $action : 'disable';            //调用启用、禁用的方法            Service::$action($name, $force);            Cache::rm('__menu__');        } catch (AddonException $e) {            $this->result($e->getData(), $e->getCode(), __($e->getMessage()));        } catch (Exception $e) {            $this->error(__($e->getMessage()));        }        $this->success(__('Operate successful'));    }    /**     * 本地上传     */    public function local()    {        Config::set('default_return_type', 'json');        $info = [];        $file = $this->request->file('file');        try {            $uid = $this->request->post("uid");            $token = $this->request->post("token");            $faversion = $this->request->post("faversion");            if (!$uid || !$token) {                throw new Exception(__('Please login and try to install'));            }            $extend = [                'uid'       => $uid,                'token'     => $token,                'faversion' => $faversion            ];            $info = Service::local($file, $extend);        } catch (AddonException $e) {            $this->result($e->getData(), $e->getCode(), __($e->getMessage()));        } catch (Exception $e) {            $this->error(__($e->getMessage()));        }        $this->success(__('Offline installed tips'), '', ['addon' => $info]);    }    /**     * 更新插件     */    public function upgrade()    {        $name = $this->request->post("name");        $addonTmpDir = RUNTIME_PATH . 'addons' . DS;        if (!$name) {            $this->error(__('Parameter %s can not be empty', 'name'));        }        if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {            $this->error(__('Addon name incorrect'));        }        if (!is_dir($addonTmpDir)) {            @mkdir($addonTmpDir, 0755, true);        }        $info = [];        try {            $uid = $this->request->post("uid");            $token = $this->request->post("token");            $version = $this->request->post("version");            $faversion = $this->request->post("faversion");            $extend = [                'uid'       => $uid,                'token'     => $token,                'version'   => $version,                'faversion' => $faversion            ];            //调用更新的方法            $info = Service::upgrade($name, $extend);            Cache::rm('__menu__');        } catch (AddonException $e) {            $this->result($e->getData(), $e->getCode(), __($e->getMessage()));        } catch (Exception $e) {            $this->error(__($e->getMessage()));        }        $this->success(__('Operate successful'), '', ['addon' => $info]);    }    /**     * 测试数据     */    public function testdata()    {        $name = $this->request->post("name");        if (!$name) {            $this->error(__('Parameter %s can not be empty', 'name'));        }        if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {            $this->error(__('Addon name incorrect'));        }        try {            Service::importsql($name, 'testdata.sql');        } catch (AddonException $e) {            $this->result($e->getData(), $e->getCode(), __($e->getMessage()));        } catch (Exception $e) {            $this->error(__($e->getMessage()), $e->getCode());        }        $this->success(__('Import successful'), '');    }    /**     * 已装插件     */    public function downloaded()    {        $offset = (int)$this->request->get("offset");        $limit = (int)$this->request->get("limit");        $filter = $this->request->get("filter");        $search = $this->request->get("search");        $search = htmlspecialchars(strip_tags($search));        $onlineaddons = $this->getAddonList();        $filter = (array)json_decode($filter, true);        $addons = get_addon_list();        $list = [];        foreach ($addons as $k => $v) {            if ($search && stripos($v['name'], $search) === false && stripos($v['title'], $search) === false && stripos($v['intro'], $search) === false) {                continue;            }            if (isset($onlineaddons[$v['name']])) {                $v = array_merge($v, $onlineaddons[$v['name']]);                $v['price'] = '-';            } else {                $v['category_id'] = 0;                $v['flag'] = '';                $v['banner'] = '';                $v['image'] = '';                $v['donateimage'] = '';                $v['demourl'] = '';                $v['price'] = __('None');                $v['screenshots'] = [];                $v['releaselist'] = [];                $v['url'] = addon_url($v['name']);                $v['url'] = str_replace($this->request->server('SCRIPT_NAME'), '', $v['url']);            }            $v['createtime'] = filemtime(ADDON_PATH . $v['name']);            if ($filter && isset($filter['category_id']) && is_numeric($filter['category_id']) && $filter['category_id'] != $v['category_id']) {                continue;            }            $list[] = $v;        }        $total = count($list);        if ($limit) {            $list = array_slice($list, $offset, $limit);        }        $result = array("total" => $total, "rows" => $list);        $callback = $this->request->get('callback') ? "jsonp" : "json";        return $callback($result);    }    /**     * 检测     */    public function isbuy()    {        $name = $this->request->post("name");        $uid = $this->request->post("uid");        $token = $this->request->post("token");        $version = $this->request->post("version");        $faversion = $this->request->post("faversion");        $extend = [            'uid'       => $uid,            'token'     => $token,            'version'   => $version,            'faversion' => $faversion        ];        try {            $result = Service::isBuy($name, $extend);        } catch (Exception $e) {            $this->error(__($e->getMessage()));        }        return json($result);    }    /**     * 刷新授权     */    public function authorization()    {        $params = [            'uid'       => $this->request->post('uid'),            'token'     => $this->request->post('token'),            'faversion' => $this->request->post('faversion'),        ];        try {            Service::authorization($params);        } catch (Exception $e) {            $this->error(__($e->getMessage()));        }        $this->success(__('Operate successful'));    }    /**     * 获取插件相关表     */    public function get_table_list()    {        $name = $this->request->post("name");        if (!preg_match("/^[a-zA-Z0-9]+$/", $name)) {            $this->error(__('Addon name incorrect'));        }        $tables = get_addon_tables($name);        $prefix = Config::get('database.prefix');        foreach ($tables as $index => $table) {            //忽略非插件标识的表名            if (!preg_match("/^{$prefix}{$name}/", $table)) {                unset($tables[$index]);            }        }        $tables = array_values($tables);        $this->success('', null, ['tables' => $tables]);    }    protected function getAddonList()    {        $onlineaddons = Cache::get("onlineaddons");        if (!is_array($onlineaddons) && config('fastadmin.api_url')) {            $onlineaddons = [];            $params = [                'uid'       => $this->request->post('uid'),                'token'     => $this->request->post('token'),                'version'   => config('fastadmin.version'),                'faversion' => config('fastadmin.version'),            ];            $json = [];            try {                $json = Service::addons($params);            } catch (\Exception $e) {            }            $rows = isset($json['rows']) ? $json['rows'] : [];            foreach ($rows as $index => $row) {                $onlineaddons[$row['name']] = $row;            }            Cache::set("onlineaddons", $onlineaddons, 600);        }        return $onlineaddons;    }}
 |