00001 <?php
00002
00003
00004
00005 class JCSSManager {
00006 const TYPE_JS = 'JS';
00007 const TYPE_CSS = 'CSS';
00008 const TYPE_CSS_IE50 = 'CSS_IE50';
00009 const TYPE_CSS_IE55 = 'CSS_IE55';
00010 const TYPE_CSS_IE6 = 'CSS_IE6';
00011 const TYPE_CSS_IE7 = 'CSS_IE7';
00012
00013
00014
00015
00016
00017
00018 public static function get_types() {
00019 return array_merge(
00020 array(self::TYPE_JS => tr(self::TYPE_JS, 'jcssmanager')),
00021 self::get_css_types()
00022 );
00023 }
00024
00025
00026
00027
00028
00029
00030 public static function get_css_types() {
00031 return array(
00032 self::TYPE_CSS => tr(self::TYPE_CSS, 'jcssmanager'),
00033 self::TYPE_CSS_IE50 => tr(self::TYPE_CSS_IE50, 'jcssmanager'),
00034 self::TYPE_CSS_IE55 => tr(self::TYPE_CSS_IE55, 'jcssmanager'),
00035 self::TYPE_CSS_IE6 => tr(self::TYPE_CSS_IE6, 'jcssmanager'),
00036 self::TYPE_CSS_IE7 => tr(self::TYPE_CSS_IE7, 'jcssmanager'),
00037 );
00038 }
00039
00040
00041
00042
00043
00044
00045
00046 public static function make_relativ($path) {
00047 return str_replace(Config::get_value(Config::URL_ABSPATH), '', $path);
00048 }
00049
00050
00051
00052
00053
00054
00055
00056 public static function make_absolute($path) {
00057 return Config::get_value(Config::URL_ABSPATH) . $path;
00058 }
00059
00060
00061
00062
00063
00064
00065 public static function collect_and_compress() {
00066 $err = new Status();
00067 Load::commands('jcssmanager/compress.js', 'jcssmanager/compress.css');
00068 Load::models('jcsscompressedfiles');
00069
00070 $out_file = Config::get_value(Config::URL_ABSPATH) . Config::get_value(ConfigJCSSManager::JS_DIR) . 'compressed.js';
00071 $in_files = array();
00072 EventSource::Instance()->invoke_event('jcssmanager_compress', JCSSManager::TYPE_JS, $in_files);
00073 $js = new JCSSManagerCompressJSCommand($in_files, $out_file);
00074 $err->merge($js->execute());
00075
00076 $css_base = Config::get_value(ConfigJCSSManager::CSS_DIR);
00077 foreach(JCSSManager::get_css_types() as $type => $tr) {
00078 $out_file = ($type !== JCSSManager::TYPE_CSS) ? 'compressed.' . strtolower($type) . '.css' : 'compressed.css';
00079 $out_file = JCSSManager::make_absolute($css_base . $out_file);
00080 $in_files = array();
00081 EventSource::Instance()->invoke_event('jcssmanager_compress', $type, $in_files);
00082 $css = new JCSSManagerCompressCSSCommand($in_files, $out_file, $type);
00083 $err->merge($css->execute());
00084 }
00085
00086
00087 if ($err->is_ok()) {
00088 $err->merge(self::update_htaccess());
00089 }
00090 return $err;
00091 }
00092
00093 private static function update_htaccess() {
00094 $err = new Status();
00095 $htc_option = '';
00096 $htc_rewrite = '';
00097 if (Config::has_feature(ConfigJCSSManager::ALSO_GZIP)) {
00098 $charset = GyroLocale::get_charset();
00099 $htc_option = array(
00100 '# Workaround Apache 1.3, which always uses gzip, x-gzip as encoding, which crashes browsers',
00101 'RemoveEncoding .gz',
00102 'AddEncoding gzip .gz',
00103 '# End workaround',
00104 '<FilesMatch .*\.js.gz$>',
00105 'AddEncoding gzip .js',
00106 "ForceType \"text/javascript;charset=$charset\"",
00107 '<IfModule mod_headers.c>',
00108 'Header append Vary "Accept-Encoding"',
00109 'Header set "Accept-Ranges" none',
00110 '</IfModule>',
00111 '</FilesMatch>',
00112 '<FilesMatch .*\.css.gz$>',
00113 'AddEncoding gzip .css',
00114 "ForceType \"text/css;charset=$charset\"",
00115 '<IfModule mod_headers.c>',
00116 'Header append Vary "Accept-Encoding"',
00117 'Header set "Accept-Ranges" none',
00118 '</IfModule>',
00119 '</FilesMatch>',
00120 '<IfModule mod_expires.c>',
00121 'ExpiresActive On',
00122 '<FilesMatch "^compressed">',
00123 "ExpiresByType text/css 'access plus 2 years'",
00124 "ExpiresByType text/javascript 'access plus 2 years'",
00125 "ExpiresByType application/x-javascript 'access plus 2 years'",
00126 '</FilesMatch>',
00127 '</IfModule>'
00128 );
00129 $htc_rewrite = array(
00130 'RewriteCond %{HTTP:Accept-encoding} gzip',
00131 'RewriteCond %{REQUEST_FILENAME}.gz -f',
00132 'RewriteRule ^(.*)$ $1.gz [QSA,L]'
00133 );
00134 }
00135 Load::components('systemupdateinstaller');
00136 $err->merge(SystemUpdateInstaller::modify_htaccess('jcssmanager', SystemUpdateInstaller::HTACCESS_OPTIONS, $htc_option));
00137 $err->merge(SystemUpdateInstaller::modify_htaccess('jcssmanager', SystemUpdateInstaller::HTACCESS_REWRITE, $htc_rewrite));
00138 return $err;
00139 }
00140
00141 public static function concat_css_files($arr_files) {
00142 $ret = '';
00143 foreach($arr_files as $file) {
00144 $ret .= self::transform_css_file($file);
00145 }
00146 return $ret;
00147 }
00148
00149 public static function transform_css_file($file) {
00150 $ret = '';
00151 if (substr($file, 0, 1) !== '/') {
00152 $file = Config::get_value(Config::URL_ABSPATH) . $file;
00153 }
00154 $handle = fopen($file, 'r');
00155 $regex = '@(url\s*\(\s*"?)([\w.][^"\)]*)@';
00156 $rel_path = str_replace(Config::get_value(Config::URL_ABSPATH), '/', realpath($file));
00157 $replace = '$1' . dirname($rel_path) . '/$2';
00158 while(($line = fgets($handle)) !== false) {
00159
00160 $line = trim($line);
00161 $token = substr($line, 0, 7);
00162 if ($token === '@charse') {
00163 continue;
00164 }
00165
00166 if ($token === '@import') {
00167 $start = strpos($line, '(', 7);
00168 if ($start !== false) {
00169 $end = strpos($line, ')', $start);
00170 if ($end !== false) {
00171 $start++;
00172 $file_to_include = trim(substr($line, $start, $end - $start), "'\" \t");
00173 if (substr($file_to_include, 0, 1) !== '/') {
00174 $file_to_include = dirname($file) . '/' . $file_to_include;
00175 }
00176 else {
00177 $file_to_include = JCSSManager::make_absolute($file_to_include);
00178 }
00179 $line = self::transform_css_file($file_to_include);
00180 }
00181 }
00182 }
00183
00184 $line = preg_replace($regex, $replace, $line);
00185 $ret .= $line;
00186 }
00187
00188 return $ret;
00189 }
00190 }