includes/clientside/jsres.php
changeset 420 301f546688d1
parent 411 d1a95497b68f
child 421 dbae4d327846
--- a/includes/clientside/jsres.php	Tue Feb 12 22:17:58 2008 -0500
+++ b/includes/clientside/jsres.php	Wed Feb 13 21:59:07 2008 -0500
@@ -13,82 +13,144 @@
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
  */
 
-if(!isset($_GET['title'])) $_GET['title'] = 'null';
-require('../common.php');
+// Setup Enano
 
-define('ENABLE_COMPRESSION', '');
+//
+// Determine the location of Enano as an absolute path.
+//
 
-ob_start();
-header('Content-type: text/javascript');
+// We need to see if this is a specially marked Enano development server. You can create an Enano
+// development server by cloning the Mercurial repository into a directory named repo, and then
+// using symlinks to reference the original files so as to segregate unique files from non-unique
+// and distribution-standard ones. Enano will pivot its root directory accordingly if the file
+// .enanodev is found in the Enano root (not /repo/).
+if ( strpos(__FILE__, '/repo/') && ( file_exists('../../.enanodev') || file_exists('../../../.enanodev') ) )
+{
+  // We have a development directory. Remove /repo/ from the picture.
+  $filename = str_replace('/repo/', '/', __FILE__);
+}
+else
+{
+  // Standard Enano installation
+  $filename = __FILE__;
+}
 
-$file = ( isset($_GET['file']) ) ? $_GET['file'] : 'enano-lib-basic.js';
+// ENANO_ROOT is sometimes defined by plugins like AjIM that need the constant before the Enano API is initialized
+if ( !defined('ENANO_ROOT') )
+  define('ENANO_ROOT', dirname(dirname(dirname($filename))));
+
+chdir(ENANO_ROOT);
+
+// CONFIG
 
-if(!preg_match('/^([a-z0-9_-]+)\.js$/i', $file))
-  die('// ERROR: Hacking attempt');
+// Files safe to run full (aggressive) compression on
+$full_compress_safe = array('ajax.js', 'editor.js', 'acl.js', 'rijndael.js', 'admin-menu.js', 'autofill.js', 'comments.js', 'misc.js', 'faders.js', 'dropdown.js');
+
+// Files that should NOT be compressed due to already being compressed, licensing, or invalid produced code
+$compress_unsafe = array('SpryEffects.js', 'json.js', 'fat.js');
+
+require('includes/functions.php');
+require('includes/json2.php');
+require('includes/js-compressor.php');
+
+// Output format will always be JS
+header('Content-type: text/javascript');
+$everything = '';
 
-$fname = './static/' . $file;
-if ( !file_exists($fname) )
-  die('// ERROR: File not found: ' . $file);
+// Load and parse enano_lib_basic
+$file = @file_get_contents('includes/clientside/static/enano-lib-basic.js');
+
+$pos_start_includes = strpos($file, '/*!START_INCLUDER*/');
+$pos_end_includes = strpos($file, '/*!END_INCLUDER*/');
 
-$everything = file_get_contents($fname);
+if ( !$pos_start_includes || !$pos_end_includes )
+{
+  die('// Error: enano-lib-basic does not have required metacomments');
+}
 
-$mtime = filemtime($fname);
-header('Last-Modified: '.enano_date('D, d M Y H:i:s T', $mtime));
-header('Content-disposition: attachment; filename=' . $file);
+$pos_end_includes += strlen('/*!END_INCLUDER*/');
+
+preg_match('/var thefiles = (\[([^\]]+?)\]);/', $file, $match);
+
+if ( empty($match) )
+  die('// Error: could not retrieve file list from enano-lib-basic');
 
