| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080 | 
							- <?php
 
- /**
 
-  * @file
 
-  * External library handling for Drupal modules.
 
-  */
 
- /**
 
-  * Implements hook_flush_caches().
 
-  */
 
- function libraries_flush_caches() {
 
-   // Clear static caches.
 
-   // We don't clear the 'libraries_load' static cache, because that could result
 
-   // in libraries that had been loaded before the cache flushing to be loaded
 
-   // again afterwards.
 
-   foreach (array('libraries_get_path', 'libraries_info') as $name) {
 
-     drupal_static_reset($name);
 
-   }
 
-   // @todo When upgrading from 1.x, update.php attempts to flush caches before
 
-   //   the cache table has been created.
 
-   // @see http://drupal.org/node/1477932
 
-   if (db_table_exists('cache_libraries')) {
 
-     return array('cache_libraries');
 
-   }
 
- }
 
- /**
 
-  * Implements hook_admin_menu_cache_info().
 
-  */
 
- function libraries_admin_menu_cache_info() {
 
-   $caches['libraries'] = array(
 
-     'title' => t('Libraries'),
 
-     'callback' => 'libraries_cache_clear',
 
-   );
 
-   return $caches;
 
- }
 
- /**
 
-  * Clears the cached library information.
 
-  */
 
- function libraries_cache_clear() {
 
-   foreach (libraries_flush_caches() as $bin) {
 
-     // Using the wildcard argument leads to DrupalDatabaseCache::clear()
 
-     // truncating the libraries cache table which is more performant that
 
-     // deleting the rows.
 
-     cache_clear_all('*', $bin, TRUE);
 
-   }
 
- }
 
- /**
 
-  * Gets the path of a library.
 
-  *
 
-  * @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().
 
-  *
 
-  * @return string
 
-  *   The path to the specified library or FALSE if the library wasn't found.
 
-  *
 
-  * @ingroup libraries
 
-  */
 
- function libraries_get_path($name, $base_path = FALSE) {
 
-   $libraries = &drupal_static(__FUNCTION__);
 
-   if (!isset($libraries)) {
 
-     $libraries = libraries_get_libraries();
 
-   }
 
-   $path = ($base_path ? base_path() : '');
 
-   if (!isset($libraries[$name])) {
 
-     return FALSE;
 
-   }
 
-   else {
 
-     $path .= $libraries[$name];
 
-   }
 
-   return $path;
 
- }
 
- /**
 
-  * Returns all enabled themes.
 
-  *
 
-  * Themes are sorted so that base themes always precede their child themes.
 
-  *
 
-  * @return array
 
-  *   An associative array of theme objects keyed by theme name.
 
-  */
 
- function libraries_get_enabled_themes() {
 
-   $themes = array();
 
-   foreach (list_themes() as $name => $theme) {
 
-     if ($theme->status) {
 
-       $themes[$name] = $theme;
 
-     }
 
-   }
 
-   return libraries_sort_themes($themes);
 
- }
 
- /**
 
-  * Sort a themes array.
 
-  *
 
-  * @param array $themes
 
-  *   Array of themes as objects, keyed by theme name.
 
-  * @param string $base
 
-  *   A base theme (internal use only).
 
-  *
 
-  * @return array
 
-  *   A similar array to $themes, but sorted in such a way that subthemes are
 
-  *   always located after its base theme.
 
-  */
 
- function libraries_sort_themes($themes, $base = '') {
 
-   $output = array();
 
-   foreach ($themes as $name => $theme) {
 
-     if (!isset($theme->base_theme) || $theme->base_theme == $base) {
 
-       $output[$name] = $theme;
 
-       unset($themes[$name]);
 
-       $subthemes = libraries_sort_themes($themes, $name);
 
-       foreach ($subthemes as $sub_name => $subtheme) {
 
-         $output[$sub_name] = $subtheme;
 
-       }
 
-     }
 
-   }
 
-   return $output;
 
- }
 
- /**
 
-  * Returns an array of library directories.
 
-  *
 
-  * Returns an array of library directories from the all-sites directory
 
-  * (i.e. sites/all/libraries/), the profiles directory, and site-specific
 
-  * directory (i.e. sites/somesite/libraries/). The returned array will be keyed
 
-  * by the library name. Site-specific libraries are prioritized over libraries
 
-  * in the default directories. That is, if a library with the same name appears
 
-  * in both the site-wide directory and site-specific directory, only the
 
-  * site-specific version will be listed.
 
-  *
 
-  * @return array
 
-  *   A list of library directories.
 
-  *
 
-  * @ingroup libraries
 
-  */
 
