update trunk and tag 1.4.2.0

git-svn-id: http://xe-core.googlecode.com/svn/trunk@7470 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
haneul 2010-05-18 08:39:37 +00:00
parent 55e72e3b47
commit fae67f375d
70 changed files with 7400 additions and 507 deletions

72
classes/cache/CacheApc.class.php vendored Normal file
View file

@ -0,0 +1,72 @@
<?php
/**
* @class CacheApc
* @author sol (sol@nhn.com)
* @brief APC Handler
* @version 0.1
*
**/
class CacheApc extends CacheBase {
var $valid_time = 36000;
function getInstance($opt=null){
if(!$GLOBALS['__CacheApc__']) {
$GLOBALS['__CacheApc__'] = new CacheApc();
}
return $GLOBALS['__CacheApc__'];
}
function CacheApc(){
}
function isSupport(){
return function_exists('apc_add');
}
function put($key, $buff, $valid_time = 0){
if($valid_time == 0) $valid_time = $this->valid_time;
return apc_store(md5(_XE_PATH_.$key), array(time(), $buff), $valid_time);
}
function isValid($key, $modified_time = 0) {
$_key = md5(_XE_PATH_.$key);
$obj = apc_fetch($_key, $success);
if(!$success || !is_array($obj)) return false;
unset($obj[1]);
if($modified_time > 0 && $modified_time > $obj[0]) {
$this->_delete($_key);
return false;
}
return true;
}
function get($key, $modified_time = 0) {
$_key = md5(_XE_PATH_.$key);
$obj = apc_fetch($_key, $success);
if(!$success || !is_array($obj)) return false;
if($modified_time > 0 && $modified_time > $obj[0]) {
$this->_delete($_key);
return false;
}
return $obj[1];
}
function _delete($_key) {
$this->put($_key,null,1);
}
function delete($key) {
$this->_delete(md5(_XE_PATH_.$key));
}
function truncate() {
apc_clear_cache('user');
}
}
?>

95
classes/cache/CacheHandler.class.php vendored Normal file
View file

@ -0,0 +1,95 @@
<?php
/**
* @class CacheHandler
* @author sol (sol@nhn.com)
* @brief Cache Handler
* @version 0.1
*
**/
class CacheHandler extends Handler {
var $handler = null;
function &getInstance($target='object') {
return new CacheHandler($target);
}
function CacheHandler($target, $info=null) {
if(!$info) $info = Context::getDBInfo();
if($info){
if($target == 'object'){
if($info->use_template_cache =='apc') $type = 'apc';
else if(substr($info->use_template_cache,0,8)=='memcache'){
$type = 'memcache';
$url = $info->use_template_cache;
}
}else if($target == 'template'){
if($info->use_template_cache =='apc') $type = 'apc';
else if(substr($info->use_template_cache,0,8)=='memcache'){
$type = 'memcache';
$url = $info->use_template_cache;
}
}
if($type){
$class = 'Cache' . ucfirst($type);
include_once sprintf('%sclasses/cache/%s.class.php', _XE_PATH_, $class);
$this->handler = call_user_func(array($class,'getInstance'), $url);
}
}
}
function isSupport(){
if($this->handler && $this->handler->isSupport()) return true;
return false;
}
function get($key, $modified_time = 0){
if(!$this->handler) return false;
return $this->handler->get($key, $modified_time);
}
function put($key, $obj, $valid_time = 0){
if(!$this->handler) return false;
return $this->handler->put($key, $obj, $valid_time);
}
function delete($key){
if(!$this->handler) return false;
return $this->handler->delete($key);
}
function isValid($key, $modified_time){
if(!$this->handler) return false;
return $this->handler->isValid($key, $modified_time);
}
function truncate(){
if(!$this->handler) return false;
return $this->handler->truncate();
}
}
class CacheBase{
function get($key, $modified_time = 0){
return false;
}
function put($key, $obj, $valid_time = 0){
return false;
}
function isValid($key, $modified_time = 0){
return false;
}
function isSupport(){
return false;
}
function truncate(){
return false;
}
}
?>

