197 lines
8.2 KiB
PHP
197 lines
8.2 KiB
PHP
<?php
|
|
|
|
/*******************************************************************
|
|
|
|
Module : /Data/Cache.php
|
|
Desc. : Class cache css dan js aplikasi
|
|
Created By : Siau Pheng ([email protected]).
|
|
Created Date : March 16th, 2008.
|
|
Last Modified : August 19th, 2026.
|
|
|
|
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
|
|
|
|
*******************************************************************/
|
|
|
|
//OK
|
|
declare(strict_types=1);
|
|
|
|
namespace siaupheng\webapp\Data;
|
|
|
|
use flight\Engine;
|
|
use FilesystemIterator;
|
|
use MatthiasMullie\Minify;
|
|
use SplFileInfo;
|
|
|
|
final class Cache {
|
|
private $__cachedir = "";
|
|
private $__cssdir = "";
|
|
private $__localedir = "";
|
|
private $__jsdir = "";
|
|
private $__jsapp = "";
|
|
private $__rootdir = "";
|
|
private $__ini = [];
|
|
protected Engine $app;
|
|
protected array $__asset = [];
|
|
|
|
public function __construct(?Engine $app = null, array $asset = []) {
|
|
$this->app = (empty($app) === true) ? Flight::app() : $app;
|
|
$this->__asset = $asset;
|
|
$rootdir = (defined('PROJECT_ROOT')) ? PROJECT_ROOT : $this->app->get('flight.root_dir');
|
|
$this->__cachedir = $rootdir . '/public/chunks/';
|
|
$this->__localedir = $rootdir . '/app/locale/';
|
|
$this->__jsapp = $rootdir . '/app/scripts/';
|
|
$this->__cssdir = __DIR__ . '/../../assets/css/';
|
|
$this->__jsdir = __DIR__ . '/../../assets/js/';
|
|
$this->__rootdir = $rootdir . '/';
|
|
if (!is_dir($this->__cachedir)) mkdir($this->__cachedir, 0755, true);
|
|
if (!file_exists($this->__cachedir . "cache.ini")) {
|
|
$this->__ini = [
|
|
'login' => [ 'stamp' => 0, 'css' => "", 'js' => "", 'app' => "", ],
|
|
'index' => [ 'stamp' => 0, 'css' => "", 'js' => "", 'app' => "", ],
|
|
'display' => [ 'stamp' => 0, 'css' => "", 'js' => "", 'app' => "", ],
|
|
];
|
|
$this->save_ini();
|
|
} else $this->__ini = parse_ini_file($this->__cachedir . "cache.ini", true);
|
|
}
|
|
|
|
private function gen_file($mode = "index", $type = "css") {
|
|
$itime = 0;
|
|
$afile = [];
|
|
if ($type == "css") {
|
|
$_afile = array_unique($this->__asset['css'][$mode] ?? []);
|
|
foreach ($_afile as $__key => $val) {
|
|
if (!file_exists($this->__cssdir . $val)) continue;
|
|
$_file = new SplFileInfo($this->__cssdir . $val);
|
|
$afile[] = $_file->getRealPath();
|
|
$itime += $_file->getMTime();
|
|
}
|
|
if (is_dir($this->__rootdir . 'app/css/')) {
|
|
$iterator = new FilesystemIterator($this->__rootdir . 'app/css/', FilesystemIterator::SKIP_DOTS);
|
|
foreach ($iterator as $_file) {
|
|
if ($_file->isFile()) {
|
|
$afile[] = $_file->getRealPath();
|
|
$itime += $_file->getMTime();
|
|
}
|
|
}
|
|
}
|
|
} else if ($type == "js") {
|
|
$_afile = array_unique($this->__asset['js'][$mode] ?? []);
|
|
foreach ($_afile as $__key => $val) {
|
|
if (!file_exists($this->__jsdir . $val)) continue;
|
|
$_file = new SplFileInfo($this->__jsdir . $val);
|
|
$afile[] = $_file->getRealPath();
|
|
$itime += $_file->getMTime();
|
|
}
|
|
// add locale file
|
|
$ljs = ($this->app->session()->get('__WEB_USER')['LOCALE'] ?? $this->app->session()->get('__WEB_APP')['DEF_LOCALE']).'.js';
|
|
if (is_dir($this->__localedir)) {
|
|
$iterator = new \FilesystemIterator($this->__localedir, \FilesystemIterator::SKIP_DOTS);
|
|
foreach ($iterator as $_file) {
|
|
if ($_file->isFile() && str_ends_with($_file->getFilename(), $ljs)) {
|
|
$afile[] = $_file->getRealPath();
|
|
$itime += $_file->getMTime();
|
|
}
|
|
}
|
|
}
|
|
} else if ($type == "app") {
|
|
if ($mode === 'index') {
|
|
if (is_dir($this->__jsapp)) {
|
|
$dirIterator = new \RecursiveDirectoryIterator($this->__jsapp, \RecursiveDirectoryIterator::SKIP_DOTS);
|
|
$iterator = new \RecursiveIteratorIterator($dirIterator);
|
|
foreach ($iterator as $_file) {
|
|
if ($_file->isFile() && !in_array($_file->getFilename(), ['login.js','display.js'])) {
|
|
$afile[] = $_file->getRealPath();
|
|
$itime += $_file->getMTime();
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (file_exists($this->__jsapp . $mode . '.js')) {
|
|
$_file = new SplFileInfo($this->__jsapp . $mode . '.js');
|
|
$afile[] = $_file->getRealPath();
|
|
$itime += $_file->getMTime();
|
|
}
|
|
}
|
|
}
|
|
return [ $afile, $itime ];
|
|
}
|
|
|
|
private function create_cache($type = "css", $afile = [], $cachefile = "") {
|
|
$contents = ''; $smini = null;
|
|
$bpublic = ($this->app->request()->ip === '127.0.0.1') ? false : true;
|
|
if ($bpublic == true) {
|
|
if ($type=="css") {
|
|
$smini = new Minify\CSS;
|
|
} else {
|
|
$smini = new Minify\JS;
|
|
}
|
|
}
|
|
foreach ($afile as $nfile) {
|
|
if (file_exists($nfile)) {
|
|
if ($bpublic == true) {
|
|
$smini->add($nfile);
|
|
} else {
|
|
$contents .= "\n". file_get_contents($nfile);
|
|
}
|
|
}
|
|
}
|
|
if ($bpublic) $contents = $smini->minify();
|
|
file_put_contents($this->__cachedir . $cachefile, $contents);
|
|
}
|
|
|
|
private function save_ini() {
|
|
$content = "";
|
|
foreach ($this->__ini as $key => $elem) {
|
|
$content .= ($content==""?"":"\n"). "[".$key."]\n";
|
|
foreach ($elem as $key2 => $elem2) {
|
|
if ($elem2=="") $content .= $key2." = \n";
|
|
else $content .= $key2." = \"".$elem2."\"\n";
|
|
}
|
|
}
|
|
file_put_contents($this->__cachedir . "cache.ini", $content);
|
|
}
|
|
|
|
public function Cache($mode = "index") {
|
|
$is_modif = false;
|
|
foreach (['css','js','app'] as $type) {
|
|
[ $afile, $lastmod ] = $this->gen_file($mode, $type);
|
|
$cachefile = md5($mode . $type . $lastmod) . ($type=='css'?'.css':'.js');
|
|
if (!file_exists($this->__cachedir . $cachefile) || ((time()-(int)$this->__ini[$mode]['stamp']) > (86400*14))) {
|
|
$this->create_cache($type, $afile, $cachefile);
|
|
$this->__ini[$mode][$type] = $cachefile;
|
|
$this->__ini[$mode]['stamp'] = time();
|
|
$is_modif = true;
|
|
}
|
|
}
|
|
if ($is_modif === true) $this->save_ini();
|
|
$acache = [ 'CSS' => [], 'JS' => [], 'JSX' => [] ];
|
|
foreach ($this->__ini[$mode] as $_type => $_file) {
|
|
if ($_type == 'stamp') continue;
|
|
if (file_exists($this->__cachedir . $_file)) {
|
|
if ($_type === 'css') {
|
|
$acache['CSS'][] = 'chunks/' . $_file;
|
|
} else $acache['JS'][] = 'chunks/' . $_file;
|
|
}
|
|
}
|
|
|
|
$session = $this->app->session();
|
|
$aoption = $session->get('__WEB_APP');
|
|
$auser = $session->get('__WEB_USER');
|
|
$nonce = $this->app->get('csp_nonce');
|
|
$_secret = $aoption['APP_CODE'] .";". $aoption['APP_SID'] .";". $this->app->request()->getVar('HTTP_HOST') .";". "http://".$this->app->request()->getVar('HTTP_HOST') .";". isMobile() .";". ($aoption['AUTH_LEVEL']?$aoption['AUTH_LEVEL']:0);
|
|
$_suser = (user_logged()) ? $auser['Username'] .";". $auser['UserID'] .";". $auser['Grup_MenuID'] .";". $auser['Level'] : "nobody;999;999;9";
|
|
|
|
$acache['JSX'][] = '<script nonce="'.$nonce.'" type="text/javascript">';
|
|
$acache['JSX'][] = 'FoniaJS.setConfig("'.base64_encode($_secret).'", "'.base64_encode($_suser).'");';
|
|
$acache['JSX'][] = '$(document).ready(function(){';
|
|
if (user_logged()) $acache['JSX'][] = 'FoniaJS.loadMenu();';
|
|
$acache['JSX'][] = '});';
|
|
$acache['JSX'][] = '</script>';
|
|
|
|
return $acache;
|
|
}
|
|
|
|
}
|
|
|
|
?>
|