- function libraries_get_libraries() {
 
-   $searchdir = array();
 
-   $profile = drupal_get_path('profile', drupal_get_profile());
 
-   $config = conf_path();
 
-   // $config and $profile should never be empty in a proper Drupal setup.
 
-   // However, we should never search into the root filesystem under any
 
-   // circumstances, so just bail out in that case.
 
-   if (!$profile && !$config) {
 
-     return array();
 
-   }
 
-   // Similar to 'modules' and 'themes' directories in the root directory,
 
-   // certain distributions may want to place libraries into a 'libraries'
 
-   // directory in Drupal's root directory.
 
-   $searchdir[] = 'libraries';
 
-   // Similar to 'modules' and 'themes' directories inside an installation
 
-   // profile, installation profiles may want to place libraries into a
 
-   // 'libraries' directory.
 
-   $searchdir[] = "$profile/libraries";
 
-   // Always search sites/all/libraries.
 
-   $searchdir[] = 'sites/all/libraries';
 
-   // Also search sites/<domain>/*.
 
-   $searchdir[] = "$config/libraries";
 
-   // Retrieve list of directories.
 
-   $directories = array();
 
-   $nomask = array('CVS');
 
-   foreach ($searchdir as $dir) {
 
-     if (is_dir($dir) && $handle = opendir($dir)) {
 
-       while (FALSE !== ($file = readdir($handle))) {
 
-         if (!in_array($file, $nomask) && $file[0] != '.') {
 
-           if (is_dir("$dir/$file")) {
 
-             $directories[$file] = "$dir/$file";
 
-           }
 
-         }
 
-       }
 
-       closedir($handle);
 
-     }
 
-   }
 
-   return $directories;
 
- }
 
- /**
 
-  * Looks for library info files.
 
-  *
 
-  * This function scans the following directories for info files:
 
-  * - libraries
 
-  * - profiles/$profilename/libraries
 
-  * - sites/all/libraries
 
-  * - sites/$sitename/libraries
 
-  * - any directories specified via hook_libraries_info_file_paths()
 
-  *
 
-  * @return array
 
-  *   An array of info files, keyed by library name. The values are the paths of
 
-  *   the files.
 
-  */
 
- function libraries_scan_info_files() {
 
-   $profile = drupal_get_path('profile', drupal_get_profile());
 
-   $config = conf_path();
 
-   // Build a list of directories.
 
-   $directories = module_invoke_all('libraries_info_file_paths');
 
-   $directories[] = 'libraries';
 
-   $directories[] = "$profile/libraries";
 
-   $directories[] = 'sites/all/libraries';
 
-   $directories[] = "$config/libraries";
 
-   // Scan for info files.
 
-   $files = array();
 
-   foreach ($directories as $dir) {
 
-     if (file_exists($dir)) {
 
-       $files = array_merge($files, file_scan_directory($dir, '@^[A-Za-z0-9._-]+\.libraries\.info$@', array(
 
-         'key' => 'name',
 
-         'recurse' => FALSE,
 
-       )));
 
-     }
 
-   }
 
-   foreach ($files as $filename => $file) {
 
-     $files[basename($filename, '.libraries')] = $file;
 
-     unset($files[$filename]);
 
-   }
 
-   return $files;
 
- }
 
- /**
 
-  * Invokes library callbacks.
 
-  *
 
-  * @param $group
 
-  *   A string containing the group of callbacks that is to be applied. Should be
 
-  *   either 'info', 'pre-detect', 'post-detect', or 'load'.
 
-  * @param $library
 
-  *   An array of library information, passed by reference.
 
-  */
 
- function libraries_invoke($group, &$library) {
 
-   // When introducing new callback groups in newer versions, stale cached
 
-   // library information somehow reaches this point during the database update
 
-   // before clearing the library cache.
 
-   if (empty($library['callbacks'][$group])) {
 
-     return;
 
-   }
 
-   foreach ($library['callbacks'][$group] as $callback) {
 
-     libraries_traverse_library($library, $callback);
 
-   }
 
- }
 
- /**
 
-  * Helper function to apply a callback to all parts of a library.
 
-  *
 
-  * Because library declarations can include variants and versions, and those
 
-  * version declarations can in turn include variants, modifying e.g. the 'files'
 
-  * property everywhere it is declared can be quite cumbersome, in which case
 
-  * this helper function is useful.
 
-  *
 
-  * @param $library
 
-  *   An array of library information, passed by reference.
 
-  * @param $callback
 
-  *   A string containing the callback to apply to all parts of a library.
 
-  */
 
- function libraries_traverse_library(&$library, $callback) {
 
-   // Always apply the callback to the top-level library.
 
-   $callback($library, NULL, NULL);
 
-   // Apply the callback to versions.
 
-   if (isset($library['versions'])) {
 
-     foreach ($library['versions'] as $version_string => &$version) {
 
-       $callback($version, $version_string, NULL);
 
-       // Versions can include variants as well.
 
-       if (isset($version['variants'])) {
 
-         foreach ($version['variants'] as $version_variant_name => &$version_variant) {
 
-           $callback($version_variant, $version_string, $version_variant_name);
 
-         }
 
-       }
 
-     }
 
-   }
 
-   // Apply the callback to variants.
 
-   if (isset($library['variants'])) {
 
-     foreach ($library['variants'] as $variant_name => &$variant) {
 
-       $callback($variant, NULL, $variant_name);
 
-     }
 
-   }
 
- }
 
