PageRenderTime 53ms CodeModel.GetById 18ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/includes/js/edit_area/edit_area/edit_area_compressor.php

https://github.com/KenBoyer/CompactCMS
PHP | 631 lines | 485 code | 37 blank | 109 comment | 40 complexity | 1fd037f9a3d7a6b110a2087b0fc2eee2 MD5 | raw file
  1<?php #! /usr/bin/php
  2//; /usr/bin/php $0 $@ ; exit 0;
  3
  4/*  ^ can't use the shebang trick here as that would produce one more line
  5	of output when this file is run from a webserver, so we take the second-best
  6	approach, which is to favor the webserver and tolerate a few sh/bash error
  7	reports while it'll start the PHP CLI for us after all.
  8
  9	Execute from the commandline (bash) like this, for example:
 10
 11	$ ./edit_area_compressor.php plugins=1 compress=1
 12
 13
 14	Don't bother about these error reports then:
 15
 16	./edit_area_compressor.php: line 1: ?php: No such file or directory
 17	./edit_area_compressor.php: line 2: //: is a directory
 18	PHP Deprecated:  Comments starting with '#' are deprecated in /etc/php5/cli/conf.d/idn.ini on line 1 in Unknown on line 0
 19
 20	The latter shows up on Ubuntu 10.04 installs; again not to bother. The first two
 21	errors are due to our hack to help bash/sh kickstart the PHP interpreter after all,
 22	which is a bit convoluted as the shebang trick cannot happen for it would output
 23	the shebang line with the generated JavaScript when the script is executed by
 24	a web server. We don't that to happen, so we tolerate the error reports when running
 25	in a UNIX shell environment.
 26*/
 27
 28	/******
 29	 *
 30	 *  EditArea PHP compressor
 31	 *  Developed by Christophe Dolivet
 32	 *  Released under LGPL, Apache and BSD licenses
 33	 *  v1.1.3 (2007/01/18)
 34	 *
 35	******/
 36
 37if (0) // if (1) when you need to diagnose your environment
 38{
 39	echo "_SERVER:\n";
 40	var_dump($_SERVER);
 41	echo "_ENV:\n";
 42	var_dump($_ENV);
 43	echo "ours:\n";
 44	echo "\n argv[0] = " . (empty($argv[0]) ? "(NULL)" : $argv[0]);
 45	echo "\n SHELL = " . (!array_key_exists('SHELL', $_ENV) ? "(NULL)" : $_ENV['SHELL']);
 46	echo "\n SESSIONNAME = " . (!array_key_exists('SESSIONNAME', $_SERVER) ? "(NULL)" : $_SERVER['SESSIONNAME']);
 47	echo "\n HTTP_HOST = " . (!array_key_exists('HTTP_HOST', $_SERVER) ? "(NULL)" : $_SERVER['HTTP_HOST']);
 48	echo "\n QUERY_STRING = " . (!array_key_exists('QUERY_STRING', $_SERVER) ? "(NULL)" : $_SERVER['QUERY_STRING']);
 49	echo "\n REQUEST_METHOD = " . (!array_key_exists('REQUEST_METHOD', $_SERVER) ? "(NULL)" : $_SERVER['REQUEST_METHOD']);
 50	die();
 51}
 52
 53/*
 54only run the compressor in here when executed from the commandline; otherwise we'll only
 55define the compressor class and wait for the other code out there to call us:
 56
 57Tests turn out that $_SERVER['SESSIONNAME'] == 'Console' only on Windows machines, while
 58UNIX boxes don't need to present $_ENV['SHELL']. Hence this check to see whether we're
 59running from a console or crontab:
 60
 61- argv[0] WILL be set when run from the command line (it should list our PHP file)
 62- $_SERVER['HTTP_HOST'] does NOT EXIST when run from the console
 63- $_SERVER['QUERY_STRING'] does NOT EXIST when run from the console (it may very well be EMPTY when run by the web server!)
 64- $_SERVER['REQUEST_METHOD'] does NOT EXIST when run from the console
 65
 66Supported arguments when run from the commandline:
 67
 68plugins           - generate the 'full_with_plugins' version instead of the 'full' one
 69
 70you can also override any of the $param[] items like so, for example:
 71
 72debug=0           - equals $params['debug'] = false;
 73
 74debug=1           - equals $params['debug'] = true;
 75
 76*/
 77if (!empty($argv[0]) && stristr($argv[0], '.php') !== false &&
 78	!array_key_exists('HTTP_HOST', $_SERVER) &&
 79	!array_key_exists('QUERY_STRING', $_SERVER) &&
 80	!array_key_exists('REQUEST_METHOD', $_SERVER))
 81{
 82	// CONFIG
 83	$param['cache_duration'] = 3600 * 24 * 10;      // 10 days util client cache expires
 84	$param['compress'] = false;                 // Enable the code compression, should be activated but it can be useful to deactivate it for easier error diagnostics (true or false)
 85	$param['debug'] = false;                        // Enable this option if you need debugging info
 86	$param['use_disk_cache'] = true;                // If you enable this option gzip files will be cached on disk.
 87	$param['use_gzip']= false;                      // Enable gzip compression
 88	$param['plugins'] = true; // isset($_GET['plugins']);    Include plugins in the compressed/flattened JS output.
 89	$param['echo2stdout'] = false;                  // Output generated JS to stdout; alternative is to store it in the object for later retrieval.
 90	$param['include_langs_and_syntaxes'] = true;    // Set to FALSE for backwards compatibility: do not include the language files and syntax definitions in the flattened output.
 91	// END CONFIG
 92
 93	for ($i = 1; $i < $argc; $i++)
 94	{
 95		$arg = explode('=', $argv[$i], 2);
 96		$param[$arg[0]] = (isset($arg[1]) ? intval($arg[1]) : true);
 97	}
 98	$param['running_from_commandline'] = true;          // UNSET or FALSE when executed from a web server
 99	$param['verbose2stdout'] = !$param['echo2stdout'];  // UNSET or FALSE when executed from a web server
100
101	if (!empty($param['verbose2stdout']))
102	{
103		echo "\nEditArea Compressor:\n";
104		echo "Settings:\n";
105		foreach($param as $key => $value)
106		{
107			echo sprintf("  %30s: %d\n", $key, $value);
108		}
109	}
110
111	$compressor = new Compressor($param);
112}
113
114	class Compressor
115	{
116		//function compressor($param)
117		//{
118		//  $this->__construct($param);
119		//}
120		//
121		//--> Strict Standards: Redefining already defined constructor for class Compressor
122
123		function __construct($param)
124		{
125			$this->datas = false;
126			$this->gzip_datas = false;
127			$this->generated_headers = array();
128
129			$this->start_time= $this->get_microtime();
130			$this->file_loaded_size=0;
131			$this->param= $param;
132			$this->script_list="";
133			$this->path= str_replace('\\','/',dirname(__FILE__)).'/';
134			if($this->param['plugins'])
135			{
136				if (!empty($this->param['verbose2stdout'])) echo "\n\n\nGenerating output with plugins included\n";
137				$this->load_all_plugins= true;
138				$this->full_cache_file= $this->path."edit_area_full_with_plugins.js";
139				$this->gzip_cache_file= $this->path."edit_area_full_with_plugins.gz";
140			}
141			else
142			{
143				if (!empty($this->param['verbose2stdout'])) echo "\n\n\nGenrating output WITHOUT plugins\n";
144				$this->load_all_plugins= false;
145				$this->full_cache_file= $this->path."edit_area_full.js";
146				$this->gzip_cache_file= $this->path."edit_area_full.gz";
147			}
148
149			$this->check_gzip_use();
150			$this->send_headers();
151			$this->check_cache();
152			$this->load_files();
153			$this->send_datas();
154		}
155
156
157		/**
158		 * Return the HTTP headers associated with the compressed/flattened output file as an array of header lines.
159		 */
160		public function get_headers()
161		{
162			return $this->generated_headers;
163		}
164
165		/**
166		 * Return the generated flattened JavaScript as a string.
167		 *
168		 * Return FALSE on error.
169		 */
170		public function get_flattened()
171		{
172			return $this->datas;
173		}
174
175		/**
176		 * Return the generated flattened and GZIPped JavaScript (as output by gzencode()).
177		 *
178		 * Return FALSE on error or when GZIPped JavaScript has not been generated.
179		 */
180		public function get_flattened_gzipped()
181		{
182			return $this->gzip_datas;
183		}
184
185		private function send_header1($headerline)
186		{
187			$this->generated_headers[] = $headerline;
188			if ($this->param['echo2stdout'] && !headers_sent())
189			{
190				header($headerline);
191			}
192		}
193
194		private function send_headers()
195		{
196			$this->send_header1("Content-type: text/javascript; charset: UTF-8");
197			$this->send_header1("Vary: Accept-Encoding"); // Handle proxies
198			$this->send_header1(sprintf("Expires: %s GMT", gmdate("D, d M Y H:i:s", time() + intval($this->param['cache_duration']))) );
199			if($this->use_gzip)
200			{
201				$this->send_header1("Content-Encoding: ".$this->gzip_enc_header);
202			}
203		}
204
205		private function check_gzip_use()
206		{
207			$encodings = array();
208			$desactivate_gzip=false;
209
210			if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
211			{
212				$encodings = explode(',', strtolower(preg_replace("/\s+/", "", $_SERVER['HTTP_ACCEPT_ENCODING'])));
213			}
214
215			// deactivate gzip for IE version < 7
216			if (!isset($_SERVER['HTTP_USER_AGENT']))
217			{
218				// run from the commandline: do NOT use gzip
219				$desactivate_gzip=true;
220			}
221			else if(preg_match("/(?:msie )([0-9.]+)/i", $_SERVER['HTTP_USER_AGENT'], $ie))
222			{
223				if($ie[1]<7)
224					$desactivate_gzip=true;
225			}
226
227			// Check for gzip header or northon internet securities
228			if (!$desactivate_gzip && $this->param['use_gzip'] && (in_array('gzip', $encodings) || in_array('x-gzip', $encodings) || isset($_SERVER['---------------'])) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression')) {
229				$this->gzip_enc_header= in_array('x-gzip', $encodings) ? "x-gzip" : "gzip";
230				$this->use_gzip=true;
231				$this->cache_file=$this->gzip_cache_file;
232			}else{
233				$this->use_gzip=false;
234				$this->cache_file=$this->full_cache_file;
235			}
236		}
237
238		private function check_cache()
239		{
240			// Only gzip the contents if clients and server support it
241			if ($this->param['use_disk_cache'] && file_exists($this->cache_file) && empty($this->param['running_from_commandline'])) {
242				// check if cache file must be updated
243				$cache_date=0;
244				if ($dir = opendir($this->path)) {
245					while (($file = readdir($dir)) !== false) {
246						if(is_file($this->path.$file) && $file!="." && $file!="..")
247							$cache_date= max($cache_date, filemtime($this->path.$file));
248					}
249					closedir($dir);
250				}
251				if($this->load_all_plugins){
252					$plug_path= $this->path."plugins/";
253					if (($dir = @opendir($plug_path)) !== false)
254					{
255						while (($file = readdir($dir)) !== false)
256						{
257							if ($file !== "." && $file !== "..")
258							{
259								if(is_dir($plug_path.$file) && file_exists($plug_path.$file."/".$file.".js"))
260									$cache_date= max($cache_date, filemtime($plug_path.$file."/".$file.".js")); // fix for: http://sourceforge.net/tracker/?func=detail&aid=2932086&group_id=164008&atid=829999
261							}
262						}
263						closedir($dir);
264					}
265				}
266
267				if(filemtime($this->cache_file) >= $cache_date){
268					// if cache file is up to date
269					$last_modified = gmdate("D, d M Y H:i:s",filemtime($this->cache_file))." GMT";
270					if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && strcasecmp($_SERVER["HTTP_IF_MODIFIED_SINCE"], $last_modified) === 0)
271					{
272						header("HTTP/1.1 304 Not Modified");
273						header("Last-modified: ".$last_modified);
274						header("Cache-Control: Public"); // Tells HTTP 1.1 clients to cache
275						header("Pragma:"); // Tells HTTP 1.0 clients to cache
276					}
277					else
278					{
279						header("Last-modified: ".$last_modified);
280						header("Cache-Control: Public"); // Tells HTTP 1.1 clients to cache
281						header("Pragma:"); // Tells HTTP 1.0 clients to cache
282						header('Content-Length: '.filesize($this->cache_file));
283						echo file_get_contents($this->cache_file);
284					}
285					die;
286				}
287			}
288			return false;
289		}
290
291		private function load_files()
292		{
293			$loader= $this->get_content("edit_area_loader.js")."\n";
294
295			// get the list of other files to load
296			$loader= preg_replace("/(t\.scripts_to_load=\s*)\[([^\]]*)\];/e"
297						, "\$this->replace_scripts('script_list', '\\1', '\\2')"
298						, $loader);
299
300			$loader= preg_replace("/(t\.sub_scripts_to_load=\s*)\[([^\]]*)\];/e"
301						, "\$this->replace_scripts('sub_script_list', '\\1', '\\2')"
302						, $loader);
303
304			// [i_a] the fix for various browsers' show issues is to flatten EVERYTHING into a single file, i.e. also the language and reg_syntax files: the load_script() and other lazyload-ing bits of code in edit_area are somehow buggy and thus circumvented.
305
306			// replace syntax definition names
307			$syntax_defs = '';
308			$reg_path= $this->path."reg_syntax/";
309			$a_displayName  = array();
310			$a_Name = array();
311			if (($dir = @opendir($reg_path)) !== false)
312			{
313				while (($file = readdir($dir)) !== false)
314				{
315					if( $file !== "." && $file !== ".." && substr($file, -3) == '.js' )
316					{
317						$jsContent  = $this->file_get_contents( $reg_path.$file );
318						if( preg_match( '@(\'|")DISPLAY_NAME\1\s*:\s*(\'|")(.*)\2@', $jsContent, $match ) )
319						{
320							$a_displayName[] = "'". substr($file, 0, strlen($file) - 3) ."':'". htmlspecialchars( $match[3], ENT_QUOTES, 'UTF-8') ."'";
321						}
322						if( preg_match( '@editAreaLoader\.load_syntax\[(\'|")([^\'"]+)\1\]\s*=@', $jsContent, $match ) )
323						{
324							$a_Name[] = htmlspecialchars( $match[2], ENT_QUOTES, 'UTF-8');
325						}
326						$syntax_defs .= $jsContent . "\n";
327						// and add 'marked as loaded' code to that as well:
328						$syntax_defs .= "editAreaLoader.loadedFiles[editAreaLoader.baseURL + 'reg_syntax/' + '" . $file . "'] = true;\n\n\n";
329					}
330				}
331				closedir($dir);
332			}
333			$loader = str_replace( '/*syntax_display_name_AUTO-FILL-BY-COMPRESSOR*/', implode( ",", $a_displayName ), $loader );
334			$loader = str_replace( '/*syntax_name_AUTO-FILL-BY-COMPRESSOR*/', implode( ",", $a_Name ), $loader );
335
336			// collect languages
337			$language_defs = '';
338			$lang_path= $this->path."langs/";
339			if (($dir = @opendir($lang_path)) !== false)
340			{
341				while (($file = readdir($dir)) !== false)
342				{
343					if( $file !== "." && $file !== ".." && substr($file, -3) == '.js' )
344					{
345						$jsContent  = $this->file_get_contents( $lang_path.$file );
346						$language_defs .= $jsContent . "\n";
347						// and add 'marked as loaded' code to that as well:
348						$language_defs .= "editAreaLoader.loadedFiles[editAreaLoader.baseURL + 'langs/' + '" . $file . "'] = true;\n\n\n";
349					}
350				}
351				closedir($dir);
352			}
353
354			$this->datas= $loader;
355			$this->compress_javascript($this->datas);
356
357			// load other scripts needed for the loader
358			preg_match_all('/"([^"]*)"/', $this->script_list, $match);
359			foreach($match[1] as $key => $value)
360			{
361				$content= $this->get_content(preg_replace("/\\|\//i", "", $value).".js");
362				$this->compress_javascript($content);
363				$this->datas.= $content."\n";
364			}
365			//$this->datas);
366			//$this->datas= preg_replace('/(( |\t|\r)*\n( |\t)*)+/s', "", $this->datas);
367
368			// improved compression step 1/2
369			if($this->param['compress'])
370			{
371				$this->datas= preg_replace(array("/(\b)EditAreaLoader(\b)/", "/(\b)editAreaLoader(\b)/", "/(\b)editAreas(\b)/"), array("EAL", "eAL", "eAs"), $this->datas);
372				//$this->datas= str_replace(array("EditAreaLoader", "editAreaLoader", "editAreas"), array("EAL", "eAL", "eAs"), $this->datas);
373				$this->datas.= "var editAreaLoader= eAL;var editAreas=eAs;EditAreaLoader=EAL;";
374			}
375
376			// load sub scripts
377			$sub_scripts="";
378			$sub_scripts_list= array();
379			preg_match_all('/"([^"]*)"/', $this->sub_script_list, $match);
380			foreach($match[1] as $value){
381				$sub_scripts_list[]= preg_replace("/\\|\//i", "", $value).".js";
382			}
383
384			if($this->load_all_plugins){
385				// load plugins scripts
386				$plug_path= $this->path."plugins/";
387				if (($dir = @opendir($plug_path)) !== false)
388				{
389					while (($file = readdir($dir)) !== false)
390					{
391						if ($file !== "." && $file !== "..")
392						{
393							if(is_dir($plug_path.$file) && file_exists($plug_path.$file."/".$file.".js"))
394								$sub_scripts_list[]= "plugins/".$file."/".$file.".js";
395						}
396					}
397					closedir($dir);
398				}
399			}
400
401			foreach($sub_scripts_list as $value){
402				$sub_scripts.= $this->get_javascript_content($value);
403			}
404			// improved compression step 2/2
405			if($this->param['compress'])
406			{
407				$sub_scripts= preg_replace(array("/(\b)editAreaLoader(\b)/", "/(\b)editAreas(\b)/", "/(\b)editArea(\b)/", "/(\b)EditArea(\b)/"), array("eAL", "eAs", "eA", "EA"), $sub_scripts);
408			//  $sub_scripts= str_replace(array("editAreaLoader", "editAreas", "editArea", "EditArea"), array("eAL", "eAs", "eA", "EA"), $sub_scripts);
409				$sub_scripts.= "var editArea= eA;EditArea=EA;";
410			}
411
412			// add the scripts
413		//  $this->datas.= sprintf("editAreaLoader.iframe_script= \"<script type='text/javascript'>%s</script>\";\n", $sub_scripts);
414
415
416			// add the script and use a last compression
417			if( $this->param['compress'] )
418			{
419				$last_comp  = array( 'Á' => 'this',
420								 'Â' => 'textarea',
421								 'Ã' => 'function',
422								 'Ä' => 'prototype',
423								 'Å' => 'settings',
424								 'Æ' => 'length',
425								 'Ç' => 'style',
426								 'È' => 'parent',
427								 'É' => 'last_selection',
428								 'Ê' => 'value',
429								 'Ë' => 'true',
430								 'Ì' => 'false'
431								 /*,
432									'Î' => '"',
433								 'Ï' => "\n",
434								 'À' => "\r"*/);
435			}
436			else
437			{
438				$last_comp  = array();
439			}
440
441			$js_replace= '';
442			foreach( $last_comp as $key => $val )
443				$js_replace .= ".replace(/". $key ."/g,'". str_replace( array("\n", "\r"), array('\n','\r'), $val ) ."')";
444
445			$this->datas.= sprintf("editAreaLoader.iframe_script= \"<script type='text/javascript'>%s</script>\"%s;\n",
446								str_replace( array_values($last_comp), array_keys($last_comp), $sub_scripts ),
447								$js_replace);
448
449			if($this->load_all_plugins)
450				$this->datas.="editAreaLoader.all_plugins_loaded=true;\n";
451
452
453			// load the template
454			$this->datas.= sprintf("editAreaLoader.template= \"%s\";\n", $this->get_html_content("template.html"));
455			// load the css
456			$this->datas.= sprintf("editAreaLoader.iframe_css= \"<style>%s</style>\";\n", $this->get_css_content("edit_area.css"));
457
458			// load the syntaxes and languages as well:
459			if ($this->param['include_langs_and_syntaxes'])
460			{
461				// make sure the syntax and/or language files are NOT nuked in the process so act conservatively when compressing:
462				$this->compress_javascript($syntax_defs, false);
463				$this->datas.= $syntax_defs;
464				$this->compress_javascript($language_defs, false);
465				$this->datas.= $language_defs;
466			}
467
468		//  $this->datas= "function editArea(){};editArea.prototype.loader= function(){alert('bouhbouh');} var a= new editArea();a.loader();";
469
470		}
471
472		private function send_datas()
473		{
474			if($this->param['debug']){
475				$header=sprintf("/* USE PHP COMPRESSION\n");
476				$header.=sprintf("javascript size: based files: %s => PHP COMPRESSION => %s ", $this->file_loaded_size, strlen($this->datas));
477				if($this->use_gzip){
478					$gzip_datas=  gzencode($this->datas, 9, FORCE_GZIP);
479					$header.=sprintf("=> GZIP COMPRESSION => %s", strlen($gzip_datas));
480					$ratio = round(100 - strlen($gzip_datas) / $this->file_loaded_size * 100.0);
481				}else{
482					$ratio = round(100 - strlen($this->datas) / $this->file_loaded_size * 100.0);
483				}
484				$header.=sprintf(", reduced by %s%%\n", $ratio);
485				$header.=sprintf("compression time: %s\n", $this->get_microtime()-$this->start_time);
486				$header.=sprintf("%s\n", implode("\n", $this->infos));
487				$header.=sprintf("*/\n");
488				$this->datas= $header.$this->datas;
489			}
490			$mtime= time(); // ensure that the 2 disk files will have the same update time
491			// generate gzip file and cache it if using disk cache
492			if($this->use_gzip){
493				$this->gzip_datas= gzencode($this->datas, 9, FORCE_GZIP);
494				if($this->param['use_disk_cache'])
495					$this->file_put_contents($this->gzip_cache_file, $this->gzip_datas, $mtime);
496			}
497
498			// generate full js file and cache it if using disk cache
499			if($this->param['use_disk_cache'])
500			{
501				if (!empty($this->param['verbose2stdout'])) echo "written to file: " . $this->full_cache_file . "\n";
502				$this->file_put_contents($this->full_cache_file, $this->datas, $mtime);
503			}
504
505			// generate output
506			if ($this->param['echo2stdout'])
507			{
508				if($this->use_gzip)
509					echo $this->gzip_datas;
510				else
511					echo $this->datas;
512			}
513
514//          die;
515		}
516
517		private function get_content($end_uri)
518		{
519			$end_uri=preg_replace("/\.\./", "", $end_uri); // Remove any .. (security)
520			$file= $this->path.$end_uri;
521			if(file_exists($file)){
522				$this->infos[]=sprintf("'%s' loaded", $end_uri);
523				/*$fd = fopen($file, 'rb');
524				$content = fread($fd, filesize($file));
525				fclose($fd);
526				return $content;*/
527				return $this->file_get_contents($file);
528			}else{
529				$this->infos[]=sprintf("'%s' not loaded", $end_uri);
530				return "";
531			}
532		}
533
534		private function get_javascript_content($end_uri)
535		{
536			$val=$this->get_content($end_uri);
537
538			$this->compress_javascript($val);
539			$this->prepare_string_for_quotes($val);
540			return $val;
541		}
542
543		private function compress_javascript(&$code, $apply_optimistic_rules = true)
544		{
545			if($this->param['compress'])
546			{
547				// remove all comments
548				//  (\"(?:[^\"\\]*(?:\\\\)*(?:\\\"?)?)*(?:\"|$))|(\'(?:[^\'\\]*(?:\\\\)*(?:\\'?)?)*(?:\'|$))|(?:\/\/(?:.|\r|\t)*?(\n|$))|(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$))
549				$code= preg_replace("/(\"(?:[^\"\\\\]*(?:\\\\\\\\)*(?:\\\\\"?)?)*(?:\"|$))|(\'(?:[^\'\\\\]*(?:\\\\\\\\)*(?:\\\\\'?)?)*(?:\'|$))|(?:\/\/(?:.|\r|\t)*?(\n|$))|(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$))/s", "$1$2$3", $code);
550				// remove line return, empty line and tabulation
551				$code= preg_replace('/(( |\t|\r)*\n( |\t)*)+/s', " ", $code);
552				// add line break before "else" otherwise navigators can't manage to parse the file
553				if ($apply_optimistic_rules)
554				{
555					$code= preg_replace('/(\b(else)\b)/', "\n$1", $code);
556				}
557				// remove unnecessary spaces
558				$code= preg_replace('/( |\t|\r)*(;|\{|\}|=|==|\-|\+|,|\(|\)|\|\||&\&|\:)( |\t|\r)*/', "$2", $code);
559			}
560		}
561
562		private function get_css_content($end_uri){
563			$code=$this->get_content($end_uri);
564			// remove comments
565			$code= preg_replace("/(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$))/s", "", $code);
566			// remove spaces
567			$code= preg_replace('/(( |\t|\r)*\n( |\t)*)+/s', "", $code);
568			// remove spaces
569			$code= preg_replace('/( |\t|\r)?(\:|,|\{|\})( |\t|\r)+/', "$2", $code);
570
571			$this->prepare_string_for_quotes($code);
572			return $code;
573		}
574
575		private function get_html_content($end_uri){
576			$code=$this->get_content($end_uri);
577			//$code= preg_replace('/(\"(?:\\\"|[^\"])*(?:\"|$))|' . "(\'(?:\\\'|[^\'])*(?:\'|$))|(?:\/\/(?:.|\r|\t)*?(\n|$))|(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$))/s", "$1$2$3", $code);
578			$code= preg_replace('/(( |\t|\r)*\n( |\t)*)+/s', " ", $code);
579			$this->prepare_string_for_quotes($code);
580			return $code;
581		}
582
583		private function prepare_string_for_quotes(&$str){
584			// prepare the code to be putted into quotes
585			/*$pattern= array("/(\\\\)?\"/", '/\\\n/'   , '/\\\r/'  , "/(\r?\n)/");
586			$replace= array('$1$1\\"', '\\\\\\n', '\\\\\\r' , '\\\n"$1+"');*/
587			$pattern= array("/(\\\\)?\"/", '/\\\n/' , '/\\\r/'  , "/(\r?\n)/");
588			if($this->param['compress'])
589				$replace= array('$1$1\\"', '\\\\\\n', '\\\\\\r' , '\n');
590			else
591				$replace= array('$1$1\\"', '\\\\\\n', '\\\\\\r' , "\\n\"\n+\"");
592			$str= preg_replace($pattern, $replace, $str);
593		}
594
595		private function replace_scripts($var, $param1, $param2)
596		{
597			$this->$var=stripslashes($param2);
598			return $param1."[];";
599		}
600
601		/* for php version that have not thoses functions */
602		private function file_get_contents($file)
603		{
604			$fd = fopen($file, 'rb');
605			$content = fread($fd, filesize($file));
606			fclose($fd);
607			$this->file_loaded_size+= strlen($content);
608			return $content;
609		}
610
611		private function file_put_contents($file, &$content, $mtime=-1)
612		{
613			if($mtime==-1)
614				$mtime=time();
615			$fp = @fopen($file, "wb");
616			if ($fp) {
617				fwrite($fp, $content);
618				fclose($fp);
619				touch($file, $mtime);
620				return true;
621			}
622			return false;
623		}
624
625		private function get_microtime()
626		{
627		   list($usec, $sec) = explode(" ", microtime());
628		   return ((float)$usec + (float)$sec);
629		}
630	}
631?>