diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index 2b2dd594e..06a610b0c 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -121,6 +121,15 @@ // 상대 경로 설정 $this->path = $this->getRequestUri(); + // 기본 JS/CSS 등록 + $this->addJsFile("./common/js/x.js"); + $this->addJsFile("./common/js/common.js"); + $this->addJsFile("./common/js/xml_handler.js"); + $this->addJsFile("./common/js/xml_js_filter.js"); + $this->addCSSFile("./common/css/default.css"); + $this->addCSSFile("./common/css/button.css"); + if(Context::get('module')=='admin' || strpos(Context::get('act'),'Admin')>0) $this->addCssFile("./modules/admin/tpl/css/admin.css"); + // rewrite module때문에 javascript에서 location.href 문제 해결을 위해 직접 실제 경로 설정 if($_SERVER['REQUEST_METHOD'] == 'GET') { if($this->get_vars) { @@ -676,6 +685,8 @@ **/ function _addJsFile($file) { if(in_array($file, $this->js_files)) return; + + if(!eregi("^http:\/\/",$file)) $file = str_replace(realpath("."), ".", realpath($file)); $this->js_files[] = $file; } @@ -691,7 +702,9 @@ * @brief js file 목록을 return **/ function _getJsFile() { - return $this->js_files; + require_once("./classes/optimizer/Optimizer.class.php"); + $oOptimizer = new Optimizer(); + return $oOptimizer->getOptimizedFiles($this->js_files, "js"); } /** @@ -707,6 +720,8 @@ **/ function _addCSSFile($file) { if(in_array($file, $this->css_files)) return; + + if(!eregi("^http:\/\/",$file)) $file = str_replace(realpath("."), ".", realpath($file)); $this->css_files[] = $file; } @@ -722,7 +737,9 @@ * @brief CSS file 목록 return **/ function _getCSSFile() { - return $this->css_files; + require_once("./classes/optimizer/Optimizer.class.php"); + $oOptimizer = new Optimizer(); + return $oOptimizer->getOptimizedFiles($this->css_files, "css"); } /** @@ -923,5 +940,18 @@ return WidgetHandler::execute($widget, $vars); } + /** + * @brief gzip encoding 여부 체크 + **/ + function isGzEnabled() { + if( + (defined('__OB_GZHANDLER_ENABLE__') && __OB_GZHANDLER_ENABLE__ == 1) && + strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')!==false && + function_exists('ob_gzhandler') && + extension_loaded('zlib') + ) return true; + return false; + } + } ?> diff --git a/classes/display/DisplayHandler.class.php b/classes/display/DisplayHandler.class.php index c6772d2f7..db6019f28 100644 --- a/classes/display/DisplayHandler.class.php +++ b/classes/display/DisplayHandler.class.php @@ -22,12 +22,7 @@ function printContent(&$oModule) { // gzip encoding 지원 여부 체크 - if( - (defined('__OB_GZHANDLER_ENABLE__') && __OB_GZHANDLER_ENABLE__ == 1) && - strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')!==false && - function_exists('ob_gzhandler') && - extension_loaded('zlib') - ) $this->gz_enabled = true; + $this->gz_enabled = Context::isGzEnabled(); // header 출력 $this->_printHeader(); diff --git a/classes/optimizer/Optimizer.class.php b/classes/optimizer/Optimizer.class.php new file mode 100644 index 000000000..bd3209d44 --- /dev/null +++ b/classes/optimizer/Optimizer.class.php @@ -0,0 +1,144 @@ +cache_path)) { + FileHandler::makeDir($this->cache_path); + } + } + + /** + * @brief optimize 대상 파일을 받아서 처리 후 optimize 된 파일이름을 return + **/ + function getOptimizedFiles($source_files, $type = "js") { + $file_count = count($source_files); + for($i=0;$i<$file_count;$i++) { + $file = trim($source_files[$i]); + if(!$file) continue; + if(eregi("^http:\/\/",$file)) $files[] = $file; + else $targets[] = $file; + } + + if(!count($targets)) return $files; + + $hashed_filename = $this->getHashFilename($targets); + + $filename = sprintf("%s%s.%s.php", $this->cache_path, $hashed_filename, $type); + + $this->doOptimizedFile($filename, $targets, $type); + + $files[] = $filename; + + return $files; + + } + + /** + * @brief optimize는 대상 파일을 \n로 연결후 md5 hashing하여 파일이름의 중복을 피함 + **/ + function getHashFilename($files) { + $buff = implode("\n", $files); + return md5($buff); + } + + /** + * @brief 이미 저장된 캐시 파일과의 시간등을 검사하여 새로 캐싱해야 할지를 체크 + **/ + function doOptimizedFile($filename, $targets, $type) { + if(!file_exists($filename)) return $this->makeOptimizedFile($filename, $targets, $type); + + $file_count = count($targets); + + $mtime = filemtime($filename); + for($i=0;$i<$file_count;$i++) { + if($mtime < filemtime($targets[$i])) return $this->makeOptimizedFile($filename, $targets, $type); + } + } + + /** + * @brief css나 js파일을 묶어서 하나의 파일로 만들고 gzip 압축이나 헤더등을 통제하기 위해서 php파일을 별도로 만들어서 진행함 + **/ + function makeOptimizedFile($filename, $targets, $type) { + /** + * 실제 css나 js의 내용을 합친 것을 구함 + **/ + // 대상 파일의 내용을 구해오고 css 파일일 경우 url()내의 경로를 변경 + $file_count = count($targets); + for($i=0;$i<$file_count;$i++) { + $file = $targets[$i]; + $str = FileHandler::readFile($file); + + // css 일경우 background:url() 변경 + if($type == "css") $str = $this->replaceCssPath($file, $str); + + $content_buff .= $str."\n"; + } + if(Context::isGzEnabled()) $content_buff = ob_gzhandler($content_buff, 5); + $content_file = eregi_replace("\.php$","",$filename); + $content_filename = str_replace($this->cache_path, '', $content_file); + + FileHandler::writeFile($content_file, $content_buff); + + /** + * 압축을 지원하고 캐시 타임을 제대로 이용하기 위한 헤더 파일 구함 + **/ + // php의 헤더파일 생성 + $modified_time = gmdate("D, d M Y H:i:s"); + + // gzip 압축 체크 + if(Context::isGzEnabled()) $gzip_header = 'header("Content-Encoding: gzip");'; + + // 확장자별 content-type 체크 + if($type == 'css') $content_type = 'text/css'; + elseif($type == 'js') $content_type = 'text/javascript'; + + $header_buff = << +EndOfBuff; + + FileHandler::writeFile($filename, $header_buff); + } + + /** + * @brief css의 경우 import/ background 등의 속성에서 사용되는 url내의 경로를 변경시켜줌 + **/ + function replaceCssPath($file, $str) { + $this->tmp_css_path = Context::getRequestUri().ereg_replace("^\.\/","",dirname($file))."/"; + $str = preg_replace_callback('!url\(("|\'){0,1}([^\)]+)("|\'){0,1}\)!is', array($this, '_replaceCssPath'), $str); + return $str; + } + + function _replaceCssPath($matches) { + if(eregi("^http",$matches[2])) return $matches[0]; + return sprintf('url(%s)', $this->tmp_css_path.$matches[2]); + } + + } +?> diff --git a/common/tpl/common_layout.html b/common/tpl/common_layout.html index 0e8444f01..c1458a9c2 100644 --- a/common/tpl/common_layout.html +++ b/common/tpl/common_layout.html @@ -1,4 +1,4 @@ - +{@ $js_files = Context::getJsFile() }{@ $css_files = Context::getCssFile() } @@ -9,16 +9,9 @@ {Context::getBrowserTitle()} - - - - - + + - - - -