- /**
 
-  * Library info callback to make all 'files' properties consistent.
 
-  *
 
-  * This turns libraries' file information declared as e.g.
 
-  * @code
 
-  * $library['files']['js'] = array('example_1.js', 'example_2.js');
 
-  * @endcode
 
-  * into
 
-  * @code
 
-  * $library['files']['js'] = array(
 
-  *   'example_1.js' => array(),
 
-  *   'example_2.js' => array(),
 
-  * );
 
-  * @endcode
 
-  * It does the same for the 'integration files' property.
 
-  *
 
-  * @param $library
 
-  *   An associative array of library information or a part of it, passed by
 
-  *   reference.
 
-  * @param $version
 
-  *   If the library information belongs to a specific version, the version
 
-  *   string. NULL otherwise.
 
-  * @param $variant
 
-  *   If the library information belongs to a specific variant, the variant name.
 
-  *   NULL otherwise.
 
-  *
 
-  * @see libraries_info()
 
-  * @see libraries_invoke()
 
-  */
 
- function libraries_prepare_files(&$library, $version = NULL, $variant = NULL) {
 
-   // Both the 'files' property and the 'integration files' property contain file
 
-   // declarations, and we want to make both consistent.
 
-   $file_types = array();
 
-   if (isset($library['files'])) {
 
-     $file_types[] = &$library['files'];
 
-   }
 
-   if (isset($library['integration files'])) {
 
-     // Integration files are additionally keyed by module.
 
-     foreach ($library['integration files'] as &$integration_files) {
 
-       $file_types[] = &$integration_files;
 
-     }
 
-   }
 
-   foreach ($file_types as &$files) {
 
-     // Go through all supported types of files.
 
-     foreach (array('js', 'css', 'php') as $type) {
 
-       if (isset($files[$type])) {
 
-         foreach ($files[$type] as $key => $value) {
 
-           // Unset numeric keys and turn the respective values into keys.
 
-           if (is_numeric($key)) {
 
-             $files[$type][$value] = array();
 
-             unset($files[$type][$key]);
 
-           }
 
-         }
 
-       }
 
-     }
 
-   }
 
- }
 
- /**
 
-  * Library post-detect callback to process and detect dependencies.
 
-  *
 
-  * It checks whether each of the dependencies of a library are installed and
 
-  * available in a compatible version.
 
-  *
 
-  * @param $library
 
-  *   An associative array of library information or a part of it, passed by
 
-  *   reference.
 
-  * @param $version
 
-  *   If the library information belongs to a specific version, the version
 
-  *   string. NULL otherwise.
 
-  * @param $variant
 
-  *   If the library information belongs to a specific variant, the variant name.
 
-  *   NULL otherwise.
 
-  *
 
-  * @see libraries_info()
 
-  * @see libraries_invoke()
 
-  */
 
- function libraries_detect_dependencies(&$library, $version = NULL, $variant = NULL) {
 
-   if (isset($library['dependencies'])) {
 
-     foreach ($library['dependencies'] as &$dependency_string) {
 
-       $dependency_info = drupal_parse_dependency($dependency_string);
 
-       $dependency = libraries_detect($dependency_info['name']);
 
-       if (!$dependency['installed']) {
 
-         $library['installed'] = FALSE;
 
-         $library['error'] = 'missing dependency';
 
-         $library['error message'] = t('The %dependency library, which the %library library depends on, is not installed.', array(
 
-           '%dependency' => $dependency['name'],
 
-           '%library' => $library['name'],
 
-         ));
 
-       }
 
-       elseif (drupal_check_incompatibility($dependency_info, $dependency['version'])) {
 
-         $library['installed'] = FALSE;
 
-         $library['error'] = 'incompatible dependency';
 
-         $library['error message'] = t('The version %dependency_version of the %dependency library is not compatible with the %library library.', array(
 
-           '%dependency_version' => $dependency['version'],
 
-           '%dependency' => $dependency['name'],
 
-           '%library' => $library['name'],
 
-         ));
 
-       }
 
-       // Remove the version string from the dependency, so libraries_load() can
 
-       // load the libraries directly.
 
-       $dependency_string = $dependency_info['name'];
 
-     }
 
-   }
 
- }
 
