'.t('Production check is a module that will add a report detailing the status of several settings and modules. The report is tailored for a production environment. It will tell you which modules should (not) be running, what settings are OK or not and much more. It is an easy way to have an overview of the status of your site when bringing it live, so that you can quickly put all the configuration details in order to be ready for production use.').'
';
- $output .= '' . t('Production check is a module that will add a report detailing the status of several settings and modules. The report is tailored for a production environment. It will tell you which modules should (not) be running, what settings are OK or not and much more. It is an easy way to have an overview of the status of your site when bringing it live, so that you can quickly put all the configuration details in order to be ready for production use.') . '
';
+ $output .= '' . t('Using the settings page, you can enable XMLRPC support so that it can report back to the Production monitor module, available as an extra module in this package. If you install the Production monitor module on a central site, you can monitor several sites in a glance, ensuring that no one changes settings without you knowing about it. See the Production monitor built in help for more information.') . '
';
+ $output .= '' . t('If you prefer using !link for monitoring, you can simply enable support for that on the settings page by ticking the appropriate checkmark. An extra set of checkboxes will appear, allowing you to configure in detail what exactly you wish !link to monitor.', prod_check_link_array('Nagios', 'http://drupal.org/project/nagios')) . '
';
break;
case 'admin/reports/prod-check':
case 'admin/reports/prod-check/status':
- $output .= '' . t("This is an overview of all checks performed by the Production check module and their status. You can click the links inside the report to jump to the module's settings page, or to go to the project page of a module, in case you need to download it for installation.") . '
';
break;
case 'admin/config/system/prod-check':
- $output .= '' . $nodata . '
' . $nodata . '
',
+ '#prefix' => '
',
'#suffix' => '
',
);
$i++;
@@ -398,8 +450,8 @@ function _prod_monitor_overview_form_table($sites) {
$view = t('View');
$flush = t('Flush');
if ($site_info['data']) {
- $view = l(t('View'), 'admin/reports/prod-monitor/site/'.$id, array('attributes' => array('title' => t('View'))));
- $flush = l(t('Flush'), 'admin/reports/prod-monitor/site/'.$id.'/flush', array('attributes' => array('title' => t('Flush'))));
+ $view = l(t('View'), 'admin/reports/prod-monitor/site/' . $id, array('attributes' => array('title' => t('View'))));
+ $flush = l(t('Flush'), 'admin/reports/prod-monitor/site/' . $id . '/flush', array('attributes' => array('title' => t('Flush'))));
}
$update_status = _prod_monitor_get_update_status($id);
@@ -407,7 +459,7 @@ function _prod_monitor_overview_form_table($sites) {
if (!empty($site_info['status'])) {
$title = t(ucwords($site_info['status']));
- $status = array('data' => '
'.l($title, 'admin/reports/prod-monitor/site/'.$id, array('attributes' => array('title' => $title, 'class' => $site_info['status']))).'', 'class' => array($site_info['status']));
+ $status = array('data' => '
' . l($title, 'admin/reports/prod-monitor/site/' . $id, array('attributes' => array('title' => $title, 'class' => $site_info['status']))) . '', 'class' => array($site_info['status']));
}
else {
$status = '';
@@ -424,17 +476,17 @@ function _prod_monitor_overview_form_table($sites) {
(!$site_info['lastupdate']) ? t('Not yet updated.') : $site_info['lastupdate'],
/* Compose links. */
$view,
- l(t('Edit'), 'admin/reports/prod-monitor/site/'.$id.'/edit', array('query' => $home, 'attributes' => array('title' => t('Edit')))),
- l(t('Fetch data'), 'admin/reports/prod-monitor/site/'.$id.'/fetch', array('attributes' => array('title' => t('Fetch & View')))),
+ l(t('Edit'), 'admin/reports/prod-monitor/site/' . $id . '/edit', array('query' => $home, 'attributes' => array('title' => t('Edit')))),
+ l(t('Fetch data'), 'admin/reports/prod-monitor/site/' . $id . '/fetch', array('attributes' => array('title' => t('Fetch & View')))),
$flush,
- l(t('Delete'), 'admin/reports/prod-monitor/site/'.$id.'/delete', array('attributes' => array('title' => t('Delete')))),
+ l(t('Delete'), 'admin/reports/prod-monitor/site/' . $id . '/delete', array('attributes' => array('title' => t('Delete')))),
),
'class' => array($site_info['status']),
);
$rows[] = $row;
}
- return theme('table', array('header' => $headers, 'rows' => $rows));
+ return theme('table', array('prod_monitor_id' => 'overview_form', 'header' => $headers, 'rows' => $rows));
}
/**
@@ -501,6 +553,8 @@ function prod_monitor_overview_form_submit($form, &$form_state) {
$site->settings = serialize(
array(
'api_key' => $form_state['values']['api_key'],
+ // Trim spaces and / from left and right side.
+ 'dbconnect_path' => trim($form_state['values']['dbconnect_path'], ' /'),
'functions' => $form_state['storage']['functions'],
'checks' => $checks,
)
@@ -511,9 +565,12 @@ function prod_monitor_overview_form_submit($form, &$form_state) {
if ($result) {
drupal_set_message(t('Website %url correctly saved.', array('%url' => $site->url)));
if ($form_state['values']['fetch']) {
- $site_info = _prod_monitor_get_site($site->id, TRUE);
+ $site_info = _prod_monitor_get_site($site->id, 'all');
+ // First: all checks.
_prod_monitor_retrieve_data($site->id, $site_info, TRUE);
- $form_state['redirect'] = 'admin/reports/prod-monitor/site/'.$site->id;
+ // MUST be second because of the status update!
+ _prod_monitor_db_connect_check($site->id, $site_info);
+ $form_state['redirect'] = 'admin/reports/prod-monitor/site/' . $site->id;
}
}
else {
@@ -523,13 +580,81 @@ function prod_monitor_overview_form_submit($form, &$form_state) {
}
}
+/**
+ * Submit handler for the fetch all button.
+ */
+function prod_monitor_fetch_all_submit($form, &$form_state) {
+ _prod_monitor_fetch_all_data_batcher_create();
+}
+
+/**
+ * Function to create the batch process. Also used in Drush!
+ */
+function _prod_monitor_fetch_all_data_batcher_create($fetch_only = FALSE, $update_only = FALSE, $msg = TRUE) {
+ $title = t('Fetching all site data and checking for updates...');
+
+ if ($fetch_only) {
+ $title = t('Fetching all site data...');
+ }
+ if ($update_only) {
+ $title = t('Checking for updates...');
+ }
+
+ $batch = array(
+ 'operations' => array(
+ array('prod_monitor_fetch_all_data_batcher', array($fetch_only, $update_only, $msg)),
+ ),
+ 'title' => $title,
+ 'file' => drupal_get_path('module', 'prod_monitor') . '/includes/prod_monitor.admin.inc',
+ );
+ batch_set($batch);
+}
+
+/**
+ * Batch fetching of all site info.
+ */
+function prod_monitor_fetch_all_data_batcher($fetch_only, $update_only, $msg, &$context) {
+ $sandbox = &$context['sandbox'];
+ if (empty($context['sandbox'])) {
+ $sandbox['sites'] = array_keys(_prod_monitor_get_sites());
+ $sandbox['count'] = count($sandbox['sites']);
+ }
+
+ // Get site info.
+ $id = array_shift($sandbox['sites']);
+ $site_info = _prod_monitor_get_site($id, 'all');
+
+ if (!$update_only) {
+ // First: all checks.
+ _prod_monitor_retrieve_data($id, $site_info, $msg);
+ // MUST be second because of the status update!
+ _prod_monitor_db_connect_check($id, $site_info);
+ }
+
+ if (!$fetch_only) {
+ // Module update status.
+ $modules = prod_monitor_load($id);
+ if (!empty($modules) && !empty($modules['projects'])) {
+ module_load_include('inc', 'prod_monitor', 'includes/prod_monitor.update');
+ _prod_monitor_update_refresh($id, $modules['projects'], $modules['sitekey']);
+ _prod_monitor_calculate_project_data($id, $modules['projects'], $modules['available']);
+ }
+ }
+
+ $context['message'] = t('Updating data for %url', array('%url' => $site_info['url']));
+ $context['finished'] = empty($sandbox['sites']) ? 1 : (1 - count($sandbox['sites']) / $sandbox['count']);
+}
+
/**
* Callback to fetch site data
*/
function prod_monitor_fetch_data($id) {
- $site_info = _prod_monitor_get_site($id, TRUE);
+ $site_info = _prod_monitor_get_site($id, 'all');
+ // First: all checks.
_prod_monitor_retrieve_data($id, $site_info, TRUE);
- drupal_goto('admin/reports/prod-monitor/site/'.$id);
+ // MUST be second because of the status update!
+ _prod_monitor_db_connect_check($id, $site_info);
+ drupal_goto('admin/reports/prod-monitor/site/' . $id);
}
/**
@@ -550,7 +675,7 @@ function prod_monitor_flush_form($form, &$form_state, $id) {
'#value' => $url,
);
- return confirm_form($form, t('Are you sure you wish to delete all fetched data for %url?', array('%url' => $url)), 'admin/reports/prod-monitor', t('Note that the module update status data will not be flushed!').'
'.t('This action cannot be undone.'));
+ return confirm_form($form, t('Are you sure you wish to delete all fetched data for %url?', array('%url' => $url)), 'admin/reports/prod-monitor', t('Note that the module update status data will not be flushed!') . '
' . t('This action cannot be undone.'));
}
/**
@@ -634,6 +759,95 @@ function _prod_monitor_update_data_form($form, $form_state, $id, $site_info) {
}
function _prod_monitor_update_data_form_submit($form, &$form_state) {
+ // First: all checks.
_prod_monitor_retrieve_data($form_state['values']['site_id'], $form_state['values']['site_info'], TRUE);
+ // MUST be second because of the status update!
+ _prod_monitor_db_connect_check($form_state['values']['site_id'], $form_state['values']['site_info']);
}
+/**
+ * Callback for module lookup form.
+ *
+ */
+function prod_monitor_module_lookup_form($form, &$form_state) {
+ $form = array();
+
+ // Show results.
+ if (isset($form_state['projects'])) {
+
+ $module = $form_state['values']['module'];
+
+ $rows = array();
+ foreach ($form_state['projects'] as $id => $project) {
+
+ $application = db_select('prod_monitor_sites', 'pms')->fields('pms', array('url'))->condition('id', $id)->execute()->fetchField();
+ $version = $project['info']['version'];
+
+ $rows[] = array(
+ $application,
+ $version,
+ l(t('View'), 'admin/reports/prod-monitor/site/' . $id),
+ );
+ }
+ $form['title'] = array(
+ '#theme' => 'html_tag',
+ '#tag' => 'h2',
+ '#value' => t('Applications where %module is used', array('%module' => $module)),
+ );
+ $form['table'] = array(
+ '#theme' => 'table',
+ '#rows' => $rows,
+ '#header' => array(t('Application'), t('Version'), t('View')),
+ );
+
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Perform another lookup'),
+ );
+ }
+ // Show lookup form.
+ else {
+ $form['module'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Module name'),
+ '#required' => TRUE,
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Fetch Applications'),
+ );
+ }
+
+ return $form;
+}
+
+/**
+ * Submission handler for module lookup form
+ */
+function prod_monitor_module_lookup_form_submit(&$form, &$form_state) {
+ if (isset($form_state['values']['module'])) {
+
+ $projects = db_select('prod_monitor_site_modules', 'psm')
+ ->fields('psm', array('id', 'projects'))
+ ->condition('projects', '%' . db_like($form_state['values']['module']) . '%', 'LIKE')
+ ->execute()->fetchAllAssoc('id');
+
+ $form_state['rebuild'] = TRUE;
+
+ if ($projects && !empty($projects)) {
+ foreach($projects as $project) {
+
+ $modules = unserialize($project->projects);
+ if (isset($modules[$form_state['values']['module']])) {
+ $form_state['projects'][$project->id] = $modules[$form_state['values']['module']];
+ }
+ }
+ }
+ if (!isset($form_state['projects'])) {
+ drupal_set_message(t('No projects found for :module', array(':module' => $form_state['values']['module'])));
+ }
+ }
+ else {
+ unset($form_state['projects']);
+ }
+}
diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.theme.inc b/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.theme.inc
index 03be6e0c..20fb357d 100644
--- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.theme.inc
+++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.theme.inc
@@ -1,5 +1,20 @@
'. $data .'';
+ $output = '
' . $data . '
';
return $output;
}
$output = '
'. ($last ? t('Last checked: @time ago', array('@time' => format_interval(time() - $last))) : t('Last checked: never'));
- $output .= ' ('. l(t('Check manually'), 'admin/reports/prod-monitor/site/'.$id.'/update-check') .')';
+ $output .= ' ('. l(t('Check manually'), 'admin/reports/prod-monitor/site/' . $id . '/update-check') . ')';
$output .= "
\n";
$header = array();
@@ -226,7 +241,7 @@ function theme_prod_monitor_update_report($variables) {
if (!empty($rows[$type_name])) {
ksort($rows[$type_name]);
$output .= "\n
" . $type_label . "
\n";
- $output .= theme('table', array('header' => $header, 'rows' => $rows[$type_name], 'attributes' => array('class' => array('update'))));
+ $output .= theme('table', array('prod_monitor_id' => 'update_report', 'header' => $header, 'rows' => $rows[$type_name], 'attributes' => array('class' => array('update'))));
}
}
drupal_add_css(drupal_get_path('module', 'update') . '/update.css');
diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.update.inc b/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.update.inc
index 2193e03c..b253a70b 100644
--- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.update.inc
+++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/includes/prod_monitor.update.inc
@@ -29,7 +29,7 @@ function _prod_monitor_update_refresh($id, $projects, $site_key) {
// As replacement for DRUPAL_CORE_COMPATIBILITY since prod_check and
// prod_monitor should be site independant.
$core = explode('.', $projects['drupal']['info']['version']);
- $core = $core[0].'.x';
+ $core = $core[0] . '.x';
$max_fetch_attempts = UPDATE_MAX_FETCH_ATTEMPTS;
@@ -65,10 +65,10 @@ function _prod_monitor_update_refresh($id, $projects, $site_key) {
}
}
$modules->available = serialize($available);
- watchdog('prod_monitor', 'Attempted to fetch information about all available new releases and updates for %link.', array('%link' => _prod_monitor_get_url($id)), WATCHDOG_NOTICE, l(t('view'), 'admin/reports/prod-monitor/site/'.$id.'/view/updates'));
+ watchdog('prod_monitor', 'Fetched information about all available new releases and updates for %link.', array('%link' => _prod_monitor_get_url($id)), WATCHDOG_NOTICE, l(t('view'), 'admin/reports/prod-monitor/site/' . $id . '/view/updates'));
}
else {
- watchdog('prod_monitor', 'Unable to fetch any information about available new releases and updates for %link.', array('%link' => _prod_monitor_get_url($id)), WATCHDOG_ERROR, l(t('view'), 'admin/reports/prod-monitor/site/'.$id.'/view/updates'));
+ watchdog('prod_monitor', 'Unable to fetch any information about available new releases and updates for %link.', array('%link' => _prod_monitor_get_url($id)), WATCHDOG_ERROR, l(t('view'), 'admin/reports/prod-monitor/site/' . $id . '/view/updates'));
}
// Whether this worked or not, we did just (try to) check for updates.
$modules->lastupdate = time();
@@ -99,7 +99,7 @@ function _prod_monitor_update_refresh($id, $projects, $site_key) {
function _prod_monitor_update_build_fetch_url($project, $site_key = '', $core) {
$name = $project['name'];
$url = _prod_monitor_update_get_fetch_url_base($project);
- $url .= '/'. $name .'/'. $core;
+ $url .= '/' . $name . '/' . $core;
// Only append a site_key and the version information if we have a site_key
// in the first place, and if this is not a disabled module or theme. We do
// not want to record usage statistics for disabled code.
@@ -169,6 +169,19 @@ function _prod_monitor_calculate_project_data($id, $projects, $available) {
}
}
+ // Handle the ignored modules.
+ if (($ignored = _prod_monitor_get_site_ignored($id))
+ && !empty($ignored['updates'])) {
+ foreach ($ignored['updates'] as $project_name) {
+ if (isset($projects[$project_name])) {
+ $projects[$project_name]['ignored'] = TRUE;
+ $projects[$project_name]['status'] = UPDATE_UNKNOWN;
+ }
+ }
+ }
+
+ drupal_alter('prod_monitor_project_data', $id, $projects, $available);
+
// Check if we need to flag a security update warning.
// Prepare object to store generated data to DB.
$modules = new stdClass();
diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.api.php b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.api.php
new file mode 100644
index 00000000..bdd6a291
--- /dev/null
+++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.api.php
@@ -0,0 +1,41 @@
+ array());
+
+ // Ignore this module (suppress warnings) because we cannot do anything
+ // about it's update status as it has been abandoned and we are not going
+ // to stop using it.
+ if ($site_id == 12) {
+ $ignore['updates'][] = 'node_embed';
+ }
+
+ return $ignore;
+}
+
+/**
+ * Implements hook_prod_monitor_project_data_alter().
+ *
+ * Allows modules to alter the data being calculated for a project.
+ *
+ * @see _prod_monitor_calculate_project_data().
+ */
+function hook_prod_monitor_project_data_alter($site_id, &$data, $available) {
+
+}
\ No newline at end of file
diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.drush.inc b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.drush.inc
index 227cc0fd..d1e4d4a3 100644
--- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.drush.inc
+++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.drush.inc
@@ -15,14 +15,15 @@ function prod_monitor_drush_command() {
),
);
$items['prod-monitor-updates'] = array(
- 'callback' => '_drush_prod_monitor_updates',
+ 'callback' => 'drush_prod_monitor_updates',
'description' => 'Display the update module status page',
'aliases' => array('pmon-up'),
'arguments' => array(
'id' => 'ID of the site to view module updates for.',
),
'options' => array(
- '--check' => 'Check for module updates.'
+ 'check' => 'Check for module updates.',
+ 'security-only' => 'Only show modules that have security updates available.',
),
);
$items['prod-monitor-fetch'] = array(
@@ -58,20 +59,38 @@ function prod_monitor_drush_command() {
*/
function drush_prod_monitor_fetch() {
$args = func_get_args();
- foreach($args as $arg) {
- $site = _prod_monitor_get_site($arg);
- if (!empty($site['url'])) {
- $result = _prod_monitor_retrieve_data($arg, $site);
- $site['url'] = _prod_monitor_sanitize_url(rtrim($site['url'], '/'));
- if ($result === FALSE) {
- drush_print("\033[1;31m".dt('Error:')." \033[0m".dt('Unable to fetch data for').' '.$site['url'].'!');
- }
- else {
- drush_print(dt('Sucessfully fetched data for').' '.$site['url'].'.');
- }
+
+ // Fetch ALL.
+ if (empty($args)) {
+ if (!drush_confirm(dt('Do you really want to fetch the data for ALL remote sites?'))) {
+ drush_set_error('prod_monitor', dt('Aborting.'));
+ return;
}
else {
- drush_print("\033[1;31m".dt('Error:')." \033[0m".dt('No site found with ID').' '.$arg.'!');
+ module_load_include('inc', 'prod_monitor', 'includes/prod_monitor.admin');
+ // Batch process data fetching.
+ _prod_monitor_fetch_all_data_batcher_create(TRUE, FALSE, FALSE);
+ drush_backend_batch_process();
+ }
+ }
+ // Fetch one or more sites as requested.
+ else {
+ foreach($args as $arg) {
+ $site = _prod_monitor_get_site($arg);
+ if (!empty($site['url'])) {
+ $result = _prod_monitor_retrieve_data($arg, $site);
+ $site['url'] = _prod_monitor_sanitize_url(rtrim($site['url'], '/'));
+ if ($result === FALSE) {
+ drush_print("\033[1;31m" . dt('Error:') . " \033[0m" . dt('Unable to fetch data for') . ' ' . $site['url'] . '!');
+ }
+ else {
+ _prod_monitor_db_connect_check($arg, $site);
+ drush_print(dt('Sucessfully fetched data for') . ' ' . $site['url'] . '.');
+ }
+ }
+ else {
+ drush_print("\033[1;31m" . dt('Error:') . " \033[0m" . dt('No site found with ID') . ' ' . $arg . '!');
+ }
}
}
}
@@ -84,19 +103,19 @@ function drush_prod_monitor_flush() {
foreach ($args as $arg) {
$url = _prod_monitor_get_url($arg);
if (!empty($url)) {
- if (!drush_confirm(dt('Do you really want to flush all data for').' '.$url.'?')) {
+ if (!drush_confirm(dt('Do you really want to flush all data for') . ' ' . $url . '?')) {
drush_die('Aborting.');
}
$result = _prod_monitor_flush_data($arg);
if ($result === FALSE) {
- drush_print("\033[1;31m".dt('Error:')." \033[0m".dt('Unable to flush data!'));
+ drush_print("\033[1;31m" . dt('Error:') . " \033[0m" . dt('Unable to flush data!'));
}
else {
drush_print(dt('Stored data successfully flushed.'));
}
}
else {
- drush_print("\033[1;31m".dt('Error:')." \033[0m".dt('No site found with ID').' '.$arg.'!');
+ drush_print("\033[1;31m" . dt('Error:') . " \033[0m" . dt('No site found with ID') . ' ' . $arg . '!');
}
}
}
@@ -109,19 +128,19 @@ function drush_prod_monitor_delsite() {
foreach ($args as $arg) {
$url = _prod_monitor_get_url($arg);
if (!empty($url)) {
- if (!drush_confirm(dt("Do you really want to delete").' '.$url.' '.dt('and all its data?'))) {
+ if (!drush_confirm(dt("Do you really want to delete") . ' ' . $url . ' ' . dt('and all its data?'))) {
drush_die('Aborting.');
}
$result = _prod_monitor_delete_site($arg);
if ($result === FALSE) {
- drush_print("\033[1;31m".dt('Error:')." \033[0m".dt('Unable to delete') . $url .'!');
+ drush_print("\033[1;31m" . dt('Error:') . " \033[0m" . dt('Unable to delete') . $url . '!');
}
else {
drush_print(dt('Website successfully deleted.'));
}
}
else {
- drush_print("\033[1;31m".dt('Error:')." \033[0m".dt('No site found with ID').' '.$arg.'!');
+ drush_print("\033[1;31m" . dt('Error:') . " \033[0m" . dt('No site found with ID') . ' ' . $arg . '!');
}
}
}
@@ -135,7 +154,7 @@ function drush_prod_monitor_statusdetail() {
if (empty($args)) {
_drush_prod_monitor_overview();
}
- else if (is_numeric($args[0])) {
+ elseif (is_numeric($args[0])) {
_drush_prod_monitor_detail($args[0]);
}
}
@@ -158,7 +177,7 @@ function _drush_prod_monitor_overview() {
dt('Last update'),
dt('Status'),
));
-
+
// TODO: check why the colour coding messes up the tabs for the table
// Worked around this by placing the status column last
foreach ($sites as $id => $site_info) {
@@ -168,10 +187,10 @@ function _drush_prod_monitor_overview() {
(!$site_info['data']) ? dt('Empty') : t('Stored'),
$site_info['added'],
(!$site_info['lastupdate']) ? dt('Not yet updated') : $site_info['lastupdate'],
- "\033[".$severity[$site_info['status']].'m'.ucwords($site_info['status'])."\033[0m",
+ "\033[" . $severity[$site_info['status']] . 'm' . ucwords($site_info['status']) . "\033[0m",
);
}
- drush_print("\033[1m".dt('Production Monitor status')."\033[0m\n", 1);
+ drush_print("\033[1m" . dt('Production Monitor status') . "\033[0m\n", 1);
if (count($rows) > 1) {
drush_print_table($rows, TRUE);
drush_print(dt('Use drush prod-monitor [id] to view the details of a specific site.'));
@@ -182,9 +201,9 @@ function _drush_prod_monitor_overview() {
}
function _drush_prod_monitor_detail($id) {
- $site = _prod_monitor_get_site($id, TRUE);
+ $site = _prod_monitor_get_site($id, 'all');
if (!isset($site['url'])) {
- drush_print("\033[1;31m".dt('Error:')." \033[0m".dt('No site found with ID').' '.$id.'!');
+ drush_print("\033[1;31m" . dt('Error:') . " \033[0m" . dt('No site found with ID') . ' ' . $id . '!');
return;
}
@@ -219,7 +238,7 @@ function _drush_prod_monitor_detail($id) {
$updates = $color . $title . "\033[0m";
// Construct block
- $block[] = array("\033[1m".dt('Overall status')."\033[0m");
+ $block[] = array("\033[1m" . dt('Overall status') . "\033[0m");
$block[] = array(
dt('Drupal core version'),
$modules['projects']['drupal']['info']['version'],
@@ -254,12 +273,12 @@ function _drush_prod_monitor_detail($id) {
foreach ($functions as $set => $data) {
if (isset($site['data'][$set])) {
$rows[] = array('');
- $rows[] = array("\033[1m".dt($data['title'])."\033[0m");
+ $rows[] = array("\033[1m" . dt($data['title']) . "\033[0m");
if (!empty($site['data'][$set])) {
foreach ($site['data'][$set] as $check => $result) {
$rows[] = array(
$result['title'],
- "\033[".$severity[$result['severity']].'m'.strip_tags($result['value'])."\033[0m",
+ "\033[" . $severity[$result['severity']] . 'm' . strip_tags($result['value']) . "\033[0m",
);
if ($error < $result['severity']) {
$error = $result['severity'];
@@ -273,7 +292,7 @@ function _drush_prod_monitor_detail($id) {
}
// Actual printing.
- drush_print("\033[1m".dt('Production Monitor status for').' '._prod_monitor_sanitize_url($url)."\033[0m", 1);
+ drush_print("\033[1m" . dt('Production Monitor status for') . ' ' . _prod_monitor_sanitize_url($url) . "\033[0m", 1);
if (!empty($block)) {
drush_print_table($block);
}
@@ -286,76 +305,109 @@ function _drush_prod_monitor_detail($id) {
if ($error > 0) {
// Would be cool if we could prefix the admin path with http://
/ so it
// will become a clickable link in some terminals. Any ideas?
- drush_print("\033[1m".dt('Some errors were reported!')."\033[0m ".dt('Check the full status page on')." \033[1m".'admin/reports/prod-monitor/'.$id.'/view'."\033[0m ".dt('for details.'));
+ drush_print("\033[1m" . dt('Some errors were reported!') . "\033[0m " . dt('Check the full status page on') . " \033[1m" . 'admin/reports/prod-monitor/' . $id . '/view' . "\033[0m " . dt('for details.'));
}
}
/**
* Update status page callback.
*/
-function _drush_prod_monitor_updates() {
+function drush_prod_monitor_updates() {
$id = func_get_args();
- if (empty($id)) {
- drush_set_error('prod_monitor', dt('You must provide a site ID!'));
- return;
- }
- $id = $id['0'];
- // Get module info.
- $modules = _prod_monitor_get_site_modules($id);
- $url = _prod_monitor_get_url($id);
- if (empty($modules)) {
- if (empty($url)) {
- drush_set_error('prod_monitor', dt('No site found with ID').' '. $id .'!');
+ // Fetch ALL.
+ if (empty($id)) {
+ if (!drush_confirm(dt('Do you really want to check ALL sites for module updates?'))) {
+ drush_set_error('prod_monitor', dt('Aborting.'));
return;
}
else {
- drush_set_error('prod_monitor', dt('No module data found for') .' '. $url.'!');
- return;
+ module_load_include('inc', 'prod_monitor', 'includes/prod_monitor.admin');
+ // Batch process update checking.
+ _prod_monitor_fetch_all_data_batcher_create(FALSE, TRUE, FALSE);
+ drush_backend_batch_process();
}
}
- else if (empty($modules['available'])) {
- drush_set_error('prod_monitor', dt('No update data found for') .' '. $url.'!');
- // No data, ask for refresh.
- _drush_prod_monitor_update_refresh($id, $modules);
- }
+ // Fetch the site as requested.
+ else {
+ $id = $id['0'];
- // Refresh if user asked for it.
- if (drush_get_option('check')) {
- _drush_prod_monitor_update_refresh($id, $modules);
- }
-
- $last = $modules['lastupdate'];
- module_load_include('inc', 'prod_monitor', 'includes/prod_monitor.update');
- $projects = _prod_monitor_calculate_project_data($id, $modules['projects'], $modules['available']);
- // Cleanup.
- unset($modules);
-
- // Table headers.
- $rows[] = array(dt('Name'), dt('Installed version'), dt('Proposed version'), dt('Status'));
-
- // Process releases, notifying user of status and building a list of proposed updates
- drush_include_engine('update_info', 'drupal', NULL, DRUSH_BASE_PATH . '/commands/pm/update_info');
- drush_include(DRUSH_BASE_PATH . '/commands/pm', 'updatecode.pm');
- $updateable = pm_project_filter($projects, $rows);
-
- // Pipe preparation
- if (drush_get_context('DRUSH_PIPE')) {
- $pipe = "";
- foreach($projects as $project){
- $pipe .= $project['name']. " ";
- $pipe .= $project['existing_version']. " ";
- $pipe .= $project['candidate_version']. " ";
- $pipe .= str_replace(' ', '-', pm_update_filter($project)). "\n";
+ // Get module info.
+ $modules = _prod_monitor_get_site_modules($id);
+ $url = _prod_monitor_get_url($id);
+ if (empty($modules)) {
+ if (empty($url)) {
+ drush_set_error('prod_monitor', dt('No site found with ID') . ' ' . $id . '!');
+ return;
+ }
+ else {
+ drush_set_error('prod_monitor', dt('No module data found for') . ' ' . $url . '!');
+ return;
+ }
+ }
+ elseif (empty($modules['available'])) {
+ drush_set_error('prod_monitor', dt('No update data found for') . ' ' . $url . '!');
+ // No data, ask for refresh.
+ _drush_prod_monitor_update_refresh($id, $modules);
}
- drush_print_pipe($pipe);
- // Automatically curtail update process if in pipe mode
- $updateable = FALSE;
- }
- drush_print("\033[1m".dt('Module update status for').' '.$url."\033[0m", 1);
- drush_print(dt('Update information last refreshed:') .' '. ($last ? format_date($last) : dt('Never'))."\n", 1);
- drush_print_table($rows, TRUE);
+ // Refresh if user asked for it.
+ if (drush_get_option('check')) {
+ _drush_prod_monitor_update_refresh($id, $modules);
+ }
+
+ $security_only = drush_get_option('security-only');
+
+ $last = $modules['lastupdate'];
+ module_load_include('inc', 'prod_monitor', 'includes/prod_monitor.update');
+ $projects = _prod_monitor_calculate_project_data($id, $modules['projects'], $modules['available']);
+ // Cleanup.
+ unset($modules);
+
+ // Table headers.
+ $rows[] = array(dt('Name'), dt('Installed version'), dt('Proposed version'), dt('Status'));
+
+ // Process releases, notifying user of status and building a list of proposed updates
+ drush_include_engine('update_info', 'drupal', NULL, DRUSH_BASE_PATH . '/commands/pm/update_info');
+ drush_include(DRUSH_BASE_PATH . '/commands/pm', 'updatecode.pm');
+ foreach ($projects as $project) {
+ // Only show security updates if the user requested it.
+ if ($security_only && $project['status'] !== UPDATE_NOT_SECURE) {
+ continue;
+ }
+ // Add color to the status.
+ $color = "\033[0m";
+ switch ($project['status']) {
+ case UPDATE_CURRENT:
+ $color = "\033[1;32m";
+ break;
+ case UPDATE_NOT_CURRENT:
+ $color = "\033[1;33m";
+ break;
+ case UPDATE_NOT_SECURE:
+ $color = "\033[1;31m";
+ break;
+ }
+ // Translate status to readable name and fill 'candidate_version'.
+ $status = pm_update_filter($project);
+ // Generate row.
+ $rows[] = array(
+ $project['name'],
+ $project['existing_version'],
+ $project['candidate_version'],
+ $color . $status . "\033[0m",
+ );
+ }
+
+ drush_print("\033[1m" . dt('Module update status for') . ' ' . $url . "\033[0m", 1);
+ drush_print(dt('Update information last refreshed:') . ' ' . ($last ? format_date($last) : dt('Never')) . "\n", 1);
+ if (count($rows) > 1) {
+ drush_print_table($rows, TRUE);
+ }
+ else {
+ drush_print("\033[1m" . dt('No updates to show!') . "\033[0m", 1);
+ }
+ }
}
/**
@@ -375,7 +427,7 @@ function _drush_prod_monitor_update_refresh($id, &$modules) {
$modules['lastupdate'] = time();
}
else {
- drush_set_error('prod_monitor', dt('Failed to refres update status information for') .' '. $url.'!');
+ drush_set_error('prod_monitor', dt('Failed to refres update status information for') . ' ' . $url . '!');
drush_die('Aborting.');
}
}
diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info
index fd22ae54..2b2ee321 100644
--- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info
+++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info
@@ -4,9 +4,9 @@ package = Monitoring
core = 7.x
configure = admin/reports/prod-monitor
-; Information added by packaging script on 2013-11-25
-version = "7.x-1.8"
+; Information added by Drupal.org packaging script on 2015-08-04
+version = "7.x-1.9"
core = "7.x"
project = "prod_check"
-datestamp = "1385405033"
+datestamp = "1438700931"
diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.install b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.install
index 97a3a89f..8afddcb7 100644
--- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.install
+++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.install
@@ -149,29 +149,6 @@ function prod_monitor_schema() {
);
}
-/**
- * Implementation of hook_requirements().
- */
-function prod_monitor_requirements($phase) {
- $requirements = array();
-
- switch ($phase) {
- case 'install':
- if (module_exists('update')) {
- $requirements['prod_monitor_update'] = array(
- 'title' => t('Production monitor'),
- 'value' => t('Update manager enabled.'),
- 'severity' => REQUIREMENT_ERROR,
- 'description' => t('You have enabled Update manager. You have to disable this module before enabling Production monitor!'),
- );
- }
- break;
- }
-
- return $requirements;
-}
-
-
/**
* Implementation of hook_uninstall().
*/
@@ -294,3 +271,25 @@ function prod_check_update_7103() {
)
);
}
+
+/**
+ * Add new dbconnect_path setting to database to prevent warnings.
+ */
+function prod_check_update_7104() {
+ $table = 'prod_monitor_sites';
+
+ // Fetch all settings.
+ $result = db_select($table, 'psm')
+ ->fields('psm', array('id', 'settings'))
+ ->execute();
+
+ // Update all sites to add new setting.
+ foreach ($result as $site) {
+ $settings = unserialize($site->settings);
+ $settings['dbconnect_path'] = '';
+ $site->settings = serialize($settings);
+
+ // Write to DB.
+ drupal_write_record($table, $site, array('id'));
+ }
+}
diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module
index e80cb92a..8110ce93 100644
--- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module
+++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module
@@ -13,21 +13,24 @@ define('PROD_MONITOR_REQUIREMENT_WARNING', 1);
define('PROD_MONITOR_REQUIREMENT_ERROR', 2);
/**
- * We do the same here for the update module constants: redefine them so that we
- * do not need to run the update module entirely!
+ * We don't want to load the Update module just to be able to run Production
+ * Monitor, so we copy the constants from Update. But we need to check them all
+ * so that we don't get notices if Update is already running.
*/
-define('UPDATE_DEFAULT_URL', 'http://updates.drupal.org/release-history');
-define('UPDATE_NOT_SECURE', 1);
-define('UPDATE_REVOKED', 2);
-define('UPDATE_NOT_SUPPORTED', 3);
-define('UPDATE_NOT_CURRENT', 4);
-define('UPDATE_CURRENT', 5);
-define('UPDATE_NOT_CHECKED', -1);
-define('UPDATE_UNKNOWN', -2);
-define('UPDATE_NOT_FETCHED', -3);
-define('UPDATE_FETCH_PENDING', -4);
-define('UPDATE_MAX_FETCH_ATTEMPTS', 2);
-define('UPDATE_MAX_FETCH_TIME', 5);
+if (!module_exists('update')) {
+ define('UPDATE_DEFAULT_URL', 'http://updates.drupal.org/release-history');
+ define('UPDATE_NOT_SECURE', 1);
+ define('UPDATE_REVOKED', 2);
+ define('UPDATE_NOT_SUPPORTED', 3);
+ define('UPDATE_NOT_CURRENT', 4);
+ define('UPDATE_CURRENT', 5);
+ define('UPDATE_NOT_CHECKED', -1);
+ define('UPDATE_UNKNOWN', -2);
+ define('UPDATE_NOT_FETCHED', -3);
+ define('UPDATE_FETCH_PENDING', -4);
+ define('UPDATE_MAX_FETCH_ATTEMPTS', 2);
+ define('UPDATE_MAX_FETCH_TIME', 5);
+}
/**
* Implementation of hook_help().
@@ -36,24 +39,29 @@ function prod_monitor_help($path, $arg) {
$output = '';
switch ($path) {
case 'admin/help#prod_monitor':
- $output .= ''.t('Production monitor is a module that can connect to the Production check module using XMLRPC and an API key. It will retrieve all specified data from the remote site to create a satus page and monitoring facility in a central place.').'
';
- $output .= t('You can add multiple sites and configure per site what data you wish (not) to monitor, allowing you to setup a central Drupal site that will monitor all of your sites that have the Production check module with XMLRPC enabled.').'
';
- $output .= t('The data retrieval mechanism can be called manually and is integrated with the cron, so you get a fresh update of data each cron run.').'
';
+ $output .= '' . t('Production monitor is a module that can connect to the Production check module using XMLRPC and an API key. It will retrieve all specified data from the remote site to create a satus page and monitoring facility in a central place.') . '
';
+ $output .= t('You can add multiple sites and configure per site what data you wish (not) to monitor, allowing you to setup a central Drupal site that will monitor all of your sites that have the Production check module with XMLRPC enabled.') . '
';
+ $output .= t('The data retrieval mechanism can be called manually and is integrated with the cron, so you get a fresh update of data each cron run.') . '
';
break;
case 'admin/reports/prod-monitor':
- $output .= ''.t('Site overview table').'
';
- $output .= t('The overview table gives you an overview of what sites you have added together with their status. The status will be the highest error detected in the retrieved data set.').'
';
- $output .= t('The per site functions View, Edit, Fetch data, Flush and Delete should be self explanatory.').'
';
+ $output .= '' . t('Site overview table') . '
';
+ $output .= t('The overview table gives you an overview of what sites you have added together with their status. The status will be the highest error detected in the retrieved data set.') . '
';
+ $output .= t('The per site functions View, Edit, Fetch data, Flush and Delete should be self explanatory.') . '
';
// No break!
case 'admin/reports/prod-monitor/site/%/edit':
- $output .= ''.t('Website URL & API key').'
';
- $output .= t('To add a site, enter it\'s full url, including the protocol, but omitting the xmlrpc.php part and the API key that you have configured for it using the Production check module. Now click the Get settings button.').'
';
- $output .= t('All of the checks that the Production check module can perform are fetched from the remote site and presented as an array of checkboxes. Finally you can configure what exactly you wish to monitor for this site, then hit the Add site button.').'
';
- $output .= t('Each time you edit a site, the settings are fetched from the remote server so that any new checks that might have been added to the Production check module there are always up to date in the monitoring section.').'
'; $output .= t('Fetch data immediately does exactly what it says and fetches all the configured data from the remote site and will direct you to the report page.').'
';
+ $output .= '' . t('Website URL & API key') . '
';
+ $output .= t("To add a site, enter it's full url, including the protocol, but omitting the xmlrpc.php part and the API key that you have configured for it using the Production check module. Now click the Get settings button.") . '
';
+ $output .= t('All of the checks that the Production check module can perform are fetched from the remote site and presented as an array of checkboxes. Finally you can configure what exactly you wish to monitor for this site, then hit the Add site button.') . '
';
+ $output .= t('Each time you edit a site, the settings are fetched from the remote server so that any new checks that might have been added to the Production check module there are always up to date in the monitoring section.') . '
';
+ $output .= t('Fetch data immediately does exactly what it says and fetches all the configured data from the remote site and will direct you to the report page.') . '
';
+ break;
+ case 'admin/reports/prod-monitor/module-lookup':
+ $output .= '' . t('Module name') . '
';
+ $output .= t("Enter (part of) the module's machine name to see what sites are using the module.") . '
';
break;
case 'admin/reports/prod-monitor/site/%':
case 'admin/reports/prod-monitor/site/%/view':
- $output .= '
'.t('This is an overview of all checks performed by the Production check module and their status on the remote site. You can click the links inside the report to jump to the module\'s settings page, or to go to the project page of a module, in case you need to download it for installation.').'
';
+ $output .= '' . t("This is an overview of all checks performed by the Production check module and their status on the remote site. You can click the links inside the report to jump to the module's settings page, or to go to the project page of a module, in case you need to download it for installation.") . '
';
break;
}
return $output;
@@ -89,6 +97,25 @@ function prod_monitor_menu() {
'file' => 'includes/prod_monitor.admin.inc',
);
+ // Default primary tab (callback for this is it's parent path).
+ $items['admin/reports/prod-monitor/overview'] = array(
+ 'title' => 'Overview',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => 0,
+ );
+
+ $items['admin/reports/prod-monitor/module-lookup'] = array(
+ 'title' => 'Module lookup',
+ 'description' => 'Searches monitored applications for module versions.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('prod_monitor_module_lookup_form'),
+ 'access callback' => 'user_access',
+ 'access arguments' => array('access production monitor'),
+ 'type' => MENU_LOCAL_TASK,
+ 'file' => 'includes/prod_monitor.admin.inc',
+ 'weight' => 1,
+ );
+
// This hook_menu() thing, still can't fully see the logic in it. However,
// this here is what I want to achieve. It would be nice to see the /view/ bit
// in the path dissapear, that would finish it entirely. I'll settle for this
@@ -330,8 +357,10 @@ function prod_monitor_cron() {
foreach ($sites as $id => $site_info) {
$elapsed = time() - $cron_start;
if ($elapsed < $time_limit) {
- //TODO: add module status update check here.
+ // First: all checks.
_prod_monitor_retrieve_data($id, $site_info);
+ // MUST be second because of the status update!
+ _prod_monitor_db_connect_check($id, $site_info);
$process++;
}
else {
@@ -367,7 +396,7 @@ function _prod_monitor_retrieve_functions($url, $api_key, $msg = TRUE) {
'error'
);
}
- else if ($msg) {
+ elseif ($msg) {
drupal_set_message(t('Settings form updated, please adjust your settings.'));
}
@@ -469,7 +498,7 @@ function _prod_monitor_retrieve_data($id, $site_info, $msg = FALSE) {
);
}
}
- else if ($msg) {
+ elseif ($msg) {
drupal_set_message(t('Module data for %link successfully updated.', array('%link' => $site_info['url'])));
}
}
@@ -495,7 +524,7 @@ function _prod_monitor_retrieve_data($id, $site_info, $msg = FALSE) {
);
}
}
- else if ($msg) {
+ elseif ($msg) {
drupal_set_message(t('Performance data for %link successfully updated.', array('%link' => $site_info['url'])));
}
}
@@ -504,6 +533,42 @@ function _prod_monitor_retrieve_data($id, $site_info, $msg = FALSE) {
}
}
+/**
+ * Perform separate dbconnect check. We cannot incorporate this at the side of
+ * prod_check as this would make no sense at all when the DB is down.
+ */
+function _prod_monitor_db_connect_check($id, $site_info) {
+ // Execute only if setup properly.
+ if (empty($site_info['settings']['dbconnect_path'])) {
+ return;
+ }
+
+ // Do the check.
+ $dbconnect_path = rtrim($site_info['url'], '/') . '/' . $site_info['settings']['dbconnect_path'];
+ $response = drupal_http_request($dbconnect_path);
+ if ($response->code !== '200' && $response->data !== 'OK') {
+ // Update status to notify the user of the problem!
+ $site_info['status'] = PROD_MONITOR_REQUIREMENT_ERROR;
+ $response->data = 'NOK';
+ }
+
+ // ALWAYS get stored site data as it should have been updated right before
+ // calling this function!
+ $site_data = _prod_monitor_get_site($id, 'data');
+ // Add data to site and save.
+ $site_data['data']['prod_mon']['prod_check_dbconnect'] = $response->code . ' ' . $response->data;
+
+ // Store site data
+ $site = new stdClass();
+ $site->id = $id;
+ if (isset($site_info['status'])) {
+ $site->status = $site_info['status'];
+ }
+ $site->data = serialize($site_data['data']);
+ $site->lastupdate = REQUEST_TIME;
+ $result = drupal_write_record('prod_monitor_sites', $site, array('id'));
+}
+
/**
* Helper function to get all sites.
*/
@@ -526,7 +591,7 @@ function _prod_monitor_get_sites($start_id = FALSE) {
if (!empty($row->data)) {
foreach ($row->data as $set => $checks) {
foreach ($checks as $check => $results) {
- $status = ($results['severity'] > $status) ? $results['severity'] : $status;
+ $status = (isset($results['severity']) && $results['severity'] > $status) ? $results['severity'] : $status;
}
}
$data_status = TRUE;
@@ -561,21 +626,33 @@ function _prod_monitor_get_sites($start_id = FALSE) {
*
* @param $id
* int site id.
- * @param $all
- * Boolean whether or not to return all fields or just the url and settings.
+ * @param $type
+ * String the amount of data to be returned.
*/
-function _prod_monitor_get_site($id, $all = FALSE) {
- if (!$all) {
- $site = db_query("SELECT url, settings FROM {prod_monitor_sites} WHERE id = :id", array(':id' => $id))->fetchAssoc();
- }
- else {
- $site = db_query("SELECT * FROM {prod_monitor_sites} WHERE id = :id", array(':id' => $id))->fetchAssoc();
+function _prod_monitor_get_site($id, $type = 'settings') {
+ switch ($type) {
+ case 'settings':
+ $site = db_query("SELECT url, settings FROM {prod_monitor_sites} WHERE id = :id", array(':id' => $id))->fetchAssoc();
+ break;
+ case 'all':
+ $site = db_query("SELECT * FROM {prod_monitor_sites} WHERE id = :id", array(':id' => $id))->fetchAssoc();
+ break;
+ case 'data':
+ $site = db_query("SELECT data FROM {prod_monitor_sites} WHERE id = :id", array(':id' => $id))->fetchAssoc();
+ break;
}
if (!empty($site)) {
- $site['settings'] = unserialize($site['settings']);
- if ($all) {
- $site['data'] = unserialize($site['data']);
+ switch ($type) {
+ case 'all':
+ $site['data'] = unserialize($site['data']);
+ // No break!
+ case 'settings':
+ $site['settings'] = unserialize($site['settings']);
+ break;
+ case 'data':
+ $site['data'] = unserialize($site['data']);
+ break;
}
}
@@ -607,6 +684,25 @@ function _prod_monitor_get_site_modules($id, $exists = FALSE) {
return $modules;
}
+/**
+ * Returns an array of ignored directives by site id.
+ *
+ * @param int $id The site id.
+ *
+ * @return array
+ * - updates array List of project names, whose update status we'll ignore.
+ */
+function _prod_monitor_get_site_ignored($id) {
+ $ignored = &drupal_static(__FUNCTION__, array());
+ if (!array_key_exists($id, $ignored)) {
+ $ignored[$id] = module_invoke_all('prod_monitor_ignore', $id) + array(
+ 'updates' => array(),
+ );
+ }
+
+ return $ignored[$id];
+}
+
/**
* Helper function to get the module status of a site by ID.
*
diff --git a/sites/all/modules/contrib/theming/colorbox/README.txt b/sites/all/modules/contrib/theming/colorbox/README.txt
index a5c217e2..31cb8901 100644
--- a/sites/all/modules/contrib/theming/colorbox/README.txt
+++ b/sites/all/modules/contrib/theming/colorbox/README.txt
@@ -89,7 +89,7 @@ Make any CSS adjustments to your "colorbox_mycolorbox.css" file.
Load images from custom links in a Colorbox:
--------------------------------------------
-Add the class "colorbox" to the link and point the src to the image
+Add the class "colorbox" to the link and point its href attribute to the image
you want to display in the Colorbox.
diff --git a/sites/all/modules/contrib/theming/colorbox/colorbox.api.php b/sites/all/modules/contrib/theming/colorbox/colorbox.api.php
index 83ead10d..61495bab 100644
--- a/sites/all/modules/contrib/theming/colorbox/colorbox.api.php
+++ b/sites/all/modules/contrib/theming/colorbox/colorbox.api.php
@@ -27,3 +27,18 @@ function hook_colorbox_settings_alter(&$settings, &$style) {
$style = 'mystyle';
}
}
+
+/**
+ * Allows to override activation of Colobox for the current URL.
+ *
+ * @param $active
+ * A boolean indicating whether colorbox should be active for the current
+ * URL or not.
+ */
+function hook_colorbox_active_alter(&$active) {
+ $path = drupal_get_path_alias($_GET['q']);
+ if (drupal_match_path($path, 'admin/config/colorbox_test')) {
+ // Enable colorbox for this URL.
+ $active = TRUE;
+ }
+}
diff --git a/sites/all/modules/contrib/theming/colorbox/colorbox.info b/sites/all/modules/contrib/theming/colorbox/colorbox.info
index 68a3d4e7..4b5fda87 100644
--- a/sites/all/modules/contrib/theming/colorbox/colorbox.info
+++ b/sites/all/modules/contrib/theming/colorbox/colorbox.info
@@ -1,14 +1,14 @@
name = Colorbox
description = A light-weight, customizable lightbox plugin for jQuery 1.4.3+.
-dependencies[] = libraries (2.x)
+dependencies[] = libraries (>=2.x)
core = 7.x
configure = admin/config/media/colorbox
files[] = views/colorbox_handler_field_colorbox.inc
-; Information added by Drupal.org packaging script on 2014-09-12
-version = "7.x-2.8"
+; Information added by Drupal.org packaging script on 2015-10-01
+version = "7.x-2.10"
core = "7.x"
project = "colorbox"
-datestamp = "1410514129"
+datestamp = "1443691449"
diff --git a/sites/all/modules/contrib/theming/colorbox/colorbox.module b/sites/all/modules/contrib/theming/colorbox/colorbox.module
index da22f8ae..e3d94d23 100644
--- a/sites/all/modules/contrib/theming/colorbox/colorbox.module
+++ b/sites/all/modules/contrib/theming/colorbox/colorbox.module
@@ -152,6 +152,9 @@ function _colorbox_active() {
}
$page_match = variable_get('colorbox_visibility', 0) == 0 ? !$page_match : $page_match;
+ // Allow other modules to change the state of colorbox for the current URL.
+ drupal_alter('colorbox_active', $page_match);
+
return $page_match;
}
diff --git a/sites/all/modules/contrib/theming/colorbox/colorbox.theme.inc b/sites/all/modules/contrib/theming/colorbox/colorbox.theme.inc
index 89e38ba7..74ceaf88 100644
--- a/sites/all/modules/contrib/theming/colorbox/colorbox.theme.inc
+++ b/sites/all/modules/contrib/theming/colorbox/colorbox.theme.inc
@@ -17,6 +17,7 @@
* @ingroup themeable
*/
function theme_colorbox_image_formatter($variables) {
+ static $gallery_token = NULL;
$item = $variables['item'];
$entity_type = $variables['entity_type'];
$entity = $variables['entity'];
@@ -123,6 +124,16 @@ function theme_colorbox_image_formatter($variables) {
$gallery_id = '';
}
+ // If gallery id is not empty add unique per-request token to avoid images being added manually to galleries.
+ if (!empty($gallery_id)) {
+ // Check if gallery token has alrady been set, we need to reuse the token for the whole request.
+ if (is_null($gallery_token)) {
+ // We use a short token since randomness is not critical.
+ $gallery_token = drupal_random_key(8);
+ }
+ $gallery_id = $gallery_id . '-' . $gallery_token;
+ }
+
if ($style_name = $settings['colorbox_image_style']) {
$path = image_style_url($style_name, $image['path']);
}
diff --git a/sites/all/modules/contrib/theming/colorbox/js/colorbox.js b/sites/all/modules/contrib/theming/colorbox/js/colorbox.js
index ace202ef..cd0520bb 100644
--- a/sites/all/modules/contrib/theming/colorbox/js/colorbox.js
+++ b/sites/all/modules/contrib/theming/colorbox/js/colorbox.js
@@ -2,7 +2,7 @@
Drupal.behaviors.initColorbox = {
attach: function (context, settings) {
- if (!$.isFunction($.colorbox)) {
+ if (!$.isFunction($.colorbox) || typeof settings.colorbox === 'undefined') {
return;
}
diff --git a/sites/all/modules/contrib/theming/colorbox/js/colorbox_inline.js b/sites/all/modules/contrib/theming/colorbox/js/colorbox_inline.js
index f515036e..0b27b655 100644
--- a/sites/all/modules/contrib/theming/colorbox/js/colorbox_inline.js
+++ b/sites/all/modules/contrib/theming/colorbox/js/colorbox_inline.js
@@ -2,7 +2,7 @@
Drupal.behaviors.initColorboxInline = {
attach: function (context, settings) {
- if (!$.isFunction($.colorbox)) {
+ if (!$.isFunction($.colorbox) || typeof settings.colorbox === 'undefined') {
return;
}
$.urlParam = function(name, url){
diff --git a/sites/all/modules/contrib/theming/colorbox/js/colorbox_load.js b/sites/all/modules/contrib/theming/colorbox/js/colorbox_load.js
index e63043ed..30e99a77 100644
--- a/sites/all/modules/contrib/theming/colorbox/js/colorbox_load.js
+++ b/sites/all/modules/contrib/theming/colorbox/js/colorbox_load.js
@@ -2,7 +2,7 @@
Drupal.behaviors.initColorboxLoad = {
attach: function (context, settings) {
- if (!$.isFunction($.colorbox)) {
+ if (!$.isFunction($.colorbox) || typeof settings.colorbox === 'undefined') {
return;
}
$.urlParams = function (url) {
diff --git a/sites/all/modules/contrib/theming/colorbox/views/colorbox_handler_field_colorbox.inc b/sites/all/modules/contrib/theming/colorbox/views/colorbox_handler_field_colorbox.inc
index 27a20452..205d0995 100644
--- a/sites/all/modules/contrib/theming/colorbox/views/colorbox_handler_field_colorbox.inc
+++ b/sites/all/modules/contrib/theming/colorbox/views/colorbox_handler_field_colorbox.inc
@@ -162,10 +162,15 @@ If you would like to have the characters %5B and %5D please use the html entity
$tokens = $this->get_render_tokens($this->options['alter']);
$popup = filter_xss_admin($this->options['popup']);
$caption = filter_xss_admin($this->options['caption']);
- $gallery = drupal_html_class($this->options['custom_gid']);
+ $gallery = filter_xss_admin($this->options['custom_gid']);
$popup = strtr($popup, $tokens);
$caption = strtr($caption, $tokens);
- $gallery = strtr($gallery, $tokens);
+ $gallery = drupal_html_class(strtr($gallery, $tokens));
+
+ // Return nothing if popup is empty.
+ if (empty($popup)) {
+ return;
+ }
$width = $this->options['width'] ? $this->options['width'] : '';
$height = $this->options['height'] ? $this->options['height'] : '';