124 lines
4.8 KiB
PHP
124 lines
4.8 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Author: ywxapp<admin@ywxapp.cn>
|
||
// +----------------------------------------------------------------------
|
||
|
||
if (!function_exists('addon_url')) {
|
||
/**
|
||
* 生成插件访问地址(MultiApp 多应用模型:/<addon>/<controller>/<action>)
|
||
* @param string $name 插件标识
|
||
* @param string $url 相对路径,如 'admin/index' 或 '/admin/index'
|
||
* @param array $vars 附加 GET 参数
|
||
* @return string
|
||
*/
|
||
function addon_url(string $name, string $url = '', array $vars = []): string
|
||
{
|
||
$path = '/' . trim($name, '/');
|
||
if ($url !== '' && $url !== '/') {
|
||
$path .= '/' . ltrim($url, '/');
|
||
}
|
||
return $vars ? $path . '?' . http_build_query($vars) : $path;
|
||
}
|
||
}
|
||
|
||
if (!function_exists('get_addon_instance')) {
|
||
/**
|
||
* 获取插件主类实例(addon\<name>\Addon)
|
||
* @param string $name 插件标识
|
||
* @return object|null
|
||
*/
|
||
function get_addon_instance(string $name)
|
||
{
|
||
$class = '\\addon\\' . $name . '\\Addon';
|
||
if (!class_exists($class)) {
|
||
return null;
|
||
}
|
||
return app($class);
|
||
}
|
||
}
|
||
|
||
if (!function_exists('get_addon_info')) {
|
||
/**
|
||
* 读取插件信息(优先缓存,force=true 强制重读)
|
||
* @param string $name 插件标识
|
||
* @param bool $force
|
||
* @return array
|
||
*/
|
||
function get_addon_info(string $name = '', bool $force = false): array
|
||
{
|
||
$instance = get_addon_instance($name);
|
||
return $instance ? $instance->getInfo($name, $force) : [];
|
||
}
|
||
}
|
||
|
||
if (!function_exists('get_addon_config')) {
|
||
/**
|
||
* 读取插件配置(优先缓存,force=true 强制重读)
|
||
* @param string $name 插件标识
|
||
* @param bool $force
|
||
* @return array
|
||
*/
|
||
function get_addon_config(string $name = '', bool $force = false): array
|
||
{
|
||
$instance = get_addon_instance($name);
|
||
return $instance ? $instance->getConfig($name, $force) : [];
|
||
}
|
||
}
|
||
|
||
if (!function_exists('is_market_client')) {
|
||
/**
|
||
* 市场是否处于「客户机」模式(「谁是中心站」由 config/ywxapp.php 决定):
|
||
* - market_mode=center → 强制中心站
|
||
* - market_mode=client → 强制客户机
|
||
* - market_mode=auto(默认):
|
||
* · api_url 为空 → 本机即中心站(直接读写本地市场 wxapp_appmarket_addon_list)
|
||
* · api_url 指向本机(同主机)→ 仍视为中心站(配置纠偏)
|
||
* · api_url 指向其他主机 → 本机作为客户机,经 RemoteService 连接该中心站
|
||
*
|
||
* auto 模式下依赖「当前请求主机」判定自身:改用框架 Request 抽象(可测试、CLI 可控),
|
||
* 不再直接读 $_SERVER['HTTP_HOST']。CLI(路由缓存/refresh-menu)无法取得主机时保守判为客户机——
|
||
* 因此中心站请保持 api_url 为空,或显式设置 market_mode=center 以彻底解除该约束。
|
||
* @return bool
|
||
*/
|
||
function is_market_client(): bool
|
||
{
|
||
$mode = \think\facade\Config::get('ywxapp.market_mode', 'auto');
|
||
if ($mode === 'center') {
|
||
return false;
|
||
}
|
||
if ($mode === 'client') {
|
||
return true;
|
||
}
|
||
|
||
// auto:基于 api_url + 自身主机推导
|
||
$apiUrl = \think\facade\Config::get('ywxapp.api_url', '');
|
||
if (empty($apiUrl)) {
|
||
return false;
|
||
}
|
||
$host = parse_url($apiUrl, PHP_URL_HOST);
|
||
if (empty($host)) {
|
||
return false;
|
||
}
|
||
|
||
// 用框架 Request 抽象主机(可 mock / CLI 可控),替代直接读 $_SERVER['HTTP_HOST']
|
||
$req = function_exists('request') ? request() : null;
|
||
$self = $req ? (string) $req->host() : '';
|
||
if ($self === '') {
|
||
// CLI(如路由缓存/refresh-menu)无法判定主机:回退到 market_mode 显式配置。
|
||
// 只有显式声明 market_mode=client 才当作客户机;否则(auto/center)按中心站处理,
|
||
// 避免中心站 CLI 刷新菜单时误删 centerOnly 项(应用市场审核/开发者/收益等运营菜单)。
|
||
return \think\facade\Config::get('ywxapp.market_mode', 'auto') === 'client';
|
||
}
|
||
$selfHost = preg_replace('/:\d+$/', '', $self);
|
||
$cmpHost = preg_replace('/:\d+$/', '', $host);
|
||
if (strcasecmp($selfHost, $cmpHost) === 0) {
|
||
return false; // api_url 指向自身 = 视为中心站(配置纠偏)
|
||
}
|
||
return true;
|
||
}
|
||
}
|