- /**
 
-  * Returns information about registered libraries.
 
-  *
 
-  * The returned information is unprocessed; i.e., as registered by modules.
 
-  *
 
-  * @param $name
 
-  *   (optional) The machine name of a library to return registered information
 
-  *   for. If omitted, information about all registered libraries is returned.
 
-  *
 
-  * @return array|false
 
-  *   An associative array containing registered information for all libraries,
 
-  *   the registered information for the library specified by $name, or FALSE if
 
-  *   the library $name is not registered.
 
-  *
 
-  * @see hook_libraries_info()
 
-  *
 
-  * @todo Re-introduce support for include file plugin system - either by copying
 
-  *   Wysiwyg's code, or directly switching to CTools.
 
-  */
 
- function &libraries_info($name = NULL) {
 
-   // This static cache is re-used by libraries_detect() to save memory.
 
-   $libraries = &drupal_static(__FUNCTION__);
 
-   if (!isset($libraries)) {
 
-     $libraries = array();
 
-     // Gather information from hook_libraries_info() in enabled modules.
 
-     foreach (module_implements('libraries_info') as $module) {
 
-       foreach (module_invoke($module, 'libraries_info') as $machine_name => $properties) {
 
-         $properties['info type'] = 'module';
 
-         $properties['module'] = $module;
 
-         $libraries[$machine_name] = $properties;
 
-       }
 
-     }
 
-     // Gather information from hook_libraries_info() in enabled themes. Themes
 
-     // are sorted to ensure that a base theme's template.php is included before
 
-     // its children's ones.
 
-     $themes = array();
 
-     foreach (libraries_get_enabled_themes() as $theme_name => $theme_info) {
 
-       if (file_exists(drupal_get_path('theme', $theme_name) . '/template.php')) {
 
-         // Collect a list of viable themes for re-use when calling the alter
 
-         // hook.
 
-         $themes[] = $theme_name;
 
-         include_once drupal_get_path('theme', $theme_name) . '/template.php';
 
-         $function = $theme_name . '_libraries_info';
 
-         if (function_exists($function)) {
 
-           foreach ($function() as $machine_name => $properties) {
 
-             $properties['info type'] = 'theme';
 
-             $properties['theme'] = $theme_name;
 
-             $libraries[$machine_name] = $properties;
 
-           }
 
-         }
 
-       }
 
-     }
 
-     // Gather information from .info files.
 
-     // .info files override module definitions.
 
-     foreach (libraries_scan_info_files() as $machine_name => $file) {
 
-       $properties = drupal_parse_info_file($file->uri);
 
-       $properties['info type'] = 'info file';
 
-       $properties['info file'] = $file->uri;
 
-       $libraries[$machine_name] = $properties;
 
-     }
 
-     // Provide defaults.
 
-     foreach ($libraries as $machine_name => &$properties) {
 
-       libraries_info_defaults($properties, $machine_name);
 
-     }
 
-     // Allow enabled modules and themes to alter the registered libraries.
 
-     // drupal_alter() only takes the currently active theme into account, not
 
-     // all enabled themes.
 
-     foreach (module_implements('libraries_info_alter') as $module) {
 
-       $function = $module . '_libraries_info_alter';
 
-       $function($libraries);
 
-     }
 
-     foreach ($themes as $theme) {
 
-       $function = $theme . '_libraries_info_alter';
 
-       // The template.php file was included above.
 
-       if (function_exists($function)) {
 
-         $function($libraries);
 
-       }
 
-     }
 
-     // Invoke callbacks in the 'info' group.
 
-     foreach ($libraries as &$properties) {
 
-       libraries_invoke('info', $properties);
 
-     }
 
-   }
 
-   if (isset($name)) {
 
-     if (!empty($libraries[$name])) {
 
-       return $libraries[$name];
 
-     }
 
-     else {
 
-       $false = FALSE;
 
-       return $false;
 
-     }
 
-   }
 
-   return $libraries;
 
- }
 
- /**
 
-  * Applies default properties to a library definition.
 
-  *
 
-  * @param array $library
 
-  *   An array of library information, passed by reference.
 
-  * @param string $name
 
-  *   The machine name of the passed-in library.
 
-  *
 
-  * @return array
 
-  *   The library information array with defaults populated.
 
-  */
 
- function libraries_info_defaults(array &$library, $name) {
 
-   $library += array(
 
-     'machine name' => $name,
 
-     'name' => $name,
 
-     'vendor url' => '',
 
-     'download url' => '',
 
-     'download file url' => '',
 
-     'path' => '',
 
-     'library path' => NULL,
 
-     'version callback' => 'libraries_get_version',
 
-     'version arguments' => array(),
 
-     'files' => array(),
 
-     'dependencies' => array(),
 
-     'variants' => array(),
 
-     'versions' => array(),
 
-     'integration files' => array(),
 
-     'callbacks' => array(),
 
-     // @todo Remove in 7.x-3.x
 
-     'post-load integration files' => FALSE,
 
-   );
 
-   $library['callbacks'] += array(
 
-     'info' => array(),
 
-     'pre-detect' => array(),
 
-     'post-detect' => array(),
 
-     'pre-dependencies-load' => array(),
 
-     'pre-load' => array(),
 
-     'post-load' => array(),
 
-   );
 
-   // Add our own callbacks before any others.
 
-   array_unshift($library['callbacks']['info'], 'libraries_prepare_files');
 
-   array_unshift($library['callbacks']['post-detect'], 'libraries_detect_dependencies');
 
-   return $library;
 
- }
 
