File: /www/wwwroot/bb.cwoyt.com/Application/Admin/Controller/AddonsController.class.php
<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: yangweijie <yangweijiester@gmail.com> <code-tech.diandian.com>
// +----------------------------------------------------------------------
namespace Admin\Controller;
/**
* 扩展后台管理页面
* @author yangweijie <yangweijiester@gmail.com>
*/
class AddonsController extends AdminController {
static protected $deny = array('addhook','edithook','delhook','updateHook');
public function _initialize(){
$this->assign('_extra_menu',array(
'已装插件后台'=> D('Addons')->getAdminList(),
));
parent::_initialize();
}
//创建向导首页
public function create(){
if(!is_writable(ONETHINK_ADDON_PATH))
$this->error('您没有创建目录写入权限,无法使用此功能');
$hooks = M('Hooks')->field('name,description')->select();
$this->assign('Hooks',$hooks);
$this->meta_title = '创建向导';
$this->display('create');
}
//预览
public function preview($output = true){
$data = $_POST;
$data['info']['status'] = (int)$data['info']['status'];
$extend = array();
$custom_config = trim($data['custom_config']);
if($data['has_config'] && $custom_config){
$custom_config = <<<str
public \$custom_config = '{$custom_config}';
str;
$extend[] = $custom_config;
}
$admin_list = trim($data['admin_list']);
if($data['has_adminlist'] && $admin_list){
$admin_list = <<<str
public \$admin_list = array(
{$admin_list}
);
str;
$extend[] = $admin_list;
}
$custom_adminlist = trim($data['custom_adminlist']);
if($data['has_adminlist'] && $custom_adminlist){
$custom_adminlist = <<<str
public \$custom_adminlist = '{$custom_adminlist}';
str;
$extend[] = $custom_adminlist;
}
$extend = implode('', $extend);
$tpl = <<<str
<?php
namespace Addons\\{$data['info']['name']};
use Common\Controller\Addon;
/**
* {$data['info']['title']}插件
* @author {$data['info']['author']}
*/
class {$data['info']['name']}Addon extends Addon{
public \$info = array(
'name'=>'{$data['info']['name']}',
'title'=>'{$data['info']['title']}',
'description'=>'{$data['info']['description']}',
'status'=>{$data['info']['status']},
'author'=>'{$data['info']['author']}',
'version'=>'{$data['info']['version']}'
);{$extend}
public function install(){
return true;
}
public function uninstall(){
return true;
}
//实现的{$data['hook']}钩子方法
public function {$data['hook']}(\$param){
}
}
str;
if($output)
exit($tpl);
else
return $tpl;
}
public function checkForm(){
$data = $_POST;
$data['info']['name'] = trim($data['info']['name']);
if(!$data['info']['name'])
$this->error('插件标识必须');
//检测插件名是否合法
$addons_dir = ONETHINK_ADDON_PATH;
if(file_exists("{$addons_dir}{$data['info']['name']}")){
$this->error('插件已经存在了');
}
$this->success('可以创建');
}
public function build(){
$data = $_POST;
$data['info']['name'] = trim($data['info']['name']);
$addonFile = $this->preview(false);
$addons_dir = ONETHINK_ADDON_PATH;
//创建目录结构
$files = array();
$addon_dir = "$addons_dir{$data['info']['name']}/";
$files[] = $addon_dir;
$addon_name = "{$data['info']['name']}Addon.class.php";
$files[] = "{$addon_dir}{$addon_name}";
if($data['has_config'] == 1);//如果有配置文件
$files[] = $addon_dir.'config.php';
if($data['has_outurl']){
$files[] = "{$addon_dir}Controller/";
$files[] = "{$addon_dir}Controller/{$data['info']['name']}Controller.class.php";
$files[] = "{$addon_dir}Model/";
$files[] = "{$addon_dir}Model/{$data['info']['name']}Model.class.php";
}
$custom_config = trim($data['custom_config']);
if($custom_config)
$data[] = "{$addon_dir}{$custom_config}";
$custom_adminlist = trim($data['custom_adminlist']);
if($custom_adminlist)
$data[] = "{$addon_dir}{$custom_adminlist}";
create_dir_or_files($files);
//写文件
file_put_contents("{$addon_dir}{$addon_name}", $addonFile);
if($data['has_outurl']){
$addonController = <<<str
<?php
namespace Addons\\{$data['info']['name']}\Controller;
use Home\Controller\AddonsController;
class {$data['info']['name']}Controller extends AddonsController{
}
str;
file_put_contents("{$addon_dir}Controller/{$data['info']['name']}Controller.class.php", $addonController);
$addonModel = <<<str
<?php
namespace Addons\\{$data['info']['name']}\Model;
use Think\Model;
/**
* {$data['info']['name']}模型
*/
class {$data['info']['name']}Model extends Model{
}
str;
file_put_contents("{$addon_dir}Model/{$data['info']['name']}Model.class.php", $addonModel);
}
if($data['has_config'] == 1)
file_put_contents("{$addon_dir}config.php", $data['config']);
$this->success('创建成功',U('index'));
}
/**
* 插件列表
*/
public function index(){
$this->meta_title = '插件列表';
$list = D('Addons')->getList();
$this->recordList($list);
$this->display();
}
/**
* 插件后台显示页面
* @param string $name 插件名
*/
public function adminList($name){
$class = get_addon_class($name);
if(!class_exists($class))
$this->error('插件不存在');
$addon = new $class();
$this->assign('addon', $addon);
$param = $addon->admin_list;
if(!$param)
$this->error('插件列表信息不正确');
$this->meta_title = $addon->info['title'];
extract($param);
$this->assign('title', $addon->info['title']);
if($addon->custom_adminlist)
$this->assign('custom_adminlist', $addon->addon_path.$addon->custom_adminlist);
$this->assign($param);
if(!isset($fields))
$fields = '*';
if(!isset($map))
$map = array();
if(isset($model))
$list = $this->lists(D("Addons://{$model}/{$model}")->field($fields),$map);
$thead = array(
//元素value中的变量就是数据集中的字段,value必须使用单引号
//所有 _ 下划线开头的元素用于使用html代码生成th和td
'_html' => array(
'th' => '<input class="check-all" type="checkbox"/>',
'td' => '<input class="ids" type="checkbox" name="id[]" value="$id" />',
),
//查询出的数据集中的字段=>字段的表头
);
if(isset($listKey))
$thead = array_merge($thead, $listKey);
if(!$list)
$list = array();
$this->assign( '_table_list', $this->tableList($list,$thead) );
$this->display();
}
/**
* 启用插件
*/
public function enable(){
$id = I('id');
$msg = array('success'=>'启用成功', 'error'=>'启用失败');
S('hooks', null);
$this->resume('Addons', "id={$id}", $msg);
}
/**
* 禁用插件
*/
public function disable(){
$id = I('id');
$msg = array('success'=>'禁用成功', 'error'=>'禁用失败');
S('hooks', null);
$this->forbid('Addons', "id={$id}", $msg);
}
/**
* 设置插件页面
*/
public function config(){
$id = (int)I('id');
$addon = M('Addons')->find($id);
if(!$addon)
$this->error('插件未安装');
$addon_class = get_addon_class($addon['name']);
if(!class_exists($addon_class))
trace("插件{$addon['name']}无法实例化,",'ADDONS','ERR');
$data = new $addon_class;
$addon['addon_path'] = $data->addon_path;
$addon['custom_config'] = $data->custom_config;
$this->meta_title = '设置插件-'.$data->info['title'];
$db_config = $addon['config'];
$addon['config'] = include $data->config_file;
if($db_config){
$db_config = json_decode($db_config, true);
foreach ($addon['config'] as $key => $value) {
if($value['type'] != 'group'){
$addon['config'][$key]['value'] = $db_config[$key];
}else{
foreach ($value['options'] as $gourp => $options) {
foreach ($options['options'] as $gkey => $value) {
$addon['config'][$key]['options'][$gourp]['options'][$gkey]['value'] = $db_config[$gkey];
}
}
}
}
}
$this->assign('data',$addon);
if($addon['custom_config'])
$this->assign('custom_config', $addon['addon_path'].$addon['custom_config']);
$this->display();
}
/**
* 保存插件设置
*/
public function saveConfig(){
$id = (int)I('id');
$config = I('config');
$flag = M('Addons')->where("id={$id}")->setField('config',json_encode($config));
if($flag !== false){
$this->success('保存成功', U('index'));
}else{
$this->error('保存失败');
}
}
/**
* 安装插件
*/
public function install(){
$addon_name = trim(I('addon_name'));
$class = get_addon_class($addon_name);
if(!class_exists($class))
$this->error('插件不存在');
$addons = new $class;
$info = $addons->info;
if(!$info || !$addons->checkInfo())//检测信息的正确性
$this->error('插件信息缺失');
session('addons_install_error',null);
$install_flag = $addons->install();
if(!$install_flag){
$this->error('执行插件预安装操作失败'.session('addons_install_error'));
}
$addonsModel = D('Addons');
$data = $addonsModel->create($info);
if(is_array($addons->admin_list) && $addons->admin_list !== array()){
$data['has_adminlist'] = 1;
}else{
$data['has_adminlist'] = 0;
}
if(!$data)
$this->error($addonsModel->getError());
if($addonsModel->add($data)){
$config = array('config'=>json_encode($addons->getConfig()));
$addonsModel->where("name='{$addon_name}'")->save($config);
$hooks_update = D('Hooks')->updateHooks($addon_name);
if($hooks_update){
S('hooks', null);
$this->success('安装成功');
}else{
$addonsModel->where("name='{$addon_name}'")->delete();
$this->error('更新钩子处插件失败,请卸载后尝试重新安装');
}
}else{
$this->error('写入插件数据失败');
}
}
/**
* 卸载插件
*/
public function uninstall(){
$addonsModel = M('Addons');
$id = trim(I('id'));
$db_addons = $addonsModel->find($id);
$class = get_addon_class($db_addons['name']);
$this->assign('jumpUrl',U('index'));
if(!$db_addons || !class_exists($class))
$this->error('插件不存在');
session('addons_uninstall_error',null);
$addons = new $class;
$uninstall_flag = $addons->uninstall();
if(!$uninstall_flag)
$this->error('执行插件预卸载操作失败'.session('addons_uninstall_error'));
$hooks_update = D('Hooks')->removeHooks($db_addons['name']);
if($hooks_update === false){
$this->error('卸载插件所挂载的钩子数据失败');
}
S('hooks', null);
$delete = $addonsModel->where("name='{$db_addons['name']}'")->delete();
if($delete === false){
$this->error('卸载插件失败');
}else{
$this->success('卸载成功');
}
}
/**
* 钩子列表
*/
public function hooks(){
$this->meta_title = '钩子列表';
$map = $fields = array();
$list = $this->lists(D("Hooks")->field($fields),$map);
int_to_string($list, array('type'=>C('HOOKS_TYPE')));
$thead = array(
//元素value中的变量就是数据集中的字段,value必须使用单引号
//查询出的数据集中的字段=>字段的表头
'id' => '',
'name' => '名称',
'description' => '描述',
'type_text' => '类型',
'插件' => array(
'编辑' => array(
'href' => 'edithook?id=$id'
),
'删除' => array(
'href' => 'delhook?id=$id',
'class' => 'confirm ajax-get',
'condition' => 'is_administrator()'
)
)
);
$this->assign('_table_class', 'data-table table-striped');
$this->assign( '_table_list', $this->tableList($list,$thead) );
$this->display();
}
public function addhook(){
$this->assign('data', null);
$this->meta_title = '新增钩子';
$this->display('edithook');
}
//钩子出编辑挂载插件页面
public function edithook($id){
$hook = M('Hooks')->field(true)->find($id);
$this->assign('data',$hook);
$this->meta_title = '编辑钩子';
$this->display('edithook');
}
//超级管理员删除钩子
public function delhook($id){
if(M('Hooks')->delete($id) !== false){
$this->success('删除成功');
}else{
$this->error('删除失败');
}
}
public function updateHook(){
$hookModel = D('Hooks');
$data = $hookModel->create();
if($data){
if($data['id']){
$flag = $hookModel->save($data);
if($flag !== false)
$this->success('更新成功', U('hooks'));
else
$this->error('更新失败');
}else{
$flag = $hookModel->add($data);
if($flag)
$this->success('新增成功', U('hooks'));
else
$this->error('新增失败');
}
}else{
$this->error($hookModel->getError());
}
}
public function execute($_addons = null, $_controller = null, $_action = null){
if(C('URL_CASE_INSENSITIVE')){
$_addons = ucfirst(parse_name($_addons, 1));
$_controller = parse_name($_controller,1);
}
if(!empty($_addons) && !empty($_controller) && !empty($_action)){
$Addons = A("Addons://{$_addons}/{$_controller}")->$_action();
} else {
$this->error('没有指定插件名称,控制器或操作!');
}
}
}