From 5a52dbf376f4d360d90d4a33afbb6df95d45a116 Mon Sep 17 00:00:00 2001 From: Chad Auld Date: Thu, 29 Oct 2009 23:12:13 -0700 Subject: [PATCH] Doc and example cleanup. Fixing combo.php query string explode bug. Modifying loader APC/Curl support checks. Adding support for APC to combo.php. Fixing most of the CSS relative image path issues with combo.php. --- CHANGES | 7 ++ INSTALL | 7 +- README | 5 +- examples/index.html | 2 +- examples/phploader-advanced_source.php | 2 +- examples/phploader-basic.php | 13 +-- examples/phploader-basic_source.php | 2 +- .../phploader-custom-modules-with-yui.php | 44 ++++----- ...ploader-custom-modules-with-yui_source.php | 14 +-- examples/phploader-custom-modules.php | 59 +++++------- examples/phploader-custom-modules_source.php | 30 +++--- examples/phploader-local-combo-handler.php | 4 +- index.php | 2 +- phploader/combo.php | 95 ++++++++++++------- phploader/loader.php | 35 +++---- 15 files changed, 166 insertions(+), 155 deletions(-) diff --git a/CHANGES b/CHANGES index 18a6ea0..23d080d 100644 --- a/CHANGES +++ b/CHANGES @@ -3,3 +3,10 @@ ChangeLog 1.0.0b1 * Initial release + +1.0.0b2 + * Doc cleanup + * Combo script incorrectly exploded the query string on & not &. + * Modified APC/Curl support checks + * Adding APC support for combo.php + * Combo.php was not handling relative image path in the raw css. Now converts to absolute paths. \ No newline at end of file diff --git a/INSTALL b/INSTALL index 06d2d7c..182720f 100644 --- a/INSTALL +++ b/INSTALL @@ -15,21 +15,20 @@ Local Combo Handler Setup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This feature will allow YUI PHP Loader to combine files without relying -on a remote combo-service. The key use case here would be someone -writing their own website/application in PHP. +on a remote combo-service. 1. The main endpoint for combo requests in this case is combo.php. Place this file in the same location as loader.php. Note: If the phploader directory does not live in the webserver's root - folder then modify the $pathToYUILoader variable in combo.php accordingly + folder then modify the PATH_TO_LOADER variable in combo.php accordingly. 2. Download and extract each version of YUI you intend to support into the phploader/lib directory. A valid setup would look something like: + htdocs/phploader/lib/2.8.0r4/build htdocs/phploader/lib/2.7.0/build - htdocs/phploader/lib/2.6.0/build etc... 3. Refer to usage documents and examples: diff --git a/README b/README index 30656d2..c518642 100644 --- a/README +++ b/README @@ -36,8 +36,9 @@ license.txt Open source license details. lib/meta - Contains the YUI module dependency metadata. The latest version is - shipped with each release, but you can manually add additional version. + Contains the YUI module dependency metadata (for versions 2 and 3). + The latest version is shipped with each release, but you can manually + add additional version. phploader/loader.php The main YUI PHP Loader class file diff --git a/examples/index.html b/examples/index.html index a2d4d43..10b86b6 100755 --- a/examples/index.html +++ b/examples/index.html @@ -59,7 +59,7 @@

  • Using PHP Loader to Load the Calendar Control (Basic): This example demonstrates a simple implementation in which we bring in the YUI Calendar Control — and its JavaScript and CSS dependencies — using the PHP Loader Utility.
  • Using PHP Loader to Load the Calendar Control (Advanced): This example demonstrates a more advanced implementation in which we bring in the YUI Calendar Control — and its JavaScript and CSS dependencies — using the PHP Loader Utility. The major difference between this and the previous example is that the CSS and JavaScript are output via separate method calls allowing for more control/optimization.
  • Adding Custom (Non-YUI) Content with PHP Loader: PHP Loader can be used to add YUI components to the page, but it can also be used to add other components that you create yourself (or that you pull from a third-party source). This example shows one simple way to pull in external content with PHP Loader.
  • -
  • Adding Custom Modules with YUI Dependencies: PHP Loader can be used to add YUI components to the page, but it can also be used to add other components that you create yourself (or that you pull from a third-party source). This example shows how to pull in external content that has dependancies on YUI components.
  • +
  • Adding Custom Modules with YUI Dependencies: PHP Loader can be used to add YUI components to the page, but it can also be used to add other components that you create yourself (or that you pull from a third-party source). This example shows how to pull in external content that has dependencies on YUI components.
  • Using the Local Combo Handler: PHP Loader ships with intrinsic combo-handling support. This feature will allow PHP Loader to combine files without relying on a remote combo-service such as the one outlined here. It should also prove useful in environments where SSL is required and/or where including scripts from remote servers is prohibited.
  • diff --git a/examples/phploader-advanced_source.php b/examples/phploader-advanced_source.php index b46813e..b417a7e 100644 --- a/examples/phploader-advanced_source.php +++ b/examples/phploader-advanced_source.php @@ -1,7 +1,7 @@ load("calendar"); diff --git a/examples/phploader-basic.php b/examples/phploader-basic.php index 63ea239..cc6b207 100644 --- a/examples/phploader-basic.php +++ b/examples/phploader-basic.php @@ -34,18 +34,19 @@

    Here's what that looks like in terms of raw source — this is the full source code for this example:

    @@ -76,31 +78,23 @@ include("loader.php"); //Create a custom module metadata set -$customConfig = array( +$customModules = array( "customJS" => array( "name" => 'customJS', "type" => 'js', // 'js' or 'css' - // "path" => 'path/to/file3.css', // includes base "fullpath" => './assets/custom/data.js', // overrides path - "global" => true, // globals are always loaded - "requires" => array (0 => 'event', 1 => 'dom', 2 => 'json'), - // "supersedes" => array (0 => 'something'), // if a rollup - // "rollup" => 3 // the rollup threshold + "requires" => array("event", "dom", "json") ), "customCSS" => array( "name" => 'customCSS', - "type" => 'css', // 'js' or 'css' - // "path" => 'path/to/file3.css', // includes base - "fullpath" => './assets/custom/custom.css', // overrides path - "global" => true, // globals are always loaded - // "supersedes" => array (0 => 'something'), // if a rollup - // "rollup" => 3 // the rollup threshold + "type" => 'css', + "fullpath" => './assets/custom/custom.css' ) ); //Get a new YAHOO_util_Loader instance which includes our custom metadata along with the base YUI metadata //Note: rand is used here to help cache bust the example -$loader = new YAHOO_util_Loader('', 'my_custom_config_'.rand(), $customConfig); +$loader = new YAHOO_util_Loader('', 'my_custom_config_'.rand(), $customModules); $loader->load("customJS", "customCSS"); ?> diff --git a/examples/phploader-custom-modules-with-yui_source.php b/examples/phploader-custom-modules-with-yui_source.php index 9027a27..dd15ab2 100644 --- a/examples/phploader-custom-modules-with-yui_source.php +++ b/examples/phploader-custom-modules-with-yui_source.php @@ -3,31 +3,23 @@ include("../phploader/loader.php"); //Create a custom module metadata set -$customConfig = array( +$customModules = array( "customJS" => array( "name" => 'customJS', "type" => 'js', // 'js' or 'css' - // "path" => 'path/to/file3.css', // includes base "fullpath" => './assets/custom/data.js', // overrides path - "global" => true, // globals are always loaded - "requires" => array (0 => 'event', 1 => 'dom', 2 => 'json'), - // "supersedes" => array (0 => 'something'), // if a rollup - // "rollup" => 3 // the rollup threshold + "requires" => array("event", "dom", "json") ), "customCSS" => array( "name" => 'customCSS', "type" => 'css', // 'js' or 'css' - // "path" => 'path/to/file3.css', // includes base "fullpath" => './assets/custom/custom.css', // overrides path - "global" => true, // globals are always loaded - // "supersedes" => array (0 => 'something'), // if a rollup - // "rollup" => 3 // the rollup threshold ) ); //Get a new YAHOO_util_Loader instance which includes our custom metadata along with the base YUI metadata //Note: rand is used here to help cache bust the example -$loader = new YAHOO_util_Loader($yuiCurrentVersion, 'my_custom_config_'.rand(), $customConfig); +$loader = new YAHOO_util_Loader($yuiCurrentVersion, 'my_custom_config_'.rand(), $customModules); $loader->load("customJS", "customCSS"); ?> diff --git a/examples/phploader-custom-modules.php b/examples/phploader-custom-modules.php index 6b2a92d..6f5f0af 100644 --- a/examples/phploader-custom-modules.php +++ b/examples/phploader-custom-modules.php @@ -27,36 +27,37 @@

    Defining a Custom Module

    - The YAHOO_util_Loader class constructor accepts three parameters: + The YAHOO_util_Loader class constructor accepts four parameters:

      +
    1. yuiVersion: Version of YUI metadata to load
    2. cacheKey: Unique name to use as the APC cache key. Module calculations are cached for performance if the environment supports APC.
    3. -
    4. modules: A list of custom modules
    5. +
    6. modules: An array of custom modules
    7. noYUI: Enable or disable the base YUI metadata

    The modules parameter expects an associative array. The array should consist of custom JavaScript and/or - CSS modules defined using the following format:

    + CSS modules. The modules array format mirrors that of the YUI metadata included with PHP Loader. Use the metadata in the lib/meta folder as + a reference for determining all the possible options. Below is an example of such an array:

    Note: The module names must be unique and should not conflict with any of the existing YUI - component names if you have chosen to leave the YUI metadata enabled. To make a custom module dependant on an existing + component names if you have chosen to leave the YUI metadata enabled. To make a custom module dependent on an existing YUI module simply default a requires key/value pair that lists out the desired YUI components.

    Simple Example with no YUI Dependencies

    @@ -73,37 +74,29 @@ include("loader.php"); //Create a custom module metadata set -$customConfig = array( - "dcJson" => array( - "name" => 'dcJson', +$customModules = array( + "JSONModule" => array( + "name" => 'JSONModule', "type" => 'js', // 'js' or 'css' - // "path" => 'path/to/file.js', // includes base - "fullpath" => 'http://www.json.org/json2.js', // overrides path - // "requires" => array (0 => 'event', 1 => 'dom'), - // "optional" => array (0 => 'connection'), - // "global" => true, // globals are always loaded - // "supersedes" => array (0 => 'something'), // if a rollup - // "rollup" => 3 // the rollup threshold + "fullpath" => 'http://www.json.org/json2.js' // overrides path ), "customJS" => array( "name" => 'customJS', - "type" => 'js', // 'js' or 'css' - "fullpath" => './assets/custom/data.js', // overrides path - "global" => true, // globals are always loaded - "requires" => array (0 => 'dcJson') + "type" => 'js', + "fullpath" => './assets/custom/data.js', + "requires" => array('JSONModule') ), "customCSS" => array( "name" => 'customCSS', - "type" => 'css', // 'js' or 'css' - "fullpath" => './assets/custom/custom.css', // overrides path - "global" => true // globals are always loaded + "type" => 'css', + "fullpath" => './assets/custom/custom.css' ) ); //Get a new YAHOO_util_Loader instance which includes just our custom metadata (No YUI metadata) //Note: rand is used here to help cache bust the example -$loader = new YAHOO_util_Loader('', 'my_custom_config_'.rand(), $customConfig, true); -$loader->load("dcJson", "customJS", "customCSS"); +$loader = new YAHOO_util_Loader('', 'my_custom_config_'.rand(), $customModules, true); +$loader->load("JSONModule", "customJS", "customCSS"); ?> A custom module set is defined
  • An instance of YUI PHP Loader is created: Our custom module set is passed to the Loader
  • YUI PHP Loader calculates the dependencies and order of our custom modules: The Loader knows - our customJS module is dependent on our dcJson module.
  • + our customJS module is dependent on our JSONModule module.
  • YUI PHP Loader loads the modules and is used to output the CSS and JavaScript: The <link> nodes are output in the document head and the <script> nodes are output just before the closing body node. This is in accordance with the best practice performance recommendations outlined here.
  • diff --git a/examples/phploader-custom-modules_source.php b/examples/phploader-custom-modules_source.php index f5e3883..23334a3 100644 --- a/examples/phploader-custom-modules_source.php +++ b/examples/phploader-custom-modules_source.php @@ -3,37 +3,29 @@ include("../phploader/loader.php"); //Create a custom module metadata set -$customConfig = array( - "dcJson" => array( - "name" => 'dcJson', +$customModules = array( + "JSONModule" => array( + "name" => 'JSONModule', "type" => 'js', // 'js' or 'css' - // "path" => 'path/to/file.js', // includes base - "fullpath" => 'http://www.json.org/json2.js', // overrides path - // "requires" => array (0 => 'event', 1 => 'dom'), - // "optional" => array (0 => 'connection'), - // "global" => true, // globals are always loaded - // "supersedes" => array (0 => 'something'), // if a rollup - // "rollup" => 3 // the rollup threshold + "fullpath" => 'http://www.json.org/json2.js' // overrides path ), "customJS" => array( "name" => 'customJS', - "type" => 'js', // 'js' or 'css' - "fullpath" => './assets/custom/data.js', // overrides path - "global" => true, // globals are always loaded - "requires" => array (0 => 'dcJson') + "type" => 'js', + "fullpath" => './assets/custom/data.js', + "requires" => array('JSONModule') ), "customCSS" => array( "name" => 'customCSS', - "type" => 'css', // 'js' or 'css' - "fullpath" => './assets/custom/custom.css', // overrides path - "global" => true // globals are always loaded + "type" => 'css', + "fullpath" => './assets/custom/custom.css' ) ); //Get a new YAHOO_util_Loader instance which includes just our custom metadata (No YUI metadata) //Note: rand is used here to help cache bust the example -$loader = new YAHOO_util_Loader($yuiCurrentVersion, 'my_custom_config_'.rand(), $customConfig, true); -$loader->load("dcJson", "customJS", "customCSS"); +$loader = new YAHOO_util_Loader($yuiCurrentVersion, 'my_custom_config_'.rand(), $customModules, true); +$loader->load("JSONModule", "customJS", "customCSS"); ?> This example implements the YUI PHP Loader Utility to load the Calendar Control. This example is almost identical to the advanced example -outlined here. The only major difference is that we are enabling the combo handling service and overriding the +outlined here. The only major difference is that we are enabling the combo handling service and overriding the default the combo service location. By default when combo handling is requested YUI PHP Loader will serve files from Yahoo! servers; see "Serving YUI Files from Yahoo!" for important information about this service.

    @@ -56,7 +56,7 @@

    This example implements the YUI PHP Loader Utility to load the Calendar Control. This example is almost identical to the -advanced example outlined here. The only major difference is that we are +advanced example outlined here. The only major difference is that we are enabling the combo handling service and overriding the default the combo service location. By default when combo handling is requested YUI PHP Loader will serve files from Yahoo! servers; see "Serving YUI Files from Yahoo!" for important information diff --git a/index.php b/index.php index 7906665..2e59360 100644 --- a/index.php +++ b/index.php @@ -61,7 +61,7 @@

    diff --git a/phploader/combo.php b/phploader/combo.php index 625e9dc..9c0ba4d 100644 --- a/phploader/combo.php +++ b/phploader/combo.php @@ -21,13 +21,17 @@ the phploader/lib directory. A valid setup would look something like: + htdocs/phploader/lib/2.8.0r4/build htdocs/phploader/lib/2.7.0/build - htdocs/phploader/lib/2.6.0/build etc... */ //Web accessible path to the YUI PHP loader lib directory (Override as needed) -define("PATH_TO_LOADER", server() . "/phploader/phploader/lib/"); +define("PATH_TO_LOADER", server() . "/phploader/lib/"); + +//APC Configuration +define("APC_AVAIL", function_exists('apc_fetch') ? true : false); +define("APC_TTL", 0); //server(): Computes the base URL of the current page (protocol, server, path) //credit: http://code.google.com/p/simple-php-framework/ (modified version of full_url), license: MIT @@ -41,45 +45,70 @@ function server() $queryString = getenv('QUERY_STRING') ? urldecode(getenv('QUERY_STRING')) : ''; if (isset($queryString) && !empty($queryString)) { - $yuiFiles = explode("&", $queryString); + $yuiFiles = explode("&", $queryString); $contentType = strpos($yuiFiles[0], ".js") ? 'application/x-javascript' : ' text/css'; - //Use the first module to determine which version of the YUI meta info to load - if (isset($yuiFiles) && !empty($yuiFiles)) { - $metaInfo = explode("/", $yuiFiles[0]); - $yuiVersion = $metaInfo[0]; + $cache = false; + if (APC_AVAIL === true) { + $cache = apc_fetch('combo:'.$queryString); } - include("./loader.php"); - $loader = new YAHOO_util_Loader($yuiVersion); - $base = PATH_TO_LOADER . $loader->comboDefaultVersion . "/build/"; //Defaults to current version + if ($cache) { + //Set cache headers and output cache content + header("Cache-Control: max-age=315360000"); + header("Expires: " . date("D, j M Y H:i:s", strtotime("now + 10 years")) ." GMT"); + header("Content-Type: " . $contentType); + echo $cache; + } else { + //Use the first module to determine which version of the YUI meta info to load + if (isset($yuiFiles) && !empty($yuiFiles)) { + $metaInfo = explode("/", $yuiFiles[0]); + $yuiVersion = $metaInfo[0]; + } - //Detect and load the required components now - $baseOverrides = array(); - $yuiComponents = array(); - foreach($yuiFiles as $yuiFile) { - $parts = explode("/", $yuiFile); - if (isset($parts[0]) && isset($parts[1]) && isset($parts[2])) { - //Add module to array for loading - $yuiComponents[] = $parts[2]; - } else { - die(''); + include("./loader.php"); + $loader = new YAHOO_util_Loader($yuiVersion); + $base = PATH_TO_LOADER . $yuiVersion . "/build/"; + $loader->base = $base; + + //Detect and load the required components now + $yuiComponents = array(); + foreach($yuiFiles as $yuiFile) { + $parts = explode("/", $yuiFile); + if (isset($parts[0]) && isset($parts[1]) && isset($parts[2])) { + //Add module to array for loading + $yuiComponents[] = $parts[2]; + } else { + die(''); + } } - } - - //Load the components - call_user_func_array(array($loader, 'load'), $yuiComponents); - //Set cache headers and output raw file content - header("Cache-Control: max-age=315360000"); - header("Expires: " . date("D, j M Y H:i:s", strtotime("now + 10 years")) ." GMT"); - header("Content-Type: " . $contentType); - if ($contentType == "application/x-javascript") { - echo $loader->script_raw(); - } else { - echo $loader->css_raw(); + //Load the components + call_user_func_array(array($loader, 'load'), $yuiComponents); + + //Set cache headers and output raw file content + header("Cache-Control: max-age=315360000"); + header("Expires: " . date("D, j M Y H:i:s", strtotime("now + 10 years")) ." GMT"); + header("Content-Type: " . $contentType); + if ($contentType == "application/x-javascript") { + $rawScript = $loader->script_raw(); + if (APC_AVAIL === true) { + apc_store('combo:'.$queryString, $rawScript, APC_TTL); + } + echo $rawScript; + } else { + $rawCSS = $loader->css_raw(); + //Handle image path corrections + $rawCSS = preg_replace('/((url\()(\w+)(.*);)/', '${2}'. $base . '${3}${4}', $rawCSS); // subdirs + $rawCSS = preg_replace('/(\.\.\/)+/', $base, $rawCSS); // relative pathes + $rawCSS = str_replace("url(/", "url($base", $rawCSS); // url(/whatever) + + if (APC_AVAIL === true) { + apc_store('combo:'.$queryString, $rawCSS, APC_TTL); + } + echo $rawCSS; + } } - } else { die(''); } diff --git a/phploader/loader.php b/phploader/loader.php index a55072d..040e44d 100644 --- a/phploader/loader.php +++ b/phploader/loader.php @@ -69,7 +69,8 @@ class YAHOO_util_Loader { var $target = ""; /** - * Combined into a single request using the combo service to pontentially reduce the number of http requests required. + * Combined into a single request using the combo service to pontentially reduce the number of + * http requests required. This option is not supported when loading custom modules. * @property combine * @type boolean * @default false @@ -224,9 +225,9 @@ function YAHOO_util_Loader($yuiVersion, $cacheKey=null, $modules=null, $noYUI=fa $this->curlAvail = function_exists('curl_exec'); $this->apcAvail = function_exists('apc_fetch'); $this->jsonAvail = function_exists('json_encode'); - $this->embedAvail = ($this->curlAvail && $this->apcAvail); + $this->customModulesInUse = empty($modules) ? false : true; $this->base = $yui_current[YUI_BASE]; - $this->comboDefaultVersion = $yuiVersion; //(ex) 2.7.0 + $this->comboDefaultVersion = $yuiVersion; //$customModules $this->fullCacheKey = null; $cache = null; @@ -866,9 +867,6 @@ function sortDependencies($moduleType, $skipSort=false) { $reqs[$name] = true; } - //print_r($this->requests); - //return; - // get and store the full list of dependencies. foreach ($this->requests as $name=>$val) { $reqs[$name] = true; @@ -1208,8 +1206,8 @@ function processDependencies($outputType, $moduleType, $skipSort=false, $showLoa $item[YUI_OPTIONAL] = $dep[YUI_OPTIONAL]; break; case YUI_TAGS: - default: - if ($this->combine === true) { + default: + if ($this->combine === true && $this->customModulesInUse === false) { $this->addToCombo($name, $dep[YUI_TYPE]); $html = $this->getComboLink($dep[YUI_TYPE]); } else { @@ -1306,8 +1304,11 @@ function getUrl($name) { * @return */ function getRemoteContent($url) { - - $remote_content = apc_fetch($url); + + $remote_content = null; + if ($this->apcAvail === true) { + $remote_content = apc_fetch($url); + } if (!$remote_content) { @@ -1330,7 +1331,9 @@ function getRemoteContent($url) { //$this->log("CONTENT: " . $remote_content); // save the contents of the remote url for 30 minutes - apc_store($url, $remote_content, $this->apcttl); + if ($this->apcAvail === true) { + apc_store($url, $remote_content, $this->apcttl); + } curl_close ($ch); } @@ -1338,9 +1341,9 @@ function getRemoteContent($url) { return $remote_content; } - function getRaw($name) { - if (!$this->embedAvail) { - return "cURL and/or APC was not detected, so the content can't be embedded"; + function getRaw($name) { + if(!$this->curlAvail) { + return ""; } $url = $this->getUrl($name); @@ -1349,8 +1352,8 @@ function getRaw($name) { function getContent($name, $type) { - if(!$this->embedAvail) { - return "" . $this->getLink($name, $type); + if(!$this->curlAvail) { + return "" . $this->getLink($name, $type); } $url = $this->getUrl($name);