- /**
 
-  * Tries to detect a library and its installed version.
 
-  *
 
-  * @param string $name
 
-  *   (optional) The machine name of a library to detect and return registered
 
-  *   information for. If omitted, information about all registered libraries is
 
-  *   returned.
 
-  *
 
-  * @return array|false
 
-  *   An associative array containing registered information for all libraries,
 
-  *   the registered information for the library specified by $name, or FALSE if
 
-  *   the library $name is not registered.
 
-  *   In addition to the keys returned by libraries_info(), the following keys
 
-  *   are contained:
 
-  *   - installed: A boolean indicating whether the library is installed. Note
 
-  *     that not only the top-level library, but also each variant contains this
 
-  *     key.
 
-  *   - version: If the version could be detected, the full version string.
 
-  *   - error: If an error occurred during library detection, one of the
 
-  *     following error statuses: "not found", "not detected", "not supported".
 
-  *   - error message: If an error occurred during library detection, a detailed
 
-  *     error message.
 
-  *
 
-  * @see libraries_info()
 
-  */
 
- function libraries_detect($name = NULL) {
 
-   if (!isset($name)) {
 
-     $libraries = &libraries_info();
 
-     foreach ($libraries as $name => $library) {
 
-       libraries_detect($name);
 
-     }
 
-     return $libraries;
 
-   }
 
-   // Re-use the statically cached value of libraries_info() to save memory.
 
-   $library = &libraries_info($name);
 
-   // Exit early if the library was not found.
 
-   if ($library === FALSE) {
 
-     return $library;
 
-   }
 
-   // If 'installed' is set, library detection ran already.
 
-   if (isset($library['installed'])) {
 
-     return $library;
 
-   }
 
-   $library['installed'] = FALSE;
 
-   // Check whether the library exists.
 
-   if (!isset($library['library path'])) {
 
-     $library['library path'] = libraries_get_path($library['machine name']);
 
-   }
 
-   if ($library['library path'] === FALSE || !file_exists($library['library path'])) {
 
-     $library['error'] = 'not found';
 
-     $library['error message'] = t('The %library library could not be found.', array(
 
-       '%library' => $library['name'],
 
-     ));
 
-     return $library;
 
-   }
 
-   // Invoke callbacks in the 'pre-detect' group.
 
-   libraries_invoke('pre-detect', $library);
 
-   // Detect library version, if not hardcoded.
 
-   if (!isset($library['version'])) {
 
-     // We support both a single parameter, which is an associative array, and an
 
-     // indexed array of multiple parameters.
 
-     if (isset($library['version arguments'][0])) {
 
-       // Add the library as the first argument.
 
-       $library['version'] = call_user_func_array($library['version callback'], array_merge(array($library), $library['version arguments']));
 
-     }
 
-     else {
 
-       $library['version'] = call_user_func_array($library['version callback'], array(&$library, $library['version arguments']));
 
-     }
 
-     if (empty($library['version'])) {
 
-       $library['error'] = 'not detected';
 
-       $library['error message'] = t('The version of the %library library could not be detected.', array(
 
-         '%library' => $library['name'],
 
-       ));
 
-       return $library;
 
-     }
 
-   }
 
-   // Determine to which supported version the installed version maps.
 
-   if (!empty($library['versions'])) {
 
-     ksort($library['versions']);
 
-     $version = 0;
 
-     foreach ($library['versions'] as $supported_version => $version_properties) {
 
-       if (version_compare($library['version'], $supported_version, '>=')) {
 
-         $version = $supported_version;
 
-       }
 
-     }
 
-     if (!$version) {
 
-       $library['error'] = 'not supported';
 
-       $library['error message'] = t('The installed version %version of the %library library is not supported.', array(
 
-         '%version' => $library['version'],
 
-         '%library' => $library['name'],
 
-       ));
 
-       return $library;
 
-     }
 
-     // Apply version specific definitions and overrides.
 
-     $library = array_merge($library, $library['versions'][$version]);
 
-     unset($library['versions']);
 
-   }
 
-   // Check each variant if it is installed.
 
-   if (!empty($library['variants'])) {
 
-     foreach ($library['variants'] as $variant_name => &$variant) {
 
-       // If no variant callback has been set, assume the variant to be
 
-       // installed.
 
-       if (!isset($variant['variant callback'])) {
 
-         $variant['installed'] = TRUE;
 
-       }
 
-       else {
 
-         // We support both a single parameter, which is an associative array,
 
-         // and an indexed array of multiple parameters.
 
-         if (isset($variant['variant arguments'][0])) {
 
-           // Add the library as the first argument, and the variant name as the second.
 
-           $variant['installed'] = call_user_func_array($variant['variant callback'], array_merge(array($library, $variant_name), $variant['variant arguments']));
 
-         }
 
-         else {
 
-           $variant['installed'] = $variant['variant callback']($library, $variant_name, $variant['variant arguments']);
 
-         }
 
-         if (!$variant['installed']) {
 
-           $variant['error'] = 'not found';
 
-           $variant['error message'] = t('The %variant variant of the %library library could not be found.', array(
 
-             '%variant' => $variant_name,
 
-             '%library' => $library['name'],
 
-           ));
 
-         }
 
-       }
 
-     }
 
-   }
 
-   // If we end up here, the library should be usable.
 
-   $library['installed'] = TRUE;
 
-   // Invoke callbacks in the 'post-detect' group.
 
-   libraries_invoke('post-detect', $library);
 
-   return $library;
 
- }
 
