updated elysia_cron, elfinder, metatag, libraries, email_registration, migrate, nodeform_cols
This commit is contained in:
@@ -153,6 +153,8 @@ Options:
|
||||
--verbose, but without enabling drush
|
||||
verbose mode)
|
||||
--ignore-disable run channels/tasks even if disabled
|
||||
--ignore-maintenance run channels/tasks even if
|
||||
maintenance mode is enabled
|
||||
--ignore-running run channels/tasks even
|
||||
if already running
|
||||
--ignore-time run channels/tasks even if not ready
|
||||
|
@@ -10,6 +10,9 @@
|
||||
*
|
||||
* @return array
|
||||
* Renderable array.
|
||||
*
|
||||
* @throws Exception
|
||||
* Exceptions from theme().
|
||||
*/
|
||||
function elysia_cron_admin_page() {
|
||||
$aoutput = array();
|
||||
@@ -151,10 +154,26 @@ function elysia_cron_admin_page() {
|
||||
$output .= '<br />';
|
||||
|
||||
$legend_icons = array(
|
||||
'idle' => theme('image', array('path' => $ipath . 'idle.png')),
|
||||
'waiting' => theme('image', array('path' => $ipath . 'waiting.png')),
|
||||
'running' => theme('image', array('path' => $ipath . 'running.png')),
|
||||
'disabled' => theme('image', array('path' => $ipath . 'disabled.png')),
|
||||
'idle' => theme('image', array(
|
||||
'path' => $ipath . 'idle.png',
|
||||
'alt' => t('Idle'),
|
||||
'title' => t('Idle'),
|
||||
)),
|
||||
'waiting' => theme('image', array(
|
||||
'path' => $ipath . 'waiting.png',
|
||||
'alt' => t('Waiting for execution'),
|
||||
'title' => t('Waiting for execution'),
|
||||
)),
|
||||
'running' => theme('image', array(
|
||||
'path' => $ipath . 'running.png',
|
||||
'alt' => t('Running'),
|
||||
'title' => t('Running'),
|
||||
)),
|
||||
'disabled' => theme('image', array(
|
||||
'path' => $ipath . 'disabled.png',
|
||||
'alt' => t('Disabled'),
|
||||
'title' => t('Disabled'),
|
||||
)),
|
||||
);
|
||||
$output .= theme('table', array(
|
||||
'header' => array(t('Legend')),
|
||||
@@ -187,6 +206,7 @@ function elysia_cron_settings_form() {
|
||||
elysia_cron_initialize();
|
||||
|
||||
$form = array();
|
||||
$form['#attached']['js'][] = drupal_get_path('module', 'elysia_cron') . '/js/elysia_cron.js';
|
||||
|
||||
$form['prefix_1'] = array(
|
||||
'#type' => 'fieldset',
|
||||
@@ -429,14 +449,6 @@ EOT
|
||||
'#collapsible' => TRUE,
|
||||
);
|
||||
|
||||
$jobchannels = array(
|
||||
'#title' => t('Job channel associations'),
|
||||
'#description' => t('Leave empty for default channel'),
|
||||
'#type' => 'fieldset',
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
|
||||
foreach ($_elysia_cron_settings_by_channel as $channel => $cconf) {
|
||||
foreach ($cconf as $job => $conf) {
|
||||
if ($job != '#data' && empty($conf['expression'])) {
|
||||
@@ -546,12 +558,6 @@ EOT
|
||||
function theme_elysia_cron_settings_form(array &$variables) {
|
||||
$form = &$variables['form'];
|
||||
|
||||
$output = '<script type="text/javascript"><!--' . "\n" .
|
||||
'function _ec_select(key, select) { if (select.value == \'custom\') {' .
|
||||
'$ = jQuery; $("#_ec_select_"+key).hide();$("#_ec_custom_"+key).show();$("#_ec_custom_"+key).focus();' .
|
||||
'}}' .
|
||||
"\n" . '--></script>';
|
||||
|
||||
$coutput = '<table>';
|
||||
|
||||
$i = 0;
|
||||
@@ -579,7 +585,8 @@ function theme_elysia_cron_settings_form(array &$variables) {
|
||||
$form['single_job'][$c]['_elysia_cron_seljob_rule_' . $key]['#suffix'] = '</span>';
|
||||
$form['single_job'][$c]['_elysia_cron_seljob_rule_' . $key]['#title'] = NULL;
|
||||
$form['single_job'][$c]['_elysia_cron_seljob_rule_' . $key]['#description'] = NULL;
|
||||
$form['single_job'][$c]['_elysia_cron_seljob_rule_' . $key]['#attributes']['onchange'] = '_ec_select(\'' . $key . '\', this)';
|
||||
$form['single_job'][$c]['_elysia_cron_seljob_rule_' . $key]['#attributes']['class'][] = 'ec-select';
|
||||
$form['single_job'][$c]['_elysia_cron_seljob_rule_' . $key]['#attributes']['data-key'] = $key;
|
||||
|
||||
$form['single_job'][$c]['_elysia_cron_job_weight_' . $key]['#title'] = NULL;
|
||||
$form['single_job'][$c]['_elysia_cron_job_weight_' . $key]['#description'] = NULL;
|
||||
@@ -631,7 +638,7 @@ function theme_elysia_cron_settings_form(array &$variables) {
|
||||
|
||||
$form['channels']['#children'] = $coutput;
|
||||
|
||||
return $output . drupal_render_children($form);
|
||||
return drupal_render_children($form);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -5,6 +5,8 @@
|
||||
* Ctools integration.
|
||||
*/
|
||||
|
||||
define('ELYSIA_CRON_CTOOLS_LINEBREAK', "\n");
|
||||
|
||||
/**
|
||||
* Get default cron jobs.
|
||||
*
|
||||
@@ -203,13 +205,13 @@ function elysia_cron_ctools_export_callback($object, $indent) {
|
||||
$schema = ctools_export_get_schema($table);
|
||||
$identifier = $schema['export']['identifier'];
|
||||
|
||||
$output = $indent . '$' . $identifier . ' = new ' . get_class($object) . ';' . PHP_EOL;
|
||||
$output = $indent . '$' . $identifier . ' = new ' . get_class($object) . '();' . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
|
||||
if ($schema['export']['can disable']) {
|
||||
$output .= $indent . '$' . $identifier . '->disabled = FALSE; /* Edit this to true to make a default ' . $identifier . ' disabled initially */' . PHP_EOL;
|
||||
$output .= $indent . '$' . $identifier . '->disabled = FALSE; /* Edit this to true to make a default ' . $identifier . ' disabled initially */' . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
}
|
||||
if (!empty($schema['export']['api']['current_version'])) {
|
||||
$output .= $indent . '$' . $identifier . '->api_version = ' . $schema['export']['api']['current_version'] . ';' . PHP_EOL;
|
||||
$output .= $indent . '$' . $identifier . '->api_version = ' . $schema['export']['api']['current_version'] . ';' . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
}
|
||||
|
||||
$fields = $schema['fields'];
|
||||
@@ -222,7 +224,7 @@ function elysia_cron_ctools_export_callback($object, $indent) {
|
||||
if (!is_null($value) && $info['type'] == 'int') {
|
||||
$value = (isset($info['size']) && $info['size'] == 'tiny') ? (bool) $value : (int) $value;
|
||||
}
|
||||
$output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ';' . PHP_EOL;
|
||||
$output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ';' . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
}
|
||||
|
||||
return $output;
|
||||
@@ -253,19 +255,19 @@ function elysia_cron_ctools_to_hook_code(array $names, $name) {
|
||||
$objects = array_intersect_key($objects, array_flip($names));
|
||||
|
||||
if ($objects) {
|
||||
$output = '/**' . PHP_EOL;
|
||||
$output .= " * Implementation of hook_{$export['default hook']}()" . PHP_EOL;
|
||||
$output .= ' */' . PHP_EOL;
|
||||
$output .= "function " . $name . "_{$export['default hook']}() {" . PHP_EOL;
|
||||
$output .= " \${$export['identifier']}s = array();" . PHP_EOL . PHP_EOL;
|
||||
$output = '/**' . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
$output .= " * Implementation of hook_{$export['default hook']}()" . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
$output .= ' */' . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
$output .= "function " . $name . "_{$export['default hook']}() {" . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
$output .= " \${$export['identifier']}s = array();" . ELYSIA_CRON_CTOOLS_LINEBREAK . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
|
||||
foreach ($objects as $object) {
|
||||
$output .= ctools_export_crud_export($table, $object, ' ');
|
||||
$output .= " \${$export['identifier']}s['" . check_plain($object->{$export['key']}) . "'] = \${$export['identifier']};" . PHP_EOL . PHP_EOL;
|
||||
$output .= " \${$export['identifier']}s['" . check_plain($object->{$export['key']}) . "'] = \${$export['identifier']};" . ELYSIA_CRON_CTOOLS_LINEBREAK . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
}
|
||||
|
||||
$output .= " return \${$export['identifier']}s;" . PHP_EOL;
|
||||
$output .= '}' . PHP_EOL;
|
||||
$output .= " return \${$export['identifier']}s;" . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
$output .= '}' . ELYSIA_CRON_CTOOLS_LINEBREAK;
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
@@ -63,7 +63,9 @@ function elysia_cron_drush_command() {
|
||||
'quiet' => 'suppress all output',
|
||||
'verbose' => 'enable extended output',
|
||||
'elysia-cron-verbose' => 'enable extended output (the same as --verbose, but without enabling drush verbose mode)',
|
||||
'force' => 'run channels/tasks even if it disabled/not ready for execution/already running',
|
||||
'ignore-disable' => 'run channels/tasks even if disabled',
|
||||
'ignore-maintenance' => 'run channels/tasks even if maintenance mode is enabled',
|
||||
'ignore-time' => 'run channels/tasks even if not ready for execution',
|
||||
'ignore-running' => 'run channels/tasks even if already running',
|
||||
),
|
||||
@@ -79,8 +81,10 @@ function elysia_cron_drush_command() {
|
||||
function drush_elysia_cron_run_wrapper($op = FALSE, $target = FALSE) {
|
||||
global $_elysia_cron_drush;
|
||||
|
||||
$force = drush_get_option('force', FALSE);
|
||||
if (variable_get('maintenance_mode', FALSE)) {
|
||||
if (!variable_get('elysia_cron_run_maintenance', FALSE)) {
|
||||
$ignore_maintenance = $force || drush_get_option('ignore-maintenance', FALSE);
|
||||
if (!$ignore_maintenance && !variable_get('elysia_cron_run_maintenance', FALSE)) {
|
||||
drush_set_error('Cron run is not allowed in maintenance mode');
|
||||
return;
|
||||
}
|
||||
@@ -91,7 +95,16 @@ function drush_elysia_cron_run_wrapper($op = FALSE, $target = FALSE) {
|
||||
if (!$verbose) {
|
||||
$verbose = drush_get_option('elysia-cron-verbose', FALSE);
|
||||
}
|
||||
$_elysia_cron_drush = $quiet ? 1 : !$verbose ? 2 : 3;
|
||||
|
||||
if ($quiet) {
|
||||
$_elysia_cron_drush = 1;
|
||||
}
|
||||
elseif ($verbose) {
|
||||
$_elysia_cron_drush = 3;
|
||||
}
|
||||
else {
|
||||
$_elysia_cron_drush = 2;
|
||||
}
|
||||
|
||||
switch ($op) {
|
||||
case 'list':
|
||||
@@ -140,13 +153,18 @@ function drush_elysia_cron_run_wrapper($op = FALSE, $target = FALSE) {
|
||||
break;
|
||||
|
||||
case 'run':
|
||||
// Collect options.
|
||||
$ignore_disable = $force || drush_get_option('ignore-disable', FALSE);
|
||||
$ignore_time = $force || drush_get_option('ignore-time', FALSE);
|
||||
$ignore_running = $force || drush_get_option('ignore-running', FALSE);
|
||||
|
||||
if (empty($target)) {
|
||||
elysia_cron_run(FALSE, drush_get_option('ignore-disable', FALSE), drush_get_option('ignore-time', FALSE), drush_get_option('ignore-running', FALSE));
|
||||
elysia_cron_run(FALSE, $ignore_disable, $ignore_time, $ignore_running);
|
||||
}
|
||||
elseif (strpos($target, '@') === 0) {
|
||||
elysia_cron_initialize();
|
||||
if (elysia_cron_channel_exists(substr($target, 1))) {
|
||||
elysia_cron_run_channel(substr($target, 1), drush_get_option('ignore-disable', FALSE), drush_get_option('ignore-time', FALSE), drush_get_option('ignore-running', FALSE));
|
||||
elysia_cron_run_channel(substr($target, 1), $ignore_disable, $ignore_time, $ignore_running);
|
||||
}
|
||||
else {
|
||||
drush_set_error('Channel ' . substr($target, 1) . ' does not exists');
|
||||
@@ -155,7 +173,7 @@ function drush_elysia_cron_run_wrapper($op = FALSE, $target = FALSE) {
|
||||
else {
|
||||
elysia_cron_initialize();
|
||||
if (elysia_cron_job_exists($target)) {
|
||||
elysia_cron_run_job($target, drush_get_option('ignore-disable', FALSE), drush_get_option('ignore-time', FALSE), drush_get_option('ignore-running', FALSE));
|
||||
elysia_cron_run_job($target, $ignore_disable, $ignore_time, $ignore_running);
|
||||
}
|
||||
else {
|
||||
drush_set_error('Job ' . $target . ' does not exists');
|
||||
|
@@ -4,9 +4,8 @@ core = 7.x
|
||||
|
||||
configure = admin/config/system/cron
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-11-23
|
||||
version = "7.x-2.4"
|
||||
; Information added by Drupal.org packaging script on 2019-04-24
|
||||
version = "7.x-2.7"
|
||||
core = "7.x"
|
||||
project = "elysia_cron"
|
||||
datestamp = "1479877741"
|
||||
|
||||
datestamp = "1556076200"
|
||||
|
@@ -64,14 +64,15 @@ function elysia_cron_menu() {
|
||||
*/
|
||||
function elysia_cron_menu_alter(&$items) {
|
||||
// Override default cron page.
|
||||
$items['admin/config/system/cron'] = array(
|
||||
'title' => 'Cron Settings',
|
||||
'description' => 'View and manage cron table',
|
||||
'page callback' => 'elysia_cron_admin_page',
|
||||
'access callback' => 'elysia_cron_access',
|
||||
'access arguments' => array('view elysia_cron'),
|
||||
'file' => NULL,
|
||||
) + $items['admin/config/system/cron'];
|
||||
$items['admin/config/system/cron']['title'] = 'Cron Settings';
|
||||
$items['admin/config/system/cron']['description'] = 'View and manage cron table';
|
||||
$items['admin/config/system/cron']['page callback'] = 'elysia_cron_admin_page';
|
||||
$items['admin/config/system/cron']['access callback'] = 'elysia_cron_access';
|
||||
$items['admin/config/system/cron']['access arguments'] = array('view elysia_cron');
|
||||
$items['admin/config/system/cron']['file'] = NULL;
|
||||
|
||||
$items['admin/reports/status/run-cron']['page callback'] = 'elysia_cron_run_manually';
|
||||
$items['admin/reports/status/run-cron']['file'] = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +114,7 @@ function elysia_cron_permission() {
|
||||
'administer elysia_cron' => array(
|
||||
'title' => t('Administer elysia cron'),
|
||||
'description' => t('Perform changes to cron jobs timings, disable cron or single jobs and access cron execution statistics'),
|
||||
'restrict access' => TRUE,
|
||||
'restrict access' => TRUE,
|
||||
),
|
||||
'execute elysia_cron' => array(
|
||||
'title' => t('Execute elysia cron jobs'),
|
||||
@@ -143,6 +144,12 @@ function elysia_cron_exit() {
|
||||
function elysia_cron_cron() {
|
||||
global $_elysia_cron_exit_phase, $_elysia_cron_drush;
|
||||
|
||||
// First cron run is executed in standard drupal way.
|
||||
// This is to enable the use of install profiles.
|
||||
if (variable_get('cron_last', 0) <= variable_get('install_time', 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If cron has been executed via "drush core-cron" or any other custom drush
|
||||
// command then we run internal cron handler which is designed to handle
|
||||
// cron executions from drush.
|
||||
@@ -150,11 +157,6 @@ function elysia_cron_cron() {
|
||||
elysia_cron_drush_invoke();
|
||||
}
|
||||
|
||||
// First cron run is executed in standard drupal way.
|
||||
// This is to enable the use of install profiles.
|
||||
if (variable_get('cron_last', 0) <= variable_get('install_time', 0)) {
|
||||
return;
|
||||
}
|
||||
// If the path is 'admin/*', or if the user is not anonymous,
|
||||
// this is a manual cron run (probably by admin/logs/status),
|
||||
// but not if we are in the exit phase (= this a "poormanscron" run).
|
||||
@@ -187,7 +189,7 @@ function elysia_cron_cron() {
|
||||
variable_set('cron_last', time());
|
||||
}
|
||||
|
||||
exit();
|
||||
drupal_exit();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,8 +240,11 @@ $GLOBALS['_ec_variables_allowed'] = array(
|
||||
*/
|
||||
function _ec_variable_init() {
|
||||
global $_ec_variables, $_ec_variables_allowed;
|
||||
|
||||
$_ec_variables = array();
|
||||
$_ec_variables = array_map('unserialize', db_query("SELECT name, value FROM {variable} where name like '" . implode("' or name like '", $_ec_variables_allowed) . "'")->fetchAllKeyed());
|
||||
foreach ($_ec_variables_allowed as $name) {
|
||||
$_ec_variables[$name] = variable_get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -925,7 +930,7 @@ function elysia_cron_debug($message, $vars = array(), $type = WATCHDOG_NOTICE) {
|
||||
if ($type < WATCHDOG_NOTICE || variable_get('elysia_cron_debug_messages', 0)) {
|
||||
watchdog('cron', $message, $vars, $type);
|
||||
}
|
||||
if (!empty($_elysia_cron_drush) && $_elysia_cron_drush >= 2 && ($type >= WATCHDOG_NOTICE || !drush_get_option("verbose", FALSE))) {
|
||||
if (!empty($_elysia_cron_drush) && $_elysia_cron_drush >= 2 && ($type >= WATCHDOG_NOTICE || drush_get_option("verbose", FALSE))) {
|
||||
if ($type >= WATCHDOG_NOTICE) {
|
||||
drush_print(strip_tags(dt($message, $vars)));
|
||||
}
|
||||
@@ -1143,7 +1148,7 @@ function elysia_cron_prepare_run($manual_run, $start = TRUE) {
|
||||
|
||||
// Try to allocate enough time to run all the hook_cron implementations.
|
||||
if (!ini_get('safe_mode') && _elysia_cron_function_available('set_time_limit')) {
|
||||
set_time_limit(variable_get('elysia_cron_time_limit', 240));
|
||||
@set_time_limit(variable_get('elysia_cron_time_limit', 240));
|
||||
}
|
||||
|
||||
// Prevent session information from being saved while cron is running.
|
||||
@@ -1294,6 +1299,21 @@ function elysia_cron_run($manual_run = FALSE, $ignore_disable = FALSE, $ignore_t
|
||||
return $execute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback: run cron manually.
|
||||
*/
|
||||
function elysia_cron_run_manually() {
|
||||
// Run cron manually
|
||||
if (elysia_cron_run(TRUE)) {
|
||||
drupal_set_message(t('Cron ran successfully.'));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Cron run failed.'), 'error');
|
||||
}
|
||||
|
||||
drupal_goto('admin/reports/status');
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function to execute all jobs in a channel.
|
||||
*
|
||||
@@ -1303,6 +1323,9 @@ function elysia_cron_run($manual_run = FALSE, $ignore_disable = FALSE, $ignore_t
|
||||
* Run channel (and all it's jobs) job even if not ready.
|
||||
* @param bool $ignore_running
|
||||
* Run the channel (and all it's jobs) even if already running.
|
||||
*
|
||||
* @return bool
|
||||
* Result of execution.
|
||||
*/
|
||||
function elysia_cron_run_channel($channel, $ignore_disable = FALSE, $ignore_time = FALSE, $ignore_running = FALSE) {
|
||||
global $_elysia_cron_settings_by_channel;
|
||||
@@ -1530,7 +1553,8 @@ function elysia_cron_check_run_job($job) {
|
||||
/**
|
||||
* Find an idle channel (not running, or stuck). If found one, set it as running and returns available jobs.
|
||||
*
|
||||
* @return if found returns array { 'name' => name of channel, 'jobs' => array of active jobs }, else return FALSE
|
||||
* @return array|bool
|
||||
* If found returns array { 'name' => name of channel, 'jobs' => array of active jobs }, else return FALSE.
|
||||
*/
|
||||
function elysia_cron_run_available_channel($ignore_disable = FALSE, $ignore_time = FALSE, $ignore_running = FALSE) {
|
||||
global $_elysia_cron_settings_by_channel;
|
||||
@@ -1592,7 +1616,7 @@ function elysia_cron_execute_aborted($channel) {
|
||||
* Used for unexpected termination of code.
|
||||
*/
|
||||
function elysia_cron_internal_execute_channel_cleanup() {
|
||||
global $_elysia_cron_settings, $_elysia_cron_current_channel, $_cron_completed, $_cron_completed_time;
|
||||
global $_elysia_cron_current_channel, $_cron_completed;
|
||||
|
||||
if ($_cron_completed) {
|
||||
return;
|
||||
@@ -1825,16 +1849,16 @@ function elysia_cron_ping_page() {
|
||||
$max_interval = variable_get('elysia_cron_alert_interval', 60) * 60;
|
||||
|
||||
if ($diff > $max_interval) {
|
||||
return drupal_not_found();
|
||||
}
|
||||
else {
|
||||
$aoutput = array();
|
||||
$aoutput[] = array(
|
||||
'#type' => 'markup',
|
||||
'#markup' => t('Cron has been called within maximum lapse time.'),
|
||||
);
|
||||
return $aoutput;
|
||||
drupal_not_found();
|
||||
drupal_exit();
|
||||
}
|
||||
|
||||
$aoutput = array();
|
||||
$aoutput[] = array(
|
||||
'#type' => 'markup',
|
||||
'#markup' => t('Cron has been called within maximum lapse time.'),
|
||||
);
|
||||
return $aoutput;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -1842,6 +1866,9 @@ function elysia_cron_ping_page() {
|
||||
* ONLY FOR D7
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Implements hook_cronapi().
|
||||
*/
|
||||
function elysia_cron_cronapi($op, $job = FALSE) {
|
||||
$items = array();
|
||||
|
||||
@@ -1879,6 +1906,14 @@ function elysia_cron_cronapi($op, $job = FALSE) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for cronapi.
|
||||
*
|
||||
* @param string $queue_name
|
||||
* Queue name.
|
||||
* @param array $info
|
||||
* Info about queue.
|
||||
*/
|
||||
function elysia_cron_queue_exec($queue_name, $info) {
|
||||
$function = $info['worker callback'];
|
||||
$end = time() + (isset($info['time']) ? $info['time'] : 15);
|
||||
@@ -1908,6 +1943,9 @@ function elysia_cron_queue_exec($queue_name, $info) {
|
||||
* Array of links under admin/* that were removed by
|
||||
* admin_menu_adjust_items(). If one of these links is added back,
|
||||
* it should be removed from the array.
|
||||
*
|
||||
* @return array
|
||||
* Links array.
|
||||
*/
|
||||
function elysia_cron_admin_menu(&$deleted) {
|
||||
$links = array();
|
||||
|
@@ -9,8 +9,6 @@
|
||||
* Function for cron run schedule.
|
||||
*/
|
||||
function elysia_cron_should_run($conf, $now = -1, $ignore_disable = FALSE, $ignore_time = FALSE) {
|
||||
// What time SHOULD the job be executed last time.
|
||||
$prev_rule_run = 0;
|
||||
if (!$ignore_disable && $conf['disabled']) {
|
||||
return FALSE;
|
||||
}
|
||||
@@ -53,17 +51,17 @@ function _elysia_cron_next_run($conf) {
|
||||
|
||||
$rule = array($rules[1], $rules[2], array($rules[3], $rules[5]), $rules[4]);
|
||||
$ruledec = array();
|
||||
$date = __cronDecodeDate($conf['last_run'], 1);
|
||||
$expected_date = __cronDecodeDate(!empty($conf['last_run_expected']) ? $conf['last_run_expected'] : 0);
|
||||
$date = _cronDecodeDate($conf['last_run'], 1);
|
||||
$expected_date = _cronDecodeDate(!empty($conf['last_run_expected']) ? $conf['last_run_expected'] : 0);
|
||||
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
if ($i != 2) {
|
||||
// Standard scheme for mins, hours, month.
|
||||
$ruledec[$i] = __cronDecodeRule($rule[$i], $ranges[$i][0], $ranges[$i][1]);
|
||||
$ruledec[$i] = _cronDecodeRule($rule[$i], $ranges[$i][0], $ranges[$i][1]);
|
||||
}
|
||||
else {
|
||||
// For mday+week we follow another scheme.
|
||||
$ruledec[$i] = __cronDecodeRuleMday($rule[2], $date[3], $date[4]);
|
||||
$ruledec[$i] = _cronDecodeRuleMday($rule[2], $date[3], $date[4]);
|
||||
}
|
||||
$r = $ruledec[$i];
|
||||
$new = $date[$i];
|
||||
@@ -74,7 +72,7 @@ function _elysia_cron_next_run($conf) {
|
||||
$new = $expected_date[$i] + ceil(($date[$i] - $expected_date[$i]) / $r['d']) * $r['d'];
|
||||
}
|
||||
elseif ($r['n']) {
|
||||
$new = __cronNextOrEqual($date[$i], $r['n'], $ranges[$i][0], $ranges[$i][1]);
|
||||
$new = _cronNextOrEqual($date[$i], $r['n'], $ranges[$i][0], $ranges[$i][1]);
|
||||
}
|
||||
if ($new != $date[$i]) {
|
||||
$date[$i] = $new;
|
||||
@@ -85,7 +83,7 @@ function _elysia_cron_next_run($conf) {
|
||||
for ($j = 0; $j < $i; $j++) {
|
||||
if ($j == 2) {
|
||||
// For mday+week decoded rule could be changed (by month+year)
|
||||
$ruledec[$j] = __cronDecodeRuleMday($rule[2], $date[3], $date[4]);
|
||||
$ruledec[$j] = _cronDecodeRuleMday($rule[2], $date[3], $date[4]);
|
||||
}
|
||||
$date[$j] = $ruledec[$j]['d'] ? ($ranges[$j][0] == 0 ? 0 : $ruledec[$j]['d']) : ($ruledec[$j]['n'] ? reset($ruledec[$j]['n']) : $ranges[$j][0]);
|
||||
$expected_date[$j] = 0;
|
||||
@@ -93,13 +91,13 @@ function _elysia_cron_next_run($conf) {
|
||||
}
|
||||
}
|
||||
|
||||
return __cronEncodeDate($date);
|
||||
return _cronEncodeDate($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for _elysia_cron_next_run().
|
||||
*/
|
||||
function __cronDecodeDate($timestamp, $min_diff = 0) {
|
||||
function _cronDecodeDate($timestamp, $min_diff = 0) {
|
||||
$time = floor($timestamp / 60);
|
||||
$time += $min_diff;
|
||||
|
||||
@@ -117,14 +115,14 @@ function __cronDecodeDate($timestamp, $min_diff = 0) {
|
||||
/**
|
||||
* Helper function for _elysia_cron_next_run().
|
||||
*/
|
||||
function __cronEncodeDate($date) {
|
||||
function _cronEncodeDate($date) {
|
||||
return mktime($date[1], $date[0], 0, $date[3], $date[2], $date[4]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for _elysia_cron_next_run().
|
||||
*/
|
||||
function __cronNextOrEqual($el, $arr, $range_start, $range_end) {
|
||||
function _cronNextOrEqual($el, $arr, $range_start, $range_end) {
|
||||
if (empty($arr)) {
|
||||
return $el;
|
||||
}
|
||||
@@ -139,7 +137,7 @@ function __cronNextOrEqual($el, $arr, $range_start, $range_end) {
|
||||
/**
|
||||
* Helper function for _elysia_cron_next_run().
|
||||
*/
|
||||
function __cronDecodeRule($rule, $min, $max) {
|
||||
function _cronDecodeRule($rule, $min, $max) {
|
||||
if ($rule == '*') {
|
||||
return array('n' => array(), 'd' => 0);
|
||||
}
|
||||
@@ -163,11 +161,11 @@ function __cronDecodeRule($rule, $min, $max) {
|
||||
/**
|
||||
* Helper function for _elysia_cron_next_run().
|
||||
*/
|
||||
function __cronDecodeRuleMday($rule, $month, $year) {
|
||||
function _cronDecodeRuleMday($rule, $month, $year) {
|
||||
$range_from = 1;
|
||||
$range_to = $month != 2 ? (in_array($month, array(4, 6, 9, 11)) ? 30 : 31) : ($year % 4 == 0 ? 29 : 28);
|
||||
$r1 = __cronDecodeRule($rule[0], $range_from, $range_to);
|
||||
$r2 = __cronDecodeRule($rule[1], $range_from, $range_to);
|
||||
$r1 = _cronDecodeRule($rule[0], $range_from, $range_to);
|
||||
$r2 = _cronDecodeRule($rule[1], $range_from, $range_to);
|
||||
if ($r2['d']) {
|
||||
for ($i = 0; $i < 7; $i++) {
|
||||
if ($i % $r2['d'] == 0) {
|
||||
@@ -178,7 +176,7 @@ function __cronDecodeRuleMday($rule, $month, $year) {
|
||||
if ($r2['n']) {
|
||||
$r2['n'] = array_unique($r2['n']);
|
||||
// Use always "31" and not $range_to, see http://drupal.org/node/1668302.
|
||||
$r1['n'] = array_merge($r1['n'], __cronMonDaysFromWeekDays($year, $month, $r2['n']), __cronMonDaysFromWeekDays($year, $month + 1, $r2['n'], 31));
|
||||
$r1['n'] = array_merge($r1['n'], _cronMonDaysFromWeekDays($year, $month, $r2['n']), _cronMonDaysFromWeekDays($year, $month + 1, $r2['n'], 31));
|
||||
}
|
||||
return $r1;
|
||||
}
|
||||
@@ -186,7 +184,7 @@ function __cronDecodeRuleMday($rule, $month, $year) {
|
||||
/**
|
||||
* Helper function for _elysia_cron_next_run().
|
||||
*/
|
||||
function __cronMonDaysFromWeekDays($year, $mon, $weekdays, $offset = 0) {
|
||||
function _cronMonDaysFromWeekDays($year, $mon, $weekdays, $offset = 0) {
|
||||
if ($mon > 12) {
|
||||
$year++;
|
||||
$mon = $mon - 12;
|
||||
@@ -350,15 +348,15 @@ function test_elysia_cron_should_run() {
|
||||
'last_run' => mktime(23, 59, 0, 2, 29, 2008),
|
||||
), mktime(23, 59, 0, 2, 6, 2009))));
|
||||
dprint("34." . (TRUE == elysia_cron_should_run(array(
|
||||
'rule' => '59 23 *' . '/10 * *',
|
||||
'rule' => '59 23 */10 * *',
|
||||
'last_run' => mktime(23, 58, 0, 1, 10, 2008),
|
||||
), mktime(23, 59, 0, 1, 10, 2008))));
|
||||
dprint("35." . (FALSE == elysia_cron_should_run(array(
|
||||
'rule' => '59 23 *' . '/10 * *',
|
||||
'rule' => '59 23 */10 * *',
|
||||
'last_run' => mktime(23, 59, 0, 1, 10, 2008),
|
||||
), mktime(23, 59, 0, 1, 11, 2008))));
|
||||
dprint("36." . (TRUE == elysia_cron_should_run(array(
|
||||
'rule' => '59 23 *' . '/10 * *',
|
||||
'rule' => '59 23 */10 * *',
|
||||
'last_run' => mktime(23, 59, 0, 1, 10, 2008),
|
||||
), mktime(23, 59, 0, 1, 20, 2008))));
|
||||
dprint("37." . (TRUE == elysia_cron_should_run(array(
|
||||
|
16
sites/all/modules/contrib/dev/elysia_cron/js/elysia_cron.js
Normal file
16
sites/all/modules/contrib/dev/elysia_cron/js/elysia_cron.js
Normal file
@@ -0,0 +1,16 @@
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.elysiaCron = {
|
||||
attach: function (context, settings) {
|
||||
$('.ec-select').once().change(function () {
|
||||
if (this.value === 'custom') {
|
||||
var key = $(this).data('key');
|
||||
|
||||
$("#_ec_select_" + key).hide();
|
||||
$("#_ec_custom_" + key).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
@@ -1,4 +1,21 @@
|
||||
|
||||
Libraries 7.x-2.5, 2018-10-5
|
||||
-----------------------------
|
||||
#2815965 by plach, Manav, tstoeckler, Proteo: Base theme is not loaded when checking for theme library info
|
||||
#2999116 by Anghelu, joshbrown81: Finds no library after update
|
||||
|
||||
Libraries 7.x-2.4, 2018-09-10
|
||||
-----------------------------
|
||||
#2779591 by mark_fullmer, cglauren, improved PHP 7.x.x support.
|
||||
#2699799 by flaviovs, hanoii: Support reading version from package.json.
|
||||
#2816781 by joelstein: Add a 'access library reports' permission.
|
||||
#2823735 by amanaplan, tstoeckler: Add admin_menu cache clear integration.
|
||||
#2745763 by Albert Volkman, tstoeckler: Allow downloading all libraries at once.
|
||||
#2310753 by tstoeckler: Avoid libraries_get_libraries() scanning the root.
|
||||
#2341955 by sadashiv, tstoeckler: Clear library cache on library report.
|
||||
#819610 by tstoeckler: Show variants and dependencies in the UI.
|
||||
#2724925 by ron_s, tstoeckler: Separate installed from uninstalled libraries.
|
||||
|
||||
Libraries 7.x-2.3, 2016-05-12
|
||||
-----------------------------
|
||||
#1884246 by BR0kEN, tstoeckler et al: Allow downloading libraries via Drush.
|
||||
@@ -94,17 +111,11 @@ by sun: Fixed testbot breaks upon .info file without .module file.
|
||||
#719896 by tstoeckler, sun: Added starting point for hook_libraries_info().
|
||||
|
||||
|
||||
Libraries 7.x-1.x, xxxx-xx-xx
|
||||
-----------------------------
|
||||
|
||||
Libraries 7.x-1.0, 2010-01-27
|
||||
-----------------------------
|
||||
#743522 by sun: Ported to D7.
|
||||
|
||||
|
||||
Libraries 6.x-1.x, xxxx-xx-xx
|
||||
-----------------------------
|
||||
|
||||
Libraries 6.x-1.0, 2010-01-27
|
||||
-----------------------------
|
||||
#1028744 by tstoeckler: Code clean-up.
|
||||
|
@@ -0,0 +1,3 @@
|
||||
.libraries-table {
|
||||
margin-bottom: 2em;
|
||||
}
|
@@ -20,41 +20,112 @@
|
||||
* 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();
|
||||
// Only show variants for installed libraries.
|
||||
$header_installed = array(t('Name'), t('Version'), t('Variants'), t('Dependencies'), t('Provider'), t('Links'));
|
||||
// Only show status for libraries with an error.
|
||||
$header_error = array(t('Name'), t('Status'), t('Version'), t('Dependencies'), t('Provider'), t('Links'));
|
||||
// For unregistered libraries the only information we can show is the path.
|
||||
$header_unregistered = array(t('Name'), t('Path'));
|
||||
|
||||
$libraries = libraries_detect();
|
||||
uasort($libraries, 'libraries_admin_sort_title');
|
||||
$rows_installed = array();
|
||||
$rows_error = array();
|
||||
$rows_unregistered = array();
|
||||
|
||||
foreach ($libraries as $machine_name => $library) {
|
||||
// Registered libraries: we prefer to use libraries_detect() since it provides
|
||||
// library metadata.
|
||||
$libraries_registered = libraries_detect();
|
||||
uasort($libraries_registered, 'libraries_admin_sort_title');
|
||||
|
||||
// Unregistered libraries: modules can depend on Libraries API without sharing
|
||||
// metadata by using libraries_get_path(). Libraries can also be placed in the
|
||||
// filesystem that are incorrectly installed, a wrong version, or a standalone
|
||||
// not connected to any module. In these cases, libraries_get_libraries()
|
||||
// provides a full library list. Libraries found by libraries_get_libraries(),
|
||||
// but not identified by libraries_detect, are displayed in a separate table.
|
||||
$libraries_unregistered = libraries_get_libraries();
|
||||
natcasesort($libraries_unregistered);
|
||||
|
||||
foreach ($libraries_registered as $machine_name => $library) {
|
||||
$actions = array();
|
||||
$row = array();
|
||||
|
||||
if ($library['vendor url']) {
|
||||
$actions[] = l('Homepage', $library['vendor url']);
|
||||
$actions[] = l(t('Homepage'), $library['vendor url']);
|
||||
}
|
||||
if ($library['download url']) {
|
||||
$actions[] = l('Download', $library['download url']);
|
||||
$actions[] = l(t('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')),
|
||||
);
|
||||
$row['data'][] = l($library['name'], 'admin/reports/libraries/' . $machine_name);
|
||||
// Only show status for libraries with an error. See above.
|
||||
if (!$library['installed']) {
|
||||
$row['data'][] = drupal_ucfirst($library['error']);
|
||||
}
|
||||
$row['data'][] = isset($library['version']) ? $library['version'] : '';
|
||||
if ($library['installed']) {
|
||||
$row['data'][] = implode(', ', array_keys($library['variants']));
|
||||
}
|
||||
$row['data'][] = libraries_admin_get_dependencies($library);
|
||||
$row['data'][] = libraries_admin_get_provider_with_type($library);
|
||||
$row['data'][] = implode(' | ', $actions);
|
||||
$row['class'] = $library['installed'] ? array('ok') : array('warning');
|
||||
|
||||
if ($library['installed']) {
|
||||
$rows_installed[] = $row;
|
||||
}
|
||||
else {
|
||||
$rows_error[] = $row;
|
||||
}
|
||||
|
||||
// Filter registered libraries from unregistered libraries.
|
||||
unset($libraries_unregistered[$library['machine name']]);
|
||||
}
|
||||
|
||||
$form['libraries']['list'] = array(
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
'#empty' => t('There are currently no libraries installed'),
|
||||
// Build table of registered libraries with installed status.
|
||||
$form['libraries']['installed'] = array(
|
||||
'#theme' => 'libraries_table_with_title',
|
||||
'#title' => t('Installed'),
|
||||
'#header' => $header_installed,
|
||||
'#rows' => $rows_installed,
|
||||
'#description' => t('These libraries are registered and installed correctly.'),
|
||||
'#empty' => t('There are currently no libraries that are registered and installed.'),
|
||||
);
|
||||
|
||||
// Build table of registered libraries with error status.
|
||||
$form['libraries']['error'] = array(
|
||||
'#theme' => 'libraries_table_with_title',
|
||||
'#title' => t('Uninstalled'),
|
||||
'#header' => $header_error,
|
||||
'#rows' => $rows_error,
|
||||
'#description' => t('These libraries are registered but not installed. They may not need to be installed in case a module or theme provides optional integration with a library.'),
|
||||
'#empty' => t('There are currently no libraries that are registered but not installed.'),
|
||||
);
|
||||
|
||||
// Build table of unregistered libraries.
|
||||
foreach ($libraries_unregistered as $name => $path) {
|
||||
$rows_unregistered[] = array(
|
||||
'data' => array(
|
||||
$name,
|
||||
$path,
|
||||
),
|
||||
);
|
||||
}
|
||||
$form['libraries']['unregistered'] = array(
|
||||
'#theme' => 'libraries_table_with_title',
|
||||
'#title' => t('Unregistered'),
|
||||
'#header' => $header_unregistered,
|
||||
'#rows' => $rows_unregistered,
|
||||
'#description' => t('These libraries were found in the filesystem but there is no metadata about them.'),
|
||||
// Do not show the table at all, if there are no unregistered libraries.
|
||||
'#access' => (bool) $libraries_unregistered,
|
||||
);
|
||||
|
||||
// Clear the cached library information so that the library can be loaded if
|
||||
// it was just downloaded. Because these instructions use libraries_detect()
|
||||
// directly, they will never use the cached information, but this avoids the
|
||||
// overview showing a library as installed but it not being loadable.
|
||||
libraries_cache_clear();
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
@@ -99,11 +170,11 @@ function libraries_admin_library_status_form(array $form, array &$form_state, $l
|
||||
break;
|
||||
|
||||
case 'missing dependency':
|
||||
$form['instructions']['instruction']['#markup'] = t('There a missing dependency in your configuration that prevent this library to work properly.') . '<br>';
|
||||
$form['instructions']['instruction']['#markup'] = t('There is a missing dependency in your configuration that prevents this library from working 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>';
|
||||
$form['instructions']['instruction']['#markup'] = t('There is an incompatible dependency in your configuration that prevents this library from working properly.') . '<br>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -483,6 +554,28 @@ function libraries_admin_sort_title(array $a, array $b) {
|
||||
return strnatcasecmp($a['name'], $b['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the library's dependencies, if any.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return string
|
||||
* The dependencies.
|
||||
*/
|
||||
function libraries_admin_get_dependencies($library) {
|
||||
$dependencies = array();
|
||||
foreach ($library['dependencies'] as $dependency_name) {
|
||||
if ($dependency = libraries_info($dependency_name)) {
|
||||
$dependencies[] = $dependency['name'];
|
||||
}
|
||||
else {
|
||||
$dependencies[] = $dependency_name;
|
||||
}
|
||||
}
|
||||
return implode(', ', $dependencies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the library's provider.
|
||||
*
|
||||
|
@@ -47,6 +47,8 @@
|
||||
* Unless 'version' is declared or libraries_get_version() is being used as
|
||||
* a version callback, 'version callback' must be declared. In the latter
|
||||
* case, however, 'version arguments' must be declared in the specified way.
|
||||
* For libraries that provide a package.json file, use
|
||||
* 'libraries_get_package_json_version' as the version callback.
|
||||
* - version arguments: (optional) A list of arguments to pass to the version
|
||||
* callback. Version arguments can be declared either as an associative
|
||||
* array whose keys are the argument names or as an indexed array without
|
||||
|
@@ -23,7 +23,9 @@ function libraries_drush_command() {
|
||||
'arguments' => array(
|
||||
'libraries' => 'A comma delimited list of library machine names.',
|
||||
),
|
||||
'required-arguments' => TRUE,
|
||||
'options' => array(
|
||||
'all' => 'Download all registered libraries.',
|
||||
),
|
||||
);
|
||||
|
||||
return $items;
|
||||
@@ -42,10 +44,7 @@ function libraries_drush_cache_clear(array &$types) {
|
||||
* 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);
|
||||
}
|
||||
libraries_cache_clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,28 +108,61 @@ function drush_libraries_list() {
|
||||
function drush_libraries_download() {
|
||||
drush_command_include('pm-download');
|
||||
|
||||
$libraries = libraries_info();
|
||||
$all_libraries = libraries_detect();
|
||||
|
||||
// @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;
|
||||
// Prepare a list of names of downloadable libraries.
|
||||
$downloadable_names = array();
|
||||
foreach ($all_libraries as $machine_name => $library) {
|
||||
// Skip libraries that are already installed.
|
||||
// @todo Allow (optionally) re-downloading installing libraries.
|
||||
if (!empty($library['download file url']) && !$library['installed']) {
|
||||
$downloadable_names[] = $machine_name;
|
||||
}
|
||||
$library = $libraries[$machine_name];
|
||||
}
|
||||
|
||||
if (empty($library['download file url'])) {
|
||||
$message = dt("The !library library cannot be downloaded.\n", array('!library' => $machine_name));
|
||||
$message .= dt("Libraries need to specify a download file URL to support being downloaded via Drush.\n");
|
||||
$message .= dt("See hook_libraries_info() for more information.\n");
|
||||
drush_set_error('DRUSH_LIBRARY_NOT_DOWNLOADABLE', $message);
|
||||
continue;
|
||||
// Gather a list of libraries to download. If '--all' was specified, that
|
||||
// takes precedence over any other arguments. Otherwise and if no arguments
|
||||
// are specified, we present a choice of all downloadable libraries.
|
||||
if (drush_get_option('all', FALSE) && $downloadable_names) {
|
||||
$machine_names = $downloadable_names;
|
||||
}
|
||||
elseif (pm_parse_arguments(func_get_args(), FALSE)) {
|
||||
$machine_names = array();
|
||||
foreach (pm_parse_arguments(func_get_args(), FALSE) as $machine_name) {
|
||||
// If there was an error with with one of the libraries, continue to try
|
||||
// to install any remaining libraries.
|
||||
if (!isset($all_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;
|
||||
}
|
||||
if (empty($all_libraries[$machine_name]['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;
|
||||
}
|
||||
$machine_names[] = $machine_name;
|
||||
}
|
||||
$download_url = $library['download file url'];
|
||||
}
|
||||
elseif ($downloadable_names) {
|
||||
$machine_names = drush_choice_multiple(drupal_map_assoc($downloadable_names), FALSE, 'Select which libraries to download.');
|
||||
// If the operation was cancelled by the user, or if no libraries were
|
||||
// selected, bail out without any further error message.
|
||||
if (!$machine_names) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
drush_log(dt('There are no registered, uninstalled libraries that can be downloaded.'), 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($machine_names as $machine_name) {
|
||||
$download_url = $all_libraries[$machine_name]['download file url'];
|
||||
|
||||
drush_log(dt('Downloading library !name ...', array('!name' => $machine_name)));
|
||||
|
||||
@@ -205,7 +237,7 @@ function drush_libraries_download() {
|
||||
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');
|
||||
drush_log(dt("Skip installation of !project to !dest.", array('!project' => $machine_name, '!dest' => $install_location)), 'warning');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@@ -8,9 +8,8 @@ files[] = tests/LibrariesLoadWebTest.test
|
||||
files[] = tests/LibrariesUnitTest.test
|
||||
files[] = tests/LibrariesWebTestBase.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
; Information added by Drupal.org packaging script on 2018-10-05
|
||||
version = "7.x-2.5"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
datestamp = "1538770685"
|
||||
|
@@ -34,3 +34,13 @@ function libraries_update_7201() {
|
||||
// during the 7.x-2.x cycle.
|
||||
registry_rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant the "View library reports" permission to roles with the "View site reports" permission.
|
||||
*/
|
||||
function libraries_update_7202() {
|
||||
$rids = array_keys(user_roles(FALSE, 'access site reports'));
|
||||
foreach ($rids as $rid) {
|
||||
_update_7000_user_role_grant_permissions($rid, array('access library reports'), 'libraries');
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,29 @@ function libraries_flush_caches() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_admin_menu_cache_info().
|
||||
*/
|
||||
function libraries_admin_menu_cache_info() {
|
||||
$caches['libraries'] = array(
|
||||
'title' => t('Libraries'),
|
||||
'callback' => 'libraries_cache_clear',
|
||||
);
|
||||
return $caches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cached library information.
|
||||
*/
|
||||
function libraries_cache_clear() {
|
||||
foreach (libraries_flush_caches() as $bin) {
|
||||
// Using the wildcard argument leads to DrupalDatabaseCache::clear()
|
||||
// truncating the libraries cache table which is more performant that
|
||||
// deleting the rows.
|
||||
cache_clear_all('*', $bin, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path of a library.
|
||||
*
|
||||
@@ -56,6 +79,52 @@ function libraries_get_path($name, $base_path = FALSE) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all enabled themes.
|
||||
*
|
||||
* Themes are sorted so that base themes always precede their child themes.
|
||||
*
|
||||
* @return array
|
||||
* An associative array of theme objects keyed by theme name.
|
||||
*/
|
||||
function libraries_get_enabled_themes() {
|
||||
$themes = array();
|
||||
foreach (list_themes() as $name => $theme) {
|
||||
if ($theme->status) {
|
||||
$themes[$name] = $theme;
|
||||
}
|
||||
}
|
||||
|
||||
return libraries_sort_themes($themes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort a themes array.
|
||||
*
|
||||
* @param array $themes
|
||||
* Array of themes as objects, keyed by theme name.
|
||||
* @param string $base
|
||||
* A base theme (internal use only).
|
||||
*
|
||||
* @return array
|
||||
* A similar array to $themes, but sorted in such a way that subthemes are
|
||||
* always located after its base theme.
|
||||
*/
|
||||
function libraries_sort_themes($themes, $base = '') {
|
||||
$output = array();
|
||||
foreach ($themes as $name => $theme) {
|
||||
if (!isset($theme->base_theme) || $theme->base_theme == $base) {
|
||||
$output[$name] = $theme;
|
||||
unset($themes[$name]);
|
||||
$subthemes = libraries_sort_themes($themes, $name);
|
||||
foreach ($subthemes as $sub_name => $subtheme) {
|
||||
$output[$sub_name] = $subtheme;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of library directories.
|
||||
*
|
||||
@@ -77,6 +146,13 @@ function libraries_get_libraries() {
|
||||
$profile = drupal_get_path('profile', drupal_get_profile());
|
||||
$config = conf_path();
|
||||
|
||||
// $config and $profile should never be empty in a proper Drupal setup.
|
||||
// However, we should never search into the root filesystem under any
|
||||
// circumstances, so just bail out in that case.
|
||||
if (!$profile && !$config) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Similar to 'modules' and 'themes' directories in the root directory,
|
||||
// certain distributions may want to place libraries into a 'libraries'
|
||||
// directory in Drupal's root directory.
|
||||
@@ -358,10 +434,12 @@ function &libraries_info($name = NULL) {
|
||||
}
|
||||
}
|
||||
|
||||
// Gather information from hook_libraries_info() in enabled themes.
|
||||
// Gather information from hook_libraries_info() in enabled themes. Themes
|
||||
// are sorted to ensure that a base theme's template.php is included before
|
||||
// its children's ones.
|
||||
$themes = array();
|
||||
foreach (list_themes() as $theme_name => $theme_info) {
|
||||
if ($theme_info->status && file_exists(drupal_get_path('theme', $theme_name) . '/template.php')) {
|
||||
foreach (libraries_get_enabled_themes() as $theme_name => $theme_info) {
|
||||
if (file_exists(drupal_get_path('theme', $theme_name) . '/template.php')) {
|
||||
// Collect a list of viable themes for re-use when calling the alter
|
||||
// hook.
|
||||
$themes[] = $theme_name;
|
||||
@@ -546,7 +624,7 @@ function libraries_detect($name = NULL) {
|
||||
$library['version'] = call_user_func_array($library['version callback'], array_merge(array($library), $library['version arguments']));
|
||||
}
|
||||
else {
|
||||
$library['version'] = call_user_func($library['version callback'], $library, $library['version arguments']);
|
||||
$library['version'] = call_user_func_array($library['version callback'], array(&$library, $library['version arguments']));
|
||||
}
|
||||
if (empty($library['version'])) {
|
||||
$library['error'] = 'not detected';
|
||||
@@ -887,16 +965,56 @@ function libraries_get_version($library, $options) {
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version information from a library's package.json file.
|
||||
*
|
||||
* @param $library
|
||||
* An associative array containing all information about the library.
|
||||
* @param $options
|
||||
* This callback expects no option.
|
||||
* @return
|
||||
* A string containing the version of the library.
|
||||
*
|
||||
* @see libraries_get_path()
|
||||
*/
|
||||
function libraries_get_package_json_version($library, $options) {
|
||||
$file = DRUPAL_ROOT . '/' . $library['library path'] . '/package.json';
|
||||
if (!file_exists($file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$content = file_get_contents($file);
|
||||
if (!$content) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = drupal_json_decode($content);
|
||||
if (isset($data['version'])) {
|
||||
return $data['version'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
function libraries_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/reports/libraries':
|
||||
return t('Click on a library for a status report or detailed installation instructions in case the library is not installed correctly.');
|
||||
return t('Click on a library for a status report or detailed installation instructions.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_permission().
|
||||
*/
|
||||
function libraries_permission() {
|
||||
return array(
|
||||
'access library reports' => array(
|
||||
'title' => t('View library reports'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
@@ -907,7 +1025,7 @@ function libraries_menu() {
|
||||
'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'),
|
||||
'access arguments' => array('access library reports'),
|
||||
'file' => 'libraries.admin.inc'
|
||||
);
|
||||
$items['admin/reports/libraries/%libraries_ui'] = array(
|
||||
@@ -915,7 +1033,7 @@ function libraries_menu() {
|
||||
'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'),
|
||||
'access arguments' => array('access library reports'),
|
||||
'file' => 'libraries.admin.inc'
|
||||
);
|
||||
return $items;
|
||||
@@ -944,3 +1062,19 @@ function libraries_menu() {
|
||||
function libraries_ui_load($name) {
|
||||
return libraries_detect($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function libraries_theme($existing, $type, $theme, $path) {
|
||||
// Because we extend the 'table' theme function, fetch the respective
|
||||
// variables dynamically.
|
||||
$common_theme = drupal_common_theme();
|
||||
$variables = $common_theme['table']['variables'] + array('title' => '', 'description' => '');
|
||||
return array(
|
||||
'libraries_table_with_title' => array(
|
||||
'variables' => $variables,
|
||||
'file' => 'libraries.theme.inc',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
36
sites/all/modules/contrib/dev/libraries/libraries.theme.inc
Normal file
36
sites/all/modules/contrib/dev/libraries/libraries.theme.inc
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides theme and preprocess functions for Libraries API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepare variables for theming a table with a title.
|
||||
*
|
||||
* @param array $variables
|
||||
* An array of theme variables, passed by reference.
|
||||
*/
|
||||
function template_preprocess_libraries_table_with_title(&$variables) {
|
||||
drupal_add_css(drupal_get_path('module', 'libraries') . '/css/libraries.admin.css');
|
||||
|
||||
$variables['attributes'] += array('class' => array());
|
||||
$variables['attributes']['class'][] = 'libraries-table';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for a table with a title.
|
||||
*
|
||||
* @param array $variables
|
||||
* An array theme variables.
|
||||
*
|
||||
* @return string
|
||||
* The HTML output for this table with a title.
|
||||
*/
|
||||
function theme_libraries_table_with_title(array $variables) {
|
||||
$output = '';
|
||||
$output .= '<h2>' . $variables['title'] . '</h2>';
|
||||
$output .= '<div class="description">' . $variables['description'] . '</div>';
|
||||
$output .= theme_table($variables);
|
||||
return $output;
|
||||
}
|
@@ -40,8 +40,20 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
|
||||
* Tests the libraries report at /admin/reports/libraries.
|
||||
*/
|
||||
public function testLibrariesReportOverview() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries');
|
||||
$this->assertRaw('Libraries');
|
||||
$this->getWithPermissions(array('access library reports'), 'admin/reports/libraries');
|
||||
// Assert the page title and table titles show up.
|
||||
$this->assertText('Libraries');
|
||||
$this->assertRaw('<h2>Installed</h2>');
|
||||
$this->assertRaw('<h2>Uninstalled</h2>');
|
||||
|
||||
// Make sure the table headings show up.
|
||||
$this->assertText('Name');
|
||||
$this->assertText('Status');
|
||||
$this->assertText('Version');
|
||||
$this->assertText('Variants');
|
||||
$this->assertText('Dependencies');
|
||||
$this->assertText('Provider');
|
||||
$this->assertText('Links');
|
||||
|
||||
// Make sure that all the libraries are listed.
|
||||
$libraries = libraries_info();
|
||||
@@ -51,8 +63,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
|
||||
$this->assertLinkByHref('admin/reports/libraries/' . $library['machine name']);
|
||||
}
|
||||
|
||||
// Make sure that all possible statuses are displayed.
|
||||
$this->assertText('OK');
|
||||
// Make sure that all possible error statuses are displayed.
|
||||
$this->assertText('Not found');
|
||||
$this->assertText('Not detected');
|
||||
$this->assertText('Not supported');
|
||||
@@ -73,7 +84,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
|
||||
* Tests the libraries report for an installed library.
|
||||
*/
|
||||
public function testLibrariesReportInstalled() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_files');
|
||||
$this->getWithPermissions(array('access library 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.
|
||||
@@ -88,7 +99,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
|
||||
* Tests the libraries report for a missing library.
|
||||
*/
|
||||
public function testLibrariesReportMissing() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_missing');
|
||||
$this->getWithPermissions(array('access library 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.
|
||||
@@ -100,7 +111,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
|
||||
* Tests the libraries report for a missing library.
|
||||
*/
|
||||
public function testLibrariesReportNotDetected() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_undetected_version');
|
||||
$this->getWithPermissions(array('access library 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.');
|
||||
}
|
||||
@@ -109,7 +120,7 @@ class LibrariesAdminWebTest extends LibrariesWebTestBase {
|
||||
* Tests the libraries report for a missing library.
|
||||
*/
|
||||
public function testLibrariesReportNotSupported() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_unsupported_version');
|
||||
$this->getWithPermissions(array('access library 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.
|
||||
|
@@ -2,9 +2,8 @@
|
||||
name = Example info file
|
||||
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
; Information added by Drupal.org packaging script on 2018-10-05
|
||||
version = "7.x-2.5"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
datestamp = "1538770685"
|
||||
|
@@ -5,9 +5,8 @@ package = Testing
|
||||
dependencies[] = libraries
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
; Information added by Drupal.org packaging script on 2018-10-05
|
||||
version = "7.x-2.5"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
datestamp = "1538770685"
|
||||
|
@@ -3,9 +3,8 @@ description = Tests that themes can provide and alter library information.
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
; Information added by Drupal.org packaging script on 2018-10-05
|
||||
version = "7.x-2.5"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
datestamp = "1538770685"
|
||||
|
Reference in New Issue
Block a user