updated login-destination, libraries
This commit is contained in:
parent
d1963312a6
commit
2b028cf376
@ -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.
|
||||
|
@ -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
sites/all/modules/contrib/dev/libraries/libraries.admin.inc
Normal file
547
sites/all/modules/contrib/dev/libraries/libraries.admin.inc
Normal file
@ -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;
|
||||
}
|
@ -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');
|
||||
|
@ -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.');
|
||||
function libraries_drush_cache_clear(array &$types) {
|
||||
$types['libraries'] = 'libraries_drush_invalidate_cache';
|
||||
}
|
||||
|
||||
case 'drush:libraries-download':
|
||||
return dt('Downloads a registered library into the libraries directory for the active site.
|
||||
|
||||
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.
|
||||
*
|
||||
* @param $name
|
||||
* The internal name of the library to download.
|
||||
* Only libraries that provide a download file URL can be downloaded.
|
||||
*
|
||||
* @see hook_libraries_info()
|
||||
* @see drush_pm_download()
|
||||
*/
|
||||
function libraries_drush_download($name) {
|
||||
return;
|
||||
function drush_libraries_download() {
|
||||
drush_command_include('pm-download');
|
||||
|
||||
// @todo Looks wonky?
|
||||
if (!drush_shell_exec('type unzip')) {
|
||||
return drush_set_error(dt('Missing dependency: unzip. Install it before using this command.'));
|
||||
}
|
||||
$libraries = libraries_info();
|
||||
|
||||
// @todo Simply use current drush site.
|
||||
$args = func_get_args();
|
||||
if ($args[0]) {
|
||||
$path = $args[0];
|
||||
}
|
||||
else {
|
||||
$path = 'sites/all/libraries';
|
||||
}
|
||||
// @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];
|
||||
|
||||
// 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');
|
||||
}
|
||||
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'];
|
||||
|
||||
// Set the directory to the download location.
|
||||
$olddir = getcwd();
|
||||
chdir($path);
|
||||
drush_log(dt('Downloading library !name ...', array('!name' => $machine_name)));
|
||||
|
||||
$filename = basename(COLORBOX_DOWNLOAD_URI);
|
||||
$dirname = basename(COLORBOX_DOWNLOAD_URI, '.zip');
|
||||
// @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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Download the zip archive
|
||||
if (!drush_shell_exec('wget '. COLORBOX_DOWNLOAD_URI)) {
|
||||
drush_shell_exec('curl -O '. COLORBOX_DOWNLOAD_URI);
|
||||
}
|
||||
// @todo Suport MD5 file hashing.
|
||||
|
||||
if (is_file($filename)) {
|
||||
// Decompress the zip archive
|
||||
drush_shell_exec('unzip -qq -o '. $filename);
|
||||
// Remove the zip archive
|
||||
drush_op('unlink', $filename);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Set working directory back to the previous working directory.
|
||||
chdir($olddir);
|
||||
// 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');
|
||||
}
|
||||
|
||||
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 Consider invoking a hook similar to
|
||||
// hook_drush_pm_download_destination_alter().
|
||||
|
||||
// @todo Consider adding version-control support similar to pm-download.
|
||||
|
||||
$install_location .= '/' . $machine_name;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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');
|
||||
|
||||
// @todo Consider invoking a hook similar to
|
||||
// hook_drush_pm_post_download().
|
||||
|
||||
// @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.
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
}
|
@ -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.
|
||||
*/
|
||||
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.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_prepare_files().
|
||||
*/
|
||||
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';
|
||||
class LibrariesLoadWebTest 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 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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.');
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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,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"
|
||||
|
||||
|
@ -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'])) {
|
||||
|
||||
$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',
|
||||
),
|
||||
);
|
||||
|
||||
$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;
|
||||
if (!isset($form[$ldid]['enabled'])) {
|
||||
continue;
|
||||
}
|
||||
$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',
|
||||
),
|
||||
);
|
||||
|
||||
$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',
|
||||
)
|
||||
);
|
||||
'%blog' => 'blog',
|
||||
'%blog-wildcard' => 'blog/*',
|
||||
'%front' => '<front>',
|
||||
'%login' => 'user',
|
||||
'%register' => 'user/register',
|
||||
'%reset' => 'user/*/edit',
|
||||
));
|
||||
|
||||
if (module_exists('php') && $access) {
|
||||
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,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"
|
||||
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +22,29 @@ function login_destination_help($path, $arg) {
|
||||
case 'admin/help#login_destination':
|
||||
$output = '';
|
||||
$output .= '<h3>' . t('About') . '</h3>';
|
||||
$output .= '<p>' . t('The Login Destination module allows you to customize the destination that the user is redirected to after logging in, registering to the site, using a one-time login link or logging out. The destination can be an internal page or an external URL. You may specify certain conditions like pages or user roles and make the destination depend upon them. You may also use a PHP snippets to provide custom conditions and destinations. Note that PHP Filter module has to be enabled and you have to be granted the "Use PHP for settings" permissions to be able to enter PHP code.') . '</p>';
|
||||
$output .= '<p>' .
|
||||
t('The Login Destination module allows you to customize the destination that the user is redirected to after logging in, registering to the site, using a one-time login link or logging out. The destination can be an internal page or an external URL. You may specify certain conditions like pages or user roles and make the destination depend upon them. You may also use a PHP snippets to provide custom conditions and destinations. Note that PHP Filter module has to be enabled and you have to be granted the "Use PHP for settings" permissions to be able to enter PHP code.') .
|
||||
'</p>';
|
||||
return $output;
|
||||
|
||||
case 'admin/config/people/login-destination':
|
||||
return '<p>' . t('Login destination rules are evaluated each time a user logs in, registers to the site, uses a one-time login link or logs out. Each rule consists of the destination, path conditions and user roles conditions. First matching rule gets executed.') . '</p>';
|
||||
return '<p>' .
|
||||
t('Login destination rules are evaluated each time a user logs in, registers to the site, uses a one-time login link or logs out. Each rule consists of the destination, path conditions and user roles conditions. First matching rule gets executed.') .
|
||||
'</p>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function login_destination_permission() {
|
||||
return array(
|
||||
'administer login destination settings' => array(
|
||||
'title' => t('Administer Login Destination settings'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
@ -39,7 +54,7 @@ function login_destination_menu() {
|
||||
'description' => 'Customize the destination that the user is redirected to after login.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('login_destination_overview_form'),
|
||||
'access arguments' => array('administer users'),
|
||||
'access arguments' => array('administer login destination settings'),
|
||||
'file' => 'login_destination.admin.inc',
|
||||
'weight' => 10,
|
||||
);
|
||||
@ -47,7 +62,7 @@ function login_destination_menu() {
|
||||
'title' => 'Add login destination rule',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('login_destination_edit_form'),
|
||||
'access arguments' => array('administer users'),
|
||||
'access arguments' => array('administer login destination settings'),
|
||||
'type' => MENU_LOCAL_ACTION,
|
||||
'weight' => 1,
|
||||
'file' => 'login_destination.admin.inc',
|
||||
@ -56,14 +71,14 @@ function login_destination_menu() {
|
||||
'title' => 'Edit login destination rule',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('login_destination_edit_form', 5),
|
||||
'access arguments' => array('administer users'),
|
||||
'access arguments' => array('administer login destination settings'),
|
||||
'file' => 'login_destination.admin.inc',
|
||||
);
|
||||
$items['admin/config/people/login-destination/delete/%login_destination'] = array(
|
||||
'title' => 'Delete login destination rule',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('login_destination_delete_form', 5),
|
||||
'access arguments' => array('administer users'),
|
||||
'access arguments' => array('administer login destination settings'),
|
||||
'file' => 'login_destination.admin.inc',
|
||||
);
|
||||
$items['admin/config/people/login-destination/list'] = array(
|
||||
@ -76,7 +91,7 @@ function login_destination_menu() {
|
||||
'description' => 'Change Login Destination settings.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('login_destination_settings'),
|
||||
'access arguments' => array('administer users'),
|
||||
'access arguments' => array('administer login destination settings'),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'file' => 'login_destination.admin.inc',
|
||||
'weight' => 10,
|
||||
@ -141,14 +156,14 @@ function login_destination_theme() {
|
||||
*/
|
||||
function login_destination_form_alter(&$form, &$form_state, $form_id) {
|
||||
// We redirect by using the drupal_goto_alter hook. If we simply
|
||||
// call drupal_goto() it may break compability with other modules. If we set
|
||||
// call drupal_goto() it may break compatibility with other modules. If we set
|
||||
// the $_GET['destination'] variable we will loose the possibility to redirect
|
||||
// to an external URL.
|
||||
|
||||
// Please note the the system_goto_action() calls drupal_goto()
|
||||
// More on this issue http://drupal.org/node/732542.
|
||||
|
||||
// If we add the $form_state['redirect'] here it will be overriden by the
|
||||
// If we add the $form_state['redirect'] here it will be overridden by the
|
||||
// user_login_submit(). So we add a submit handler instead and will set the
|
||||
// redirect later. Our submit handler will be executed after the execution
|
||||
// of user_login_submit(). This is because form_submit() functions are
|
||||
@ -203,7 +218,6 @@ function login_destination_validate($form, &$form_state) {
|
||||
$_GET['current'] = $_GET['destination'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,11 +244,16 @@ function login_destination_menu_link_alter(&$item) {
|
||||
* Implements hook_translated_menu_link_alter().
|
||||
*/
|
||||
function login_destination_translated_menu_link_alter(&$item, $map) {
|
||||
global $user;
|
||||
$paths = array('user/login', 'user');
|
||||
// Append the current path to URL.
|
||||
if ($item['link_path'] == 'user/logout' || (in_array($item['link_path'], $paths) && user_is_anonymous())) {
|
||||
$item['localized_options']['query'] = array('current' => $_GET['q']);
|
||||
if ($item['link_path'] == 'user/logout' ||
|
||||
(in_array($item['link_path'], $paths) && user_is_anonymous())
|
||||
) {
|
||||
$current = $_GET['q'];
|
||||
if ($current == '<front>') {
|
||||
$current = '';
|
||||
}
|
||||
$item['localized_options']['query'] = array('current' => $current);
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +263,7 @@ function login_destination_translated_menu_link_alter(&$item, $map) {
|
||||
function login_destination_page_alter(&$page) {
|
||||
// Substitute toolbar's pre_render function to change links.
|
||||
if (isset($page['page_top']['toolbar']['#pre_render'])) {
|
||||
$page['page_top']['toolbar']['#pre_render'][0] = 'login_destination_toolbar_pre_render';
|
||||
$page['page_top']['toolbar']['#pre_render'][] = 'login_destination_toolbar_pre_render';
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,9 +271,9 @@ function login_destination_page_alter(&$page) {
|
||||
* Helper function to change toolbar's links.
|
||||
*/
|
||||
function login_destination_toolbar_pre_render($toolbar) {
|
||||
$toolbar = toolbar_pre_render($toolbar);
|
||||
// Add current param to be able to evaluate previous page.
|
||||
$toolbar['toolbar_user']['#links']['logout']['query'] = array('current' => $_GET['q']);
|
||||
|
||||
return $toolbar;
|
||||
}
|
||||
|
||||
@ -262,7 +281,11 @@ function login_destination_toolbar_pre_render($toolbar) {
|
||||
* Implements hook_user_login().
|
||||
*/
|
||||
function login_destination_user_login(&$edit, $account) {
|
||||
if (!isset($_POST['form_id']) || $_POST['form_id'] != 'user_pass_reset' || variable_get('login_destination_immediate_redirect', FALSE)) {
|
||||
$form_exception = 'user_pass_reset';
|
||||
if (module_exists('change_pwd_page')) {
|
||||
$form_exception = 'change_pwd_page_user_pass_reset';
|
||||
}
|
||||
if (!isset($_POST['form_id']) || $_POST['form_id'] != $form_exception || variable_get('login_destination_immediate_redirect', FALSE)) {
|
||||
login_destination_perform_redirect('login');
|
||||
}
|
||||
}
|
||||
@ -291,23 +314,22 @@ function login_destination_user_logout($account) {
|
||||
* Implements hook_drupal_goto_alter().
|
||||
*/
|
||||
function login_destination_drupal_goto_alter(&$path, &$options, &$http_response_code) {
|
||||
// Note that this functionality cannot be backported do 6.x as Drupal 6 does
|
||||
// Note that this functionality cannot be backported to 6.x as Drupal 6 does
|
||||
// not call drupal_alter for drupal_goto.
|
||||
|
||||
// This actually may be used also by templates.
|
||||
if (isset($GLOBALS['destination'])) {
|
||||
$destination = $GLOBALS['destination'];
|
||||
if (!isset($GLOBALS['destination'])) {
|
||||
return;
|
||||
}
|
||||
$destination = $GLOBALS['destination'];
|
||||
$path = $destination;
|
||||
|
||||
// Alter drupal_goto.
|
||||
if (is_array($destination)) {
|
||||
$path = $destination[0];
|
||||
$options = array();
|
||||
if (count($destination) > 1) {
|
||||
$options = $destination[1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$path = $destination;
|
||||
// Alter drupal_goto.
|
||||
if (is_array($destination)) {
|
||||
$path = $destination[0];
|
||||
$options = array();
|
||||
if (count($destination) > 1) {
|
||||
$options = $destination[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -317,7 +339,9 @@ function login_destination_drupal_goto_alter(&$path, &$options, &$http_response_
|
||||
*/
|
||||
function login_destination_prepare_goto($destination) {
|
||||
// Check if $_GET['destination'] should overwrite us.
|
||||
if (!isset($_GET['destination']) || !variable_get('login_destination_preserve_destination', FALSE)) {
|
||||
if (!isset($_GET['destination']) ||
|
||||
!variable_get('login_destination_preserve_destination', FALSE)
|
||||
) {
|
||||
$GLOBALS['destination'] = $destination;
|
||||
}
|
||||
}
|
||||
@ -357,14 +381,13 @@ function login_destination_get_destination($trigger = '', $current = NULL) {
|
||||
'destination_type',
|
||||
'destination',
|
||||
'enabled',
|
||||
)
|
||||
)
|
||||
))
|
||||
->orderBy('weight')
|
||||
->execute()
|
||||
->fetchAll();
|
||||
|
||||
if ($current == NULL) {
|
||||
$current = $_GET['q'];
|
||||
if ($current === NULL) {
|
||||
$current = _login_destination_get_current($trigger);
|
||||
}
|
||||
|
||||
// Examine path matches.
|
||||
@ -402,6 +425,11 @@ function _login_destination_role_options() {
|
||||
|
||||
/**
|
||||
* Get the current path (before trigger was invoked).
|
||||
*
|
||||
* @param string $trigger
|
||||
* Trigger.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function _login_destination_get_current($trigger = '') {
|
||||
if (isset($_GET['current'])) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user