91
classes/cache/CacheMemcache.class.php vendored Normal file
View file

@ -0,0 +1,91 @@
<?php
/**
* @class CacheMemcache
* @author sol (sol@nhn.com)
* @brief Memcache Handler
* @version 0.1
*
**/
class CacheMemcache extends CacheBase {
var $valid_time = 36000;
var $Memcache;
function getInstance($url){
if(!$GLOBALS['__CacheMemcache__']) {
$GLOBALS['__CacheMemcache__'] = new CacheMemcache($url);
}
return $GLOBALS['__CacheMemcache__'];
}
function CacheMemcache($url){
//$config['url'] = array('memcache://localhost:11211');
$config['url'] = is_array($url)?$url:array($url);
$this->Memcache = new Memcache;
foreach($config['url'] as $url) {
$info = parse_url($url);
$this->Memcache->addServer($info['host'], $info['port']);
}
}
function isSupport(){
return $this->Memcache->set('xe', 'xe', MEMCACHE_COMPRESSED, 1);
}
function getKey($key){
return md5(_XE_PATH_.$key);
}
function put($key, $buff, $valid_time = 0){
if($valid_time == 0) $valid_time = $this->valid_time;
return $this->Memcache->set($this->getKey($key), array(time(), $buff), MEMCACHE_COMPRESSED, $valid_time);
}
function isValid($key, $modified_time = 0) {
$_key = $this->getKey($key);
$obj = $this->Memcache->get($_key);
if(!$obj || !is_array($obj)) return false;
unset($obj[1]);
if($modified_time > 0 && $modified_time > $obj[0]) {
$this->_delete($_key);
return false;
}
return true;
}
function get($key, $modified_time = 0) {
$_key = $this->getKey($key);
$obj = $this->Memcache->get($_key);
if(!$obj || !is_array($obj)) return false;
if($modified_time > 0 && $modified_time > $obj[0]) {
$this->_delete($_key);
return false;
}
unset($obj[0]);
return $obj[1];
}
function delete($key) {
$_key = $this->getKey($key);
$this->_delete($_key);
}
function _delete($_key) {
$this->Memcache->delete($_key);
}
function truncate() {
// not support memcached
return false;
}
}
?>

View file

