Files
OMS/app/base/kernel.php
2025-12-28 23:13:25 +08:00

501 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Copyright © ShopeX http://www.shopex.cn. All rights reserved.
* See LICENSE file for license details.
*/
if(!defined('APP_DIR')){
define('APP_DIR',ROOT_DIR.'/app');
}
if(!defined('TRAIT_DIR')){
define('TRAIT_DIR',ROOT_DIR.'/trait');
}
if(!defined('ECAE_MODE') && defined('ECAE_SITE_ID') && ECAE_SITE_ID > 0){
define('ECAE_MODE', true);
}else{
define('ECAE_MODE', false);
}
error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED ^ E_WARNING);
require_once(dirname(__FILE__) . '/lib/ego/ego.php');
class kernel{
static $base_url = null;
static $url_app_map = array();
static $app_url_map = array();
static $console_output = false;
static private $__online = null;
static private $__router = null;
static private $__db_instance = null;
static private $__singleton_instance = array();
static private $__request_instance = null;
static private $__single_apps = array();
static private $__service_list = array();
static private $__base_url = array();
static private $__language = null;
static function cleanInstance() {
self::$__db_instance = null;
self::$__singleton_instance = [];
self::$__request_instance =null;
self::$__single_apps =[];
}
static function boot(){
set_error_handler(array('kernel', 'exception_error_handler'));
try{
// 如果已经安装直接引入CONFIG
if (self::is_online()) {
require ROOT_DIR . '/config/config.php';
@include APP_DIR . '/base/defined.php';
}
// 兼容PHP ERROR
if (defined('SENTRY_OPTIONS') && constant('SENTRY_OPTIONS') && is_array(constant('SENTRY_OPTIONS'))){
\Sentry\init(constant('SENTRY_OPTIONS'));
}
require(ROOT_DIR.'/config/mapper.php');
self::$url_app_map = $urlmap;
foreach(self::$url_app_map AS $flag=>$value){
self::$app_url_map[$value['app']] = $flag;
}
/*// xss 和 sql 注入问题
$before_request = json_encode($_REQUEST);
$after_request = json_encode(self::request_filter($_REQUEST));
if ($before_request != $after_request) {
header("HTTP/1.1 508 Not Found");
exit;
}*/
// if(!self::register_autoload()){
// require(dirname(__FILE__) . '/autoload.php');
// }
$pathinfo = self::request()->get_path_info();
$jump = false;
if(isset($pathinfo[1])){
if($p = strpos($pathinfo,'/',2)){
$part = substr($pathinfo,0,$p);
}else{
$part = $pathinfo;
$jump = true;
}
}else{
$part = '/';
}
if($part=='/api'){
cachemgr::init();
if(isset($_POST['method']) && (substr($_POST['method'],0,4) == 'wms.' ||substr($_POST['method'],0,6) == 'store.' || in_array($_POST['method'],['ome.order.deliverypriority']))){
#wms请求处理
//return kernel::single('rpc_service')->process($pathinfo);
return kernel::single('erpapi_rpc_service',1)->process($pathinfo);
}else{
return kernel::single('base_rpc_service',1)->process($pathinfo);
}
}elseif($part=='/callback'){
// RPC callback 功能已移除
// cachemgr::init();
// return kernel::single('rpc_service',1)->callback($pathinfo);
die('RPC callback function has been removed');
}elseif($part=='/openapi'){
cachemgr::init();
return kernel::single('base_rpc_service',1)->process($pathinfo);
}elseif($part=='/app-doc'){
cachemgr::init();
return kernel::single('base_misc_doc',1)->display($pathinfo);
}elseif($part=='/qimen'){
//qimen路由(birkenstock勃肯中间件使用)
cachemgr::init();
return kernel::single('qimen_rpc_service',1)->process($pathinfo);
}
if(isset(self::$url_app_map[$part])){
if($jump){
$request_uri = self::request()->get_request_uri();
$urlinfo = parse_url($request_uri);
$query = $urlinfo['query']?'?'.$urlinfo['query']:'';
header('Location: '.$urlinfo['path'].'/'.$query);
exit;
}else{
$app = self::$url_app_map[$part]['app'];
$prefix_len = strlen($part)+1;
// kernel::set_lang(self::$url_app_map[$part]['lang']);
}
}else{
if ($part !== '/index.php') {
header("HTTP/1.1 404 Not Found");exit;
}
$app = self::$url_app_map['/']['app'];
$prefix_len = 1;
// kernel::set_lang(self::$url_app_map['/']['lang']);
}
$lang = kernel::single('base_component_request', 1)->get_cookie('oms-language');
kernel::set_lang($lang ?: self::$url_app_map['/']['lang']);
if(!$app){
readfile(ROOT_DIR.'/app/base/readme.html');
exit;
}
if(!self::is_online()){
if(file_exists(APP_DIR.'/setup/app.xml')){
if($app!='setup'){
//todo:进入安装check
setcookie('LOCAL_SETUP_URL', app::get('setup')->base_url(1), 0, '/');
header('Location: '. kernel::base_url().'/app/setup/check.php');
exit;
}
}else{
echo '<h1>System is Offline, install please.</h1>';
exit;
}
}
date_default_timezone_set(
defined('DEFAULT_TIMEZONE') ? ('Etc/GMT'.(DEFAULT_TIMEZONE>=0?(DEFAULT_TIMEZONE*-1):'+'.(DEFAULT_TIMEZONE*-1))):'UTC'
);
if(isset($pathinfo[$prefix_len])){
$path = substr($pathinfo,$prefix_len);
}else{
$path = '';
}
//init cachemgr
if($app=='setup'){
cachemgr::init(false);
}else{
cachemgr::init();
}
//get app router
self::$__router = app::get($app)->router();
self::$__router->dispatch($path);
}catch(Exception $e){
// 异常上报
\Sentry\captureException($e);
base_errorpage::exception_handler($e);
}
}
static function request_filter($data){
if(is_array($data)){
foreach($data as $key=>$v){
$data[$key] = self::request_filter($data[$key]);
}
}else{
$length=strlen($data);
if($length){
if($length<3000){// 字符长度超过太长的跳过验证
$filter_rule=array(
'xss' =>"[\'\"\;\*\<\>]+.*\b(on)[a-zA-Z]{3,15}[\s\r\n\v\f]*\=|\b(expression)\(|<script[\s\\\\\/]*.*>|(<!\[cdata\[)|\b(eval|alert|prompt|msgbox)\s*\(|url\((\#|data|javascript)",
'sql' =>"([^{\s]{1}.+(select|update|insert((\/\*[\S\s]*?\*\/)|(\s)|(\+))+into).+?(from|set)((\/\*[\S\s]*?\*\/)|(\s)|(\+))+)|[^{\s]{1}.+(create|delete|drop|truncate|rename|desc)((\/\*[\S\s]*?\*\/)|(\s)|(\+))+(table|from|database)((\/\*[\S\s]*?\*\/)|(\s)|(\+))|(into((\/\*[\S\s]*?\*\/)|\s|\+)+(dump|out)file\b)|\bsleep\((\s*)(\d*)(\s*)\)|benchmark\(([^\,]*)\,([^\,]*)\)|\b(declare|set|select)\b.*@|union\b.*(select|all)\b|(select|update|insert|create|delete|drop|grant|truncate|rename|exec|desc|from|table|database|set|where)\b.*((charset|ascii|bin|char|uncompress|concat|concat_ws|conv|export_set|hex|instr|left|load_file|locate|mid|sub|substring|oct|reverse|right|unhex)\(|(master\.\.sysdatabases|msysaccessobjects|msysqueries|sysmodules|mysql\.db|sys\.database_name|information_schema\.|sysobjects|sp_makewebtask|xp_cmdshell|sp_oamethod|sp_addextendedproc|sp_oacreate|xp_regread|sys\.dbms_export_extension))",
);
foreach ($filter_rule as $key => $value) {
$data = preg_replace("/" . $value . "/si", "", $data);
}
}
} else {
$data = $data;
}
}
return $data;
}
static function exception_error_handler($errno, $errstr, $errfile, $errline )
{
switch ($errno) {
case E_ERROR:
case E_USER_ERROR:
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
break;
case E_STRICT:
case E_USER_WARNING:
case E_USER_NOTICE:
default:
//do nothing
break;
}
return true;
}//End Function
/**
* @return base_router
*/
static function router(){
return self::$__router;
}
static function openapi_url($openapi_service_name,$method='access',$params=null){
if(substr($openapi_service_name,0,8)!='openapi.'){
trigger_error('$openapi_service_name must start with: openapi.');
return false;
}
$arg = array();
foreach((array)$params as $k=>$v){
$arg[] = urlencode($k);
$arg[] = urlencode(str_replace('/','%2F',$v));
}
return kernel::base_url(1).kernel::url_prefix().'/openapi/'.substr($openapi_service_name,8).'/'.$method.'/'.implode('/',$arg);
}
static function request(){
if(!isset(self::$__request_instance)){
self::$__request_instance = kernel::single('base_request',1);
}
return self::$__request_instance;
}
static function url_prefix(){
return (defined('WITH_REWRITE') && WITH_REWRITE === true)?'':'/index.php';
}
static function this_url($full=false){
return self::base_url($full).self::url_prefix().self::request()->get_path_info();
}
static function log($message,$keepline=false){
if(self::$console_output){
if($keepline){
echo $message;
}else{
echo $message = $message."\n";
}
}else{
$kernel_log = app::get('ome')->getConf('ome.kernel.log');
if($kernel_log == 'true'){
//modify by edwin.lzh@gmail.com 2010/6/10
$message = sprintf("%s\t%s\n", date("Y-m-d H:i:s"), $message);
switch(LOG_TYPE)
{
case 3:
if(defined('LOG_FILE')){
$logfile = str_replace('{date}', date("Ymd"), LOG_FILE);
$ip = ($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
$ip = str_replace(array('.', ':'), array('_', '_'), $ip);
$logfile = str_replace('{ip}', $ip, $logfile);
}else{
$logfile = DATA_DIR . '/logs/all.php';
}
if(!file_exists($logfile)){
if(!is_dir(dirname($logfile))) utils::mkdir_p(dirname($logfile));
file_put_contents($logfile, (defined(LOG_HEAD_TEXT))?LOG_HEAD_TEXT:'<'.'?php exit()?'.">\n");
}
@error_log($message, 3, $logfile);
break;
// case 0:
// default:
// @error_log($message, 0);
}//End Switch
}
}
}
static function base_url($full=false){
$c = ($full) ? 'true' : 'false';
if(!isset(self::$__base_url[$c])){
if(defined('BASE_URL')){
if($full){
self::$__base_url[$c] = constant('BASE_URL');
}else{
$url = parse_url(constant('BASE_URL'));
if(isset($url['path'])){
self::$__base_url[$c] = $url['path'];
}else{
self::$__base_url[$c] = '';
}
}
}else{
if(!isset(self::$base_url)){
self::$base_url = self::request()->get_base_url();
}
if(self::$base_url == '/'){
self::$base_url = '';
}
if($full){
self::$__base_url[$c] = strtolower(self::request()->get_schema()).'://'.self::request()->get_host().self::$base_url;
}else{
self::$__base_url[$c] = self::$base_url;
}
}
}
return self::$__base_url[$c];
}
/**
* 获取当前网站的域名
* @param bool $full
*/
public static function domain_url($full = true)
{
$result = kernel::base_url($full);
if (empty(strpos($result, '://'))) {
return $result;
}
list($prefix, $domain) = explode('://', $result);
return $domain;
}
public static function get_host_url()
{
return strtolower(self::request()->get_schema()).'://'.self::request()->get_host();
}
static function set_online($mode){
self::$__online = $mode;
}
static function is_online(){
if(self::$__online===null){
self::$__online = file_exists(ROOT_DIR.'/config/config.php');
}
return self::$__online;
}
static function single($class_name,$arg=null){
if($arg===null){
$p = strpos($class_name,'_');
if($p){
$app_id = substr($class_name,0,$p);
if(!isset(self::$__single_apps[$app_id])){
self::$__single_apps[$app_id] = app::get($app_id);
}
$arg = self::$__single_apps[$app_id];
}
}
if(is_object($arg)){
$key = get_class($arg);
if($key==='app'){
$key .= '.' . $arg->app_id;
}
$key = '__class__' . $key;
}else{
$key = md5('__key__'.serialize($arg));
}
if(!isset(self::$__singleton_instance[$class_name][$key])){
self::$__singleton_instance[$class_name][$key] = new $class_name($arg);
}
return self::$__singleton_instance[$class_name][$key];
}
/** @return base_db_connections */
static function database(){
if(!isset(self::$__db_instance)){
$classname = defined('DATABASE_OBJECT') ? constant('DATABASE_OBJECT') : 'base_db_connections';
$obj = new $classname;
if($obj instanceof base_interface_db){
self::$__db_instance = $obj;
}else{
trigger_error(DATABASE_OBJECT.' must implements base_interface_db!', E_USER_ERROR);
exit;
}
}
return self::$__db_instance;
}
static function service($srv_name,$filter=null){
$defined_service = app::get('base')->getConf('server.'.$srv_name);
if($defined_service && $defined_service = kernel::single($defined_service)){
return $defined_service;
}
return self::servicelist($srv_name,$filter)->current();
}
static function servicelist($srv_name,$filter=null){
if(self::is_online()){
if(base_kvstore::instance('service')->fetch($srv_name,$service_define)){
return $service_define ? new service($service_define,$filter) : new ArrayIterator(array());
}
if(!(defined('WITHOUT_KVSTORE_PERSISTENT') && constant('WITHOUT_KVSTORE_PERSISTENT')) && get_class(base_kvstore::instance('service')->get_controller())!='base_kvstore_mysql'){
if(kernel::single('base_kvstore_mysql', 'service')->fetch($srv_name, $service_define)) {
base_kvstore::instance('service')->store($srv_name, $service_define);
return $service_define ? new service($service_define,$filter) : new ArrayIterator(array());
}
base_kvstore::instance('service')->store($srv_name, []);
}
}
return new ArrayIterator(array());
}
static function strip_magic_quotes(&$var){
foreach($var as $k=>$v){
if(is_array($v)){
self::strip_magic_quotes($var[$k]);
}else{
$var[$k] = stripcslashes($v);
}
}
}
static function register_autoload($load=array('kernel', 'autoload'))
{
if(function_exists('spl_autoload_register')){
return spl_autoload_register($load);
}else{
return false;
}
}
static function unregister_autoload($load=array('kernel', 'autoload'))
{
if(function_exists('spl_autoload_register')){
return spl_autoload_unregister($load);
}else{
return false;
}
}
static function autoload($class_name)
{
self::require_ego();
_eogo_auto_load($class_name);
}
/**
* 设置_lang
* @param mixed $language language
* @return mixed 返回操作结果
*/
static public function set_lang($language)
{
self::$__language = trim(strtolower($language));
}//End Function
/**
* 获取_lang
* @return mixed 返回结果
*/
static public function get_lang()
{
return self::$__language ? self::$__language : ((defined('LANG')&&constant('LANG')) ? LANG : 'zh-cn');
}//End Function
/**
* require_ego
* @return mixed 返回值
*/
static public function require_ego() {
require_once(dirname(__FILE__) . '/lib/ego/ego.php');
}
}
function __($str){
return $str;
}