Files
shopxo/app/service/ThemeAdminService.php

910 lines
31 KiB
PHP
Raw Permalink Normal View History

2018-12-28 18:58:37 +08:00
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
2021-03-16 10:34:52 +08:00
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
2018-12-28 18:58:37 +08:00
// +----------------------------------------------------------------------
2021-03-16 10:34:52 +08:00
// | Licensed ( https://opensource.org/licenses/mit-license.php )
2018-12-28 18:58:37 +08:00
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\service;
2021-07-18 23:42:10 +08:00
use think\facade\Db;
2021-02-15 22:45:33 +08:00
use app\service\ResourcesService;
2023-05-26 11:07:03 +08:00
use app\service\ConfigService;
use app\service\StoreService;
2024-04-15 10:25:01 +08:00
use app\service\ThemeDataService;
2018-12-28 18:58:37 +08:00
/**
2024-04-15 10:25:01 +08:00
* 主题管理服务层
2018-12-28 18:58:37 +08:00
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-01T21:51:08+0800
*/
2024-04-15 10:25:01 +08:00
class ThemeAdminService
2018-12-28 18:58:37 +08:00
{
// 静态目录和html目录
2021-07-30 11:35:25 +08:00
private static $html_path = 'app'.DS.'index'.DS.'view'.DS;
private static $static_path = 'public'.DS.'static'.DS.'index'.DS;
2018-12-28 18:58:37 +08:00
2020-11-21 16:42:35 +08:00
/**
* 默认主题标识符
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2020-11-20
* @desc description
*/
public static function DefaultTheme()
{
return MyC('common_default_theme', 'default', true);
}
2024-04-15 10:25:01 +08:00
/**
* 主题首页是否主题数据模式
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2024-04-05
* @desc description
* @param [string] $theme [主题标识]
*/
public static function HomeIsThemeDataMode($theme)
{
$ret = self::ThemeAdminConfig($theme);
return (!empty($ret['data']) && isset($ret['data']['home_is_theme_data_mode']) && $ret['data']['home_is_theme_data_mode'] == 1);
}
2026-06-02 16:12:10 +08:00
/**
* 敏感联系方式出图样式
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2026-05-13
* @param [string] $theme 当前 PC 模板目录名(如 default、website3
* @param [bool] $use_theme_footer_masking_color true= theme_style.color_footer_maskingfalse 不使用主题定义的脱敏色
* @return [array] color_rgb
*/
public static function SensitiveContactMaskingStyleForTheme($theme, $use_theme_footer_masking_color = true)
{
$out = [];
if(!empty($theme) && $use_theme_footer_masking_color)
{
$rgb = self::FooterMaskingColorRgb($theme);
if($rgb !== null)
{
$out['color_rgb'] = $rgb;
}
}
return $out;
}
/**
* 底部脱敏联系方式图文字颜色(读取指定主题 config.json theme_style.color_footer_masking default;如 #ffffff / #fff
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2026-05-13
* @param [string] $theme [主题标识]
* @return [array|null] [RGB 索引 0255非法串返回 null。解析使用公共函数 HexToRgb]
*/
public static function FooterMaskingColorRgb($theme)
{
if(!is_string($theme) || $theme === '')
{
return null;
}
$ret = self::ThemeAdminConfig($theme);
if(empty($ret['data']) || empty($ret['data']['theme_style']) || !is_array($ret['data']['theme_style']))
{
return null;
}
$ts = $ret['data']['theme_style'];
if(empty($ts['color_footer_masking']) || !is_string($ts['color_footer_masking']))
{
return null;
}
$raw = trim($ts['color_footer_masking']);
if($raw === '')
{
return null;
}
$hex = str_replace('#', '', $raw);
if(!preg_match('/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/', $hex))
{
return null;
}
$rgb = HexToRgb($raw);
return [(int) $rgb['r'], (int) $rgb['g'], (int) $rgb['b']];
}
2018-12-28 18:58:37 +08:00
/**
* 获取模板列表
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-05-10T10:24:40+0800
* @param [array] $params [输入参数]
* @return [array] [模板列表]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminList($params = [])
2018-12-28 18:58:37 +08:00
{
$result = [];
$dir = ROOT.self::$html_path;
2018-12-28 18:58:37 +08:00
if(is_dir($dir))
{
if($dh = opendir($dir))
{
2019-01-11 17:35:35 +08:00
$default_preview = __MY_PUBLIC_URL__.'static'.DS.'common'.DS.'images'.DS.'default-preview.jpg';
2018-12-28 18:58:37 +08:00
while(($temp_file = readdir($dh)) !== false)
{
2022-08-11 11:34:02 +08:00
if(substr($temp_file, 0, 1) == '.' || in_array($temp_file, ['index.html']) || is_dir($temp_file))
2019-01-11 17:35:35 +08:00
{
continue;
}
2018-12-28 18:58:37 +08:00
$config = $dir.$temp_file.DS.'config.json';
if(!file_exists($config))
{
continue;
}
// 读取配置文件
2024-04-15 10:25:01 +08:00
$config = json_decode(file_get_contents($config), true);
if(!empty($config) && is_array($config))
2018-12-28 18:58:37 +08:00
{
2024-04-15 10:25:01 +08:00
if(empty($config['name']) || empty($config['ver']) || empty($config['author']))
2018-12-28 18:58:37 +08:00
{
continue;
}
$preview = ROOT.self::$static_path.$temp_file.DS.'images'.DS.'preview.jpg';
2026-06-02 16:12:10 +08:00
$footer_masking = '';
if(!empty($config['theme_style']) && is_array($config['theme_style']) && array_key_exists('color_footer_masking', $config['theme_style']))
{
$footer_masking = $config['theme_style']['color_footer_masking'];
}
2018-12-28 18:58:37 +08:00
$result[] = array(
2024-04-15 10:25:01 +08:00
'theme' => $temp_file,
'name' => htmlentities($config['name']),
'ver' => str_replace(array('',','), ', ', htmlentities($config['ver'])),
'author' => htmlentities($config['author']),
'home' => isset($config['home']) ? $config['home'] : '',
'preview' => file_exists($preview) ? __MY_PUBLIC_URL__.'static'.DS.'index'.DS.$temp_file.DS.'images'.DS.'preview.jpg' : $default_preview,
'is_theme_data_admin' => (isset($config['is_theme_data_admin']) && $config['is_theme_data_admin'] == 1) ? 1 : 0,
'home_is_theme_data_mode' => (isset($config['home_is_theme_data_mode']) && $config['home_is_theme_data_mode'] == 1) ? 1 : 0,
2026-06-02 16:12:10 +08:00
'color_footer_masking' => $footer_masking,
2024-04-15 10:25:01 +08:00
'is_delete' => ($temp_file == 'default') ? 0 : 1,
2018-12-28 18:58:37 +08:00
);
}
}
closedir($dh);
}
}
return $result;
}
2024-12-25 17:35:54 +08:00
/**
* 主题数据
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2024-12-20
* @desc description
* @param [array] $params [输入参数]
*/
public static function ThemeAdminData($params = [])
{
$data = [];
if(!empty($params['id']))
{
$list = self::ThemeAdminList($params);
if(!empty($list))
{
$list = array_column($list, null, 'theme');
if(array_key_exists($params['id'], $list))
{
$data = $list[$params['id']];
}
}
}
return $data;
}
2018-12-28 18:58:37 +08:00
/**
* 模板上传
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2018-12-19T00:53:45+0800
* @param [array] $params [输入参数]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminUpload($params = [])
2018-12-28 18:58:37 +08:00
{
// 文件上传校验
$error = FileUploadError('theme');
if($error !== true)
{
return DataReturn($error, -1);
}
// 文件格式化校验
2021-02-15 22:45:33 +08:00
$type = ResourcesService::ZipExtTypeList();
2018-12-28 18:58:37 +08:00
if(!in_array($_FILES['theme']['type'], $type))
{
2023-02-06 18:30:08 +08:00
return DataReturn(MyLang('form_upload_zip_message'), -2);
2018-12-28 18:58:37 +08:00
}
2021-02-24 12:40:34 +08:00
// 上传处理
2024-04-15 10:25:01 +08:00
return self::ThemeAdminUploadHandle($_FILES['theme']['tmp_name'], $params);
2021-02-24 12:40:34 +08:00
}
/**
* 模板上传处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-17
* @desc description
* @param [string] $package_file [软件包地址]
* @param [array] $params [输入参数]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminUploadHandle($package_file, $params = [])
2021-02-24 12:40:34 +08:00
{
2018-12-28 18:58:37 +08:00
// 目录是否有权限
if(!is_writable(ROOT.self::$html_path))
2018-12-28 18:58:37 +08:00
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.view_dir_no_power_tips').'['.ROOT.self::$html_path.']', -10);
2018-12-28 18:58:37 +08:00
}
if(!is_writable(ROOT.self::$static_path))
2018-12-28 18:58:37 +08:00
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.static_dir_no_power_tips').'['.self::$static_path.']', -10);
2018-12-28 18:58:37 +08:00
}
2026-06-02 16:12:10 +08:00
if(!ZipPackageFileIsReadablePkMagic($package_file))
{
return DataReturn(MyLang('form_open_zip_message').'[-12]', -11);
}
2019-02-14 11:33:41 +08:00
// 资源目录
$dir_list = [
'_html_' => ROOT.self::$html_path,
'_static_' => ROOT.self::$static_path,
];
2018-12-28 18:58:37 +08:00
// 开始解压文件
2021-08-11 17:30:06 +08:00
$zip = new \ZipArchive();
$resource = $zip->open($package_file);
2024-04-15 10:25:01 +08:00
if($resource !== true)
2018-12-28 18:58:37 +08:00
{
2023-02-06 18:30:08 +08:00
return DataReturn(MyLang('form_open_zip_message').'['.$resource.']', -11);
2021-08-11 17:30:06 +08:00
}
2024-10-21 10:51:14 +08:00
2026-06-02 16:12:10 +08:00
// 配置信息(取首个合法 config并锁定主题标识防子串误匹配 _html_/_static_
$theme_package = '';
2024-10-21 10:51:14 +08:00
for($i=0; $i<$zip->numFiles; $i++)
{
$file = $zip->getNameIndex($i);
2026-06-02 16:12:10 +08:00
if(stripos($file, 'config.json') === false)
2024-10-21 10:51:14 +08:00
{
2026-06-02 16:12:10 +08:00
continue;
}
if(ZipArchiveEntryRelativePathUnsafe($file))
{
$zip->close();
return DataReturn(MyLang('common_service.themeadmin.upload_config_file_get_fail_tips'), -1);
}
$slash_pos = strpos($file, '/');
if($slash_pos === false)
{
continue;
}
$theme = substr($file, 0, $slash_pos);
if($theme === '' || !preg_match('/^[a-zA-Z0-9_\\-]+$/', $theme))
{
$zip->close();
return DataReturn(MyLang('common_service.themeadmin.config_file_no_exist_tips'), -1);
}
2024-10-21 10:51:14 +08:00
2026-06-02 16:12:10 +08:00
// 打开文件资源
$stream = $zip->getStream($file);
if($stream === false)
{
$zip->close();
return DataReturn(MyLang('common_service.themeadmin.upload_config_file_get_fail_tips'), -1);
}
2024-10-21 10:51:14 +08:00
2026-06-02 16:12:10 +08:00
// 获取配置信息并解析
$file_content = stream_get_contents($stream);
fclose($stream);
$config = empty($file_content) ? [] : json_decode($file_content, true);
if(empty($config))
{
$zip->close();
return DataReturn(MyLang('common_service.themeadmin.config_file_no_exist_tips'), -1);
}
2024-10-21 10:51:14 +08:00
2026-06-02 16:12:10 +08:00
// 安全验证
$ret = self::ThemeAdminLegalCheck($theme, $config);
if($ret['code'] != 0)
{
$zip->close();
return $ret;
2024-10-21 10:51:14 +08:00
}
2026-06-02 16:12:10 +08:00
$theme_package = $theme;
break;
}
if($theme_package === '')
{
$zip->close();
return DataReturn(MyLang('common_service.themeadmin.config_file_no_exist_tips'), -1);
2024-10-21 10:51:14 +08:00
}
// 处理文件
2021-08-11 17:30:06 +08:00
$success = 0;
for($i=0; $i<$zip->numFiles; $i++)
{
// 资源文件
$file = $zip->getNameIndex($i);
2018-12-28 18:58:37 +08:00
2021-08-11 17:30:06 +08:00
// 排除临时文件和临时目录
if(strpos($file, '/.') === false && strpos($file, '__') === false)
{
2026-06-02 16:12:10 +08:00
if(ZipArchiveEntryRelativePathUnsafe($file))
{
continue;
}
$norm_file = str_replace('\\', '/', $file);
// 文件包对应系统所在目录(须为 主题标识/_html_|_static_/ 前缀)
2021-08-11 17:30:06 +08:00
$is_has_find = false;
2026-06-02 16:12:10 +08:00
$new_file = '';
2021-08-11 17:30:06 +08:00
foreach($dir_list as $dir_key=>$dir_value)
2018-12-28 18:58:37 +08:00
{
2026-06-02 16:12:10 +08:00
$expected = $theme_package.'/'.$dir_key.'/';
if(strncmp($norm_file, $expected, strlen($expected)) !== 0)
{
continue;
}
$rel = substr($norm_file, strlen($expected));
if(ZipArchiveEntryRelativePathUnsafe($rel))
2018-12-28 18:58:37 +08:00
{
2026-06-02 16:12:10 +08:00
continue;
2018-12-28 18:58:37 +08:00
}
2026-06-02 16:12:10 +08:00
$base = rtrim(str_replace(['\\', '/'], DS, $dir_value), DS).DS;
$new_file = $base.str_replace('/', DS, $rel);
$is_has_find = true;
break;
2021-08-11 17:30:06 +08:00
}
2018-12-28 18:58:37 +08:00
2021-08-11 17:30:06 +08:00
// 没有匹配到则指定目录跳过
if($is_has_find == false)
{
continue;
}
2019-02-14 12:39:15 +08:00
2021-08-11 17:30:06 +08:00
// 排除后缀文件
$pos = strripos($file, '.');
if($pos !== false)
{
$info = pathinfo($file);
2026-06-02 16:12:10 +08:00
if(isset($info['extension']) && ZipPublicDirExtensionIsForbidden($info['extension']))
2020-08-15 11:25:48 +08:00
{
2021-08-11 17:30:06 +08:00
continue;
2020-08-15 11:25:48 +08:00
}
2021-08-11 17:30:06 +08:00
}
2020-08-15 11:25:48 +08:00
2021-08-11 17:30:06 +08:00
// 截取文件路径
2026-06-02 16:12:10 +08:00
$rpos = strrpos(str_replace('\\', '/', $new_file), '/');
if($rpos === false)
{
$rpos = strrpos($new_file, '\\');
}
$file_path = $rpos === false ? $new_file : substr($new_file, 0, $rpos);
2018-12-28 18:58:37 +08:00
2021-08-11 17:30:06 +08:00
// 路径不存在则创建
if(!is_dir($file_path))
{
mkdir($file_path, 0777, true);
}
2018-12-28 18:58:37 +08:00
2021-08-11 17:30:06 +08:00
// 如果不是目录则写入文件
if(!is_dir($new_file))
{
// 读取这个文件
$stream = $zip->getStream($file);
if($stream !== false)
2018-12-28 18:58:37 +08:00
{
2021-08-11 17:30:06 +08:00
$file_content = stream_get_contents($stream);
if($file_content !== false)
{
if(file_put_contents($new_file, $file_content))
{
$success++;
}
}
fclose($stream);
2018-12-28 18:58:37 +08:00
}
}
}
}
2021-08-11 17:30:06 +08:00
// 关闭zip
$zip->close();
// 未匹配成功一个文件则认为插件包无效
if($success <= 0)
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.package_invalid_tips'), -1);
2021-08-11 17:30:06 +08:00
}
2024-04-15 10:25:01 +08:00
// 主题数据处理
ThemeDataService::ThemeDataUploadHandle($package_file, array_merge($params, ['is_theme_upload'=>1]));
// 返回成功
2023-02-04 16:47:48 +08:00
return DataReturn(MyLang('install_success'), 0);
2018-12-28 18:58:37 +08:00
}
2023-05-26 11:07:03 +08:00
/**
* 主题切换保存
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2023-05-26
* @desc description
* @param [array] $params [输入参数]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminSwitch($params = [])
2023-05-26 11:07:03 +08:00
{
// 主题标识
$theme = empty($params['theme']) ? 'default' : $params['theme'];
// 安全判断
2024-04-15 10:25:01 +08:00
$ret = self::ThemeAdminLegalCheck($theme);
2023-05-26 11:07:03 +08:00
if($ret['code'] != 0)
{
return $ret;
}
// 切换配置
$params['common_default_theme'] = $theme;
2024-04-15 10:25:01 +08:00
$ret = ConfigService::ConfigSave($params);
if($ret['code'] == 0)
{
// 同步前端主题session数据
DefaultTheme($theme);
}
return $ret;
2023-05-26 11:07:03 +08:00
}
2018-12-28 18:58:37 +08:00
/**
* 模板删除
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2018-12-19T00:46:02+0800
* @param [array] $params [输入参数]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminDelete($params = [])
2018-12-28 18:58:37 +08:00
{
2020-11-21 16:42:35 +08:00
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'id',
2024-04-15 10:25:01 +08:00
'error_msg' => MyLang('common_service.themeadmin.template_id_error_tips'),
2020-11-21 16:42:35 +08:00
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
2018-12-28 18:58:37 +08:00
{
2020-11-21 16:42:35 +08:00
return DataReturn($ret, -1);
2018-12-28 18:58:37 +08:00
}
2019-06-16 16:22:43 +08:00
// 防止路径回溯
2019-01-06 00:20:24 +08:00
$id = htmlentities(str_replace(array('.', '/', '\\', ':'), '', strip_tags($params['id'])));
2018-12-28 18:58:37 +08:00
if(empty($id))
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.theme_name_error_tips'), -1);
2018-12-28 18:58:37 +08:00
}
// default不能删除
if($id == 'default')
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.system_theme_not_delete_tips'), -2);
2018-12-28 18:58:37 +08:00
}
// 不能删除正在使用的主题
2020-11-21 16:42:35 +08:00
if(self::DefaultTheme() == $id)
2018-12-28 18:58:37 +08:00
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.current_use_theme_error_tips'), -2);
2018-12-28 18:58:37 +08:00
}
// 开始删除主题
if(\base\FileUtil::UnlinkDir(ROOT.self::$html_path.$id) && \base\FileUtil::UnlinkDir(ROOT.self::$static_path.$id))
2018-12-28 18:58:37 +08:00
{
2023-01-19 17:44:03 +08:00
return DataReturn(MyLang('delete_success'), 0);
2018-12-28 18:58:37 +08:00
}
2023-02-04 16:47:48 +08:00
return DataReturn(MyLang('delete_fail'), -100);
2018-12-28 18:58:37 +08:00
}
2019-06-16 16:22:43 +08:00
/**
* 主题打包
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-03-22
* @desc description
* @param [array] $params [输入参数]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminDownload($params = [])
2024-12-25 17:35:54 +08:00
{
// 生成下载包
$package = self::ThemeAdminDownloadHandle($params);
if($package['code'] != 0)
{
return $package;
}
// 开始下载
if(\base\FileUtil::DownloadFile($package['data']['file'], $package['data']['config']['name'].'_v'.$package['data']['config']['ver'].'.zip', true))
{
return DataReturn(MyLang('download_success'), 0);
}
return DataReturn(MyLang('download_fail'), -100);
}
/**
* 上传到应用商店
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2023-08-17
* @desc description
* @param [array] $params [输入参数]
*/
public static function ThemeAdminStoreUpload($params = [])
{
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'version_new',
'error_msg' => MyLang('common_service.themeadmin.form_item_version_message'),
],
[
'checked_type' => 'empty',
'key_name' => 'describe',
'error_msg' => MyLang('common_service.themeadmin.form_item_desc_message'),
],
[
'checked_type' => 'empty',
'key_name' => 'apply_version',
'error_msg' => MyLang('common_service.themeadmin.form_item_apply_version_message'),
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 生成下载包
$package = self::ThemeAdminDownloadHandle($params);
if($package['code'] != 0)
{
return $package;
}
// 帐号信息
$user = StoreService::AccountsData();
if(empty($user['accounts']) || empty($user['password']))
{
return DataReturn(MyLang('store_account_not_bind_tips'), -300);
}
// 上传到远程
$params['theme'] = $package['data']['theme'];
$params['file'] = new \CURLFile($package['data']['file']);
$ret = StoreService::RemoteStoreData($user['accounts'], $user['password'], MyConfig('shopxo.store_themeadmin_upload_url'), $params, 2);
// 是个与否都删除本地生成的zip包
@unlink($package['data']['file']);
// 返回数据
return $ret;
}
/**
* 主题打包处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-03-22
* @desc description
* @param [array] $params [输入参数]
*/
public static function ThemeAdminDownloadHandle($params = [])
2019-06-16 16:22:43 +08:00
{
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'id',
2024-04-15 10:25:01 +08:00
'error_msg' => MyLang('common_service.themeadmin.template_id_error_tips'),
2019-06-16 16:22:43 +08:00
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 是否开启开发者模式
2021-07-18 23:42:10 +08:00
if(MyConfig('shopxo.is_develop') !== true)
2019-06-16 16:22:43 +08:00
{
2023-02-06 18:30:08 +08:00
return DataReturn(MyLang('not_open_developer_mode_tips'), -1);
2019-06-16 16:22:43 +08:00
}
// 防止路径回溯
$theme = htmlentities(str_replace(array('.', '/', '\\', ':'), '', strip_tags($params['id'])));
if(empty($theme))
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.theme_name_error_tips'), -1);
2019-06-16 16:22:43 +08:00
}
2019-10-14 21:33:20 +08:00
// 获取配置信息
2024-04-15 10:25:01 +08:00
$config_res = self::ThemeAdminConfig($theme);
2021-04-23 16:43:23 +08:00
if($config_res['code'] != 0)
2019-10-14 21:33:20 +08:00
{
2021-04-23 16:43:23 +08:00
return $config_res;
2019-10-14 21:33:20 +08:00
}
2021-04-23 16:43:23 +08:00
$config = $config_res['data'];
2019-10-14 21:33:20 +08:00
2024-10-21 10:51:14 +08:00
// 安全判断
$ret = self::ThemeAdminLegalCheck($theme, $config);
if($ret['code'] != 0)
{
return $ret;
}
2019-06-16 16:22:43 +08:00
// 目录不存在则创建
$new_dir = ROOT.'runtime'.DS.'data'.DS.'theme_package'.DS.$theme;
\base\FileUtil::CreateDir($new_dir);
// 复制包目录 - 视图
$old_dir = ROOT.self::$html_path.$theme;
if(is_dir($old_dir))
{
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_html_') != true)
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('project_copy_fail_tips').'['.MyLang('common_service.themeadmin.theme_copy_view_fail_tips').']', -2);
2019-06-16 16:22:43 +08:00
}
}
// 复制包目录 - 静态文件
$old_dir = ROOT.self::$static_path.$theme;
if(is_dir($old_dir))
{
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_static_') != true)
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('project_copy_fail_tips').'['.MyLang('common_service.themeadmin.theme_copy_static_fail_tips').']', -2);
2019-06-16 16:22:43 +08:00
}
}
// 配置文件历史信息更新
$new_config_file = $new_dir.DS.'_html_'.DS.'config.json';
if(!file_exists($new_config_file))
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.theme_new_config_error_tips'), -10);
}
if(empty($config['history']))
{
$config['history'] = [];
}
$config['history'][] = [
'host' => __MY_HOST__,
'url' => __MY_URL__,
'ip' => __MY_ADDR__,
'time' => date('Y-m-d H:i:s'),
];
if(@file_put_contents($new_config_file, JsonFormat($config)) === false)
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.theme_new_config_update_fail_tips'), -11);
}
2024-04-15 10:25:01 +08:00
// 主题数据包同步到主题里面一起下载
ThemeDataService::ThemeDownloadPackageHandle(['theme'=>$theme, 'dir'=>$new_dir.DS.'_theme_data_'.DS]);
2019-06-16 16:22:43 +08:00
// 生成压缩包
$zip = new \base\ZipFolder();
if(!$zip->zip($new_dir.'.zip', $new_dir))
{
2023-02-06 18:30:08 +08:00
return DataReturn(MyLang('form_generate_zip_message'), -100);
2019-06-16 16:22:43 +08:00
}
// 生成成功删除目录
\base\FileUtil::UnlinkDir($new_dir);
2024-12-25 17:35:54 +08:00
// 返回数据
return DataReturn('success', 0, [
'file' => $new_dir.'.zip',
'config' => $config,
'theme' => $theme,
]);
2019-06-16 16:22:43 +08:00
}
2021-04-23 16:43:23 +08:00
2023-05-26 11:07:03 +08:00
/**
* 主题安全判断
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2023-05-26
* @desc description
* @param [string] $theme [主题标识]
2024-10-21 10:51:14 +08:00
* @param [array] $data [主题数据]
2023-05-26 11:07:03 +08:00
*/
2024-10-21 10:51:14 +08:00
public static function ThemeAdminLegalCheck($theme, $data = [])
2023-05-26 11:07:03 +08:00
{
2024-12-25 17:35:54 +08:00
if(RequestModule() == 'admin')
2023-05-26 11:07:03 +08:00
{
2024-12-25 17:35:54 +08:00
$key = 'theme_legal_check_'.$theme;
$ret = MyCache($key);
if(empty($ret))
2023-05-26 11:07:03 +08:00
{
2024-12-25 17:35:54 +08:00
if(empty($data))
2023-05-26 11:07:03 +08:00
{
2024-12-25 17:35:54 +08:00
$config_res = self::ThemeAdminConfig($theme);
if($config_res['code'] != 0)
{
return $config_res;
}
$data = $config_res['data'];
2023-05-26 11:07:03 +08:00
}
2024-12-25 17:35:54 +08:00
$check_params = [
'type' => 'webtheme',
'config' => $data,
'plugins' => $theme,
'author' => isset($data['author']) ? $data['author'] : '',
'ver' => isset($data['version']) ? $data['version'] : (isset($data['ver']) ? $data['ver'] : ''),
];
$ret = StoreService::PluginsLegalCheck($check_params);
MyCache($key, $ret, 3600);
}
if(!in_array($ret['code'], [0, -9999]))
{
return $ret;
2023-05-26 11:07:03 +08:00
}
}
return DataReturn('success', 0);
}
2021-04-23 16:43:23 +08:00
/**
* 主题配置信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [string] $theme [主题标识]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminConfig($theme)
2021-04-23 16:43:23 +08:00
{
// 获取配置信息
$config_file = ROOT.self::$html_path.$theme.DS.'config.json';
if(!file_exists($config_file))
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.config_file_no_exist_tips'), -1);
2021-04-23 16:43:23 +08:00
}
$config = json_decode(file_get_contents($config_file), true);
if(empty($config))
{
2024-04-15 10:25:01 +08:00
return DataReturn(MyLang('common_service.themeadmin.config_error_tips'), -1);
2021-04-23 16:43:23 +08:00
}
return DataReturn('success', 0, $config);
}
/**
* web主题更新信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-04-22
* @desc description
* @param [array] $params [输入参数]
*/
2024-04-15 10:25:01 +08:00
public static function ThemeAdminUpgradeInfo($params = [])
2021-04-23 16:43:23 +08:00
{
if(!empty($params))
{
// 数据处理
$data = [];
foreach($params as $v)
{
if(!empty($v['name']) && !empty($v['ver']) && !empty($v['theme']) && !empty($v['author']))
{
$data[] = [
'plugins' => $v['theme'],
'name' => $v['name'],
'ver' => $v['ver'],
'author' => $v['author'],
];
}
}
if(!empty($data))
{
// 获取更新信息
$request_params = [
'plugins_type' => 'webtheme',
'plugins_data' => $data,
];
$res = StoreService::PluginsUpgradeInfo($request_params);
2021-11-09 22:54:59 +08:00
if(!empty($res['data']) && is_array($res['data']))
2021-04-23 16:43:23 +08:00
{
$res['data'] = array_column($res['data'], null, 'plugins');
}
return $res;
}
}
2023-02-11 17:01:04 +08:00
return DataReturn(MyLang('plugins_no_data_tips'), 0);
2021-04-23 16:43:23 +08:00
}
2024-04-15 10:25:01 +08:00
/**
* 主题数据管理url
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2024-04-11
* @desc description
* @param [array] $params [输入参数]
*/
public static function ThemeAdminDataUrl($params = [])
{
// 链接数据
$data = [
'themedata' => MyUrl('admin/themedata/saveinfo', ['is_theme_data_admin' => 1]),
'goods' => MyUrl('admin/goods/saveinfo', ['is_theme_data_admin' => 1]),
'goods_category' => MyUrl('admin/goodscategory/index', ['is_theme_data_admin' => 1]),
'brand' => MyUrl('admin/brand/saveinfo', ['is_theme_data_admin' => 1]),
'brand_list' => MyUrl('admin/brand/index', ['is_theme_data_admin' => 1]),
'article' => MyUrl('admin/article/saveinfo', ['is_theme_data_admin' => 1]),
'article_list' => MyUrl('admin/article/index', ['is_theme_data_admin' => 1]),
'article_category' => MyUrl('admin/articlecategory/index', ['is_theme_data_admin' => 1]),
'link_list' => MyUrl('admin/link/index', ['is_theme_data_admin' => 1]),
'navigation_header' => MyUrl('admin/navigation/index', ['type' => 'header', 'is_theme_data_admin' => 1]),
'navigation_footer' => MyUrl('admin/navigation/index', ['type' => 'footer', 'is_theme_data_admin' => 1]),
'slide_list' => MyUrl('admin/slide/index', ['is_theme_data_admin' => 1]),
2024-04-15 10:25:01 +08:00
'store_config' => MyUrl('admin/config/store', ['is_theme_data_admin' => 1]),
'user_login' => MyUrl('admin/site/index', ['nav_type' => 'login', 'is_theme_data_admin' => 1]),
'user_register' => MyUrl('admin/site/index', ['nav_type' => 'register', 'is_theme_data_admin' => 1]),
'user_forget' => MyUrl('admin/site/index', ['nav_type' => 'forgetpwd', 'is_theme_data_admin' => 1]),
'screening_price' => MyUrl('admin/screeningprice/index', ['is_theme_data_admin' => 1]),
2024-04-25 14:47:59 +08:00
'site_base' => MyUrl('admin/site/index', ['nav_type'=>'base', 'switch'=>'site-base', 'is_theme_data_admin' => 1]),
'site_filing' => MyUrl('admin/site/index', ['nav_type'=>'base', 'switch'=>'site-filing', 'is_theme_data_admin' => 1]),
2024-04-15 10:25:01 +08:00
];
// 主题数据管理url钩子
$hook_name = 'plugins_service_theme_admin_data_url';
MyEventTrigger($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'data' => &$data,
]);
return $data;
}
2024-10-21 10:51:14 +08:00
/**
* 模板市场
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2022-04-19
* @desc description
* @param [array] $params [输入参数]
*/
public static function ThemeAdminMarket($params = [])
{
$params['type'] = 'webtheme';
return StoreService::PackageDataList($params);
}
2018-12-28 18:58:37 +08:00
}
?>