@ -86,8 +86,8 @@
}
Context::set('site_module_info', $site_module_info);
if($site_module_info->site_srl && isSiteID($site_module_info->domain)) Context::set('vid', $site_module_info->domain, true);
if($site_module_info->site_srl && isSiteID($site_module_info->domain)) Context::set('vid', $site_module_info->domain);
$this->db_info->lang_type = $site_module_info->default_language;
if(!$this->db_info->lang_type) $this->db_info->lang_type = 'en';
}
@ -96,7 +96,10 @@
$lang_supported = $this->loadLangSelected();
// Retrieve language type set in user's cookie
if($_COOKIE['lang_type']) $this->lang_type = $_COOKIE['lang_type'];
if($this->get('l')) {
$_COOKIE['lang_type'] = $this->lang_type = $this->get('l');
}
else if($_COOKIE['lang_type']) $this->lang_type = $_COOKIE['lang_type'];
// If it's not exists, follow default language type set in db_info
if(!$this->lang_type) $this->lang_type = $this->db_info->lang_type;
@ -153,7 +156,7 @@
else $this->allow_rewrite = false;
// add common JS/CSS files
$this->addJsFile("./common/js/jquery.js");
$this->addJsFile("./common/js/jquery.js", true, '', -100000);
$this->addJsFile("./common/js/x.js");
$this->addJsFile("./common/js/common.js");
$this->addJsFile("./common/js/js_app.js");
@ -163,7 +166,11 @@
$this->addCSSFile("./common/css/button.css");
// for admin page, add admin css
if(Context::get('module')=='admin' || strpos(Context::get('act'),'Admin')>0) $this->addCssFile("./modules/admin/tpl/css/admin.css", false);
if(Context::get('module')=='admin' || strpos(Context::get('act'),'Admin')>0){
$this->addCssFile("./modules/admin/tpl/css/font.css", true, 'all', '',10000);
$this->addCssFile("./modules/admin/tpl/css/pagination.css", true, 'all', '', 100001);
$this->addCssFile("./modules/admin/tpl/css/admin.css", true, 'all', '', 100002);
}
// set locations for javascript use
if($_SERVER['REQUEST_METHOD'] == 'GET') {
@ -1355,8 +1362,8 @@
$filename = trim($list[$i]);
if(!$filename) continue;
if(substr($filename,0,2)=='./') $filename = substr($filename,2);
if(preg_match('/\.js$/i',$filename)) $this->_addJsFile($plugin_path.$filename, false, '', null);
elseif(preg_match('/\.css$/i',$filename)) $this->_addCSSFile($plugin_path.$filename, false, 'all','', null);
if(preg_match('/\.js$/i',$filename)) $this->_addJsFile($plugin_path.$filename, true, '', null);
elseif(preg_match('/\.css$/i',$filename)) $this->_addCSSFile($plugin_path.$filename, true, 'all','', null);
}
if(is_dir($plugin_path.'lang')) $this->_loadLang($plugin_path.'lang');
@ -1530,7 +1537,7 @@
$xe = _XE_PATH_;
$path = strtr($path, "\\", "/");
$base_url = preg_replace('@^https?://[^/]+/+@', '', Context::getDefaultUrl());
$base_url = preg_replace('@^https?://[^/]+/?@', '', Context::getRequestUri());
$_xe = explode('/', $xe);
$_path = explode('/', $path);

View file