- /**
 
-  * Loads a library.
 
-  *
 
-  * @param $name
 
-  *   The name of the library to load.
 
-  * @param $variant
 
-  *   The name of the variant to load. Note that only one variant of a library
 
-  *   can be loaded within a single request. The variant that has been passed
 
-  *   first is used; different variant names in subsequent calls are ignored.
 
-  *
 
-  * @return
 
-  *   An associative array of the library information as returned from
 
-  *   libraries_info(). The top-level properties contain the effective definition
 
-  *   of the library (variant) that has been loaded. Additionally:
 
-  *   - installed: Whether the library is installed, as determined by
 
-  *     libraries_detect_library().
 
-  *   - loaded: Either the amount of library files that have been loaded, or
 
-  *     FALSE if the library could not be loaded.
 
-  *   See hook_libraries_info() for more information.
 
-  */
 
- function libraries_load($name, $variant = NULL) {
 
-   $loaded = &drupal_static(__FUNCTION__, array());
 
-   if (!isset($loaded[$name])) {
 
-     $library = cache_get($name, 'cache_libraries');
 
-     if ($library) {
 
-       $library = $library->data;
 
-     }
 
-     else {
 
-       $library = libraries_detect($name);
 
-       cache_set($name, $library, 'cache_libraries');
 
-     }
 
-     // Exit early if the library was not found.
 
-     if ($library === FALSE) {
 
-       $loaded[$name] = $library;
 
-       return $loaded[$name];
 
-     }
 
-     // If a variant was specified, override the top-level properties with the
 
-     // variant properties.
 
-     if (isset($variant)) {
 
-       // Ensure that the $variant key exists, and if it does not, set its
 
-       // 'installed' property to FALSE by default. This will prevent the loading
 
-       // of the library files below.
 
-       $library['variants'] += array($variant => array('installed' => FALSE));
 
-       $library = array_merge($library, $library['variants'][$variant]);
 
-     }
 
-     // Regardless of whether a specific variant was requested or not, there can
 
-     // only be one variant of a library within a single request.
 
-     unset($library['variants']);
 
-     // Invoke callbacks in the 'pre-dependencies-load' group.
 
-     libraries_invoke('pre-dependencies-load', $library);
 
-     // If the library (variant) is installed, load it.
 
-     $library['loaded'] = FALSE;
 
-     if ($library['installed']) {
 
-       // Load library dependencies.
 
-       if (isset($library['dependencies'])) {
 
-         foreach ($library['dependencies'] as $dependency) {
 
-           libraries_load($dependency);
 
-         }
 
-       }
 
-       // Invoke callbacks in the 'pre-load' group.
 
-       libraries_invoke('pre-load', $library);
 
-       // Load all the files associated with the library.
 
-       $library['loaded'] = libraries_load_files($library);
 
-       // Invoke callbacks in the 'post-load' group.
 
-       libraries_invoke('post-load', $library);
 
-     }
 
-     $loaded[$name] = $library;
 
-   }
 
-   return $loaded[$name];
 
- }
 
- /**
 
-  * Loads a library's files.
 
-  *
 
-  * @param $library
 
-  *   An array of library information as returned by libraries_info().
 
-  *
 
-  * @return
 
-  *   The number of loaded files.
 
-  */
 
