cms-manage/app/controller/frontend/BaseController.php

323 lines
10 KiB
PHP

<?php
declare (strict_types = 1);
namespace app\controller\frontend;
use app\BaseController as AppBaseController;
use app\model\Theme;
use app\model\VisitLog;
use app\model\Website;
use app\service\ApiService;
use think\facade\Cache;
use think\facade\View;
class BaseController extends AppBaseController
{
protected $rootDomain;
protected $domain;
protected $siteId;
protected $sellerId;
protected $theme;
protected $lang;
protected $viewBase;
protected $settingData;
protected $parentSiteId;
protected $realSiteId;
protected $viewSiteId;
protected $preview;
/**
* @throws \app\exception\ModelException
* @throws \Exception
*/
public function initialize()
{
$this->setCommonParam();
$this->getRootDomain();
$this->setRealSiteId();
$this->getActiveTheme();
$this->setVisitedData();
parent::initialize();
}
/**
* @throws \app\exception\ModelException
*/
public function setCommonParam()
{
// 更新版本标识
updateVersion();
$domain = $this->request->host();
$Website = new Website();
$website = $Website->getWebsiteByDomain($domain,'id,domain,seller_id,parent_id,status')['data'];
if ($website['status'] == 2) {
$this->to404();
}
// 是否为预览状态
$historyViewTime = session('history-view');
$preview = $this->request->param('preview', '');
if (!empty($preview)) {
if ((time() - $historyViewTime) < 30 * 60) {
// 30分钟内可预览
$this->preview = 1;
} else {
header('Location: /');
return;
}
}
$this->domain = $domain;
$this->siteId = $website['id'];
$this->parentSiteId = $website['parent_id'];
$this->sellerId = $website['seller_id'];
$this->lang = $this->setLang();
$this->viewBase = config('view.view_dir_name');
define('INDEX_SITE_ID',$this->siteId);
define('INDEX_SELLER_ID',$this->sellerId);
define('INDEX_LANG',$this->lang);
}
public function getRootDomain()
{
$rootDomain = $this->request->rootDomain();
if( $rootDomain === 'com.cn'){
$domainArr = explode('.',$this->domain);
array_shift($domainArr);
$this->rootDomain = implode('.',$domainArr);
}else{
$this->rootDomain = $rootDomain;
}
}
/**
* @throws \app\exception\ModelException
* @throws \app\exception\ModelEmptyException
*/
public function getActiveTheme()
{
$Theme = new Theme();
$theme = $Theme->getActiveTheme(['seller_id'=>$this->sellerId,'website_id'=>$this->viewSiteId,'lang'=>$this->lang,'is_active'=>1])['data']->toArray();
$cacheKey = $this->sellerId .'_'.$this->siteId .'_'. $this->lang . '_website_cache_key';
$settingData = Cache::get($cacheKey);
if(empty($settingData)){
$settingData = ApiService::setWebsiteSetting($this->sellerId,$this->siteId,$this->lang);
}
$this->settingData = $settingData;
if(isMobile() && !empty($settingData['common_template']) && $settingData['common_template'] == 2){
$this->theme = 'm_' . $theme['theme'];
}else{
$this->theme = $theme['theme'];
}
}
public function setRealSiteId()
{
$siteId = $this->siteId;
$Theme = new Theme();
$theme = $Theme->getActiveTheme(['seller_id'=>$this->sellerId,'website_id'=>$siteId,'lang'=>$this->lang,'is_active'=>1])['data'];
$this->viewSiteId = $siteId;
// 本站点没有安装启用模板,页面加载用父级的模板
if ($this->parentSiteId && empty($theme)){
$this->viewSiteId = $this->parentSiteId;
}
if($this->parentSiteId){
$siteId = $this->parentSiteId;
}
define('INDEX_REAL_SITE_ID',$siteId);
return $this->realSiteId = $siteId;
}
public function setLang(): string
{
$baseUrl = trim($this->request->baseUrl(),'/');
$firstPath = explode('/',$baseUrl)[0];
$langArr = config('system.lang');
if(empty($firstPath) || !in_array($firstPath,$langArr)){
$firstPath = config('lang.default_lang');
}
return $firstPath;
}
protected function assign($name,$value = ''): \think\View
{
return View::assign($name, $value);
}
/**
* 加载模板输出
* @access protected
* @param string $template 模板文件名
* @param array $vars 模板输出变量
* @return mixed
*/
protected function fetch(string $template = '', array $vars = [])
{
$template = $this->parseTemplate($template);
$this->_initializeView($this->viewSiteId,$this->lang,$this->theme);
$html = View::fetch($template, $vars);
$replace = <<<EOL
<script id="baseJs" src="/system_file/js/base.min.js"></script>
</head>
EOL;
$html = str_replace('</head>', $replace, $html);
return $html;
}
/**
* 加载模板输出(system_file)
* @access protected
* @param string $template 模板文件名
* @param array $vars 模板输出变量
* @return mixed
*/
protected function fetchSystem(string $template = '', array $vars = [])
{
$template = $this->parseTemplateSystem($template);
$this->_initializeViewSystem($this->viewSiteId,$this->lang,$this->theme);
$html = View::fetch($template, $vars);
$replace = <<<EOL
<script id="baseJs" src="/system_file/js/base.min.js"></script>
</head>
EOL;
$html = str_replace('</head>', $replace, $html);
return $html;
}
/**
* 定位模板
* @param $template
* @return string
*/
private function parseTemplate($template): string
{
$path = CMS_ROOT . $this->viewBase . DIRECTORY_SEPARATOR . $this->viewSiteId.DIRECTORY_SEPARATOR .$this->lang.DIRECTORY_SEPARATOR.$this->theme;
if (!empty($this->preview)) {
$path = CMS_ROOT . 'public/themes/preview/'.$this->theme;
}
$ext = getFileExt($template);
$path .= DIRECTORY_SEPARATOR . ltrim($template,'/');
if( $ext != config('view.view_suffix')){
$path .= '.'.config('view.view_suffix');
}
return $path ;
}
/**
* 定位模板
* @param $template
* @return string
*/
private function parseTemplateSystem($template): string
{
$path = CMS_ROOT . 'public/system_file' . DIRECTORY_SEPARATOR;
$ext = getFileExt($template);
$path .= DIRECTORY_SEPARATOR . ltrim($template,'/');
if( $ext != config('view.view_suffix')){
$path .= '.'.config('view.view_suffix');
}
return $path ;
}
/**
* 常量替换
* @param $siteId
* @param $lang
* @param $themeName
*/
protected function _initializeView($siteId,$lang,$themeName)
{
if (!empty($this->preview)) {
$viewReplaceStr = [
'__TMPL__' => "/themes/preview/{$themeName}",
'__STATIC__' => empty($this->settingData['static_file']) ? "/themes/preview/{$themeName}/static" : $this->settingData['static_file'] ,
];
View::engine()->config([
'view_path' => CMS_ROOT . '/public/themes/preview/' .$this->theme . '/',
'tpl_replace_string' => $viewReplaceStr,
'display_cache' => false,
'tpl_cache' => false,
]);
} else {
$viewReplaceStr = [
'__TMPL__' => "/themes/website/{$siteId}/{$lang}/{$themeName}",
'__STATIC__' => empty($this->settingData['static_file']) ? "/themes/website/{$siteId}/{$lang}/{$themeName}/static" : $this->settingData['static_file'] ,
];
View::engine()->config([
'view_path' => CMS_ROOT . $this->viewBase . DIRECTORY_SEPARATOR . $siteId. DIRECTORY_SEPARATOR .$this->lang.DIRECTORY_SEPARATOR.$this->theme .DIRECTORY_SEPARATOR,
'tpl_replace_string' => $viewReplaceStr,
'display_cache' => false,
'tpl_cache' => false,
]);
}
}
/**
* 常量替换
* @param $siteId
* @param $lang
* @param $themeName
*/
protected function _initializeViewSystem($siteId,$lang,$themeName)
{
$viewReplaceStr = [
'__TMPL__' => "/themes/website/{$siteId}/{$lang}/{$themeName}",
'__STATIC__' => empty($this->settingData['static_file']) ? "/themes/website/{$siteId}/{$lang}/{$themeName}/static" : $this->settingData['static_file'] ,
];
View::engine()->config([
'view_path' => CMS_ROOT . 'public/system_file' . DIRECTORY_SEPARATOR,
'tpl_replace_string' => $viewReplaceStr,
'display_cache' => false,
'tpl_cache' => false,
]);
}
/**
* @throws \Exception
*/
private function setVisitedData()
{
$VisitLog = new VisitLog();
$ip = request()->ip();
$agent = !empty(request()->header()['user-agent']) ? request()->header()['user-agent'] : '未知设备';
$address = getLocationByIp($ip,2);
if(empty($address['province'])){
$area = "内网ip";
}else{
$area = $address['province']."-".$address['city'];
}
$url = $this->request->domain().$this->request->url();
$device = getDeviceInfo($agent);
$param = [
'seller_id' => $this->sellerId,
'website_id' => $this->siteId,
'domain' => $this->domain,
'referrer' => empty($_SERVER['HTTP_REFERER']) ? '未知' : $_SERVER['HTTP_REFERER'],
'url' => $url,
'ip' => $ip,
'agent' => $agent,
'visited_area' => $area,
'visited_device' => $device['deviceOs'] .'/'.$device['deviceVersion'],
'visited_time' => date('Y-m-d',time())
];
$VisitLog -> addCustomData($param);
}
public function to404()
{
header('Location: /system_file/hc_error/404.html');
exit();
}
}