@ -167,18 +167,23 @@
// leave error log if an error occured (if __DEBUG_DB_OUTPUT__ is defined)
if($this->isError()) {
$site_module_info = Context::get('site_module_info');
$log['module'] = $site_module_info->module;
$log['act'] = Context::get('act');
$log['query_id'] = $this->query_id;
$log['time'] = date('Y-m-d H:i:s');
$log['result'] = 'Failed';
$log['errno'] = $this->errno;
$log['errstr'] = $this->errstr;
if(__DEBUG_DB_OUTPUT__ == 1) {
$debug_file = _XE_PATH_."files/_debug_db_query.php";
$buff = sprintf("%s\n",print_r($log,true));
$buff = array();
if(!file_exists($debug_file)) $buff[] = '<?php exit(); ?>';
$buff[] = print_r($log, true);
if($display_line) $buff = "\n<?php\n/*\n====================================\n".$buff."------------------------------------\n*/\n?>\n";
if(@!$fp = fopen($debug_file,"a")) return;
fwrite($fp, $buff);
if(@!$fp = fopen($debug_file, "a")) return;
fwrite($fp, implode("\n", $buff)."\n\n");
fclose($fp);
}
} else {
@ -239,6 +244,7 @@
**/
function executeQuery($query_id, $args = NULL) {
if(!$query_id) return new Object(-1, 'msg_invalid_queryid');
$this->query_id = $query_id;
$id_args = explode('.', $query_id);
if(count($id_args) == 2) {

View file

@ -172,9 +172,27 @@
function _fetch($result) {
if(!$this->isConnected() || $this->isError() || !$result) return;
$col_types = cubrid_column_types ($result);
$col_names = cubrid_column_names ($result);
if (($max = count ($col_types)) == count ($col_names)) {
$count = 0;
while ($count < $max) {
if (preg_match ("/^char/", $col_types[$count]) > 0) {
$char_type_fields[] = $col_names[$count];
}
$count++;
}
}
while($tmp = cubrid_fetch($result, CUBRID_OBJECT)) {
if (is_array ($char_type_fields)) {
foreach ($char_type_fields as $val) {
$tmp->{$val} = rtrim ($tmp->{$val});
}
}
$output[] = $tmp;
}
unset ($char_type_fields);
if($result) cubrid_close_request($result);
@ -413,7 +431,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
$operation = $v['operation'];
@ -638,7 +656,7 @@
}
$alias = $val['alias'] ? sprintf('"%s"',$val['alias']) : null;
if(substr($name,-1) == '*') {
if($name == '*') {
$column_list[] = $name;
} elseif(strpos($name,'.')===false && strpos($name,'(')===false) {
$name = sprintf($click_count,$name);

View file

@ -646,7 +646,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
$operation = $v['operation'];

View file

@ -422,7 +422,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
if(preg_match('/^substr\(/i',$name)) $name = preg_replace('/^substr\(/i','substring(',$name);

View file

@ -402,7 +402,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
$operation = $v['operation'];

View file

@ -411,7 +411,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
$operation = $v['operation'];

View file

@ -391,7 +391,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
$operation = $v['operation'];

View file

@ -527,7 +527,7 @@ class DBPostgresql extends DB
continue;
if ($v['value'] === '')
continue;
if (!in_array(gettype($v['value']), array('string', 'integer')))
if (!in_array(gettype($v['value']), array('string', 'integer', 'double')))
continue;
$name = $v['column'];

View file

@ -383,7 +383,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
$operation = $v['operation'];

View file

@ -413,7 +413,7 @@
foreach($val['condition'] as $v) {
if(!isset($v['value'])) continue;
if($v['value'] === '') continue;
if(!in_array(gettype($v['value']), array('string', 'integer'))) continue;
if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue;
$name = $v['column'];
$operation = $v['operation'];

View file

@ -32,7 +32,10 @@
// request method에 따른 컨텐츠 결과물 추출
if(Context::get('xeVirtualRequestMethod')=='xml') $output = $this->_toVirtualXmlDoc($oModule);
else if(Context::getRequestMethod() == 'XMLRPC') $output = $this->_toXmlDoc($oModule);
else if(Context::getRequestMethod() == 'XMLRPC') {
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) $this->gz_enabled = false;
$output = $this->_toXmlDoc($oModule);
}
else if(Context::getRequestMethod() == 'JSON') $output = $this->_toJSON($oModule);
else $output = $this->_toHTMLDoc($oModule);

View file

@ -200,17 +200,23 @@
static $oFtp = null;
// if safe_mode is on, use FTP
if(ini_get('safe_mode') && $oFtp == null) {
if(!Context::isFTPRegisted()) return;
if(ini_get('safe_mode')) {
$ftp_info = Context::getFTPInfo();
if($oFtp == null) {
if(!Context::isFTPRegisted()) return;
require_once(_XE_PATH_.'libs/ftp.class.php');
$ftp_info = Context::getFTPInfo();
$oFtp = new ftp();
if(!$oFtp->ftp_connect('localhost')) return;
if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) {
$oFtp->ftp_quit();
return;
}
require_once(_XE_PATH_.'libs/ftp.class.php');
$oFtp = new ftp();
if(!$ftp_info->ftp_host) $ftp_info->ftp_host = "127.0.0.1";
if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21;
if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)) return;
if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) {
$oFtp->ftp_quit();
return;
}
}
$ftp_path = $ftp_info->ftp_root_path;
if(!$ftp_path) $ftp_path = "/";
}
$path_string = str_replace(_XE_PATH_,'',$path_string);
@ -220,10 +226,11 @@
for($i=0;$i<count($path_list);$i++) {
if(!$path_list[$i]) continue;
$path .= $path_list[$i].'/';
$ftp_path .= $path_list[$i].'/';
if(!is_dir($path)) {
if(ini_get('safe_mode')) {
$oFtp->ftp_mkdir($path);
$oFtp->ftp_site("CHMOD 777 ".$path);
$oFtp->ftp_mkdir($ftp_path);
$oFtp->ftp_site("CHMOD 777 ".$ftp_path);
} else {
@mkdir($path, 0755);
@chmod($path, 0755);
@ -325,8 +332,8 @@
* @remarks if the target is moved (when return code is 300~399), this function follows the location specified response header.
**/
function getRemoteResource($url, $body = null, $timeout = 3, $method = 'GET', $content_type = null, $headers = array(), $cookies = array(), $post_data = array()) {
set_include_path(_XE_PATH_."libs/PEAR");
require_once('PEAR.php');
//set_include_path(_XE_PATH_."libs/PEAR");
requirePear();
require_once('HTTP/Request.php');
if(__PROXY_SERVER__!==null) {
@ -499,34 +506,36 @@
$target_type = strtolower($target_type);
// create temporary image with target size
if(function_exists('imagecreatetruecolor')) $thumb = @imagecreatetruecolor($resize_width, $resize_height);
else $thumb = @imagecreate($resize_width, $resize_height);
if(function_exists('imagecreatetruecolor')) $thumb = imagecreatetruecolor($resize_width, $resize_height);
else if(function_exists('imagecreate')) $thumb = imagecreate($resize_width, $resize_height);
else return false;
if(!$thumb) return false;
$white = @imagecolorallocate($thumb, 255,255,255);
@imagefilledrectangle($thumb,0,0,$resize_width-1,$resize_height-1,$white);
$white = imagecolorallocate($thumb, 255,255,255);
imagefilledrectangle($thumb,0,0,$resize_width-1,$resize_height-1,$white);
// create temporary image having original type
switch($type) {
case 'gif' :
if(!function_exists('imagecreatefromgif')) return false;
$source = @imagecreatefromgif($source_file);
$source = imagecreatefromgif($source_file);
break;
// jpg
case 'jpeg' :
case 'jpg' :
if(!function_exists('imagecreatefromjpeg')) return false;
$source = @imagecreatefromjpeg($source_file);
$source = imagecreatefromjpeg($source_file);
break;
// png
case 'png' :
if(!function_exists('imagecreatefrompng')) return false;
$source = @imagecreatefrompng($source_file);
$source = imagecreatefrompng($source_file);
break;
// bmp
case 'wbmp' :
case 'bmp' :
if(!function_exists('imagecreatefromwbmp')) return false;
$source = @imagecreatefromwbmp($source_file);
$source = imagecreatefromwbmp($source_file);
break;
default :
return;
@ -545,8 +554,8 @@
}
if($source) {
if(function_exists('imagecopyresampled')) @imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
else @imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
if(function_exists('imagecopyresampled')) imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
else imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height);
} else return false;
// create directory
@ -557,26 +566,26 @@
switch($target_type) {
case 'gif' :
if(!function_exists('imagegif')) return false;
$output = @imagegif($thumb, $target_file);
$output = imagegif($thumb, $target_file);
break;
case 'jpeg' :
case 'jpg' :
if(!function_exists('imagejpeg')) return false;
$output = @imagejpeg($thumb, $target_file, 100);
$output = imagejpeg($thumb, $target_file, 100);
break;
case 'png' :
if(!function_exists('imagepng')) return false;
$output = @imagepng($thumb, $target_file, 9);
$output = imagepng($thumb, $target_file, 9);
break;
case 'wbmp' :
case 'bmp' :
if(!function_exists('imagewbmp')) return false;
$output = @imagewbmp($thumb, $target_file, 100);
$output = imagewbmp($thumb, $target_file, 100);
break;
}
@imagedestroy($thumb);
@imagedestroy($source);
imagedestroy($thumb);
imagedestroy($source);
if(!$output) return false;
@chmod($target_file, 0644);

View file

@ -9,6 +9,7 @@
class Optimizer {
var $cache_path = "./files/cache/optimized/";
var $script_file = "./common/script.php?l=%s&amp;t=.%s";
/**
* @brief Constructor which check if a directory, 'optimized' exists in designated path. If not create a new one
@ -37,48 +38,59 @@
function getOptimizedFiles($source_files, $type = "js") {
if(!is_array($source_files) || !count($source_files)) return;
// $source_files의 역슬래쉬 경로를 슬래쉬로 변경 (윈도우즈 대비)
foreach($source_files as $key => $file){
$source_files[$key]['file'] = str_replace("\\","/",$file['file']);
}
// 관리자 설정시 설정이 되어 있지 않으면 패스
$db_info = Context::getDBInfo();
if($db_info->use_optimizer == 'N') return $this->_getOptimizedRemoved($source_files);
// 캐시 디렉토리가 없으면 실행하지 않음
if(!is_dir($this->cache_path)) return $this->_getOptimizedRemoved($source_files);
$files = array();
$db_info = Context::getDBInfo();
if($db_info->use_optimizer == 'N' || !is_dir($this->cache_path)) return $this->_getOptimizedRemoved($source_files);
if(!count($source_files)) return;
foreach($source_files as $file) {
if(!$file || !$file['file']) continue;
$files = array();
$hash = "";
foreach($source_files as $key => $file) {
if($file['file'][0] == '/')
{
if(!file_exists($_SERVER['DOCUMENT_ROOT'].$file['file'])) continue;
}
else if(!$file || !$file['file'] || !file_exists($file['file'])) continue;
$file['file'] = $source_files[$key]['file'] = str_replace("\\","/",$file['file']);
if(empty($file['optimized']) || preg_match('/^https?:\/\//i', $file['file']) ) $files[] = $file;
else $targets[] = $file;
else{
$targets[] = $file;
$hash .= $file['file'];
}
}
if(!count($targets)) return $this->_getOptimizedRemoved($files);
$list_file_hash = md5($hash);
$oCacheHandler = &CacheHandler::getInstance('template');
if($oCacheHandler->isSupport()){
if(!$oCacheHandler->isValid($list_file_hash)){
$buff = array();
foreach($targets as $file) $buff[] = $file['file'];
$oCacheHandler->put($list_file_hash, $buff);
}
}else{
$list_file = FileHandler::getRealPath($this->cache_path . $list_file_hash);
$optimized_info = $this->getOptimizedInfo($targets);
$path = sprintf("%s%s", $this->cache_path, $optimized_info[0]);
$filename = sprintf("%s.%s.%s.php", $optimized_info[0], $optimized_info[1], $type);
$this->doOptimizedFile($path, $filename, $targets, $type);
array_unshift($files, array('file' => $path.'/'.$filename, 'media' => 'all'));
if(!file_exists($list_file)){
$str = '<?php $f=array();';
foreach($targets as $file) $str .= '$f[]="'. $file['file'] . '";';
$str .= ' return $f; ?>';
FileHandler::writeFile($list_file, $str);
}
}
array_unshift($files, array('file' => sprintf($this->script_file, $list_file_hash, $type) , 'media' => 'all'));
$files = $this->_getOptimizedRemoved($files);
if(!count($files)) return $files;
$url_info = parse_url(Context::getRequestUri());
$abpath = $url_info['path'];
foreach($files as $key => $val) {
$file = $val['file'];
if(substr($file,0,1)=='/' || strpos($file,'://')!==false) continue;
if($file{0} == '/' || strpos($file,'://')!==false) continue;
if(substr($file,0,2)=='./') $file = substr($file,2);
$file = $abpath.$file;
while(strpos($file,'/../')!==false) {
@ -86,184 +98,8 @@
}
$files[$key]['file'] = $file;
}
return $files;
}
/**
* @brief retrive a list of files from a given parameter
* @param[in] files a list containing files
**/
function _getOnlyFileList($files) {
foreach($files as $key => $val) $files[$key] = $val['file'];
return $files;
}
/**
* @brief method to generate a unique key from list of files along with a last modified date
* @param[in] files an array containing file names
**/
function getOptimizedInfo($files) {
// 개별 요소 파일이 갱신되었으면 새로 옵티마이징
$count = count($files);
$last_modified = 0;
for($i=0;$i<$count;$i++) {
$mtime = filemtime($files[$i]['file']);
if($last_modified < $mtime) $last_modified = $mtime;
}
$buff = implode("\n", $this->_getOnlyFileList($files));
return array(md5($buff), $last_modified);
}
/**
* @brief method that check if a valid cache file exits for a given filename. If not create new one.
* @param[in] path directory path of the cache files
* @param[in] filename a filename for cache files
* @param[in] targets
* @param[in] type a type of cache file
**/
function doOptimizedFile($path, $filename, $targets, $type) {
// 대상 파일이 있으면 그냥 패스~
if(file_exists($path.'/'.$filename)) return;
// 대상 파일이 없으면 hashed_filename으로 생성된 파일들을 모두 삭제
FileHandler::removeFilesInDir($path);
// 새로 캐시 파일을 생성
$this->makeOptimizedFile($path, $filename, $targets, $type);
}
/**
* @brief method produce a php code to merge css/js files, compress the resultant files and modified the HTML header accordingly.
* @param[in] path
* @param[in] filename a name of a resultant file
* @param[in] targets list of files to be used for the operation
* @param[in] type a type of file such as css or js
* @return NONE
**/
function makeOptimizedFile($path, $filename, $targets, $type) {
/**
* 실제 css나 js의 내용을 합친 것을 구함
**/
// 대상 파일의 내용을 구해오고 css 파일일 경우 url()내의 경로를 변경
$content_filename = substr($filename, 0, -4);
$file_object = FileHandler::openFile($path."/".$content_filename, "w");
if($type == 'css') $file_object->write('@charset "UTF-8";'."\n");
foreach($targets as $file) {
$str = FileHandler::readFile($file['file']);
$str = trim(Context::convertEncodingStr($str));
// css 일경우 background:url() 변경 / media 적용
if($type == 'css') {
$str = $this->replaceCssPath($file['file'], $str);
if($file['media'] != 'all') $str = '@media '.$file['media'].' {'."\n".$str."\n".'}';
}
$file_object->write($str);
$file_object->write("\n");
unset($str);
}
$file_object->close();
/**
* 캐시 타임을 제대로 이용하기 위한 헤더 파일 구함
**/
// 확장자별 content-type 체크
if($type == 'css') $content_type = 'text/css';
elseif($type == 'js') $content_type = 'text/javascript';
// 캐시를 위한 처리
$unique = crc32($content_filename);
$size = filesize($path.'/'.$content_file);
$mtime = filemtime($path.'/'.$content_file);
// js, css 파일을 php를 통해서 출력하고 이 출력시에 헤더값을 조작하여 캐싱과 압축전송이 되도록 함 (IE6는 CSS파일일 경우 gzip압축하지 않음)
$header_buff = '<?php
$content_filename = "'.$content_filename.'";
$mtime = '.$mtime.';
$cached = false;
$type = "'.$type.'";
if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
$time = strtotime(preg_replace("/;.*$/", "", $_SERVER["HTTP_IF_MODIFIED_SINCE"]));
if($mtime == $time) {
header("HTTP/1.1 304");
$cached = true;
}
}
if( preg_match("/MSIE 6.0/i",$_SERVER["HTTP_USER_AGENT"]) || strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "gzip")===false || !function_exists("ob_gzhandler") ) {
$size = filesize($content_filename);
} else {
$f = fopen($content_filename,"r");
$buff = fread($f, filesize($content_filename));
fclose($f);
$buff = ob_gzhandler($buff, 5);
$size = strlen($buff);
header("Content-Encoding: gzip");
}
header("Content-Type: '.$content_type.'; charset=UTF-8");
header("Date: '.substr(gmdate('r'), 0, -5).'GMT");
header("Expires: '.substr(gmdate('r', strtotime('+1 MONTH')), 0, -5).'GMT");
header("Cache-Control: private, max-age=2592000");
header("Pragma: cache");
header("Last-Modified: '.substr(gmdate('r', $mtime), 0, -5).'GMT");
header("ETag: \"'.dechex($unique).'-".dechex($size)."-'.dechex($mtime).'\"");
if(!$cached) {
if(empty($buff)) {
$f = fopen($content_filename,"r");
fpassthru($f);
} else print $buff;
}
?>';
FileHandler::writeFile($path.'/'.$filename, $header_buff);
}
/**
* @brief method that modify a path for import or background element in a given css file
* @param[in] file a file to be modified
* @param[in] str a buffer to store resultant content
* @return Returns resultant content
**/
function replaceCssPath($file, $str) {
// css 파일의 위치를 구함
$this->tmp_css_path = preg_replace("/^\.\//is","",dirname($file))."/";
// url() 로 되어 있는 css 파일의 경로를 변경
$str = preg_replace_callback('/url\(([^\)]*)\)/is', array($this, '_replaceCssPath'), $str);
// charset 지정 문구를 제거
$str = preg_replace('!@charset([^;]*?);!is','',$str);
return $str;
}
/**
* @brief callback method that is responsible for replacing strings in css file with predefined ones.
* @param[in] matches a list of strings to be examined and modified if necessary
* @return Returns resultant content
**/
function _replaceCssPath($matches) {
static $abpath = null;
if(is_null($abpath)) {
$url_info = parse_url(Context::getRequestUri());
$abpath = $url_info['path'];
}
$path = str_replace(array('"',"'"),'',$matches[1]);
if(substr($path,0,1)=='/' || strpos($path,'://')!==false || strpos($path,'.htc')!==false) return 'url("'.$path.'")';
if(substr($path,0,2)=='./') $path = substr($path,2);
$target = $abpath.$this->tmp_css_path.$path;
while(strpos($target,'/../')!==false) {
$target = preg_replace('/\/([^\/]+)\/\.\.\//','/',$target);
}
return 'url("'.$target.'")';
}
}
?>

View file

@ -55,14 +55,26 @@
$this->tpl_path = preg_replace('/^\.\//','',$tpl_path);
$this->tpl_file = $tpl_file;
// get cached compiled file name
$compiled_tpl_file = FileHandler::getRealPath($this->_getCompiledFileName($tpl_file));
$oCacheHandler = &CacheHandler::getInstance('template');
if($oCacheHandler->isSupport()){
$cache_key = 'template:' . $tpl_file;
$buff = $oCacheHandler->get($cache_key, filemtime(FileHandler::getRealPath($tpl_file)));
if(!$buff){
$buff = $this->_compileTplFile($tpl_file);
$oCacheHandler->put($cache_key, $buff);
}
// compile
$buff = $this->_compile($tpl_file, $compiled_tpl_file);
$output = $this->_fetch('', $buff, $tpl_path);
}else{
// get cached compiled file name
$compiled_tpl_file = FileHandler::getRealPath($this->_getCompiledFileName($tpl_file));
// make a result, combining Context and compiled_tpl_file
$output = $this->_fetch($compiled_tpl_file, $buff, $tpl_path);
// compile
$buff = $this->_compile($tpl_file, $compiled_tpl_file);
// make a result, combining Context and compiled_tpl_file
$output = $this->_fetch($compiled_tpl_file, $buff, $tpl_path);
}
if(__DEBUG__==3 ) $GLOBALS['__template_elapsed__'] += getMicroTime() - $start;