- function libraries_load_files($library) {
 
-   // As this key was added after 7.x-2.1 cached library structures might not
 
-   // have it.
 
-   $library += array('post-load integration files' => FALSE);
 
-   // Load integration files.
 
-   if (!$library['post-load integration files'] && !empty($library['integration files'])) {
 
-     $enabled_themes = array();
 
-     foreach (list_themes() as $theme_name => $theme) {
 
-       if ($theme->status) {
 
-         $enabled_themes[] = $theme_name;
 
-       }
 
-     }
 
-     foreach ($library['integration files'] as $provider => $files) {
 
-       if (module_exists($provider)) {
 
-         libraries_load_files(array(
 
-           'files' => $files,
 
-           'path' => '',
 
-           'library path' => drupal_get_path('module', $provider),
 
-           'post-load integration files' => FALSE,
 
-         ));
 
-       }
 
-       elseif (in_array($provider, $enabled_themes)) {
 
-         libraries_load_files(array(
 
-           'files' => $files,
 
-           'path' => '',
 
-           'library path' => drupal_get_path('theme', $provider),
 
-           'post-load integration files' => FALSE,
 
-         ));
 
-       }
 
-     }
 
-   }
 
-   // Construct the full path to the library for later use.
 
-   $path = $library['library path'];
 
-   $path = ($library['path'] !== '' ? $path . '/' . $library['path'] : $path);
 
-   // Count the number of loaded files for the return value.
 
-   $count = 0;
 
-   // Load both the JavaScript and the CSS files.
 
-   // The parameters for drupal_add_js() and drupal_add_css() require special
 
-   // handling.
 
-   // @see drupal_process_attached()
 
-   foreach (array('js', 'css') as $type) {
 
-     if (!empty($library['files'][$type])) {
 
-       foreach ($library['files'][$type] as $data => $options) {
 
-         // If the value is not an array, it's a filename and passed as first
 
-         // (and only) argument.
 
-         if (!is_array($options)) {
 
-           $data = $options;
 
-           $options = array();
 
-         }
 
-         // 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
 
-         // array.
 
-         if (is_numeric($data)) {
 
-           $data = $options['data'];
 
-           unset($options['data']);
 
-         }
 
-         // Prepend the library path to the file name.
 
-         $data = "$path/$data";
 
-         // Apply the default group if the group isn't explicitly given.
 
-         if (!isset($options['group'])) {
 
-           $options['group'] = ($type == 'js') ? JS_DEFAULT : CSS_DEFAULT;
 
-         }
 
-         call_user_func('drupal_add_' . $type, $data, $options);
 
-         $count++;
 
-       }
 
-     }
 
-   }
 
-   // Load PHP files.
 
-   if (!empty($library['files']['php'])) {
 
-     foreach ($library['files']['php'] as $file => $array) {
 
-       $file_path = DRUPAL_ROOT . '/' . $path . '/' . $file;
 
-       if (file_exists($file_path)) {
 
-         _libraries_require_once($file_path);
 
-         $count++;
 
-       }
 
-     }
 
-   }
 
-   // Load integration files.
 
-   if ($library['post-load integration files'] && !empty($library['integration files'])) {
 
-     $enabled_themes = array();
 
-     foreach (list_themes() as $theme_name => $theme) {
 
-       if ($theme->status) {
 
-         $enabled_themes[] = $theme_name;
 
-       }
 
-     }
 
-     foreach ($library['integration files'] as $provider => $files) {
 
-       if (module_exists($provider)) {
 
-         libraries_load_files(array(
 
-           'files' => $files,
 
-           'path' => '',
 
-           'library path' => drupal_get_path('module', $provider),
 
-           'post-load integration files' => FALSE,
 
-         ));
 
-       }
 
-       elseif (in_array($provider, $enabled_themes)) {
 
-         libraries_load_files(array(
 
-           'files' => $files,
 
-           'path' => '',
 
-           'library path' => drupal_get_path('theme', $provider),
 
-           'post-load integration files' => FALSE,
 
-         ));
 
-       }
 
-     }
 
-   }
 
-   return $count;
 
- }
 
- /**
 
-  * Wrapper function for require_once.
 
-  *
 
-  * A library file could set a $path variable in file scope. Requiring such a
 
-  * file directly in libraries_load_files() would lead to the local $path
 
-  * variable being overridden after the require_once statement. This would
 
-  * break loading further files. Therefore we use this trivial wrapper which has
 
-  * no local state that can be tampered with.
 
-  *
 
-  * @param $file_path
 
-  *   The file path of the file to require.
 
-  */
 
- function _libraries_require_once($file_path) {
 
-   require_once $file_path;
 
- }
 
- /**
 
-  * Gets the version information from an arbitrary library.
 
-  *
 
-  * @param $library
 
-  *   An associative array containing all information about the library.
 
-  * @param $options
 
-  *   An associative array containing with the following keys:
 
-  *   - file: The filename to parse for the version, relative to the library
 
-  *     path. For example: 'docs/changelog.txt'.
 
-  *   - pattern: A string containing a regular expression (PCRE) to match the
 
-  *     library version. For example: '@version\s+([0-9a-zA-Z\.-]+)@'. Note that
 
-  *     the returned version is not the match of the entire pattern (i.e.
 
-  *     '@version 1.2.3' in the above example) but the match of the first
 
-  *     sub-pattern (i.e. '1.2.3' in the above example).
 
-  *   - lines: (optional) The maximum number of lines to search the pattern in.
 
-  *     Defaults to 20.
 
-  *   - cols: (optional) The maximum number of characters per line to take into
 
-  *     account. Defaults to 200. In case of minified or compressed files, this
 
-  *     prevents reading the entire file into memory.
 
-  *
 
-  * @return
 
-  *   A string containing the version of the library.
 
-  *
 
-  * @see libraries_get_path()
 
-  */
 
