? .cvsignore
? .project
Index: libraries.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/libraries/libraries.api.php,v
retrieving revision 1.5
diff -u -p -r1.5 libraries.api.php
--- libraries.api.php	3 Nov 2010 22:22:42 -0000	1.5
+++ libraries.api.php	15 Dec 2010 22:30:18 -0000
@@ -22,16 +22,30 @@
  *     the actual library files in a sub-directory.
  *   - library path: (optional) The absolute path to the library directory. This
  *     should not be declared normally, as it is automatically detected, to
- *     allow for multiple possible library locations. A valid use-case is an
- *     external library, in which case the full URL to the library should be
- *     specified here.
- *   - version callback: (optional) The name of a function that detects and
- *     returns the full version string of the library. The first argument is
- *     always $library, an array containing all library information as described
- *     here. There are two ways to declare the version callback's additional
- *     arguments, either as a single $options parameter or as multiple
- *     parameters, which correspond to the two ways to specify the argument
- *     values (see 'version arguments'). Defaults to libraries_get_version().
+ *     allow for multiple possible library locations. A valid use-case is a
+ *     library that is only available externally, in which case the full URL to
+ *     the library should be specified here.
+ *   - location callback: (optional) A callback to determine the location of the
+ *     library. The first argument is always $name, a string containing the name
+ *     of the library. There are two ways to declare the location callback's
+ *     additional arguments, either as a single $options parameter or as
+ *     multiple parameters, which correspond to the two ways to specify the
+ *     argument values (see 'location arguments'). Defaults to
+ *     'libraries_get_path'.
+ *   - location arguments: (optional) A list of arguments to pass to the
+ *     location callback. Location arguments can be declared either as an
+ *     associative array whose keys are the argument names or as an indexed
+ *     array without specifying keys. If declared as an associative array, the
+ *     arguments get passed to the location callback as a single $options
+ *     parameter whose keys are the argument names (i.e. $options is identical
+ *     to the specified array). If declared as an indexed array, the array
+ *     values get passed to the version callback as seperate arguments in the
+ *     order they were declared. The default location callback
+ *     'libraries_get_path' takes no arguments by default. Libraries that are
+ *     available both locally and remotely can provide an indexed array with the
+ *     only value being the remote path at which the library is available.
+ *     libraries_get_path() will then use the specified remote path in case the
+ *     library is not found locally.
  *   - version: (optional) The version of the library. This should not be
  *     declared normally, as it is automatically detected (see 'version
  *     callback' below) to allow for version changes of libraries without code
@@ -39,6 +53,13 @@
  *     library simultaneously (though only one version can be installed per
  *     site). A valid use-case is an external library whose version cannot be
  *     determined programatically.
+ *   - version callback: (optional) The name of a function that detects and
+ *     returns the full version string of the library. The first argument is
+ *     always $library, an array containing all library information as described
+ *     here. There are two ways to declare the version callback's additional
+ *     arguments, either as a single $options parameter or as multiple
+ *     parameters, which correspond to the two ways to specify the argument
+ *     values (see 'version arguments'). Defaults to libraries_get_version().
  *   - version arguments: A list of arguments to pass to the version callback.
  *     Version arguments can be declared either as an associative array whose
  *     keys are the argument names or as an indexed array without specifying
@@ -114,7 +135,7 @@ function hook_libraries_info() {
   // directory, which should contain the entire, original extracted library.
   $libraries['example'] = array(
     // Only used in administrative UI of Libraries API.
-    'title' => 'Example library',
+    'name' => 'Example library',
     'vendor url' => 'http://example.com',
     'download url' => 'http://example.com/download',
     // Optional: If, after extraction, the actual library files are contained in
@@ -226,7 +247,7 @@ function hook_libraries_info() {
   // A very simple library. No changing APIs (hence, no versions), no variants.
   // Expected to be extracted into 'sites/all/libraries/simple'.
   $libraries['simple'] = array(
-    'title' => 'Simple library',
+    'name' => 'Simple library',
     'vendor url' => 'http://example.com/simple',
     'download url' => 'http://example.com/simple',
     'version arguments' => array(
@@ -245,7 +266,7 @@ function hook_libraries_info() {
 
   // A library that (naturally) evolves over time with API changes.
   $libraries['tinymce'] = array(
-    'title' => 'TinyMCE',
+    'name' => 'TinyMCE',
     'vendor url' => 'http://tinymce.moxiecode.com',
     'download url' => 'http://tinymce.moxiecode.com/download.php',
     'path' => 'jscripts/tiny_mce',
@@ -323,6 +344,49 @@ function hook_libraries_info() {
       ),
     ),
   );
+
+  // A simple external library.
+  $libraries['external'] = array(
+    'name' => 'External library',
+    // This library does not have a download url!
+    'vendor url' => 'http://example.com/external',
+    // It is only availably externally so we must declare the library path.
+    'library path' => 'http://example.com/external/source',
+    // The version cannot be detected programmatically, so it must be declared
+    // upfront.
+    'version' => '1.0.1',
+    // The library only consists of one file, which is located at
+    // http://example.com/external/source/external.js. We have already declared
+    // the library path above, so we only need to specify the filename here.
+    'files' => array(
+      'js' => array(
+        'external.js',
+      ),
+    ),
+  );
+
+  // A library that is both available locally and externally, i.e. you can
+  // download it to your server for performance or use the online version for
+  // convenience.
+  $libraries['openlayers'] = array(
+    'name' => 'OpenLayers',
+    'vendor url' => 'http://openlayers.org/',
+    'download url' => 'http://trac.osgeo.org/openlayers/wiki/HowToDownload',
+    // Because we want people to be able to use the library locally, but fall
+    // back to the external library, we declare the optional $remote_path
+    // argument for libraries_get_path(). The path we specify is then used as a
+    // fall back, if the library is not found locally.
+    'location arguments' => array(
+      'http://openlayers.org/api',
+    ),
+    // Regardless of whether it is available locally or externally, the files
+    // are the same.
+    'files' => array(
+      'js' => array(
+        'OpenLayers.js',
+      ),
+    ),
+  );
   return $libraries;
 }
 
Index: libraries.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/libraries/libraries.module,v
retrieving revision 1.16
diff -u -p -r1.16 libraries.module
--- libraries.module	15 Dec 2010 21:09:52 -0000	1.16
+++ libraries.module	15 Dec 2010 22:30:19 -0000
@@ -11,32 +11,28 @@
  *
  * @param $name
  *   The machine name of a library to return the path for.
- * @param $base_path
- *   Whether to prefix the resulting path with base_path().
+ * @param $remote_path
+ *   (optional) In case the library is not found locally, a remote path where it
+ *   is available.
  *
  * @return
- *   The path to the specified library.
+ *   The path to the specified library or FALSE if it is not found.
  *
  * @ingroup libraries
  */
-function libraries_get_path($name, $base_path = FALSE) {
+function libraries_get_path($name, $remote_path = NULL) {
   $libraries = &drupal_static(__FUNCTION__);
 
   if (!isset($libraries)) {
     $libraries = libraries_get_libraries();
   }
 
-  $path = ($base_path ? base_path() : '');
   if (!isset($libraries[$name])) {
-    // Most often, external libraries can be shared across multiple sites, so
-    // we return sites/all/libraries as the default path.
-    $path .= 'sites/all/libraries/' . $name;
+    return (!empty($remote_path) ? $remote_path : FALSE);
   }
   else {
-    $path .= $libraries[$name];
+    return $libraries[$name];
   }
-
-  return $path;
 }
 
 /**
@@ -264,14 +260,15 @@ function libraries_detect_library(&$libr
 
   // Check whether the library exists.
   if (!isset($library['library path'])) {
-    $library['library path'] = libraries_get_path($name);
-  }
-  if (!file_exists($library['library path'])) {
-    $library['error'] = 'not found';
-    $library['error message'] = t('%library could not be found.', array(
-      '%library' => $library['name'],
-    ));
-    return;
+    // We support both a single parameter, which is an associative array, and an
+    // indexed array of multiple parameters.
+    if (isset($library['location arguments'][0])) {
+      // Add the library as the first argument.
+      $library['library path'] = call_user_func_array($library['location callback'], array_merge(array($name), $library['location arguments']));
+    }
+    else {
+      $library['library path'] = $library['location callback']($name, $library['location arguments']);
+    } 
   }
 
   // Detect library version, if not hardcoded.
@@ -418,9 +415,10 @@ function libraries_load_files($library) 
         // If the value is not an array, it's a filename and passed as first
         // (and only) argument.
         if (!is_array($options)) {
-          // Prepend the library path to the file name.
           $data = "$path/$options";
-          $options = NULL;
+          // This is needed because drupal_add_css() does not detect external
+          // paths automatically. See http://drupal.org/node/953340
+          $options = (url_is_external($data) ? array('type' => 'external') : NULL);
         }
         // In some cases, the first parameter ($data) is an array. Arrays can't
         // be passed as keys in PHP, so we have to get $data from the value
@@ -442,9 +440,9 @@ function libraries_load_files($library) 
   // Load PHP files.
   if (!empty($library['files']['php'])) {
     foreach ($library['files']['php'] as $file) {
-      $file_path = DRUPAL_ROOT . '/' . $path . '/' . $file;
-      if (file_exists($file_path)) {
-        require_once $file_path;
+      $filepath = (url_is_external($file) ? $file : DRUPAL_ROOT . '/' . $path . '/' . $file);
+      if (url_is_external($filepath) || file_exists($filepath)) {
+        include_once $filepath;
         $count++;
       }
     }
@@ -484,11 +482,12 @@ function libraries_get_version($library,
     'cols' => 200,
   );
 
-  $file = DRUPAL_ROOT . '/' . $library['library path'] . '/' . $options['file'];
-  if (empty($options['file']) || !file_exists($file)) {
+  $filepath = $library['library path'] . '/' . $options['file'];
+  $filepath = (url_is_external($filepath) ? $filepath : DRUPAL_ROOT . '/' . $filepath);
+  if (empty($options['file']) || (!url_is_external($filepath) && !file_exists($filepath))) {
     return;
   }
-  $file = fopen($file, 'r');
+  $file = fopen($filepath, 'r');
   while ($options['lines'] && $line = fgets($file, $options['cols'])) {
     if (preg_match($options['pattern'], $line, $version)) {
       fclose($file);
