Compressed output for static files
To achieve this, these are only 2 files to add (./compressingoutput.inc and ./handlers/page/co.php), and 2 or 3 files with small updates (./actions/header.php, ./mime_types.txt, and maybe ./handlers/page/edit.php)
Create a file named
compressingoutput.inc in ./
The content of that file is :
<?php
# Each time this file, or a file including this one is changed,
# you should modify the REINITIALIZE_ETAG value by anything you want
define ('REINITIALIZE_ETAG',
'something_new');
define ('STORE_GZ_FILE',
true);
define ('CHARSET',
'iso-8859-1');
function ParseHeaderLine
($hl)
{
# Parse a server value like HTTP_ACCEPT_ENCODING
# ( Accept-Encoding: gzip; q= 0.00, deflate ; q =0.5
# ( ==> array ('gzip' => 0, 'deflate' => 0.5);
$ar_hl =
explode(',',
$hl);
foreach ($ar_hl as $val)
{
if (preg_match('/^(.*);\s*q\s*=\s*([0-9\.]*)/i',
$val,
$match))
{
$res[trim(strtolower($match[1]))] =
doubleval($match[2]);
}
else
{
$res[strtolower($val)] =
1;
}
}
return ($res);
}
function Response
($code)
{
# Apache ignores these texts. It stands here just for developpers.
$text =
array('404' =>
'Not Found',
'304' =>
'Not Modified');
header ("HTTP/1.1 $code {$text[$code]}");
}
function compressed_output
($tag,
$content_type=
'auto',
$path_to_file=
'css/')
{
for($i=
0;
$i<
6;
$i++
)
{ # Clean all possible opened buffers
@
ob_end_clean();
}
if ($content_type ==
'auto')
{ # Automatically determine content-type with file extension
$filetype =
explode('.',
$tag);
$pathinfo =
pathinfo($tag);
$extension =
$pathinfo['extension'];
$mimes =
file('mime_types.txt');
$type =
preg_grep("/^([^#]+).*\t.*$extension\s*/i",
$mimes);
foreach ($type as $typeline)
{
$content_type =
preg_split("/\s+/",
$typeline, -
1, PREG_SPLIT_NO_EMPTY
);
$content_type =
$content_type[0];
break;
}
}
$accept_encoding =
$_SERVER['HTTP_ACCEPT_ENCODING'];
$zlib_outputcompression =
ini_get('zlib.output_compression');
if (preg_match('=[1-9]+|on=i',
$zlib_outputcompression)) $accept_encoding =
'';
header("Content-type: $content_type; charset=".CHARSET
);
$filename =
$path_to_file.strtolower
($tag);
if (!
file_exists($filename)) die (Response
('404'));
$filemtime =
filemtime($filename);
$last_modified =
gmdate("D, d M Y H:i:s",
$filemtime).
" GMT";
$etag =
md5("$tag:$filemtime:".REINITIALIZE_ETAG
);
#Id est: when file is modified or when REINITIALIZE_ETAG changes, Etag also changes
header("Etag: $etag");
header("Last-modified: $last_modified");
$expires =
gmdate("D, d M Y H:i:s",
$filemtime+
31536000);
header("Expires: $expires");
header("Cache-Control: public");
// HTTP/1.1
header("Pragma: cache");
if (isset($_SERVER['HTTP_IF_NONE_MATCH']))
{
if ($etag ==
$_SERVER['HTTP_IF_NONE_MATCH']) die(Response
('304'));
}
else if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
{
$last_modified =
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
if ($filemtime <=
$last_modified) die(Response
('304'));
}
#Dealing accept encoding
$accept_encoding = ParseHeaderLine
($accept_encoding);
if (isset($accept_encoding['gzip']) &&
($accept_encoding['gzip'] >
0))
{
header ("Content-Encoding: gzip");
if (STORE_GZ_FILE
)
{ # Assumed that storing .gz file in server decreases CPU Load, but to be proven
if ((!
file_exists("$filename.gz")) ||
(filemtime("$filename.gz") !=
$filemtime) )
{
$zp = @
gzopen("$filename.gz",
"wb9");
if (!
$zp)
{ # No write access?
die ("/*You should give write access to folder css/, or change STORE_GZ_FILE in functions.inc*/");
}
ob_start();
readfile($filename);
$contents =
ob_get_contents();
ob_end_clean();
gzwrite($zp,
$contents);
gzclose($zp);
if (!
touch("$filename.gz",
$filemtime))
{ # todo: You could create a file in css/, but couldn't change its date.
}
}
$filename=
$filename.
".gz";
header ("Content-Length: ".filesize
($filename));
header ("Vary: Accept-Encoding");
}
else
{ # todo: And if ob_gzhandler() was unavailable?
ob_start('ob_gzhandler');
}
}
readfile($filename);
if (!STORE_GZ_FILE
)
{
ob_end_flush();
}
die();
}
?>
Add a file named
co.php in ./handlers/page/ (you can use another name like css.css.php, co stands for compressed output)
The content of co.php is
<?php
/**
* @name css.css
* @author {@link http://wikka.jsnx.com/DotMG DotMG}
* @version 0.1
* @link http://wikka.jsnx.com/WikkaOptimizationCompressedStaticFiles
* @summary
> URL like /yourcssname.css/css.css has the same content as /css/yourcssname.css
> but the output is gz-compressed.
> All the code is in compressingoutput.inc, so that you can use another file like js.js.php
> to compress javascript files.
* @requires functions.inc
* To do elsewhere :
> Modify header.php, change url css/filename.css to $this->Href('co', 'filename.css')
> Modify mime_types.txt, uncomment line "text/css css" and comment on application/x-ilinc-pointplus
**/
include ('compressingoutput.inc');
$tag =
$this->
GetPageTag();
$path =
'css/';
# Actually, co.php is mainly used for css files
if (preg_match('/^(protoedit\.js|wikiedit2\.js)$/i',
$tag))
{
$path =
'3rdparty/plugins/wikiedit/';
}
compressed_output
($tag,
'auto',
$path);
?>
Modify ./actions/header.php and ./mime_types.txt as shown in source of co.php, ie
<link rel="stylesheet" type="text/css" href="<?php echo $this->Href('co', $this->GetConfigValue("stylesheet")); ?>" />
<link rel="stylesheet" type="text/css" href="<?php echo $this->Href('co', 'print.css'); ?>" media="print" />
and
# ILinc support
# COMMENTED application/x-ilinc-pointplus css
(...)
# conflict with ILinc? UNCOMMENTED
text/css css
You could also change ./handlers/page/edit.php like this :
'<script language="JavaScript" src="'.$this->Href('co', 'protoedit.js').'"></script>'."\n".
'<script language="JavaScript" src="'.$this->Href('co', 'wikiedit2.js).'"></script>'."\n";
CategoryUserContributions CategoryDevelopmentArchitecture