diff --git a/sites/all/modules/contrib/admin/google_analytics/README.txt b/sites/all/modules/contrib/admin/google_analytics/README.txt index fab2f2ec..25fd22aa 100644 --- a/sites/all/modules/contrib/admin/google_analytics/README.txt +++ b/sites/all/modules/contrib/admin/google_analytics/README.txt @@ -12,12 +12,20 @@ Requirements * Google Analytics user account - Installation ============ Copy the 'googleanalytics' module directory in to your Drupal sites/all/modules directory as usual. +Upgrading from 6.x-3.x and 7.x-1.x +================================== +If you upgrade from 6.x-3.x and 7.x-1.x (ga.js) to 7.x-2.x (analytics.js) you +should verify if you used custom variables. Write down your settings or make a +screenshot. You need to re-configure the settings to use custom dimensions or +metrics. There is no automatic upgrade path for custom variables feature. All +other module settings are upgraded automatically. + +See https://support.google.com/analytics/answer/2795983?hl=en for more details. Usage ===== @@ -27,12 +35,8 @@ All pages will now have the required JavaScript added to the HTML footer can confirm this by viewing the page source from your browser. -New approach to page tracking in 5.x-1.5 and 6.x-1.1 -==================================================== -With 5.x-1.5 and 6.x-1.1 there are new settings on the settings page at -admin/config/system/googleanalytics. The "Page specific tracking" area now -comes with an interface that copies Drupal's block visibility settings. - +Page specific tracking +====================== The default is set to "Add to every page except the listed pages". By default the following pages are listed for exclusion: @@ -44,23 +48,24 @@ node/*/* user/*/* These defaults are changeable by the website administrator or any other -user with 'administer google analytics' permission. +user with 'Administer Google Analytics' permission. -Like the blocks visibility settings in Drupal core, there is now a -choice for "Add if the following PHP code returns TRUE." Sample PHP snippets -that can be used in this textarea can be found on the handbook page -"Overview-approach to block visibility" at http://drupal.org/node/64135. +Like the blocks visibility settings in Drupal core, there is a choice for +"Add if the following PHP code returns TRUE." Sample PHP snippets that can be +used in this textarea can be found on the handbook page "Overview-approach to +block visibility" at http://drupal.org/node/64135. Custom dimensions and metrics ============================= One example for custom dimensions tracking is the "User roles" tracking. -1. In the Google Analytics Management Interface you need to setup Dimension #1 - with name e.g. "User roles". This step is required. Do not miss it, please. +1. In the Google Analytics Management Interface (http://www.google.com/analytics/) + you need to setup Dimension #1 with name e.g. "User roles". This step is + required. Do not miss it, please. -2. Enter the below configuration data into the custom dimensions settings form - under admin/config/system/googleanalytics. You can also choose another index, - but keep it always in sync with the index used in step #1. +2. Enter the below configuration data into the Drupal custom dimensions settings + form under admin/config/system/googleanalytics. You can also choose another + index, but keep it always in sync with the index used in step #1. Index: 1 Value: [current-user:role-names] @@ -77,3 +82,23 @@ provided for any customisations you include. To speed up page loading you may also cache the Google Analytics "analytics.js" file locally. + +Manual JS debugging +=================== +For manual debugging of the JS code you are able to create a test node. This +is the example HTML code for this test node. You need to enable debugging mode +in your Drupal configuration of Google Analytics settings to see verbose +messages in your browsers JS console. + +Title: Google Analytics test page + +Body: +
ga("send", "pageview");
.'),
+ '#description' => t('Code in this textarea will be added before ga("send", "pageview");
.') . $user_access_add_js_snippets_permission_warning,
);
$form['advanced']['codesnippet']['googleanalytics_codesnippet_after'] = array(
'#type' => 'textarea',
'#title' => t('Code snippet (after)'),
'#default_value' => variable_get('googleanalytics_codesnippet_after', ''),
+ '#disabled' => $user_access_add_js_snippets,
'#rows' => 5,
- '#description' => t('Code in this textarea will be added after ga("send", "pageview");
. This is useful if you\'d like to track a site in two accounts.'),
+ '#description' => t('Code in this textarea will be added after ga("send", "pageview");
. This is useful if you\'d like to track a site in two accounts.') . $user_access_add_js_snippets_permission_warning,
);
$form['advanced']['googleanalytics_debug'] = array(
@@ -541,6 +557,12 @@ function googleanalytics_admin_settings_form_validate($form, &$form_state) {
/**
* Layout for the custom variables table in the admin settings form.
+ *
+ * @param array $variables
+ * An array contains the form elements.
+ *
+ * @return string
+ * The rendered output.
*/
function theme_googleanalytics_admin_custom_var_table($variables) {
$form = $variables['form'];
@@ -551,7 +573,7 @@ function theme_googleanalytics_admin_custom_var_table($variables) {
);
$rows = array();
- foreach (element_children($form['indexes']) as $key => $id) {
+ foreach (element_children($form['indexes']) as $id) {
$rows[] = array(
'data' => array(
drupal_render($form['indexes'][$id]['index']),
@@ -600,11 +622,18 @@ function googleanalytics_token_element_validate(&$element, &$form_state) {
return $element;
}
+/**
+ * @param array $value
+ * An array of token values.
+ *
+ * @return array
+ * A unique array of invalid tokens.
+ */
function _googleanalytics_get_forbidden_tokens($value) {
$invalid_tokens = array();
$value_tokens = is_string($value) ? token_scan($value) : $value;
- foreach ($value_tokens as $type => $tokens) {
+ foreach ($value_tokens as $tokens) {
if (array_filter($tokens, '_googleanalytics_contains_forbidden_token')) {
$invalid_tokens = array_merge($invalid_tokens, array_values($tokens));
}
@@ -617,8 +646,9 @@ function _googleanalytics_get_forbidden_tokens($value) {
/**
* Validate if a string contains forbidden tokens not allowed by privacy rules.
*
- * @param $token_string
+ * @param string $token_string
* A string with one or more tokens to be validated.
+ *
* @return boolean
* TRUE if blacklisted token has been found, otherwise FALSE.
*/
@@ -724,7 +754,7 @@ function _googleanalytics_extract_create_field_values($string) {
$list = array_map('trim', $list);
$list = array_filter($list, 'strlen');
- foreach ($list as $position => $text) {
+ foreach ($list as $text) {
// Check for an explicit key.
$matches = array();
if (preg_match('/(.*)\|(.*)/', $text, $matches)) {
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.admin.js b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.admin.js
index 083eeaa3..c81470d7 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.admin.js
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.admin.js
@@ -65,6 +65,15 @@ Drupal.behaviors.trackingSettingsSummary = {
if ($('input#edit-googleanalytics-trackfiles', context).is(':checked')) {
vals.push(Drupal.t('Downloads'));
}
+ if ($('input#edit-googleanalytics-trackcolorbox', context).is(':checked')) {
+ vals.push(Drupal.t('Colorbox'));
+ }
+ if ($('input#edit-googleanalytics-tracklinkid', context).is(':checked')) {
+ vals.push(Drupal.t('Link attribution'));
+ }
+ if ($('input#edit-googleanalytics-trackurlfragments', context).is(':checked')) {
+ vals.push(Drupal.t('URL fragments'));
+ }
if (!vals.length) {
return Drupal.t('Not tracked');
}
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.debug.js b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.debug.js
index 861f7fdb..a0be81ae 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.debug.js
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.debug.js
@@ -8,16 +8,16 @@ $(document).ready(function() {
// clicks on all elements.
$(document.body).bind("mousedown keyup touchstart", function(event) {
console.group("Running Google Analytics for Drupal.");
- console.info(event);
+ console.info("Event '%s' has been detected.", event.type);
// Catch the closest surrounding link of a clicked element.
$(event.target).closest("a,area").each(function() {
- console.info("Element '%o' has been detected. Link '%s' found.", this, this.href);
+ console.info("Closest element '%o' has been found. URL '%s' extracted.", this, this.href);
// Is the clicked URL internal?
if (Drupal.googleanalytics.isInternal(this.href)) {
// Skip 'click' tracking, if custom tracking events are bound.
- if ($(this).is('.colorbox')) {
+ if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
// Do nothing here. The custom event will handle all tracking.
console.info("Click on .colorbox item has been detected.");
}
@@ -25,12 +25,22 @@ $(document).ready(function() {
else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
// Download link clicked.
console.info("Download url '%s' has been found. Tracked download as extension '%s'.", Drupal.googleanalytics.getPageUrl(this.href), Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase());
- ga("send", "event", "Downloads", Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), Drupal.googleanalytics.getPageUrl(this.href));
+ ga("send", {
+ "hitType": "event",
+ "eventCategory": "Downloads",
+ "eventAction": Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(),
+ "eventLabel": Drupal.googleanalytics.getPageUrl(this.href),
+ "transport": "beacon"
+ });
}
else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
// Keep the internal URL for Google Analytics website overlay intact.
console.info("Click on internal special link '%s' has been tracked.", Drupal.googleanalytics.getPageUrl(this.href));
- ga("send", "pageview", { "page": Drupal.googleanalytics.getPageUrl(this.href) });
+ ga("send", {
+ "hitType": "pageview",
+ "page": Drupal.googleanalytics.getPageUrl(this.href),
+ "transport": "beacon"
+ });
}
else {
// e.g. anchor in same page or other internal page link
@@ -41,13 +51,25 @@ $(document).ready(function() {
if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
// Mailto link clicked.
console.info("Click on e-mail '%s' has been tracked.", this.href.substring(7));
- ga("send", "event", "Mails", "Click", this.href.substring(7));
+ ga("send", {
+ "hitType": "event",
+ "eventCategory": "Mails",
+ "eventAction": "Click",
+ "eventLabel": this.href.substring(7),
+ "transport": "beacon"
+ });
}
else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
- if (Drupal.settings.googleanalytics.trackDomainMode != 2 || (Drupal.settings.googleanalytics.trackDomainMode == 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
+ if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
// External link clicked / No top-level cross domain clicked.
console.info("Outbound link '%s' has been tracked.", this.href);
- ga("send", "event", "Outbound links", "Click", this.href);
+ ga("send", {
+ "hitType": "event",
+ "eventCategory": "Outbound links",
+ "eventAction": "Click",
+ "eventLabel": this.href,
+ "transport": "beacon"
+ });
}
else {
console.info("Internal link '%s' clicked, not tracked.", this.href);
@@ -63,19 +85,27 @@ $(document).ready(function() {
if (Drupal.settings.googleanalytics.trackUrlFragments) {
window.onhashchange = function() {
console.info("Track URL '%s' as pageview. Hash '%s' has changed.", location.pathname + location.search + location.hash, location.hash);
- ga('send', 'pageview', location.pathname + location.search + location.hash);
- }
+ ga("send", {
+ "hitType": "pageview",
+ "page": location.pathname + location.search + location.hash
+ });
+ };
}
// Colorbox: This event triggers when the transition has completed and the
// newly loaded content has been revealed.
- $(document).bind("cbox_complete", function () {
- var href = $.colorbox.element().attr("href");
- if (href) {
- console.info("Colorbox transition to url '%s' has been tracked.", Drupal.googleanalytics.getPageUrl(href));
- ga("send", "pageview", { "page": Drupal.googleanalytics.getPageUrl(href) });
- }
- });
+ if (Drupal.settings.googleanalytics.trackColorbox) {
+ $(document).bind("cbox_complete", function () {
+ var href = $.colorbox.element().attr("href");
+ if (href) {
+ console.info("Colorbox transition to url '%s' has been tracked.", Drupal.googleanalytics.getPageUrl(href));
+ ga("send", {
+ "hitType": "pageview",
+ "page": Drupal.googleanalytics.getPageUrl(href)
+ });
+ }
+ });
+ }
});
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.info b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.info
index adbf134a..2b814605 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.info
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.info
@@ -5,9 +5,9 @@ package = Statistics
configure = admin/config/system/googleanalytics
files[] = googleanalytics.test
test_dependencies[] = token
-; Information added by Drupal.org packaging script on 2014-11-29
-version = "7.x-2.1"
+; Information added by Drupal.org packaging script on 2016-08-09
+version = "7.x-2.3"
core = "7.x"
project = "google_analytics"
-datestamp = "1417276982"
+datestamp = "1470779953"
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.install b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.install
index d7b2edfb..a4f4e83a 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.install
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.install
@@ -25,6 +25,7 @@ function googleanalytics_uninstall() {
variable_del('googleanalytics_roles');
variable_del('googleanalytics_site_search');
variable_del('googleanalytics_trackadsense');
+ variable_del('googleanalytics_trackcolorbox');
variable_del('googleanalytics_trackdoubleclick');
variable_del('googleanalytics_tracker_anonymizeip');
variable_del('googleanalytics_trackfiles');
@@ -446,16 +447,16 @@ function googleanalytics_update_7200() {
if (!empty($googleanalytics_codesnippet_before) && stristr($googleanalytics_codesnippet_before, '_gaq.push(')) {
variable_set('googleanalytics_codesnippet_before_backup_7200', $googleanalytics_codesnippet_before);
variable_del('googleanalytics_codesnippet_before');
- drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet."), 'warning');
- $messages[] = t('Manual upgrade of custom "before" code snippet is required.');
+ drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet (ga.js) has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet to analytics.js API."), 'warning');
+ $messages[] = t('Manual upgrade of custom "before" code snippet from ja.js to analytics.js API is required.');
}
$googleanalytics_codesnippet_after = variable_get('googleanalytics_codesnippet_after', '');
if (!empty($googleanalytics_codesnippet_after) && stristr($googleanalytics_codesnippet_after, '_gaq.push(')) {
variable_set('googleanalytics_codesnippet_after_backup_7200', $googleanalytics_codesnippet_after);
variable_del('googleanalytics_codesnippet_after');
- drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet has been saved in database table '{variable}' as 'googleanalytics_codesnippet_before_backup_7200'. You need to manually upgrade the custom 'before' code snippet."), 'warning');
- $messages[] = t('Manual upgrade of custom "after" code snippet is required.');
+ drupal_set_message(Database::getConnection()->prefixTables("A backup of your previous Google Analytics code snippet (ga.js) has been saved in database table '{variable}' as 'googleanalytics_codesnippet_after_backup_7200'. You need to manually upgrade the custom 'after' code snippet to analytics.js API."), 'warning');
+ $messages[] = t('Manual upgrade of custom "after" code snippet from ja.js to analytics.js API is required.');
}
return empty($messages) ? t('No custom code snipped found. Nothing to do.') : implode(' ', $messages);
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.js b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.js
index 1eed3c32..8d5bde1b 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.js
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.js
@@ -14,29 +14,51 @@ $(document).ready(function() {
// Is the clicked URL internal?
if (Drupal.googleanalytics.isInternal(this.href)) {
// Skip 'click' tracking, if custom tracking events are bound.
- if ($(this).is('.colorbox')) {
+ if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
// Do nothing here. The custom event will handle all tracking.
//console.info("Click on .colorbox item has been detected.");
}
// Is download tracking activated and the file extension configured for download tracking?
else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
// Download link clicked.
- ga("send", "event", "Downloads", Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), Drupal.googleanalytics.getPageUrl(this.href));
+ ga("send", {
+ "hitType": "event",
+ "eventCategory": "Downloads",
+ "eventAction": Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(),
+ "eventLabel": Drupal.googleanalytics.getPageUrl(this.href),
+ "transport": "beacon"
+ });
}
else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
// Keep the internal URL for Google Analytics website overlay intact.
- ga("send", "pageview", { "page": Drupal.googleanalytics.getPageUrl(this.href) });
+ ga("send", {
+ "hitType": "pageview",
+ "page": Drupal.googleanalytics.getPageUrl(this.href),
+ "transport": "beacon"
+ });
}
}
else {
if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
// Mailto link clicked.
- ga("send", "event", "Mails", "Click", this.href.substring(7));
+ ga("send", {
+ "hitType": "event",
+ "eventCategory": "Mails",
+ "eventAction": "Click",
+ "eventLabel": this.href.substring(7),
+ "transport": "beacon"
+ });
}
else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
- if (Drupal.settings.googleanalytics.trackDomainMode != 2 || (Drupal.settings.googleanalytics.trackDomainMode == 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
+ if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
// External link clicked / No top-level cross domain clicked.
- ga("send", "event", "Outbound links", "Click", this.href);
+ ga("send", {
+ "hitType": "event",
+ "eventCategory": "Outbound links",
+ "eventAction": "Click",
+ "eventLabel": this.href,
+ "transport": "beacon"
+ });
}
}
}
@@ -46,18 +68,26 @@ $(document).ready(function() {
// Track hash changes as unique pageviews, if this option has been enabled.
if (Drupal.settings.googleanalytics.trackUrlFragments) {
window.onhashchange = function() {
- ga('send', 'pageview', location.pathname + location.search + location.hash);
- }
+ ga("send", {
+ "hitType": "pageview",
+ "page": location.pathname + location.search + location.hash
+ });
+ };
}
// Colorbox: This event triggers when the transition has completed and the
// newly loaded content has been revealed.
- $(document).bind("cbox_complete", function () {
- var href = $.colorbox.element().attr("href");
- if (href) {
- ga("send", "pageview", { "page": Drupal.googleanalytics.getPageUrl(href) });
- }
- });
+ if (Drupal.settings.googleanalytics.trackColorbox) {
+ $(document).bind("cbox_complete", function () {
+ var href = $.colorbox.element().attr("href");
+ if (href) {
+ ga("send", {
+ "hitType": "pageview",
+ "page": Drupal.googleanalytics.getPageUrl(href)
+ });
+ }
+ });
+ }
});
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.module b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.module
index 4051b1b9..b45ee103 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.module
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.module
@@ -69,6 +69,11 @@ function googleanalytics_permission() {
'description' => t('Enter PHP code in the field for tracking visibility settings.'),
'restrict access' => TRUE,
),
+ 'add JS snippets for google analytics' => array(
+ 'title' => t('Add JavaScript snippets'),
+ 'description' => 'Enter JavaScript code snippets for advanced Google Analytics functionality.',
+ 'restrict access' => TRUE,
+ ),
);
}
@@ -125,6 +130,9 @@ function googleanalytics_page_alter(&$page) {
$link_settings['trackDownload'] = $track_download;
$link_settings['trackDownloadExtensions'] = $trackfiles_extensions;
}
+ if (module_exists('colorbox') && ($track_colorbox = variable_get('googleanalytics_trackcolorbox', 1))) {
+ $link_settings['trackColorbox'] = $track_colorbox;
+ }
if ($track_domain_mode = variable_get('googleanalytics_domain_mode', 0)) {
$link_settings['trackDomainMode'] = $track_domain_mode;
}
@@ -294,10 +302,7 @@ function googleanalytics_page_alter(&$page) {
// Track logged in users across all devices.
if (variable_get('googleanalytics_trackuserid', 0) && user_is_logged_in()) {
- // The USER_ID value should be a unique, persistent, and non-personally
- // identifiable string identifier that represents a user or signed-in
- // account across devices.
- $create_only_fields['userId'] = drupal_hmac_base64($user->uid, drupal_get_private_key() . drupal_get_hash_salt());
+ $create_only_fields['userId'] = google_analytics_user_id_hash($user->uid);
}
// Create a tracker.
@@ -352,13 +357,30 @@ function googleanalytics_page_alter(&$page) {
// Custom tracking. Prepend before all other JavaScript.
// @TODO: https://support.google.com/adsense/answer/98142
// sounds like it could be appended to $script.
- drupal_add_js($googleanalytics_adsense_script, array('type' => 'inline', 'group' => JS_LIBRARY-1));
+ drupal_add_js($googleanalytics_adsense_script, array('type' => 'inline', 'group' => JS_LIBRARY-1, 'requires_jquery' => FALSE));
}
- drupal_add_js($script, array('scope' => 'header', 'type' => 'inline'));
+ drupal_add_js($script, array('scope' => 'header', 'type' => 'inline', 'requires_jquery' => FALSE));
}
}
+/**
+ * Generate user id hash to implement USER_ID.
+ *
+ * The USER_ID value should be a unique, persistent, and non-personally
+ * identifiable string identifier that represents a user or signed-in
+ * account across devices.
+ *
+ * @param int $uid
+ * User id.
+ *
+ * @return string
+ * User id hash.
+ */
+function google_analytics_user_id_hash($uid) {
+ return drupal_hmac_base64($uid, drupal_get_private_key() . drupal_get_hash_salt());
+}
+
/**
* Implements hook_field_extra_fields().
*/
@@ -456,7 +478,7 @@ function googleanalytics_preprocess_search_results(&$variables) {
// found. But the pager item mumber can tell the number of search results.
global $pager_total_items;
- drupal_add_js('window.googleanalytics_search_results = ' . intval($pager_total_items[0]) . ';', array('type' => 'inline', 'group' => JS_LIBRARY-1));
+ drupal_add_js('window.googleanalytics_search_results = ' . intval($pager_total_items[0]) . ';', array('type' => 'inline', 'group' => JS_LIBRARY-1, 'requires_jquery' => FALSE));
}
}
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.test b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.test
index 0b64bb82..745047a8 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.test
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.test
@@ -6,6 +6,13 @@
*/
class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
+ /**
+ * User without permissions to edit snippets.
+ *
+ * @var \StdClass
+ */
+ protected $noSnippetUser;
+
public static function getInfo() {
return array(
'name' => 'Google Analytics basic tests',
@@ -25,6 +32,8 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
);
// User to set up google_analytics.
+ $this->noSnippetUser = $this->drupalCreateUser($permissions);
+ $permissions[] = 'add JS snippets for google analytics';
$this->admin_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($this->admin_user);
}
@@ -48,6 +57,26 @@ class GoogleAnalyticsBasicTest extends DrupalWebTestCase {
$edit['googleanalytics_account'] = $this->randomName(2);
$this->drupalPost('admin/config/system/googleanalytics', $edit, t('Save configuration'));
$this->assertRaw(t('A valid Google Analytics Web Property ID is case sensitive and formatted like UA-xxxxxxx-yy.'), '[testGoogleAnalyticsConfiguration]: Invalid Web Property ID number validated.');
+
+ // User should have access to code snippets.
+ $this->assertFieldByName('googleanalytics_codesnippet_create');
+ $this->assertFieldByName('googleanalytics_codesnippet_before');
+ $this->assertFieldByName('googleanalytics_codesnippet_after');
+ $this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_create' and @disabled='disabled']", NULL, '"Create only fields" is enabled.');
+ $this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_before' and @disabled='disabled']", NULL, '"Code snippet (before)" is enabled.');
+ $this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_after' and @disabled='disabled']", NULL, '"Code snippet (after)" is enabled.');
+
+ // Login as user without JS permissions.
+ $this->drupalLogin($this->noSnippetUser);
+ $this->drupalGet('admin/config/system/googleanalytics');
+
+ // User should *not* have access to snippets, but create fields.
+ $this->assertFieldByName('googleanalytics_codesnippet_create');
+ $this->assertFieldByName('googleanalytics_codesnippet_before');
+ $this->assertFieldByName('googleanalytics_codesnippet_after');
+ $this->assertNoFieldByXPath("//textarea[@name='googleanalytics_codesnippet_create' and @disabled='disabled']", NULL, '"Create only fields" is enabled.');
+ $this->assertFieldByXPath("//textarea[@name='googleanalytics_codesnippet_before' and @disabled='disabled']", NULL, '"Code snippet (before)" is disabled.');
+ $this->assertFieldByXPath("//textarea[@name='googleanalytics_codesnippet_after' and @disabled='disabled']", NULL, '"Code snippet (after)" is disabled.');
}
function testGoogleAnalyticsPageVisibility() {
@@ -284,6 +313,7 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
// User to set up google_analytics.
$this->admin_user = $this->drupalCreateUser($permissions);
+ $this->drupalLogin($this->admin_user);
}
function testGoogleAnalyticsCustomDimensions() {
@@ -362,34 +392,30 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
1 => array(
'index' => 1,
'value' => '6',
- 'value_expected' => 6,
),
2 => array(
'index' => 2,
'value' => '8000',
- 'value_expected' => 8000,
),
3 => array(
'index' => 3,
'value' => '7.8654',
- 'value_expected' => 7.8654,
),
4 => array(
'index' => 4,
'value' => '1123.4',
- 'value_expected' => 1123.4,
),
5 => array(
'index' => 5,
'value' => '5,67',
- 'value_expected' => 5,
),
);
+
variable_set('googleanalytics_custom_metric', $googleanalytics_custom_metric);
$this->drupalGet('');
foreach ($googleanalytics_custom_metric as $metric) {
- $this->assertRaw('ga("set", ' . drupal_json_encode('metric' . $metric['index']) . ', ' . drupal_json_encode($metric['value_expected']) . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Metric #' . $metric['index'] . ' is shown.');
+ $this->assertRaw('ga("set", ' . drupal_json_encode('metric' . $metric['index']) . ', ' . drupal_json_encode((float) $metric['value']) . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Metric #' . $metric['index'] . ' is shown.');
}
// Test whether tokens are replaced in custom metric values.
@@ -421,6 +447,30 @@ class GoogleAnalyticsCustomDimensionsAndMetricsTest extends DrupalWebTestCase {
$this->assertNoRaw('ga("set", ' . drupal_json_encode('metric3') . ', ' . drupal_json_encode('') . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Empty value is not shown.');
$this->assertRaw('ga("set", ' . drupal_json_encode('metric4') . ', ' . drupal_json_encode(0) . ');', '[testGoogleAnalyticsCustomDimensionsAndMetrics]: Value 0 is shown.');
}
+
+ /**
+ * Tests if Custom Dimensions token form validation works.
+ */
+ public function testGoogleAnalyticsCustomDimensionsTokenFormValidation() {
+ $ua_code = 'UA-123456-1';
+
+ // Check form validation.
+ $edit['googleanalytics_account'] = $ua_code;
+ $edit['googleanalytics_custom_dimension[indexes][1][value]'] = '[current-user:name]';
+ $edit['googleanalytics_custom_dimension[indexes][2][value]'] = '[current-user:edit-url]';
+ $edit['googleanalytics_custom_dimension[indexes][3][value]'] = '[user:name]';
+ $edit['googleanalytics_custom_dimension[indexes][4][value]'] = '[term:name]';
+ $edit['googleanalytics_custom_dimension[indexes][5][value]'] = '[term:tid]';
+
+ $this->drupalPost('admin/config/system/googleanalytics', $edit, t('Save configuration'));
+
+ $this->assertRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 1)), '@invalid-tokens' => implode(', ', array('[current-user:name]')))));
+ $this->assertRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 2)), '@invalid-tokens' => implode(', ', array('[current-user:edit-url]')))));
+ $this->assertRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 3)), '@invalid-tokens' => implode(', ', array('[user:name]')))));
+ // BUG #2037595
+ //$this->assertNoRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 4)), '@invalid-tokens' => implode(', ', array('[term:name]')))));
+ //$this->assertNoRaw(t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => t('Custom dimension value #@index', array('@index' => 5)), '@invalid-tokens' => implode(', ', array('[term:tid]')))));
+ }
}
class GoogleAnalyticsStatusMessagesTest extends DrupalWebTestCase {
diff --git a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.variable.inc b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.variable.inc
index 6a657350..9d142a27 100644
--- a/sites/all/modules/contrib/admin/google_analytics/googleanalytics.variable.inc
+++ b/sites/all/modules/contrib/admin/google_analytics/googleanalytics.variable.inc
@@ -40,6 +40,10 @@ function googleanalytics_variable_group_info() {
/**
* Validate Web Property ID variable.
+ *
+ * @param array $variable
+ *
+ * @return string
*/
function googleanalytics_validate_googleanalytics_account($variable) {
// Replace all type of dashes (n-dash, m-dash, minus) with the normal dashes.
diff --git a/sites/all/modules/contrib/dev/elysia_cron/API.txt b/sites/all/modules/contrib/dev/elysia_cron/API.txt
index 8eebf380..727b970a 100644
--- a/sites/all/modules/contrib/dev/elysia_cron/API.txt
+++ b/sites/all/modules/contrib/dev/elysia_cron/API.txt
@@ -126,7 +126,7 @@ You can use the "hook_cron_alter" function to edit cronapi data of other
modules.
Example:
-function module_cron_alter($data) {
+function module_cron_alter(&$data) {
$data['key']['rule'] = '0 */6 * * *';
}
@@ -182,6 +182,19 @@ function phptemplate_elysia_cron_description($job) {
Note: module default theme_elysia_cron_description($job) already contains
some common tasks descriptions.
+-----------------------------------------------------------------------------
+DISABLE CRON JOBS VIA settings.php FILE
+-----------------------------------------------------------------------------
+If you have some instances for the project you can want to disable some cron
+jobs on different instances. For example you don't want to execute PROD cron
+jobs on DEV instance. There is no need to make it via interface or via SQL
+query. You can define variable for each cron job to manage it state. For more
+information please look at `_elysia_cron_is_job_disabled` and `_ec_get_name`
+functions.
+
+For example, if you have cron job with name googleanalytics_cron, you can
+add this string to your settings.php file:
+$conf['ec_googleanalytics_cron_d'] = TRUE;
-----------------------------------------------------------------------------
OLD 1.x MODULE API (OBSOLETE)
diff --git a/sites/all/modules/contrib/dev/elysia_cron/INSTALL.txt b/sites/all/modules/contrib/dev/elysia_cron/INSTALL.txt
index dac08617..dd92d9be 100644
--- a/sites/all/modules/contrib/dev/elysia_cron/INSTALL.txt
+++ b/sites/all/modules/contrib/dev/elysia_cron/INSTALL.txt
@@ -16,8 +16,7 @@ up and running.
You can stop here if you don't need a great precision over task execution and
you don't have to execute a task more often than once an hour.
For example, if you need only the "Once a day", "Once a week" or "Once a month"
-schedule rules the basic install is fine. (For D6 users that want to stop here:
-you should have installed Drupal crontab as described in Drupal INSTALL guide).
+schedule rules the basic install is fine.
Instead, if you need:
- to run some tasks more often than once an hour (eg: you have a function that
@@ -41,8 +40,8 @@ The only difference is that you should use the "* * * * *" rule part instead of
"0 * * * *" or "45 * * * *" as described in the guide.
While you're editing the system crontab, it's also recommended to replace the
-"/cron.php" part with "/sites/modules/elysia_cron/cron.php" (if you have
-installed elysia_cron in "sites/modules" directory).
+"/cron.php" part with "/sites/all/modules/elysia_cron/cron.php" (if you have
+installed elysia_cron in "sites/all/modules" directory).
This is an optional step (you can leave "/cron.php" if you want), doing it will
result in a better performance in bigger sites (elysia_cron's cron.php handles
cache in a better way).
@@ -78,6 +77,10 @@ red; font-weight: bold; }
PERMISSIONS
------------
-You can also give 'administer elysia_cron' permission to all user roles that
-needs to administer cron jobs. You can do this with standard drupal users
-administration.
+There are three permission provided by module:
+ * Administer elysia cron - Perform changes to cron jobs timings, disable cron
+ or single jobs and access cron execution statistics;
+ * Execute elysia cron jobs - Allow users to view statistics, execution status
+ and do manually execute cron jobs;
+ * View elysia cron stats - Allows users to view statistics and execution status
+ of cron jobs;
diff --git a/sites/all/modules/contrib/dev/elysia_cron/README.txt b/sites/all/modules/contrib/dev/elysia_cron/README.txt
index 30e7878d..e5f5d56c 100644
--- a/sites/all/modules/contrib/dev/elysia_cron/README.txt
+++ b/sites/all/modules/contrib/dev/elysia_cron/README.txt
@@ -9,27 +9,27 @@ For module developers API documetation read API.TXT
FEATURES
-----------------------------------------------------------------------------
-Elysia Cron extends Drupal standard cron, allowing a fine grain control over
+Elysia Cron extends Drupal standard cron, allowing a fine grain control over
each task and several ways to add custom cron jobs to your site.
- Set the timings and frequencies of each cron task (you can run some jobs every
day at a specified hour, other only monthly and so on...).
- For each task you can simply choose between some frequently used options
- ("once a day", "once a month" ...), or use a powerful "linux crontab"-like
- syntax to set the accurate timings. You can even define your frequently used
+ For each task you can simply choose between some frequently used options
+ ("once a day", "once a month" ...), or use a powerful "linux crontab"-like
+ syntax to set the accurate timings. You can even define your frequently used
options to speed up site configuration.
-- Parallel execution of cron task: you can group jobs in channels and execute
+- Parallel execution of cron task: you can group jobs in channels and execute
then simultaneously: so a task that takes a lot of time to execute won't block
other tasks that need to be executed every 5 minutes...
- You can disable all tasks, an entire channel or a single task.
- Change the priority/order of task execution.
- Manual force the execution of a cron tasks.
-- Detailed overview of cron status with time statistics for single tasks and
+- Detailed overview of cron status with time statistics for single tasks and
channels.
-- Powerful API for module developers: you can define extra cron tasks for your
- modules, each one with own default timings (site administrators can override
- them by configuration, other modules via hook_alter). Elysia Cron 2.0 gives a
+- Powerful API for module developers: you can define extra cron tasks for your
+ modules, each one with own default timings (site administrators can override
+ them by configuration, other modules via hook_alter). Elysia Cron 2.0 gives a
brand new API support (compatible with 1.0 version) with a lot of features.
- Administrators can define custom jobs (call to functions with parameters), via
the "script" option.
@@ -43,7 +43,7 @@ It also can be used in a Drupal install profile.
3rd party integration:
- Ping feature, for external tracking services like host-tracker to tell whether
cron is functioning properly on your site.
-- Drush support: you can call "drush elysia-cron" to manually run extended cron.
+- Drush support: you can call "drush elysia-cron run" to manually run extended cron.
- CTools support for exports/backup of task settings.
- Features support.
@@ -53,35 +53,35 @@ USAGE EXAMPLES
Elysia cron is usually used in large sites that needs performance optimization.
-- Avoid drupal peak loads by distributing heavy load tasks during quiet periods
- of the day: for example you may want to rebuild the XML Sitemap of your site
- at 2:00AM in the morning, where usually only a few people are visiting your
- site. You can even move some tasks to be executed only once a month (log
+- Avoid drupal peak loads by distributing heavy load tasks during quiet periods
+ of the day: for example you may want to rebuild the XML Sitemap of your site
+ at 2:00AM in the morning, where usually only a few people are visiting your
+ site. You can even move some tasks to be executed only once a month (log
rotation, old records expiry...).
-- If you have tasks that should be executed very often, but don't want to
- execute ALL drupal cron tasks that often! For example, you may want to check
- for emails that needs to be sent to your users every 2 minutes. Standard cron
- is managed in a "monolithic" way, so even if you find out how to execute it
+- If you have tasks that should be executed very often, but don't want to
+ execute ALL drupal cron tasks that often! For example, you may want to check
+ for emails that needs to be sent to your users every 2 minutes. Standard cron
+ is managed in a "monolithic" way, so even if you find out how to execute it
every 2 minutes, you will end in having all cron tasks executed so often, with
a lot of performance problems.
-- Fine tune cron cache management : drupal cron will invalidate variable cache
- every cron run, and this is a great performance problem if you have a
- frequently called task. Elysia cron optimize cache management, and doesn't
+- Fine tune cron cache management : drupal cron will invalidate variable cache
+ every cron run, and this is a great performance problem if you have a
+ frequently called task. Elysia cron optimize cache management, and doesn't
need to invalidate cache.
-- Setup tasks that should be run at a precise time: for example if you want to
+- Setup tasks that should be run at a precise time: for example if you want to
send a SimpleNews newsletter every monday at 9:00AM, you can do it.
-- Parallel execution: if you have a task that takes a lot of time to execute,
- you can setup a different channel for it so it won't block other tasks that
+- Parallel execution: if you have a task that takes a lot of time to execute,
+ you can setup a different channel for it so it won't block other tasks that
need to be executed every 5 minutes.
- Turn off (disable) a cron task/feature you don't need.
- Debug system cron problems. If your cron does not terminate correctly you can
- use extended logging, see at each cron timings and disable task to track down
+ use extended logging, see at each cron timings and disable task to track down
the problem.
-----------------------------------------------------------------------------
@@ -93,11 +93,11 @@ Channels are groups of tasks. Each channel is a "parallel line" of execution
Tasks inside a channel will be executed sequentially (if they should).
WARNING: It's not recommended to create more than 2 or 3 channels.
-Every channel will increase the delay between each cron check (of the same
+Every channel will increase the delay between each cron check (of the same
channel), because each cron call will cycle between all channels.
So, for example:
If you have 1 channel it will be checked once a minute.
-If you have 2 channel each one will be checked every 2 minutes (almost usually,
+If you have 2 channel each one will be checked every 2 minutes (almost usually,
when the other one is running it will be checked once a minute).
It you have 10 channels there will be a check every 10 minutes... if you have
a job that should be executed every 5 minutes it won't do so!
@@ -106,10 +106,10 @@ a job that should be executed every 5 minutes it won't do so!
EXPORT VIA CTOOLS/FEATURES MODULE
-----------------------------------------------------------------------------
-With 2.0 version of Elysia Cron you can use "Bulk Export" functionality of
+With 2.0 version of Elysia Cron you can use "Bulk Export" functionality of
"Chaos Tools Suite" to export cron settings.
To use it simply enable all modules, go to Structure > Bulk Exporter and
-select the tasks you want to export settings. You can also select all
+select the tasks you want to export settings. You can also select all
"elysia_cron" prefixed variables to export global options.
Than generate the module.
@@ -117,7 +117,7 @@ The generated code will set the new defaults of elysia cron settings. This way
you can simply enable it to use them, but you are free to override them in
the future using the normal settings page.
Note that if you want to delete all overrides, and return to exported settings,
-you should do a "reset to defaults" from elysia cron settings page.
+you should do a "reset to defaults" from elysia cron settings page.
You can also use "Features" module to create a Feature module will the settings
you need.
@@ -133,7 +133,32 @@ DRUSH SUPPORT
Elysia Cron 2.0 adds a simple support for Drush module.
-You can execute the "elysia-cron" command to run cron.
+Run all cron tasks in all active modules for specified site using elysia cron
+system. This replaces the standard "core-cron" drush handler.
+
+Examples:
+ elysia-cron run Run all cron tasks in all active
+ modules (as the standard "core-cron")
+ elysia-cron run --verbose Run all cron tasks in verbose mode
+ elysia-cron run @channel Run all cron tasks in specified
+ channel
+ elysia-cron run search_cron --ignore-time Run only search index
+ build task (force execution)
+ elysia-cron list --elysia-cron-verbose List all channels/tasks
+ in verbose mode
+ elysia-cron disable search_cron Disable search index build task
+
+Options:
+ --elysia-cron-verbose enable extended output (the same as
+ --verbose, but without enabling drush
+ verbose mode)
+ --ignore-disable run channels/tasks even if disabled
+ --ignore-running run channels/tasks even
+ if already running
+ --ignore-time run channels/tasks even if not ready
+ for execution
+ --quiet suppress all output
+ --verbose enable extended output
-----------------------------------------------------------------------------
RULES AND SCRIPT SYNTAX
@@ -150,17 +175,17 @@ RULES AND SCRIPT SYNTAX
| | | | |
* * * * *
-Each of the patterns from the first five fields may be either * (an asterisk),
-which matches all legal values, or a list of elements separated by commas
+Each of the patterns from the first five fields may be either * (an asterisk),
+which matches all legal values, or a list of elements separated by commas
(see below).
-For "day of the week" (field 5), 0 is considered Sunday, 6 is Saturday (7 is
+For "day of the week" (field 5), 0 is considered Sunday, 6 is Saturday (7 is
an illegal value)
-A job is executed when the time/date specification fields all match the current
-time and date. There is one exception: if both "day of month" and "day of week"
-are restricted (not "*"), then either the "day of month" field (3) or the "day
-of week" field (5) must match the current day (even though the other of the two
+A job is executed when the time/date specification fields all match the current
+time and date. There is one exception: if both "day of month" and "day of week"
+are restricted (not "*"), then either the "day of month" field (3) or the "day
+of week" field (5) must match the current day (even though the other of the two
fields need not match the current day).
2. FIELDS OPERATOR
@@ -169,13 +194,13 @@ fields need not match the current day).
There are several ways of specifying multiple date/time values in a field:
* The comma (',') operator specifies a list of values, for example: "1,3,4,7,8"
-* The dash ('-') operator specifies a range of values, for example: "1-6", which
+* The dash ('-') operator specifies a range of values, for example: "1-6", which
is equivalent to "1,2,3,4,5,6"
-* The asterisk ('*') operator specifies all possible values for a field. For
- example, an asterisk in the hour time field would be equivalent to 'every hour'
+* The asterisk ('*') operator specifies all possible values for a field. For
+ example, an asterisk in the hour time field would be equivalent to 'every hour'
(subject to matching other specified fields).
-* The slash ('/') operator (called "step") can be used to skip a given number of
- values. For example, "*/3" in the hour time field is equivalent to
+* The slash ('/') operator (called "step") can be used to skip a given number of
+ values. For example, "*/3" in the hour time field is equivalent to
"0,3,6,9,12,15,18,21".
3. EXAMPLES
@@ -190,10 +215,10 @@ There are several ways of specifying multiple date/time values in a field:
4. SCRIPTS
---------------------------------
-You can use the script section to easily create new jobs (by calling a php
+You can use the script section to easily create new jobs (by calling a php
function) or to change the scheduling of an existing job.
-Every line of the script can be a comment (if it starts with #) or a job
+Every line of the script can be a comment (if it starts with #) or a job
definition.
The syntax of a job definition is:
@@ -207,10 +232,10 @@ The syntax of a job definition is:
* [job]: could be the name of a supported job (for example: 'search_cron') or a
function call, ending with ; (for example: 'process_queue();').
-A comment on the line just preceding a job definition is considered the job
+A comment on the line just preceding a job definition is considered the job
description.
-Remember that script OVERRIDES all settings on single jobs sections or channel
+Remember that script OVERRIDES all settings on single jobs sections or channel
sections of the configuration
5. EXAMPLE OF SCRIPT
@@ -219,7 +244,7 @@ sections of the configuration
# Search indexing every 2 hours (i'm setting this as the job description)
0 */2 * * * search_cron
-# I'll check for module status only on sunday nights
+# I'll check for module status only on sunday nights
# (and this is will not be the job description, see the empty line below)
0 2 * * 0 update_status_cron
diff --git a/sites/all/modules/contrib/dev/elysia_cron/cron.php b/sites/all/modules/contrib/dev/elysia_cron/cron.php
index 3ba20503..294a1c4d 100644
--- a/sites/all/modules/contrib/dev/elysia_cron/cron.php
+++ b/sites/all/modules/contrib/dev/elysia_cron/cron.php
@@ -8,9 +8,11 @@
if (!file_exists('includes/bootstrap.inc')) {
if (!empty($_SERVER['DOCUMENT_ROOT']) && file_exists($_SERVER['DOCUMENT_ROOT'] . '/includes/bootstrap.inc')) {
chdir($_SERVER['DOCUMENT_ROOT']);
- } elseif (preg_match('@^(.*)[\\\\/]sites[\\\\/][^\\\\/]+[\\\\/]modules[\\\\/]([^\\\\/]+[\\\\/])?elysia(_cron)?$@', getcwd(), $r) && file_exists($r[1] . '/includes/bootstrap.inc')) {
+ }
+ elseif (preg_match('@^(.*)[\\\\/]sites[\\\\/][^\\\\/]+[\\\\/]modules[\\\\/]([^\\\\/]+[\\\\/])?elysia(_cron)?$@', getcwd(), $r) && file_exists($r[1] . '/includes/bootstrap.inc')) {
chdir($r[1]);
- } else {
+ }
+ else {
die("Cron Fatal Error: Can't locate bootstrap.inc. Check cron.php position.");
}
}
@@ -21,16 +23,14 @@ if (!file_exists('includes/bootstrap.inc')) {
define('DRUPAL_ROOT', getcwd());
include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
-drupal_override_server_variables(array(
- 'SCRIPT_NAME' => '/cron.php',
-));
+drupal_override_server_variables(array('SCRIPT_NAME' => '/cron.php'));
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-if (!isset($_GET['cron_key']) || variable_get('cron_key', 'drupal') != $_GET['cron_key']) {
+if ((variable_get('cron_key') && empty($_GET['cron_key'])) || !empty($_GET['cron_key']) && variable_get('cron_key') != $_GET['cron_key']) {
watchdog('cron', 'Cron could not run because an invalid key was used.', array(), WATCHDOG_NOTICE);
drupal_access_denied();
}
-elseif (variable_get('maintenance_mode', 0)) {
+elseif (variable_get('maintenance_mode', 0) && !variable_get('elysia_cron_run_maintenance', FALSE)) {
watchdog('cron', 'Cron could not run because the site is in maintenance mode.', array(), WATCHDOG_NOTICE);
drupal_access_denied();
}
diff --git a/sites/all/modules/contrib/dev/elysia_cron/elysia_cron-multilingual-image-path-2096571-1.patch b/sites/all/modules/contrib/dev/elysia_cron/elysia_cron-multilingual-image-path-2096571-1.patch
deleted file mode 100644
index ddd57ea1..00000000
--- a/sites/all/modules/contrib/dev/elysia_cron/elysia_cron-multilingual-image-path-2096571-1.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/elysia_cron.admin.inc b/elysia_cron.admin.inc
-index fa5c6de..4011d91 100644
---- a/elysia_cron.admin.inc
-+++ b/elysia_cron.admin.inc
-@@ -42,7 +42,7 @@ function elysia_cron_admin_page() {
-
- $rows = array();
-
-- $ipath = url(drupal_get_path('module', 'elysia_cron') . '/images/icon_');
-+ $ipath = file_create_url(drupal_get_path('module', 'elysia_cron') . '/images/icon_');
-
- foreach ($elysia_cron_settings_by_channel as $channel => $data) {
- $running = elysia_cron_is_channel_running($channel);
diff --git a/sites/all/modules/contrib/dev/elysia_cron/elysia_cron.admin.inc b/sites/all/modules/contrib/dev/elysia_cron/elysia_cron.admin.inc
index 4011d913..ba6251d8 100644
--- a/sites/all/modules/contrib/dev/elysia_cron/elysia_cron.admin.inc
+++ b/sites/all/modules/contrib/dev/elysia_cron/elysia_cron.admin.inc
@@ -1,35 +1,34 @@
' . t('Global disable') . ': ' . ($v ? '' . t('YES') . '' : 'no') . '';
- $output .= '' . t('Last channel executed') . ': ' . (($c = elysia_cron_last_channel()) ? $c : t('n/a')) . '
'; - - if (EC_DRUPAL_VERSION < 7) { - if (_ec_variable_get('elysia_cron_semaphore', 0)) { - $output .= '' . t('Global semaphore active since !date', array('!date' => elysia_cron_date(_ec_variable_get('elysia_cron_semaphore', 0)))) . '
'; - } + if (elysia_cron_access('execute elysia_cron')) { + $aoutput[] = drupal_get_form('elysia_cron_run_form'); } + $output = ''; + elysia_cron_initialize(); + global $_elysia_cron_settings_by_channel; + + $global_disabled = variable_get('elysia_cron_disabled', FALSE); + $last_channel = elysia_cron_last_channel(); + $output .= '' . t('Global disable') . ': ' . ($global_disabled ? '' . t('YES') . '' : t('no')) . '
'; + $output .= '' . t('Last channel executed') . ': ' . ($last_channel ? $last_channel : t('n/a')) . '
'; + $running = ''; - foreach ($elysia_cron_settings_by_channel as $channel => $data) { + foreach ($_elysia_cron_settings_by_channel as $channel => $data) { if (elysia_cron_is_channel_running($channel)) { $running .= $channel . ' '; } @@ -39,19 +38,33 @@ function elysia_cron_admin_page() { } $output .= '' . t('Last run') . ': ' . elysia_cron_date(_ec_variable_get('elysia_cron_last_run', 0)) . '
'; - $rows = array(); - - $ipath = file_create_url(drupal_get_path('module', 'elysia_cron') . '/images/icon_'); - - foreach ($elysia_cron_settings_by_channel as $channel => $data) { + $ipath = drupal_get_path('module', 'elysia_cron') . '/images/icon_'; + + foreach ($_elysia_cron_settings_by_channel as $channel => $data) { $running = elysia_cron_is_channel_running($channel); $rows[] = array( - array('data' => '@@ -190,7 +239,7 @@ or to change the scheduling of an existing job.<-> [rule] <ch:CHANNEL> [job]
-(Tokens betweens [] are mandatory)
+(Tokens between [] are mandatory)