Browse Source

updated login-destination, libraries

Bachir Soussi Chiadmi 7 years ago
parent
commit
2b028cf376
20 changed files with 1282 additions and 262 deletions
  1. 16 0
      sites/all/modules/contrib/dev/libraries/CHANGELOG.txt
  2. 5 4
      sites/all/modules/contrib/dev/libraries/README.txt
  3. 547 0
      sites/all/modules/contrib/dev/libraries/libraries.admin.inc
  4. 11 1
      sites/all/modules/contrib/dev/libraries/libraries.api.php
  5. 163 85
      sites/all/modules/contrib/dev/libraries/libraries.drush.inc
  6. 7 4
      sites/all/modules/contrib/dev/libraries/libraries.info
  7. 9 0
      sites/all/modules/contrib/dev/libraries/libraries.install
  8. 89 12
      sites/all/modules/contrib/dev/libraries/libraries.module
  9. 119 0
      sites/all/modules/contrib/dev/libraries/tests/LibrariesAdminWebTest.test
  10. 38 68
      sites/all/modules/contrib/dev/libraries/tests/LibrariesLoadWebTest.test
  11. 78 0
      sites/all/modules/contrib/dev/libraries/tests/LibrariesUnitTest.test
  12. 64 0
      sites/all/modules/contrib/dev/libraries/tests/LibrariesWebTestBase.test
  13. 3 3
      sites/all/modules/contrib/dev/libraries/tests/libraries/example_info_file.libraries.info
  14. 3 3
      sites/all/modules/contrib/dev/libraries/tests/modules/libraries_test_module/libraries_test_module.info
  15. 5 0
      sites/all/modules/contrib/dev/libraries/tests/modules/libraries_test_module/libraries_test_module.module
  16. 3 3
      sites/all/modules/contrib/dev/libraries/tests/themes/libraries_test_theme/libraries_test_theme.info
  17. 87 75
      sites/all/modules/contrib/users/login_destination/login_destination.admin.inc
  18. 3 3
      sites/all/modules/contrib/users/login_destination/login_destination.info
  19. 32 1
      sites/all/modules/contrib/users/login_destination/login_destination.install
  20. 0 0
      sites/all/modules/contrib/users/login_destination/login_destination.module

+ 16 - 0
sites/all/modules/contrib/dev/libraries/CHANGELOG.txt

@@ -1,4 +1,20 @@
 
+Libraries 7.x-2.3, 2016-05-12
+-----------------------------
+#1884246 by BR0kEN, tstoeckler et al: Allow downloading libraries via Drush.
+by tstoeckler: Allow detecting all libraries by calling libraries_detect().
+by tstoeckler: Prevent LibrariesWebTestBase from being displayed in the UI.
+#819610 by tstoeckler: Add tests for the Libraries UI.
+#1884246 by BR0kEN, tstoeckler: Show the provider in drush libraries-list
+#819610 by Pol, tstoeckler: Show the provider in the UI.
+#2634732 by Rob Holmes, tstoeckler: Sort libraries by title in the UI.
+#2585395 by robinsonsarah01: Allow object methods as version callbacks.
+#819610 by tstoeckler, Pol: Provide a status report for library information.
+#2352251 by netw3rker: Fix incorrect hook name in libraries.api.php.
+#2352237 by netw3rker, tstoeckler: Allow clearing the libraries cache from Drush.
+#2193969 by tstoeckler: Avoid warnings for stale library caches.
+#2287529 by drupalshrek, tstoeckler: Update installation link in README.txt.
+
 Libraries 7.x-2.2, 2014-02-09
 -----------------------------
 #2046919 by tstoeckler: Clarify 'version' docs.

+ 5 - 4
sites/all/modules/contrib/dev/libraries/README.txt

@@ -16,10 +16,11 @@ Bug reports, feature suggestions and latest developments:
 
 -- INSTALLATION --
 
-* Install as usual, see http://drupal.org/node/70151 for further information.
-  Note that installing external libraries is separate from installing this
-  module and should happen in the sites/all/libraries directory. See
-  http://drupal.org/node/1440066 for more information.
+* Install as usual, see
+  https://www.drupal.org/documentation/install/modules-themes/modules-7 for
+  further information. Note that installing external libraries is separate from
+  installing this module and should happen in the sites/all/libraries directory.
+  See http://drupal.org/node/1440066 for more information.
 
 
 -- CONTACT --

+ 547 - 0
sites/all/modules/contrib/dev/libraries/libraries.admin.inc