-if(defined('ENABLE_COMPRESSION'))
+// Decode file list
+try
+{
+  $file_list = enano_json_decode($match[1]);
+}
+catch ( Exception $e )
 {
-  echo "/*
- * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
- * Version 1.1.2 (Caoineag alpha 2)
- * [Aggressively compressed] Javascript client code
- * Copyright (C) 2006-2007 Dan Fuhry
- * Enano is Free Software, licensed under the GNU General Public License; see http://enanocms.org/ for details.
- */
+  die("// Exception caught during file list parsing");
+}
+
+$apex = filemtime('includes/clientside/static/enano-lib-basic.js');
+
+$before_includes = substr($file, 0, $pos_start_includes);
+$after_includes = substr($file, $pos_end_includes);
+
+$everything .= $before_includes;
+$everything .= $after_includes;
 
-";
+foreach ( $file_list as $js_file )
+{
+  $file_contents = file_get_contents("includes/clientside/static/$js_file");
+  $file_md5 = md5($file_contents);
+  $time = filemtime("includes/clientside/static/$js_file");
+  if ( $time > $apex )
+    $apex = $time;
+  // Is this file cached?
+  $cache_path = ENANO_ROOT . "/cache/jsres_$js_file.json";
+  $loaded_cache = false;
   
-  $cache_file = ENANO_ROOT . '/cache/jsres-' . $file . '.php';
-  
-  if ( file_exists($cache_file) )
+  if ( file_exists($cache_path) )
   {
-    $cached = file_get_contents ( $cache_file );
-    $data = unserialize ( $cached );
-    if ( $data['md5'] == md5 ( $everything ) )
+    // Load the cache file and parse it.
+    $cache_file = file_get_contents($cache_path);
+    try
+    {
+      $cache_file = enano_json_decode($cache_file);
+    }
+    catch ( Exception $e )
+    {
+      // Don't do anything - let our fallbacks come into place
+    }
+    if ( is_array($cache_file) && isset($cache_file['md5']) && isset($cache_file['src']) )
     {
-      echo "// The code in this file was fetched from cache\n\n";
-      echo $data['code'];
-      exit;
+      if ( $cache_file['md5'] === $file_md5 )
+      {
+        $loaded_cache = true;
+        $file_contents = $cache_file['src'];
+      }
+    }
+  }
+  if ( !$loaded_cache )
+  {
+    // Try to open the cache file and write to it. If we can't do that, just don't compress the code.
+    $handle = @fopen($cache_path, 'w');
+    if ( $handle )
+    {
+      $aggressive = in_array($js_file, $full_compress_safe);
+      if ( !in_array($js_file, $compress_unsafe) )
+        $file_contents = perform_js_compress($file_contents, $aggressive);
+      
+      $payload = enano_json_encode(array(
+          'md5' => $file_md5,
+          'src' => $file_contents
+        ));
+      fwrite($handle, $payload);
+      fclose($handle);
     }
   }
   
-  if ( getConfig('cache_thumbs') == '1' )
-  {
-    $js_compressor = new JavascriptCompressor();
-    $packed = $js_compressor->getPacked($everything);
-    $data = Array(
-      'md5' => md5 ( $everything ),
-      'code' => $packed
-      );
-    echo "// The code in this file was fetched from the static scripts and compressed (packed code cached)\n\n";
-    echo $packed;
-    
-    $fh = @fopen($cache_file, 'w');
-    if (!$fh)
-      die('// ERROR: Can\'t open cache file for writing');
-    fwrite($fh, serialize ( $data ) );
-    fclose($fh);
-    
-    exit;
-  }
-  
-  echo "// The code in this file was not compressed because packed-script caching is disabled\n\n";
-  echo $everything;
-  
+  $everything .= "\n // $js_file\n";
+  $everything .= "\n" . $file_contents;
 }
-else
-{
-  echo "// The code in this file was not compressed because all script compression is disabled\n\n";
-  echo $everything;
-}
-?>
+
+$date = date('r', $apex);
+header("Date: $date");
+header("Last-Modified: $date");
+
+echo $everything;
+