- function libraries_get_version($library, $options) {
 
-   // Provide defaults.
 
-   $options += array(
 
-     'file' => '',
 
-     'pattern' => '',
 
-     'lines' => 20,
 
-     'cols' => 200,
 
-   );
 
-   $file = DRUPAL_ROOT . '/' . $library['library path'] . '/' . $options['file'];
 
-   if (empty($options['file']) || !file_exists($file)) {
 
-     return;
 
-   }
 
-   $file = fopen($file, 'r');
 
-   while ($options['lines'] && $line = fgets($file, $options['cols'])) {
 
-     if (preg_match($options['pattern'], $line, $version)) {
 
-       fclose($file);
 
-       return $version[1];
 
-     }
 
-     $options['lines']--;
 
-   }
 
-   fclose($file);
 
- }
 
- /**
 
-  * Gets the version information from a library's package.json file.
 
-  *
 
-  * @param $library
 
-  *   An associative array containing all information about the library.
 
-  * @param $options
 
-  *   This callback expects no option.
 
-  * @return
 
-  *   A string containing the version of the library.
 
-  *
 
-  * @see libraries_get_path()
 
-  */
 
- function libraries_get_package_json_version($library, $options) {
 
-   $file = DRUPAL_ROOT . '/' . $library['library path'] . '/package.json';
 
-   if (!file_exists($file)) {
 
-     return;
 
-   }
 
-   $content = file_get_contents($file);
 
-   if (!$content) {
 
-     return;
 
-   }
 
-   $data = drupal_json_decode($content);
 
-   if (isset($data['version'])) {
 
-     return $data['version'];
 
-   }
 
- }
 
- /**
 
-  * Implements hook_help().
 
-  */
 
- function libraries_help($path, $arg) {
 
-   switch ($path) {
 
-     case 'admin/reports/libraries':
 
-       return t('Click on a library for a status report or detailed installation instructions.');
 
-   }
 
- }
 
- /**
 
-  * Implements hook_permission().
 
-  */
 
- function libraries_permission() {
 
-   return array(
 
-     'access library reports' => array(
 
-       'title' => t('View library reports'),
 
-     ),
 
-   );
 
- }
 
- /**
 
-  * Implements hook_menu().
 
-  */
 
- function libraries_menu() {
 
-   $items = array();
 
-   $items['admin/reports/libraries'] = array(
 
-     'title' => 'Libraries',
 
-     'description' => 'An overview of libraries installed on this site.',
 
-     'page callback' => 'drupal_get_form',
 
-     'page arguments' => array('libraries_admin_overview'),
 
-     'access arguments' => array('access library reports'),
 
-     'file' => 'libraries.admin.inc'
 
-   );
 
-   $items['admin/reports/libraries/%libraries_ui'] = array(
 
-     'title' => 'Library status report',
 
-     'description' => 'Status overview for a single library',
 
-     'page callback' => 'drupal_get_form',
 
-     'page arguments' => array('libraries_admin_library_status_form', 3),
 
-     'access arguments' => array('access library reports'),
 
-     'file' => 'libraries.admin.inc'
 
-   );
 
-   return $items;
 
- }
 
- /**
 
-  * Loads library information for display in the user interface.
 
-  *
 
-  * This can be used as a menu loader function by specifying a '%libraries_ui'
 
-  * parameter in a path.
 
-  *
 
-  * We do not use libraries_load() (and, thus, a '%libraries' parameter) directly
 
-  * for displaying library information in the user interface as we do not want
 
-  * the library files to be loaded.
 
-  *
 
-  * @param string $name
 
-  *   The machine name of a library to return registered information for.
 
-  *
 
-  * @return array|false
 
-  *   An associative array containing registered information for the library
 
-  *   specified by $name, or FALSE if the library $name is not registered.
 
-  *
 
-  * @see libraries_detect()
 
-  * @see libraries_menu()
 
-  */
 
- function libraries_ui_load($name) {
 
-   return libraries_detect($name);
 
- }
 
- /**
 
-  * Implements hook_theme().
 
-  */
 
- function libraries_theme($existing, $type, $theme, $path) {
 
-   // Because we extend the 'table' theme function, fetch the respective
 
-   // variables dynamically.
 
-   $common_theme = drupal_common_theme();
 
-   $variables = $common_theme['table']['variables'] + array('title' => '', 'description' => '');
 
-   return array(
 
-     'libraries_table_with_title' => array(
 
-       'variables' => $variables,
 
-       'file' => 'libraries.theme.inc',
 
-     ),
 
-   );
 
- }
 
 
  |