@@ -0,0 +1,547 @@
+<?php
+
+/**
+ * @file
+ * Provides administrative page and form callbacks for Libraries module.
+ */
+
+/**
+ * Form generation callback for the libraries overview table.
+ *
+ * This is a form instead of a page to allow easier extending in contributed
+ * modules.
+ *
+ * @param array $form
+ *   An associative array containing the structure of the form.
+ * @param array $form_state
+ *   A keyed array containing the current state of the form.
+ *
+ * @return array
+ *   The form array for the overview form.
+ */
+function libraries_admin_overview(array $form, array &$form_state) {
+  $header = array(t('Name'), t('Status'), t('Installed version'), t('Provider'), t('Links'));
+  $rows = array();
+
+  $libraries = libraries_detect();
+  uasort($libraries, 'libraries_admin_sort_title');
+
+  foreach ($libraries as $machine_name => $library) {
+    $actions = array();
+
+    if ($library['vendor url']) {
+      $actions[] = l('Homepage', $library['vendor url']);
+    }
+    if ($library['download url']) {
+      $actions[] = l('Download', $library['download url']);
+    }
+
+    $rows[] = array(
+      'data' => array(
+        l($library['name'], 'admin/reports/libraries/' . $machine_name),
+        ($library['installed'] ? t('OK') : drupal_ucfirst($library['error'])),
+        (isset($library['version']) ? $library['version'] : ''),
+        libraries_admin_get_provider_with_type($library),
+        implode(' | ', $actions),
+      ),
+      'class' => ($library['installed'] ? array('ok') : array('error')),
+    );
+  }
+
+  $form['libraries']['list'] = array(
+    '#theme' => 'table',
+    '#header' => $header,
+    '#rows' => $rows,
+    '#empty' => t('There are currently no libraries installed'),
+  );
+
+  return $form;
+}
+
+/**
+ * Form generation callback for the status overview for a single library.
+ *
+ * This is a form instead of a page to allow easier extending in contributed
+ * modules.
+ *
+ * @param array $form
+ *   An associative array containing the structure of the form.
+ * @param array $form_state
+ *   A keyed array containing the current state of the form.
+ * @param array $library
+ *   A library information array.
+ *
+ * @return array|null
+ *   The form array for the status form or NULL if the library was not found.
+ *
+ * @todo Add some var_export($library)-style output
+ */
+function libraries_admin_library_status_form(array $form, array &$form_state, $library) {
+  drupal_set_title(t('Status report for library %library', array('%library' => $library['name'])), PASS_THROUGH);
+
+  if ($library['installed']) {
+    drupal_set_message(t('The %name library is installed correctly.', array('%name' => $library['name'])));
+    $form['status'] = libraries_admin_status_table($library);
+  }
+  else {
+    drupal_set_message($library['error message'], 'error');
+    switch ($library['error']) {
+      case 'not found':
+        $form['instructions'] = libraries_admin_instructions_missing($library);
+        break;
+
+      case 'not detected':
+        $form['instructions'] = libraries_admin_instructions_undetected($library);;
+        break;
+
+      case 'not supported':
+        $form['instructions'] = libraries_admin_instructions_unsupported($library);
+        break;
+
+      case 'missing dependency':
+        $form['instructions']['instruction']['#markup'] = t('There a missing dependency in your configuration that prevent this library to work properly.') . '<br>';
+        break;
+
+      case 'incompatible dependency':
+        $form['instructions']['instruction']['#markup'] = t('There an incompatible dependency in your configuration that prevent this library to work properly.') . '<br>';
+        break;
+    }
+  }
+
+  return $form;
+}
+
+
+/**
+ * Displays a table of status information about a library.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return array
+ *   A renderable array containing a table with status information.
+ */
+function libraries_admin_status_table(array $library) {
+  $header = array(array(
+    // @todo The title implies that other type of information is displayed, as
+    //   well, but this is currently not the case.
+    // @todo Use CSS instead of a <strong> element.
+    'data' => '<strong>' . t('General information') . '</strong>',
+    'colspan' => 2,
+    'class' => 'table-heading',
+    'no_striping' => TRUE,
+  ));
+
+  $rows = array();
+  // @todo Use CSS instead of <strong> elements.
+  $rows['name'] = array('<strong>' . t('Name') . '</strong>', check_plain($library['name']));
+  $rows['machine_name'] = array('<strong>' . t('Machine name') . '</strong>', check_plain($library['machine name']));
+  if ($library['vendor url']) {
+    $rows['vendor_url'] = array('<strong>' . t('Vendor URL') . '</strong>', l($library['vendor url'], $library['vendor url']));
+  }
+  if ($library['download url']) {
+    $rows['download_url'] = array('<strong>' . t('Download URL') . '</strong>', l($library['download url'], $library['download url']));
+  }
+  $rows['provider'] = array('<strong>' . t('Provider') . '</strong>', libraries_admin_get_provider_with_type($library));
+  $rows['library_path'] = array('<strong>' . t('Library path') . '</strong>', $library['library path']);
+  $rows['version'] = array('<strong>' . t('Version') . '</strong>', $library['version']);
+  if (!empty($library['variants'])) {
+    $rows['variants'] = array('<strong>' . t('Variants') . '</strong>', implode(', ', array_keys($library['variants'])));
+  }
+
+  return array(
+    '#theme' => 'table',
+    '#header' => $header,
+    '#rows' => $rows,
+  );
+}
+
+/**
+ * Returns instructions for dealing with a missing library.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return array
+ *   A renderable array containing the instructions.
+ */
+function libraries_admin_instructions_missing(array $library) {
+  $build = array();
+
+  $build['instruction']['#markup'] = t('Follow these steps to install the library:');
+
+  $items = array();
+  // 1. Download the library.
+  // If no supported versions are specified, the latest version is
+  // recommended.
+  if (empty($library['versions'])) {
+    $items[] = t('Download the latest version of the library <a href="@download-url">here</a>.', array(
+      '@download-url' => $library['download url'],
+    ));
+  }
+  // Otherwise, the latest supported version is recommended.
+  else {
+    $versions = array_keys($library['versions']);
+    usort($versions, 'version_compare');
+    $versions = array_reverse($versions);
+    $version = $versions[0];
+    $items[] = t('Download version %version of the library <a href="@download-url">here</a>.', array(
+      '%version' => $version,
+      '@download-url' => $library['download url'],
+    ));
+  }
+  // 2. Unpack it.
+  $items[] = t('If the library is an archive, i.e. if the file ending is for example <em>.tar.gz</em> or <em>.zip</em>, unpack it.');
+  // 3. Create the libraries folder.
+  $items[] = t('In the %library-directory directory of your Drupal installation create a %library directory.', array(
+    '%library-directory' => 'sites/all/libraries',
+    '%library' => $library['machine name'],
+  ));
+  // 4. Upload it.
+  // If the library has variant-independent files, give the user the
+  // location of an example file to check his filesystem against.
+  if ($directory_layout = libraries_admin_directory_layout($library)) {
+    $items[] = t('Upload the whole library (which can consist of multiple directories) into the newly created %library-path directory. The following files and directories should be contained in that directory: !directory-layout', array(
+      '%library-path' => 'sites/all/libraries/' . $library['machine name'],
+      '!directory-layout' => drupal_render($directory_layout),
+    ));
+  }
+  else {
+    $items[] = t('Upload the whole library (which can consist of multiple directories) into the newly created %library-path directory.', array(
+      '%library-path' => 'sites/all/libraries/' . $library['machine name'],
+    ));
+  }
+  // 5. Reload.
+  $items[] = t('<a href="">Reload</a> the page. If successful, you should see status information about this library.');
+
+  $build['steps'] = array(
+    '#theme' => 'item_list',
+    '#items' => $items,
+    '#type' => 'ol'
+  );
+
+  return $build;
+}
+
+
+/**
+ * Returns instructions for dealing with an undetected library.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return array
+ *   A renderable array containing the instructions.
+ */
+function libraries_admin_instructions_undetected($library) {
+  $build = array();
+  // Re-check location.
+  // @todo Avoid usage of <br> elements.
+  $build['instruction']['#markup'] = t('Check that the whole library is located at %library-path.', array(
+      '%library-path' => $library['library path'],
+    )) . '<br>';
+  // If the library has variant-independent files, give the user the
+  // exact location of the files to check against.
+  // @todo It should be possible to display even variant-specific files
+  //   in case the variant is installed, but libraries_detect() does not
+  //   detect variants if the library version cannot be detected.
+  if ($directory_layout = libraries_admin_directory_layout($library)) {
+    $build['directory_layout'] = $directory_layout;
+    $build['directory_layout']['#prefix'] = t('The following files and directories should be contained in that directory:');
+  }
+
+  // If the library is placed correctly the library information is
+  // incorrect.
+  // This switch could be avoided by using $library['info type'], but that would
+  // hinder properly translating these strings.
+  $build['reload']['#markup'] = t('If you have moved any files, <a href="">reload</a> the page. If successful, you should see status information about this library.') . '<br>';
+  $build['notice']['#markup'] = t('If the files are placed correctly and the version can still not be detected, the library information is incorrect.') . '<br>';
+
+  $provider = libraries_admin_get_provider($library);
+  switch ($library['info type']) {
+    case 'module':
+      $build['contact']['#markup'] = t('Contact the maintainer of the %module module to correct this.', array(
+          '%module' => $provider,
+        )) . '<br>';
+      break;
+
+    case 'theme':
+      $build['contact']['#markup'] = t('Contact the maintainer of the %theme theme to correct this.', array(
+          '%theme' => $provider,
+        )) . '<br>';
+      break;
+
+    case 'info file':
+      $build['contact']['#markup'] = t('Contact the maintainer of the %info-file info file to correct this.', array(
+          '%info-file' => $provider,
+        )) . '<br>';
+      break;
+  }
+  return $build;
+}
+
+
+/**
+ * Returns instructions for dealing with an unsupported library.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return array
+ *   A renderable array containing the instructions.
+ */
+function libraries_admin_instructions_unsupported($library) {
+  $build = array();
+  $items = array();
+
+  // Either download a different version of the library...
+  $versions = array_keys($library['versions']);
+  usort($versions, 'version_compare');
+  $versions = array_reverse($versions);
+  $version = $versions[0];
+  $build['instruction']['#markup'] = t('Please install version %version of the library by following the following steps:',
+    array(
+      '%version' => $version,
+    ));
+  // 1. Delete the old library.
+  $items[] = t('Delete the entire contents of the %library-path directory.',
+    array(
+      '%library-path' => $library['library path'],
+    ));
+  // 2. Download the new library.
+  $items[] = t('Download version %version of the library <a href="@download-url">here</a>.',
+    array(
+      '%version' => $version,
+      '@download-url' => $library['download url'],
+    ));
+  // 3. Unpack it.
+  $items[] = t('If the library is an archive, i.e. if the file ending is for example <em>.tar.gz</em> or <em>.zip</em>, unpack it.');
+  // 4. Upload the new library.
+  // If the library has variant-independent files, give the user the
+  // location of an example file to check his filesystem against.
+  if ($directory_layout = libraries_admin_directory_layout($library)) {
+    $items[] = t('Upload the new files into the %library-path directory. The following files and directories should be contained in that directory: !directory-layout',
+      array(
+        '%library-path' => $library['library path'],
+        '!directory-layout' => drupal_render($directory_layout),
+      ));
+  }
+  else {
+    $items[] = t('Upload the new files into the %library-path directory.',
+      array(
+        '%library-path' => $library['library path'],
+      ));
+  }
+  // 5. Reload.
+  $items[] = t('<a href="">Reload</a> the page. If successful, you should see status information about this library.');
+  $build['steps'] = array(
+    '#theme' => 'item_list',
+    '#items' => $items,
+    '#type' => 'ol',
+  );
+  // ...or contact the maintainer of the library information.
+  $provider = libraries_admin_get_provider($library);
+  switch ($library['info type']) {
+    case 'module':
+      $build['contact']['#markup'] = t('If you are bound to version @version of the library, ask the maintainer of the %module module to provide support for it.', array(
+          '@version' => $library['version'],
+          '%module' => $provider,
+        )) . '<br>';
+      break;
+
+    case 'theme':
+      $build['contact']['#markup'] = t('If you are bound to version @version of the library, ask the maintainer of the %theme theme to provide support for it.', array(
+          '@version' => $library['version'],
+          '%theme' => $provider,
+        )) . '<br>';
+      break;
+
+    case 'info file':
+      $build['contact']['#markup'] = t('If you are bound to version @version of the library, ask the maintainer of the %info-file info file to provide support for it.', array(
+          '@version' => $library['version'],
+          '%info-file' => $provider,
+        )) . '<br>';
+      break;
+  }
+  return $build;
+}
+
+/**
+ * Returns the directory layout of the library, if possible.
+ *
+ * The result of this function can help users to verify that they have uploaded
+ * the library to the correct location.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return array|false
+ *   A renderable array containing the directory layout of the library or FALSE
+ *   if a directory layout could not be generated.
+ */
+function libraries_admin_directory_layout(array $library) {
+  $build = array(
+    '#theme' => 'item_list',
+    '#type' => 'ul',
+    '#items' => array(),
+  );
+
+  $items = &$build['#items'];
+  if ($library['path']) {
+    $items = &libraries_admin_path_to_tree($items, $library['path']);
+  }
+  foreach (array('js', 'css', 'php') as $type) {
+    if (!empty($library['files'][$type])) {
+      $files = array_keys($library['files'][$type]);
+      foreach ($files as $file) {
+        // Skip JavaScript settings.
+        if (is_int($file)) {
+          continue;
+        }
+
+        $children = &$items;
+        libraries_admin_path_to_tree($children, $file);
+      }
+    }
+  }
+  return $build['#items'] ? $build : FALSE;
+}
+
+/**
+ * Converts a file path into a tree structure for use in an item list.
+ *
+ * For example, the path 'foo/bar/baz' will be converted into the tree structure
+ * represented by the following list:
+ * - foo
+ *   - bar
+ *     - baz
+ *
+ * The $items array that is modified by reference or returned (see below) can
+ * be used as the 'items' variable for theme_item_list().
+ *
+ * This function modifies passed-in $items array, so that multiple paths can
+ * be placed into the same tree structure easily.
+ *
+ * @code
+ *   $items = array();
+ *   foreach ($paths as $path) {
+ *     libraries_admin_path_to_tree($items, $path);
+ *   }
+ * @endcode
+ *
+ * It also returns the last item by reference, so that it can also be used to
+ * traverse into a sub-structure and add further children there.
+ *
+ * @code
+ *   $items = array();
+ *   $children = &libraries_admin_path_to_tree($items, $path);
+ *   foreach ($sub_paths as $sub_path) {
+ *     libraries_admin_path_to_tree($children, $sub_path);
+ *   }
+ * @endcode
+ *
+ * @param array $items
+ * @param string $path
+ *
+ * @return array
+ */
+function &libraries_admin_path_to_tree(array &$items, $path) {
+  $part = strtok($path, '/');
+  while ($part) {
+    if (!isset($items[$part])) {
+      $items[$part] = array(
+        'data' => $part,
+        'children' => array(),
+      );
+    }
+    $items = &$items[$part]['children'];
+    $part = strtok('/');
+  }
+
+  return $items;
+}
+
+/**
+ * Sorts libraries by name.
+ *
+ * This function can be used as a callback for usort() or uasort().
+ *
+ * @param array $a
+ *   The first library information array.
+ * @param array $b
+ *   The second library information array.
+ *
+ * @return int
+ *   Returns -1 if $a is considered smaller than $b, 1 if $a considered greater
+ *   than $b and 0 if $a and $b are considered equal.
+ *
+ * @see strnatcasecmp()
+ * @see usort()
+ * @see uasort()
+ */
+function libraries_admin_sort_title(array $a, array $b) {
+  return strnatcasecmp($a['name'], $b['name']);
+}
+
+/**
+ * Returns the library's provider.
+ *
+ * The provider can be a module, a theme, or an info file.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return string
+ *   The provider.
+ */
+function libraries_admin_get_provider($library) {
+  $provider = '';
+
+  switch ($library['info type']) {
+    case 'module':
+    case 'theme':
+      $info = system_get_info($library['info type'], $library[$library['info type']]);
+      $provider = $info['name'];
+      break;
+
+    case 'info file':
+      $provider = basename($library['info file']);
+      break;
+  }
+
+  return $provider;
+}
+
+/**
+ * Returns the library's provider and provider type.
+ *
+ * The provider type is either 'module', 'theme', or 'info file'.
+ *
+ * @param array $library
+ *   A library information array.
+ *
+ * @return string
+ *   The provider and provider type.
+ */
+function libraries_admin_get_provider_with_type($library) {
+  $provider = libraries_admin_get_provider($library);
+  $provider_with_type = '';
+
+  // This switch could be avoided by using $library['info type'], but that would
+  // hinder properly translating these strings.
+  switch ($library['info type']) {
+    case 'module':
+      $provider_with_type = t('%module module', array('%module' => $provider));
+      break;
+
+    case 'theme':
+      $provider_with_type = t('%theme theme', array('%theme' => $provider));
+      break;
+
+    case 'info file':
+      $provider_with_type = t('%info-file info file', array('%info-file' => $provider));
+      break;
+  }
+
+  return $provider_with_type;
+}

+ 11 - 1
sites/all/modules/contrib/dev/libraries/libraries.api.php

@@ -16,6 +16,10 @@
  *   - name: The official, human-readable name of the library.
  *   - vendor url: The URL of the homepage of the library.
  *   - download url: The URL of a web page on which the library can be obtained.
+ *   - download file url: (optional) The URL where the latest version of the
+ *     library can be downloaded. In case such a static URL exists the library
+ *     can be downloaded automatically via Drush. Run
+ *     'drush help libraries-download' in the command-line for more information.
  *   - path: (optional) A relative path from the directory of the library to the
  *     actual library. Only required if the extracted download package contains
  *     the actual library files in a sub-directory.
@@ -211,6 +215,9 @@ function hook_libraries_info() {
     'name' => 'Example library',
     'vendor url' => 'http://example.com',
     'download url' => 'http://example.com/download',
+    // It is important that this URL does not include the actual version to
+    // download. Not all libraries provide such a static URL.
+    'download file url' => 'http://example.com/latest.tar.gz',
     // Optional: If, after extraction, the actual library files are contained in
     // 'sites/all/libraries/example/lib', specify the relative path here.
     'path' => 'lib',
@@ -343,6 +350,9 @@ function hook_libraries_info() {
     'name' => 'Simple library',
     'vendor url' => 'http://example.com/simple',
     'download url' => 'http://example.com/simple',
+    // The download file URL can also point to a single file (instead of an
+    // archive).
+    'download file url' => 'http://example.com/latest/simple.js',
     'version arguments' => array(
       'file' => 'readme.txt',
       // Best practice: Document the actual version strings for later reference.
@@ -467,7 +477,7 @@ function hook_libraries_info_alter(&$libraries) {
  * @return
  *   An array of paths.
  */
-function hook_libraries_paths() {
+function hook_libraries_info_file_paths() {
   // Taken from the Libraries test module, which needs to specify the path to
   // the test library.
   return array(drupal_get_path('module', 'libraries_test') . '/example');

+ 163 - 85
sites/all/modules/contrib/dev/libraries/libraries.drush.inc

@@ -1,5 +1,4 @@
 <?php
-
 /**
  * @file
  * Drush integration for Libraries API.
@@ -9,59 +8,71 @@
  * Implements hook_drush_command().
  */
 function libraries_drush_command() {
+  $items = array();
+
   $items['libraries-list'] = array(
-    'callback' => 'libraries_drush_list',
-    'description' => dt('Lists registered library information.'),
+    'description' => dt('Show a list of registered libraries.'),
     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
+    'aliases' => array('lls', 'lib-list'),
   );
-  /**$items['libraries-download'] = array(
-    'callback' => 'libraries_drush_download',
-    'description' => dt('Downloads a registered library into the libraries directory for the active site.'),
+
+  $items['libraries-download'] = array(
+    'description' => dt('Download library files of registered libraries.'),
+    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
+    'aliases' => array('ldl', 'lib-download'),
     'arguments' => array(
-      'name' => dt('The internal name of the registered library.'),
+      'libraries' => 'A comma delimited list of library machine names.',
     ),
-  );*/
+    'required-arguments' => TRUE,
+  );
+
   return $items;
 }
 
 /**
- * Implements hook_drush_help().
+ * Implements hook_drush_cache_clear().
+ *
+ * @see drush_cache_clear_types()
  */
-function libraries_drush_help($section) {
-  switch ($section) {
-    case 'drush:libraries-list':
-      return dt('Lists registered library information.');
-
-    case 'drush:libraries-download':
-      return dt('Downloads a registered library into the libraries directory for the active site.
+function libraries_drush_cache_clear(array &$types) {
+  $types['libraries'] = 'libraries_drush_invalidate_cache';
+}
 
-See libraries-list for a list of registered libraries.');
+/**
+ * Clears the library cache.
+ */
+function libraries_drush_invalidate_cache() {
+  // @see drupal_flush_all_caches()
+  foreach (libraries_flush_caches() as $table) {
+    cache_clear_all('*', $table, TRUE);
   }
 }
 
 /**
- * Lists registered library information.
+ * Command callback. Show a list of registered libraries.
  */
-function libraries_drush_list() {
-  $libraries = array();
-  foreach (libraries_info() as $name => $info) {
-    $libraries[$name] = libraries_detect($name);
-  }
+function drush_libraries_list() {
+  $libraries = libraries_detect();
   ksort($libraries);
 
   if (empty($libraries)) {
     drush_print('There are no registered libraries.');
   }
-
   else {
+    module_load_include('inc', 'libraries', 'libraries.admin');
+
     $rows = array();
     // drush_print_table() automatically treats the first row as the header, if
     // $header is TRUE.
-    $rows[] = array(dt('Name'), dt('Status'), dt('Version'), dt('Variants'), dt('Dependencies'));
+    $rows[] = array(
+      dt('Name'),
+      dt('Status'),
+      dt('Version'),
+      dt('Variants'),
+      dt('Dependencies'),
+      dt('Provider'),
+    );
     foreach ($libraries as $name => $library) {
-      $status = ($library['installed'] ? dt('OK') : drupal_ucfirst($library['error']));
-      $version = (($library['installed'] && !empty($library['version'])) ? $library['version'] : '-');
-
       // Only list installed variants.
       $variants = array();
       foreach ($library['variants'] as $variant_name => $variant) {
@@ -69,83 +80,150 @@ function libraries_drush_list() {
           $variants[] = $variant_name;
         }
       }
-      $variants = (empty($variants) ? '-' : implode(', ', $variants));
 
-      $dependencies = (!empty($library['dependencies']) ? implode(', ', $library['dependencies']) : '-');
-
-      $rows[] = array($name, $status, $version, $variants, $dependencies);
+      $rows[] = array(
+        $name,
+        $library['installed'] ? dt('OK') : drupal_ucfirst($library['error']),
+        ($library['installed'] && $library['version']) ? '-' : $library['version'],
+        $variants ? implode(', ', $variants) : '-',
+        $library['dependencies'] ? implode(', ', $library['dependencies']) : '-',
+        libraries_admin_get_provider($library),
+      );
     }
+
     // Make the possible values for the 'Status' column and the 'Version' header
     // wrap nicely.
-    $widths = array(0, 12, 7, 0, 0);
+    $widths = array(0, 12, 7, 0, 0, 0);
     drush_print_table($rows, TRUE, $widths);
   }
 }
 
 /**
- * Downloads a library.
+ * Command callback. Downloads a library.
+ *
+ * Only libraries that provide a download file URL can be downloaded.
  *
- * @param $name
- *   The internal name of the library to download.
+ * @see hook_libraries_info()
+ * @see drush_pm_download()
  */
-function libraries_drush_download($name) {
-  return;
+function drush_libraries_download() {
+  drush_command_include('pm-download');
+
+  $libraries = libraries_info();
+
+  // @todo Consider supporting downloading all downloadable libraries.
+  // @todo Consider offering a selection if no library is specified.
+  foreach (pm_parse_arguments(func_get_args(), FALSE) as $machine_name) {
+    if (!isset($libraries[$machine_name])) {
+      $message = dt("The !library library is not registered with Libraries API.\n", array('!library' => $machine_name));
+      $message .= dt("Provide an info file for it or implement hook_libraries_info().\n");
+      $message .= dt("See hook_libraries_info() for more information.\n");
+      drush_set_error('DRUSH_LIBRARY_UKNOWN', $message);
+      continue;
+    }
+    $library = $libraries[$machine_name];
+
+    if (empty($library['download file url'])) {
+      $message = dt("The !library library cannot be downloaded.\n", array('!library' => $machine_name));
+      $message .= dt("Libraries need to specify a download file URL to support being downloaded via Drush.\n");
+      $message .= dt("See hook_libraries_info() for more information.\n");
+      drush_set_error('DRUSH_LIBRARY_NOT_DOWNLOADABLE', $message);
+      continue;
+    }
+    $download_url = $library['download file url'];
+
+    drush_log(dt('Downloading library !name ...', array('!name' => $machine_name)));
+
+    // @see package_handler_download_project() in wget.inc
+    // It cannot be used directly because it will always try to extract the
+    // archive which fails when downloading a single file.
+    // @todo Modify upstream to be able to use
+    //   package_handler_download_project() directly.
+    // Prepare download path. On Windows file name cannot contain '?'.
+    // See http://drupal.org/node/1782444
+    $filename = str_replace('?', '_', basename($download_url));
+    $download_path = drush_tempdir() . '/' . $filename;
+
+    // Download the tarball.
+    // Never cache the downloaded file. The downloading relies on the fact that
+    // different versions of the library are available under the same URL as new
+    // versions are released.
+    $download_path = drush_download_file($download_url, $download_path, 0);
+    if ($download_path || drush_get_context('DRUSH_SIMULATE')) {
+      drush_log(dt('Downloading !filename was successful.', array('!filename' => $filename)));
+    }
+    else {
+      drush_set_error('DRUSH_PM_DOWNLOAD_FAILED', dt('Unable to download !project to !path from !url.', array('!project' => $machine_name, '!path' => $download_path, '!url' => $download_url)));
+      drush_log(dt('Error downloading !name', array('!name' => $machine_name)), 'error');
+      continue;
+    }
 
-  // @todo Looks wonky?
-  if (!drush_shell_exec('type unzip')) {
-    return drush_set_error(dt('Missing dependency: unzip. Install it before using this command.'));
-  }
+    // @todo Suport MD5 file hashing.
 
-  // @todo Simply use current drush site.
-  $args = func_get_args();
-  if ($args[0]) {
-    $path = $args[0];
-  }
-  else {
-    $path = 'sites/all/libraries';
-  }
+    // Extract the tarball in place and return the full path to the untarred directory.
+    $download_base = dirname($download_path);
+    if (drush_file_is_tarball($download_path)) {
+      if (!$tar_file_list = drush_tarball_extract($download_path, $download_base, TRUE)) {
+        // An error has been logged.
+        return FALSE;
+      }
+      $tar_directory = drush_trim_path($tar_file_list[0]);
+      $download_path = $download_base . '/' . $tar_directory;
+    }
+    else {
+      $download_path = $download_base;
+    }
 
-  // Create the path if it does not exist.
-  if (!is_dir($path)) {
-    drush_op('mkdir', $path);
-    drush_log(dt('Directory @path was created', array('@path' => $path)), 'notice');
-  }
+    // Determine the install location for the project.  User provided
+    // --destination has preference.
+    $destination = drush_get_option('destination');
+    if (!empty($destination)) {
+      if (!file_exists($destination)) {
+        drush_mkdir($destination);
+      }
+      $install_location = realpath($destination);
+    }
+    else {
+      /** @see _pm_download_destination_lookup() */
+      // _pm_download_destination_lookup() pluralizes the passed type by
+      // appending an s.
+      // This relies on the fact that there is no library named 'contrib'.
+      // @todo Request that this be turned into a proper API upstream.
+      $install_location = _pm_download_destination('librarie');
+    }
 
-  // Set the directory to the download location.
-  $olddir = getcwd();
-  chdir($path);
+    // @todo Consider invoking a hook similar to
+    //   hook_drush_pm_download_destination_alter().
 
-  $filename = basename(COLORBOX_DOWNLOAD_URI);
-  $dirname = basename(COLORBOX_DOWNLOAD_URI, '.zip');
+    // @todo Consider adding version-control support similar to pm-download.
 
-  // Remove any existing Colorbox plugin directory
-  if (is_dir($dirname)) {
-    drush_log(dt('A existing Colorbox plugin was overwritten at @path', array('@path' => $path)), 'notice');
-  }
-  // Remove any existing Colorbox plugin zip archive
-  if (is_file($filename)) {
-    drush_op('unlink', $filename);
-  }
+    $install_location .= '/' . $machine_name;
 
-  // Download the zip archive
-  if (!drush_shell_exec('wget '. COLORBOX_DOWNLOAD_URI)) {
-    drush_shell_exec('curl -O '. COLORBOX_DOWNLOAD_URI);
-  }
+    // Check if install location already exists.
+    if (is_dir($install_location)) {
+      if (drush_confirm(dt('Install location !location already exists. Do you want to overwrite it?', array('!location' => $install_location)))) {
+        drush_delete_dir($install_location, TRUE);
+      }
+      else {
+        drush_log(dt("Skip installation of !project to !dest.", array('!project' => $library['machine name'], '!dest' => $install_location)), 'warning');
+        continue;
+      }
+    }
 
-  if (is_file($filename)) {
-    // Decompress the zip archive
-    drush_shell_exec('unzip -qq -o '. $filename);
-    // Remove the zip archive
-    drush_op('unlink', $filename);
-  }
+    // Copy the project to the install location.
+    if (drush_op('_drush_recursive_copy', $download_path, $install_location)) {
+      drush_log(dt("Library !project downloaded to !dest.", array('!project' => $machine_name, '!dest' => $install_location)), 'success');
 
-  // Set working directory back to the previous working directory.
-  chdir($olddir);
+      // @todo Consider invoking a hook similar to
+      //   hook_drush_pm_post_download().
 
-  if (is_dir($path .'/'. $dirname)) {
-    drush_log(dt('Colorbox plugin has been downloaded to @path', array('@path' => $path)), 'success');
-  }
-  else {
-    drush_log(dt('Drush was unable to download the Colorbox plugin to @path', array('@path' => $path)), 'error');
+      // @todo Support printing release notes.
+    }
+    else {
+      // We don't `return` here in order to proceed with downloading additional projects.
+      drush_set_error('DRUSH_PM_DOWNLOAD_FAILED', dt("Project !project could not be downloaded to !dest.", array('!project' => $machine_name, '!dest' => $install_location)));
+    }
+
+    // @todo Consider adding notify support.
   }
 }

+ 7 - 4
sites/all/modules/contrib/dev/libraries/libraries.info

@@ -3,11 +3,14 @@ description = Allows version-dependent and shared usage of external libraries.
 core = 7.x
 ; We use hook_system_theme_info() which was added in Drupal 7.11
 dependencies[] = system (>=7.11)
-files[] = tests/libraries.test
+files[] = tests/LibrariesAdminWebTest.test
+files[] = tests/LibrariesLoadWebTest.test
+files[] = tests/LibrariesUnitTest.test
+files[] = tests/LibrariesWebTestBase.test
 
-; Information added by Drupal.org packaging script on 2014-02-09
-version = "7.x-2.2"
+; Information added by Drupal.org packaging script on 2016-05-12
+version = "7.x-2.3"
 core = "7.x"
 project = "libraries"
-datestamp = "1391965716"
+datestamp = "1463077450"
 

+ 9 - 0
sites/all/modules/contrib/dev/libraries/libraries.install

@@ -25,3 +25,12 @@ function libraries_update_7200() {
     db_create_table('cache_libraries', $specs['cache_libraries']);
   }
 }
+
+/**
+ * Rebuild the class registry.
+ */
+function libraries_update_7201() {
+  // The tests were split from a single libraries.test file into multiple files
+  // during the 7.x-2.x cycle.
+  registry_rebuild();
+}

+ 89 - 12
sites/all/modules/contrib/dev/libraries/libraries.module

@@ -33,7 +33,7 @@ function libraries_flush_caches() {
  * @param $base_path
  *   Whether to prefix the resulting path with base_path().
  *
- * @return
+ * @return string
  *   The path to the specified library or FALSE if the library wasn't found.
  *
  * @ingroup libraries
@@ -67,7 +67,7 @@ function libraries_get_path($name, $base_path = FALSE) {
  * in both the site-wide directory and site-specific directory, only the
  * site-specific version will be listed.
  *
- * @return
+ * @return array
  *   A list of library directories.
  *
  * @ingroup libraries
@@ -122,7 +122,7 @@ function libraries_get_libraries() {
  * - sites/$sitename/libraries
  * - any directories specified via hook_libraries_info_file_paths()
  *
- * @return
+ * @return array
  *   An array of info files, keyed by library name. The values are the paths of
  *   the files.
  */
@@ -429,17 +429,21 @@ function &libraries_info($name = NULL) {
 /**
  * Applies default properties to a library definition.
  *
- * @library
+ * @param array $library
  *   An array of library information, passed by reference.
- * @name
+ * @param string $name
  *   The machine name of the passed-in library.
+ *
+ * @return array
+ *   The library information array with defaults populated.
  */
-function libraries_info_defaults(&$library, $name) {
+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',
@@ -472,12 +476,15 @@ function libraries_info_defaults(&$library, $name) {
 /**
  * Tries to detect a library and its installed version.
  *
- * @param $name
- *   The machine name of a library to return registered information for.
+ * @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 the library
- *   specified by $name, or FALSE if the library $name is not registered.
+ *   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
@@ -491,7 +498,15 @@ function libraries_info_defaults(&$library, $name) {
  *
  * @see libraries_info()
  */
-function libraries_detect($name) {
+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);
 
@@ -531,7 +546,7 @@ function libraries_detect($name) {
       $library['version'] = call_user_func_array($library['version callback'], array_merge(array($library), $library['version arguments']));
     }
     else {
-      $library['version'] = $library['version callback']($library, $library['version arguments']);
+      $library['version'] = call_user_func($library['version callback'], $library, $library['version arguments']);
     }
     if (empty($library['version'])) {
       $library['error'] = 'not detected';
@@ -693,6 +708,10 @@ function libraries_load($name, $variant = NULL) {
  *   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();
@@ -867,3 +886,61 @@ function libraries_get_version($library, $options) {
   }
   fclose($file);
 }
+
+/**
+ * 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 in case the library is not installed correctly.');
+  }
+}
+
+/**
+ * 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 site 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 site 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);
+}

+ 119 - 0
sites/all/modules/contrib/dev/libraries/tests/LibrariesAdminWebTest.test

@@ -0,0 +1,119 @@
+<?php
+
+/**
+ * @file
+ * Contains LibrariesAdminWebTest.
+ *
+ * Simpletest automatically discovers test files using PSR-4. We cannot,
+ * however, declare a namespace for this class, as that would require PHP 5.3.
+ * To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
+ * split each test class into its own file and use the correct base name, but
+ * for now use the 'test' extension and register them explicitly in
+ * libraries.info.
+ *
+ * @see simpletest_test_get_all()
+ */
+
+/**
+ * Tests the administrative interface for libraries.
+ */
+class LibrariesAdminWebTest extends LibrariesWebTestBase {
+
+  /**
+   * Provides metadata about this test.
+   *
+   * @return array
+   *   An array of test metadata with the following keys:
+   *   - name: The name of the test.
+   *   - description: The description of the test.
+   *   - group: The group of the test.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Libraries administration',
+      'description' => 'Tests the administrative interface for libraries.',
+      'group' => 'Libraries API',
+    );
+  }
+
+  /**
+   * Tests the libraries report at /admin/reports/libraries.
+   */
+  public function testLibrariesReportOverview() {
+    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries');
+    $this->assertRaw('Libraries');
+
+    // Make sure that all the libraries are listed.
+    $libraries = libraries_info();
+    $this->assertTrue($libraries);
+    foreach ($libraries as $library) {
+      $this->assertText($library['name']);
+      $this->assertLinkByHref('admin/reports/libraries/' . $library['machine name']);
+    }
+
+    // Make sure that all possible statuses are displayed.
+    $this->assertText('OK');
+    $this->assertText('Not found');
+    $this->assertText('Not detected');
+    $this->assertText('Not supported');
+    $this->assertText('Missing dependency');
+    $this->assertText('Incompatible dependency');
+
+    // Make sure that the providers are displayed.
+    $this->assertRaw('<em class="placeholder">Libraries test module</em> module');
+    $this->assertRaw('<em class="placeholder">Libraries test theme</em> theme');
+    $this->assertRaw('<em class="placeholder">example_info_file.libraries.info</em> info file');
+
+    // Make sure that homepage and download links are displayed.
+    $this->assertLinkByHref('http://example.com');
+    $this->assertLinkByHref('http://example.com/download');
+  }
+
+  /**
+   * Tests the libraries report for an installed library.
+   */
+  public function testLibrariesReportInstalled() {
+    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_files');
+    $this->assertRaw('Status report for library <em class="placeholder">Example files</em>');
+    $this->assertRaw('The <em class="placeholder">Example files</em> library is installed correctly.');
+    // Check that the information in the status report is displayed.
+    $this->assertText('Example files');
+    $this->assertText('example_files');
+    $this->assertRaw('<em class="placeholder">Libraries test module</em> module');
+    $this->assertText(drupal_get_path('module', 'libraries') . '/tests/libraries/example');
+    $this->assertText('1');
+  }
+
+  /**
+   * Tests the libraries report for a missing library.
+   */
+  public function testLibrariesReportMissing() {
+    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_missing');
+    $this->assertRaw('Status report for library <em class="placeholder">Example missing</em>');
+    $this->assertRaw('The <em class="placeholder">Example missing</em> library could not be found.');
+    // Check that the download link is being displayed.
+    $this->assertLinkByHref('http://example.com/download');
+  }
+
+
+  /**
+   * Tests the libraries report for a missing library.
+   */
+  public function testLibrariesReportNotDetected() {
+    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_undetected_version');
+    $this->assertRaw('Status report for library <em class="placeholder">Example undetected version</em>');
+    $this->assertRaw('The version of the <em class="placeholder">Example undetected version</em> library could not be detected.');
+  }
+
+  /**
+   * Tests the libraries report for a missing library.
+   */
+  public function testLibrariesReportNotSupported() {
+    $this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_unsupported_version');
+    $this->assertRaw('Status report for library <em class="placeholder">Example unsupported version</em>');
+    $this->assertRaw('The installed version <em class="placeholder">1</em> of the <em class="placeholder">Example unsupported version</em> library is not supported.');
+    // Check that the download link is being displayed.
+    $this->assertLinkByHref('http://example.com/download');
+  }
+
+}

+ 38 - 68
sites/all/modules/contrib/dev/libraries/tests/libraries.test → sites/all/modules/contrib/dev/libraries/tests/LibrariesLoadWebTest.test

@@ -2,67 +2,29 @@
 
 /**
  * @file
- * Tests for Libraries API.
+ * Contains LibrariesLoadWebTest.
+ *
+ * Simpletest automatically discovers test files using PSR-4. We cannot,
+ * however, declare a namespace for this class, as that would require PHP 5.3.
+ * To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
+ * place the test files in the correct directory already, but for now register
+ * them explicitly in libraries.info
  */
 
 /**
- * Tests basic Libraries API functions.
+ * Tests basic detection and loading of libraries.
  */
-class LibrariesUnitTestCase extends DrupalUnitTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Libraries API unit tests',
-      'description' => 'Tests basic functions provided by Libraries API.',
-      'group' => 'Libraries API',
-    );
-  }
-
-  function setUp() {
-    drupal_load('module', 'libraries');
-    parent::setUp();
-  }
-
-  /**
-   * Tests libraries_get_path().
-   */
-  function testLibrariesGetPath() {
-    // Note that, even though libraries_get_path() doesn't find the 'example'
-    // library, we are able to make it 'installed' by specifying the 'library
-    // path' up-front. This is only used for testing purposed and is strongly
-    // discouraged as it defeats the purpose of Libraries API in the first
-    // place.
-    $this->assertEqual(libraries_get_path('example'), FALSE, 'libraries_get_path() returns FALSE for a missing library.');
-  }
+class LibrariesLoadWebTest extends LibrariesWebTestBase {
 
   /**
-   * Tests libraries_prepare_files().
+   * Provides metadata about this test.
+   *
+   * @return array
+   *   An array of test metadata with the following keys:
+   *   - name: The name of the test.
+   *   - description: The description of the test.
+   *   - group: The group of the test.
    */
-  function testLibrariesPrepareFiles() {
-    $expected = array(
-      'files' => array(
-        'js' => array('example.js' => array()),
-        'css' => array('example.css' => array()),
-        'php' => array('example.php' => array()),
-      ),
-    );
-    $library = array(
-      'files' => array(
-        'js' => array('example.js'),
-        'css' => array('example.css'),
-        'php' => array('example.php'),
-      ),
-    );
-    libraries_prepare_files($library, NULL, NULL);
-    $this->assertEqual($expected, $library, 'libraries_prepare_files() works correctly.');
-  }
-}
-
-/**
- * Tests basic detection and loading of libraries.
- */
-class LibrariesTestCase extends DrupalWebTestCase {
-  protected $profile = 'testing';
-
   public static function getInfo() {
     return array(
       'name' => 'Libraries detection and loading',
@@ -71,15 +33,10 @@ class LibrariesTestCase extends DrupalWebTestCase {
     );
   }
 
-  function setUp() {
-    parent::setUp('libraries', 'libraries_test_module');
-    theme_enable(array('libraries_test_theme'));
-  }
-
   /**
    * Tests libraries_detect_dependencies().
    */
-  function testLibrariesDetectDependencies() {
+  public function testLibrariesDetectDependencies() {
     $library = array(
       'name' => 'Example',
       'dependencies' => array('example_missing'),
@@ -158,7 +115,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
   /**
    * Tests libraries_scan_info_files().
    */
-  function testLibrariesScanInfoFiles() {
+  public function testLibrariesScanInfoFiles() {
     $expected = array('example_info_file' => (object) array(
       'uri' => drupal_get_path('module', 'libraries') . '/tests/libraries/example_info_file.libraries.info',
       'filename' => 'example_info_file.libraries.info',
@@ -171,7 +128,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
   /**
    * Tests libraries_info().
    */
-  function testLibrariesInfo() {
+  public function testLibrariesInfo() {
     // Test that modules can provide and alter library information.
     $info = libraries_info();
     $this->assertTrue(isset($info['example_module']));
@@ -226,7 +183,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
   /**
    * Tests libraries_detect().
    */
-  function testLibrariesDetect() {
+  public function testLibrariesDetect() {
     // Test missing library.
     $library = libraries_detect('example_missing');
     $this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
@@ -306,10 +263,24 @@ class LibrariesTestCase extends DrupalWebTestCase {
     $this->assertEqual($library['variants']['example_variant']['installed'], TRUE, 'Existing variant found.');
   }
 
+  /**
+   * Tests libraries_detect() without a $name parameter.
+   */
+  public function testLibrariesDetectAll() {
+    // Test that an array with all library information is returned and that the
+    // libraries are properly detected.
+    $libraries = libraries_detect();
+    $this->verbose('<pre>' . var_export($libraries, TRUE) . '</pre>');
+    $this->assertEqual($libraries['example_missing']['error'], 'not found');
+    $this->assertEqual($libraries['example_undetected_version']['error'], 'not detected');
+    $this->assertEqual($libraries['example_unsupported_version']['error'], 'not supported');
+    $this->assertEqual($libraries['example_supported_version']['installed'], TRUE);
+  }
+
   /**
    * Tests libraries_load().
    */
-  function testLibrariesLoad() {
+  public function testLibrariesLoad() {
     // Test dependencies.
     $library = libraries_load('example_dependency_missing');
     $this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
@@ -334,7 +305,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
   /**
    * Tests the applying of callbacks.
    */
-  function testCallbacks() {
+  public function testCallbacks() {
     $expected = array(
       'name' => 'Example callback',
       'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
@@ -453,7 +424,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
    *
    * @see _libraries_test_module_load()
    */
-  function testLibrariesOutput() {
+  public function testLibrariesOutput() {
     // Test loading of a simple library with a top-level files property.
     $this->drupalGet('libraries-test-module/files');
     $this->assertLibraryFiles('example_1', 'File loading');
@@ -527,7 +498,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
    *   (optional) The expected file extensions of $name. Defaults to
    *   array('js', 'css', 'php').
    */
-  function assertLibraryFiles($name, $label = '', $extensions = array('js', 'css', 'php')) {
+  public function assertLibraryFiles($name, $label = '', $extensions = array('js', 'css', 'php')) {
     $label = ($label !== '' ? "$label: " : '');
 
     // Test that the wrong files are not loaded...
@@ -570,4 +541,3 @@ class LibrariesTestCase extends DrupalWebTestCase {
   }
 
 }
-

+ 78 - 0
sites/all/modules/contrib/dev/libraries/tests/LibrariesUnitTest.test

@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * @file
+ * Contains LibrariesUnitTest.
+ *
+ * Simpletest automatically discovers test files using PSR-4. We cannot,
+ * however, declare a namespace for this class, as that would require PHP 5.3.
+ * To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
+ * place the test files in the correct directory already, but for now register
+ * them explicitly in libraries.info.
+ */
+
+/**
+ * Tests basic Libraries API functions.
+ */
+class LibrariesUnitTest extends DrupalUnitTestCase {
+
+  /**
+   * Provides metadata about this test.
+   *
+   * @return array
+   *   An array of test metadata with the following keys:
+   *   - name: The name of the test.
+   *   - description: The description of the test.
+   *   - group: The group of the test.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Libraries API unit tests',
+      'description' => 'Tests basic functions provided by Libraries API.',
+      'group' => 'Libraries API',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    drupal_load('module', 'libraries');
+    parent::setUp();
+  }
+
+  /**
+   * Tests libraries_get_path().
+   */
+  public function testLibrariesGetPath() {
+    // Note that, even though libraries_get_path() doesn't find the 'example'
+    // library, we are able to make it 'installed' by specifying the 'library
+    // path' up-front. This is only used for testing purposed and is strongly
+    // discouraged as it defeats the purpose of Libraries API in the first
+    // place.
+    $this->assertEqual(libraries_get_path('example'), FALSE, 'libraries_get_path() returns FALSE for a missing library.');
+  }
+
+  /**
+   * Tests libraries_prepare_files().
+   */
+  public function testLibrariesPrepareFiles() {
+    $expected = array(
+      'files' => array(
+        'js' => array('example.js' => array()),
+        'css' => array('example.css' => array()),
+        'php' => array('example.php' => array()),
+      ),
+    );
+    $library = array(
+      'files' => array(
+        'js' => array('example.js'),
+        'css' => array('example.css'),
+        'php' => array('example.php'),
+      ),
+    );
+    libraries_prepare_files($library, NULL, NULL);
+    $this->assertEqual($expected, $library, 'libraries_prepare_files() works correctly.');
+  }
+
+}

+ 64 - 0
sites/all/modules/contrib/dev/libraries/tests/LibrariesWebTestBase.test

@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Contains LibrariesWebTestBase.
+ *
+ * Simpletest automatically discovers test files using PSR-4. We cannot,
+ * however, declare a namespace for this class, as that would require PHP 5.3.
+ * To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
+ * place the test files in the correct directory already, but for now register
+ * them explicitly in libraries.info
+ */
+
+/**
+ * Base class for Libraries API web tests.
+ */
+abstract class LibrariesWebTestBase extends DrupalWebTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $profile = 'testing';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp('libraries', 'libraries_test_module');
+    theme_enable(array('libraries_test_theme'));
+  }
+
+  /**
+   * Retrieves a path making sure a set of permissions is required to access it.
+   *
+   * After calling this method, a user with the given permissions is logged in
+   * and the retrieved page is loaded into the internal browser.
+   *
+   * @param array $permissions
+   *   An array of permission names to assign to user. Note that the user always
+   *   has the default permissions derived from the "authenticated users" role.
+   * @param string $path
+   *   Drupal path or URL to load into the internal browser.
+   * @param array $options
+   *   Options to be forwarded to url().
+   * @param array $headers
+   *   An array containing additional HTTP request headers, each formatted as
+   *   "name: value".
+   *
+   * @return string
+   *   The retrieved HTML string, also available as $this->drupalGetContent().
+   *
+   * @see \DrupalWebTestCase::drupalGet()
+   * @see \DrupalWebTestCase::drupalCreateUser()
+   */
+  protected function getWithPermissions(array $permissions, $path, array $options = array(), array $headers = array()) {
+    $this->drupalGet($path, $options, $headers);
+    $this->assertResponse(403);
+
+    $this->drupalLogin($this->drupalCreateUser($permissions));
+    $this->drupalGet($path, $options, $headers);
+    $this->assertResponse(200);
+  }
+
+}

+ 3 - 3
sites/all/modules/contrib/dev/libraries/tests/libraries/example_info_file.libraries.info

@@ -2,9 +2,9 @@
 name = Example info file
 
 
-; Information added by Drupal.org packaging script on 2014-02-09
-version = "7.x-2.2"
+; Information added by Drupal.org packaging script on 2016-05-12
+version = "7.x-2.3"
 core = "7.x"
 project = "libraries"
-datestamp = "1391965716"
+datestamp = "1463077450"
 

+ 3 - 3
sites/all/modules/contrib/dev/libraries/tests/modules/libraries_test_module/libraries_test_module.info

@@ -5,9 +5,9 @@ package = Testing
 dependencies[] = libraries
 hidden = TRUE
 
-; Information added by Drupal.org packaging script on 2014-02-09
-version = "7.x-2.2"
+; Information added by Drupal.org packaging script on 2016-05-12
+version = "7.x-2.3"
 core = "7.x"
 project = "libraries"
-datestamp = "1391965716"
+datestamp = "1463077450"
 

+ 5 - 0
sites/all/modules/contrib/dev/libraries/tests/modules/libraries_test_module/libraries_test_module.module

@@ -18,6 +18,9 @@ function libraries_test_module_libraries_info() {
   // Test library detection.
   $libraries['example_missing'] = array(
     'name' => 'Example missing',
+    // Provide a vendor and download URL to test that the UI links to it.
+    'vendor url' => 'http://example.com',
+    'download url' => 'http://example.com/download',
     'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/missing',
   );
   $libraries['example_undetected_version'] = array(
@@ -28,6 +31,8 @@ function libraries_test_module_libraries_info() {
   );
   $libraries['example_unsupported_version'] = array(
     'name' => 'Example unsupported version',
+    // Provide a download URL to test that the UI links to it.
+    'download url' => 'http://example.com/download',
     'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
     'version callback' => '_libraries_test_module_return_version',
     'version arguments' => array('1'),

+ 3 - 3
sites/all/modules/contrib/dev/libraries/tests/themes/libraries_test_theme/libraries_test_theme.info

@@ -3,9 +3,9 @@ description = Tests that themes can provide and alter library information.
 core = 7.x
 hidden = TRUE
 
-; Information added by Drupal.org packaging script on 2014-02-09
-version = "7.x-2.2"
+; Information added by Drupal.org packaging script on 2016-05-12
+version = "7.x-2.3"
 core = "7.x"
 project = "libraries"
-datestamp = "1391965716"
+datestamp = "1463077450"
 

+ 87 - 75
sites/all/modules/contrib/users/login_destination/login_destination.admin.inc

@@ -11,7 +11,6 @@
  * Shows list of all login destination.
  */
 function login_destination_overview_form($form, &$form_state) {
-
   // Get all login destination rules from the database.
   $result = db_select('login_destination', 'l')
     ->fields('l', array(
@@ -23,8 +22,7 @@ function login_destination_overview_form($form, &$form_state) {
       'destination',
       'weight',
       'enabled',
-      )
-    )
+    ))
     ->orderBy('weight')
     ->execute()
     ->fetchAll();
@@ -33,7 +31,6 @@ function login_destination_overview_form($form, &$form_state) {
 
   // Loop through the categories and add them to the table.
   foreach ($result as $data) {
-
     $triggers = array_map('check_plain', unserialize($data->triggers));
     if (empty($triggers)) {
       $triggers = array();
@@ -46,7 +43,10 @@ function login_destination_overview_form($form, &$form_state) {
 
     $form[$data->id]['destination']['#markup'] = theme('login_destination_destination', array('destination' => $data->destination));
     $form[$data->id]['triggers']['#markup'] = theme('login_destination_triggers', array('items' => $triggers));
-    $form[$data->id]['pages']['#markup'] = theme('login_destination_pages', array('pages' => $data->pages, 'pages_type' => $data->pages_type));
+    $form[$data->id]['pages']['#markup'] = theme('login_destination_pages', array(
+      'pages' => $data->pages,
+      'pages_type' => $data->pages_type,
+    ));
     $form[$data->id]['roles']['#markup'] = theme('login_destination_roles', array('items' => $roles));
 
     $form[$data->id]['weight'] = array(
@@ -77,9 +77,7 @@ function login_destination_overview_form($form, &$form_state) {
       '#title' => t('delete'),
       '#href' => 'admin/config/people/login-destination/delete/' . $data->id,
     );
-
     $form[$data->id]['operations'] = $operations;
-
   }
 
   if (element_children($form)) {
@@ -104,6 +102,8 @@ function login_destination_overview_form($form, &$form_state) {
  *   - form: A render element representing the form.
  *
  * @ingroup themeable
+ *
+ * @return string
  */
 function theme_login_destination_overview_form($variables) {
   $form = $variables['form'];
@@ -122,38 +122,42 @@ function theme_login_destination_overview_form($variables) {
 
   $rows = array();
   foreach (element_children($form) as $ldid) {
-    if (isset($form[$ldid]['enabled'])) {
+    if (!isset($form[$ldid]['enabled'])) {
+      continue;
+    }
+    $element = &$form[$ldid];
+    $operations = array();
 
-      $element = &$form[$ldid];
-
-      $operations = array();
-      foreach (element_children($element['operations']) as $op) {
-        $operations[] = array('data' => drupal_render($element['operations'][$op]), 'class' => array('login-destination-operations'));
-      }
-      while (count($operations) < 2) {
-        $operations[] = '';
-      }
-
-      $row = array();
-      $row[] = drupal_render($element['destination']);
-      $row[] = drupal_render($element['triggers']);
-      $row[] = drupal_render($element['pages']);
-      $row[] = drupal_render($element['roles']);
-      $row[] = array(
-        'data' => drupal_render($element['enabled']),
-        'class' => array(
-          'checkbox', 'login-destination-enabled',
-        ),
+    foreach (element_children($element['operations']) as $op) {
+      $operations[] = array(
+        'data' => drupal_render($element['operations'][$op]),
+        'class' => array('login-destination-operations'),
       );
+    }
+    while (count($operations) < 2) {
+      $operations[] = '';
+    }
 
-      $form[$ldid]['weight']['#attributes']['class'] = array('login-destination-weight');
+    $row = array();
+    $row[] = drupal_render($element['destination']);
+    $row[] = drupal_render($element['triggers']);
+    $row[] = drupal_render($element['pages']);
+    $row[] = drupal_render($element['roles']);
+    $row[] = array(
+      'data' => drupal_render($element['enabled']),
+      'class' => array(
+        'checkbox',
+        'login-destination-enabled',
+      ),
+    );
 
-      $row[] = drupal_render($element['weight']);
-      $row = array_merge($row, $operations);
-      $row = array_merge(array('data' => $row), array());
-      $row['class'][] = 'draggable';
-      $rows[] = $row;
-    }
+    $form[$ldid]['weight']['#attributes']['class'] = array('login-destination-weight');
+
+    $row[] = drupal_render($element['weight']);
+    $row = array_merge($row, $operations);
+    $row = array_merge(array('data' => $row), array());
+    $row['class'][] = 'draggable';
+    $rows[] = $row;
   }
 
   $output = '';
@@ -175,7 +179,6 @@ function theme_login_destination_overview_form($variables) {
   );
 
   $output .= theme('table', $table_arguments);
-
   $output .= drupal_render_children($form);
 
   return $output;
@@ -220,15 +223,20 @@ function login_destination_overview_form_submit($form, &$form_state) {
  */
 function _login_destination_update_rules($login_destination_rule) {
 
-  if (!(isset($login_destination_rule['enabled']) && isset($login_destination_rule['weight']) && isset($login_destination_rule['ldid']))) {
+  if (!(isset($login_destination_rule['enabled']) &&
+    isset($login_destination_rule['weight']) &&
+    isset($login_destination_rule['ldid']))
+  ) {
     return FALSE;
   }
 
-  if ($login_destination_rule['enabled'] != 0 && $login_destination_rule['enabled'] != 1) {
+  if ($login_destination_rule['enabled'] != 0 &&
+    $login_destination_rule['enabled'] != 1
+  ) {
     return FALSE;
   }
 
-  $login_destination_rule['weight'] = intval($login_destination_rule['weight']);
+  $login_destination_rule['weight'] = (int) $login_destination_rule['weight'];
 
   if (!is_int($login_destination_rule['weight'])) {
     return FALSE;
@@ -367,21 +375,20 @@ function login_destination_edit_form($form, &$form_state, array $rule = array())
       LOGIN_DESTINATION_STATIC => t('Internal page or external URL'),
     );
     $description = t("Specify page by using its path. Example path is %blog for the blog page. %front is the front page. %current is the current page. Precede with http:// for an external URL. Leave empty to redirect to a default page.", array(
-        '%blog' => 'blog',
-        '%front' => '<front>',
-        '%current' => '<current>',
-      )
-    );
+      '%blog' => 'blog',
+      '%front' => '<front>',
+      '%current' => '<current>',
+    ));
 
-    if (module_exists('php') && $access) {
+    if ($access && module_exists('php')) {
       $options += array(LOGIN_DESTINATION_SNIPPET => t('Page returned by this PHP code (experts only)'));
-      $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. It should return either a string value or an array of params that the %function function will understand, for example. %example. For more information, see the online API entry for <a href="@url">url function</a>. Note that executing incorrect PHP code can break your Drupal site.', array(
+      $description .= ' ' .
+        t('If the PHP option is chosen, enter PHP code between %php. It should return either a string value or an array of params that the %function function will understand, for example. %example. For more information, see the online API entry for <a href="@url">url function</a>. Note that executing incorrect PHP code can break your Drupal site.', array(
           '%php' => '<?php ?>',
           '%function' => 'url($path = \'\', array $options = array())',
           '%example' => '<?php return array(\'blog\', array(\'fragment\' => \'overlay=admin/config\', ), ); ?>',
           '@url' => 'http://api.drupal.org/api/drupal/includes--common.inc/function/url/7',
-        )
-      );
+        ));
     }
 
     $form['destination_type'] = array(
@@ -405,7 +412,10 @@ function login_destination_edit_form($form, &$form_state, array $rule = array())
   $form['triggers'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Redirect upon triggers'),
-    '#options' => array('login' => t('Login, registration, one-time login link'), 'logout' => t('Logout')),
+    '#options' => array(
+      'login' => t('Login, registration, one-time login link'),
+      'logout' => t('Logout'),
+    ),
     '#default_value' => $triggers,
     '#description' => t('Redirect only upon selected trigger(s). If you select no triggers, all of them will be used.'),
   );
@@ -428,18 +438,18 @@ function login_destination_edit_form($form, &$form_state, array $rule = array())
       LOGIN_DESTINATION_REDIRECT_LISTED => t('Only the listed pages'),
     );
     $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page. %login is the login form. %register is the registration form. %reset is the one-time login (e-mail validation).", array(
-        '%blog' => 'blog',
-        '%blog-wildcard' => 'blog/*',
-        '%front' => '<front>',
-        '%login' => 'user',
-        '%register' => 'user/register',
-        '%reset' => 'user/*/edit',
-      )
-    );
-
-    if (module_exists('php') && $access) {
+      '%blog' => 'blog',
+      '%blog-wildcard' => 'blog/*',
+      '%front' => '<front>',
+      '%login' => 'user',
+      '%register' => 'user/register',
+      '%reset' => 'user/*/edit',
+    ));
+
+    if ($access && module_exists('php')) {
       $options += array(LOGIN_DESTINATION_REDIRECT_PHP => t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'));
-      $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
+      $description .= ' ' .
+        t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
     }
 
     $form['pages_type'] = array(
@@ -489,16 +499,25 @@ function login_destination_edit_form($form, &$form_state, array $rule = array())
  */
 function login_destination_edit_form_validate($form, &$form_state) {
   $destination = $form_state['values']['destination'];
- $destination_type = $form_state['values']['destination_type'];
+  $destination_type = $form_state['values']['destination_type'];
 
   // Check user has enter any path.
-  if (!empty($destination) && $destination_type == 0) {
-    $destination = preg_replace("/\?.+/", "", $destination);
-    if (!drupal_valid_path($destination)) {
-      form_set_error('destination', t('Incorrect path, Please Enter valid Path'));
-    }
+  $available_urls = array('<current>', '<front>');
+  if (empty($destination) || $destination_type != 0 || in_array($destination, $available_urls)) {
+    return;
+  }
+  $destination = preg_replace("/\?.+/", "", $destination);
+  if (url_is_external($destination)) {
+    return;
+  }
+  // Get source path if an alias entered.
+  $source_path = drupal_lookup_path('source', $destination);
+  if (!empty($source_path)) {
+    $destination = $source_path;
+  }
+  if (!drupal_valid_path($destination)) {
+    form_set_error('destination', t('Incorrect path, please enter a valid path.'));
   }
-
 }
 
 /**
@@ -529,14 +548,7 @@ function login_destination_delete_form($form, &$form_state, array $rule) {
     '#value' => $rule,
   );
 
-  return confirm_form(
-    $form,
-    t('Are you sure you want to delete the login destination %destination ?', array('%destination' => $rule['destination'])),
-    'admin/config/people/login-destination',
-    t('This action cannot be undone.'),
-    t('Delete'),
-    t('Cancel')
-  );
+  return confirm_form($form, t('Are you sure you want to delete the login destination %destination ?', array('%destination' => $rule['destination'])), 'admin/config/people/login-destination', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
 }
 
 /**

+ 3 - 3
sites/all/modules/contrib/users/login_destination/login_destination.info

@@ -3,9 +3,9 @@ description = Customize the destination that the user is redirected to after log
 core = 7.x
 configure = admin/config/people/login-destination
 
-; Information added by Drupal.org packaging script on 2015-05-11
-version = "7.x-1.1+6-dev"
+; Information added by Drupal.org packaging script on 2016-01-22
+version = "7.x-1.4"
 core = "7.x"
 project = "login_destination"
-datestamp = "1431374284"
+datestamp = "1453451940"
 

+ 32 - 1
sites/all/modules/contrib/users/login_destination/login_destination.install

@@ -81,7 +81,11 @@ function login_destination_schema() {
 function login_destination_install() {
   // Update the alter option of 'user/logout' to TRUE,
   // (menu_save invokes necessary hooks).
-  $result = db_query("SELECT mlid, menu_name FROM {menu_links} WHERE link_path = 'user/logout' OR link_path = 'user/login' OR  link_path = 'user' ORDER BY mlid ASC");
+  $result = db_query("
+    SELECT mlid, menu_name
+    FROM {menu_links}
+    WHERE link_path = 'user/logout' OR link_path = 'user/login' OR  link_path = 'user'
+    ORDER BY mlid ASC");
   foreach ($result as $res) {
     $item = menu_link_load($res->mlid);
     $item['options']['alter'] = TRUE;
@@ -163,3 +167,30 @@ function login_destination_update_7001() {
 
   db_add_field('login_destination', 'enabled', $spec);
 }
+
+/**
+ * Clear hooks cache.
+ */
+function login_destination_update_7002() {
+  cache_clear_all('hook_info', 'cache_bootstrap');
+}
+
+/**
+ * Automatically give all roles with permission "Administer Users" the new dedicated permission
+ * "Administer Login Destination settings".
+ */
+function login_destination_update_7003() {
+  drupal_set_message(t('The Login Destination module has just been updated.<br>
+  A new permission called "Administer Login Destination settings" has now been
+  added.<br>Previously the access to the Login Destination\'s settings page was
+  managed by the "Administer Users" permission.<br>That\'s why all roles with
+  that old permission have been just automatically given the new dedicated
+  "Administer Login Destination settings" permission.<br>If you want to
+  duoble-check things, you can go to the
+  <a href="/admin/people/permissions" title="Permissions page" >Permissions page</a> now.'));
+
+  $roles = user_roles(TRUE, 'administer users');
+  foreach ($roles as $rid => $role_name) {
+    user_role_grant_permissions($rid, array('administer login destination settings'));
+  }
+}

File diff suppressed because it is too large
+ 0 - 0
sites/all/modules/contrib/users/login_destination/login_destination.module


Some files were not shown because too many files changed in this diff