diff --git a/composer.json b/composer.json
index 6396785c31d90cf24ca741130bb86a0607687c3b..378475bbedc24917eec462618e568fa9e563bf9b 100644
--- a/composer.json
+++ b/composer.json
@@ -128,7 +128,7 @@
         "drupal/file_browser": "1.1",
         "drupal/focal_point": "1.0-beta6",
         "drupal/geolocation": "1.10",
-        "drupal/google_analytics": "2.2",
+        "drupal/google_analytics": "2.4",
         "drupal/google_tag": "^1.3",
         "drupal/honeypot": "^1.28",
         "drupal/image_popup": "1.1",
diff --git a/composer.lock b/composer.lock
index 72bf4e97232a361d93cb1e95771d100b2a6e6c60..56f349310f58599b23c3a66dc7167cbb4e3f7018 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "b6620065182be6bb85da3f6c9b1102e7",
+    "content-hash": "5d437286ae2e43f67225efd0efc295c9",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -5056,20 +5056,20 @@
         },
         {
             "name": "drupal/google_analytics",
-            "version": "2.2.0",
+            "version": "2.4.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/google_analytics.git",
-                "reference": "8.x-2.2"
+                "reference": "8.x-2.4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/google_analytics-8.x-2.2.zip",
-                "reference": "8.x-2.2",
-                "shasum": "15cd0642ad99f3776a46b702e5012713405a0733"
+                "url": "https://ftp.drupal.org/files/projects/google_analytics-8.x-2.4.zip",
+                "reference": "8.x-2.4",
+                "shasum": "f2e78ec140024ddcd19e027704ba73c33731f656"
             },
             "require": {
-                "drupal/core": "~8.0"
+                "drupal/core": "~8.5"
             },
             "require-dev": {
                 "drupal/php": "*",
@@ -5081,8 +5081,8 @@
                     "dev-2.x": "2.x-dev"
                 },
                 "drupal": {
-                    "version": "8.x-2.2",
-                    "datestamp": "1506372845",
+                    "version": "8.x-2.4",
+                    "datestamp": "1548968580",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
@@ -5106,7 +5106,7 @@
             "description": "Allows your site to be tracked by Google Analytics by adding a Javascript tracking code to every page.",
             "homepage": "https://www.drupal.org/project/google_analytics",
             "support": {
-                "source": "http://git.drupal.org/project/google_analytics.git",
+                "source": "https://git.drupal.org/project/google_analytics.git",
                 "issues": "https://www.drupal.org/project/issues/google_analytics"
             }
         },
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index ba8d07220989551d75ea6a7ebc4cede0e6748691..6d90aa965d82613bac25451e5065af616f2ce679 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -5209,21 +5209,21 @@
     },
     {
         "name": "drupal/google_analytics",
-        "version": "2.2.0",
-        "version_normalized": "2.2.0.0",
+        "version": "2.4.0",
+        "version_normalized": "2.4.0.0",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/google_analytics.git",
-            "reference": "8.x-2.2"
+            "reference": "8.x-2.4"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/google_analytics-8.x-2.2.zip",
-            "reference": "8.x-2.2",
-            "shasum": "15cd0642ad99f3776a46b702e5012713405a0733"
+            "url": "https://ftp.drupal.org/files/projects/google_analytics-8.x-2.4.zip",
+            "reference": "8.x-2.4",
+            "shasum": "f2e78ec140024ddcd19e027704ba73c33731f656"
         },
         "require": {
-            "drupal/core": "~8.0"
+            "drupal/core": "~8.5"
         },
         "require-dev": {
             "drupal/php": "*",
@@ -5235,8 +5235,8 @@
                 "dev-2.x": "2.x-dev"
             },
             "drupal": {
-                "version": "8.x-2.2",
-                "datestamp": "1506372845",
+                "version": "8.x-2.4",
+                "datestamp": "1548968580",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
@@ -5261,7 +5261,7 @@
         "description": "Allows your site to be tracked by Google Analytics by adding a Javascript tracking code to every page.",
         "homepage": "https://www.drupal.org/project/google_analytics",
         "support": {
-            "source": "http://git.drupal.org/project/google_analytics.git",
+            "source": "https://git.drupal.org/project/google_analytics.git",
             "issues": "https://www.drupal.org/project/issues/google_analytics"
         }
     },
diff --git a/web/modules/google_analytics/README.txt b/web/modules/google_analytics/README.txt
index d424de51cb3b45a2aa878403ef2de80f6bfafc94..4d8765ef67da5688b7337735dfc458cbcbfc23fb 100644
--- a/web/modules/google_analytics/README.txt
+++ b/web/modules/google_analytics/README.txt
@@ -1,6 +1,6 @@
 
 Module: Google Analytics
-Author: Alexander Hass <http://drupal.org/user/85918>
+Author: Alexander Hass <https://drupal.org/user/85918>
 
 
 Description
@@ -45,15 +45,15 @@ user with 'Administer Google Analytics' permission.
 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.
+block visibility" at https://drupal.org/node/64135.
 
 Custom dimensions and metrics
 =============================
 One example for custom dimensions tracking is the "User roles" tracking.
 
-1. In the Google Analytics (http://www.google.com/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 (https://marketingplatform.google.com/about/analytics/)
+   Management Interface 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 Drupal custom dimensions settings
    form under admin/config/system/googleanalytics. You can also choose another
@@ -69,7 +69,7 @@ Advanced Settings
 =================
 You can include additional JavaScript snippets in the custom javascript
 code textarea. These can be found on the official Google Analytics pages
-and a few examples at http://drupal.org/node/248699. Support is not
+and a few examples at https://drupal.org/node/248699. Support is not
 provided for any customisations you include.
 
 To speed up page loading you may also cache the Google Analytics "analytics.js"
@@ -89,7 +89,7 @@ Body:
   <li><a href="mailto:foo@example.com">Mailto</a></li>
   <li><a href="/files/test.txt">Download file</a></li>
   <li><a class="colorbox" href="#">Open colorbox</a></li>
-  <li><a href="http://example.com/">External link</a></li>
+  <li><a href="https://example.com/">External link</a></li>
   <li><a href="/go/test">Go link</a></li>
 </ul>
 
diff --git a/web/modules/google_analytics/composer.json b/web/modules/google_analytics/composer.json
index fcb5776898883dd79b7cebe9dcc88e8ebd412b1d..2204e9a4be230582c970d6b3dc4f81fc8e55cee1 100644
--- a/web/modules/google_analytics/composer.json
+++ b/web/modules/google_analytics/composer.json
@@ -15,8 +15,10 @@
   ],
   "support": {
     "issues": "https://www.drupal.org/project/issues/google_analytics",
-    "source": "http://git.drupal.org/project/google_analytics.git"
+    "source": "https://git.drupal.org/project/google_analytics.git"
   },
   "license": "GPL-2.0+",
-  "require": {}
+  "require": {
+    "drupal/core": "~8.5"  
+  }
 }
diff --git a/web/modules/google_analytics/google_analytics.info.yml b/web/modules/google_analytics/google_analytics.info.yml
index a1d32b10572399d423f2418a806eda3ca15305f0..cd1d387ef175c91534c328268a357306ba784c16 100644
--- a/web/modules/google_analytics/google_analytics.info.yml
+++ b/web/modules/google_analytics/google_analytics.info.yml
@@ -4,12 +4,14 @@ description: 'Allows your site to be tracked by Google Analytics by adding a Jav
 package: Statistics
 # core: 8.x
 configure: google_analytics.admin_settings_form
+dependencies:
+  - drupal:system (>= 8.5)
 test_dependencies:
   - php:php
   - token:token
 
-# Information added by Drupal.org packaging script on 2017-09-25
-version: '8.x-2.2'
+# Information added by Drupal.org packaging script on 2019-01-31
+version: '8.x-2.4'
 core: '8.x'
 project: 'google_analytics'
-datestamp: 1506372866
+datestamp: 1548968592
diff --git a/web/modules/google_analytics/google_analytics.install b/web/modules/google_analytics/google_analytics.install
index 259bf2c19692612ff03fda3c8893a74422fc7eb6..f616f8f9ee23017ded30cfc6930b55b1db5dc0a3 100644
--- a/web/modules/google_analytics/google_analytics.install
+++ b/web/modules/google_analytics/google_analytics.install
@@ -6,6 +6,21 @@
  */
 
 use Drupal\Core\Url;
+use Drupal\user\Entity\Role;
+
+/**
+ * Implements hook_install().
+ */
+function google_analytics_install() {
+  // Make the default install more user and GDPR friendly.
+  $role = Role::load('authenticated');
+  $role->grantPermission('opt-in or out of google analytics tracking');
+  $success = $role->save();
+  if ($success) {
+    $messenger = \Drupal::messenger();
+    $messenger->addMessage(t('Module %module granted %permission permission to authenticated users.', ['%module' => 'Google Analytics', '%permission' => t('Opt-in or out of tracking')]), 'status');
+  }
+}
 
 /**
  * Implements hook_uninstall().
diff --git a/web/modules/google_analytics/google_analytics.module b/web/modules/google_analytics/google_analytics.module
index addd4ec27ec7fcb790af003c76f6a82efd88f958..3996b242d81561f0c03c8f6751c40bad848ef2cf 100644
--- a/web/modules/google_analytics/google_analytics.module
+++ b/web/modules/google_analytics/google_analytics.module
@@ -7,7 +7,7 @@
  * Adds the required Javascript to all your Drupal pages to allow tracking by
  * the Google Analytics statistics package.
  *
- * @author: Alexander Hass <http://drupal.org/user/85918>
+ * @author: Alexander Hass <https://drupal.org/user/85918>
  */
 
 use Drupal\Component\Serialization\Json;
@@ -22,11 +22,6 @@
 use GuzzleHttp\Exception\RequestException;
 use Drupal\google_analytics\Component\Render\GoogleAnalyticsJavaScriptSnippet;
 
-/**
- * Define the default file extension list that should be tracked as download.
- */
-define('GOOGLE_ANALYTICS_TRACKFILES_EXTENSIONS', '7z|aac|arc|arj|asf|asx|avi|bin|csv|doc(x|m)?|dot(x|m)?|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|msi|msp|pdf|phps|png|ppt(x|m)?|pot(x|m)?|pps(x|m)?|ppam|sld(x|m)?|thmx|qtm?|ra(m|r)?|sea|sit|tar|tgz|torrent|txt|wav|wma|wmv|wpd|xls(x|m|b)?|xlt(x|m)|xlam|xml|z|zip');
-
 /**
  * Advertise the supported google analytics api details.
  */
@@ -52,7 +47,7 @@ function google_analytics_help($route_name, RouteMatchInterface $route_match) {
       return $output;
 
     case 'google_analytics.admin_settings_form':
-      return t('<a href=":ga_url">Google Analytics</a> is a free (registration required) website traffic and marketing effectiveness service.', [':ga_url' => 'http://www.google.com/analytics/']);
+      return t('<a href=":ga_url">Google Analytics</a> is a free (registration required) website traffic and marketing effectiveness service.', [':ga_url' => 'https://marketingplatform.google.com/about/analytics/']);
   }
 }
 
@@ -142,12 +137,12 @@ function google_analytics_page_attachments(array &$page) {
         'error' => t('Error message'),
       ];
 
-      foreach (drupal_get_messages(NULL, FALSE) as $type => $messages) {
+      foreach (\Drupal::messenger()->all(NULL, FALSE) as $type => $messages) {
         // Track only the selected message types.
         if (in_array($type, $message_types)) {
           foreach ($messages as $message) {
             // @todo: Track as exceptions?
-            $message_events .= 'ga("send", "event", ' . Json::encode(t('Messages')) . ', ' . Json::encode($status_heading[$type]) . ', ' . Json::encode(strip_tags($message)) . ');';
+            $message_events .= 'ga("send", "event", ' . Json::encode(t('Messages')) . ', ' . Json::encode($status_heading[$type]) . ', ' . Json::encode(strip_tags((string) $message)) . ');';
           }
         }
       }
@@ -176,7 +171,7 @@ function google_analytics_page_attachments(array &$page) {
 
     // Track access denied (403) and file not found (404) pages.
     if ($status == '403') {
-      // See http://www.google.com/support/analytics/bin/answer.py?answer=86927
+      // See https://www.google.com/support/analytics/bin/answer.py?answer=86927
       $url_custom = '"' . $base_path . '403.html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer';
     }
     elseif ($status == '404') {
@@ -443,11 +438,12 @@ function google_analytics_user_profile_form_submit($form, FormStateInterface $fo
  */
 function google_analytics_cron() {
   $config = \Drupal::config('google_analytics.settings');
+  $request_time = \Drupal::time()->getRequestTime();
 
   // Regenerate the tracking code file every day.
-  if (REQUEST_TIME - \Drupal::state()->get('google_analytics.last_cache') >= 86400 && $config->get('cache')) {
+  if ($request_time - \Drupal::state()->get('google_analytics.last_cache') >= 86400 && $config->get('cache')) {
     _google_analytics_cache('https://www.google-analytics.com/analytics.js', TRUE);
-    \Drupal::state()->set('google_analytics.last_cache', REQUEST_TIME);
+    \Drupal::state()->set('google_analytics.last_cache', $request_time);
   }
 }
 
@@ -495,9 +491,9 @@ function _google_analytics_cache($location, $synchronize = FALSE) {
   if (!file_exists($file_destination) || $synchronize) {
     // Download the latest tracking code.
     try {
-      $data = \Drupal::httpClient()
+      $data = (string) \Drupal::httpClient()
         ->get($location)
-        ->getBody(TRUE);
+        ->getBody();
 
       if (file_exists($file_destination)) {
         // Synchronize tracking code and and replace local file if outdated.
diff --git a/web/modules/google_analytics/js/google_analytics.admin.js b/web/modules/google_analytics/js/google_analytics.admin.js
index 8ee9b94cf2cf30769e4caeb9df8c341263225485..c989f2d678dc5eb1e5bf16ea11c06f9137a12749 100644
--- a/web/modules/google_analytics/js/google_analytics.admin.js
+++ b/web/modules/google_analytics/js/google_analytics.admin.js
@@ -3,7 +3,7 @@
  * Google Analytics admin behaviors.
  */
 
-(function ($, window) {
+(function ($) {
 
   'use strict';
 
@@ -141,4 +141,4 @@
     }
   };
 
-})(jQuery, window);
+})(jQuery);
diff --git a/web/modules/google_analytics/js/google_analytics.debug.js b/web/modules/google_analytics/js/google_analytics.debug.js
index d60eca3559b3af0acf579615fa5336e6d63578b7..2df140a92b20a386228f3e454f5ef153f0db45a2 100644
--- a/web/modules/google_analytics/js/google_analytics.debug.js
+++ b/web/modules/google_analytics/js/google_analytics.debug.js
@@ -179,8 +179,8 @@
    * Extract the relative internal URL from an absolute internal URL.
    *
    * Examples:
-   * - http://mydomain.com/node/1 -> /node/1
-   * - http://example.com/foo/bar -> http://example.com/foo/bar
+   * - https://mydomain.com/node/1 -> /node/1
+   * - https://example.com/foo/bar -> https://example.com/foo/bar
    *
    * @param {string} url
    *   The web url to check.
diff --git a/web/modules/google_analytics/js/google_analytics.js b/web/modules/google_analytics/js/google_analytics.js
index 0490c2b9440333150731bd751948c86db4c26559..82b46cf612810e6ea082db2a0981bbfde6918989 100644
--- a/web/modules/google_analytics/js/google_analytics.js
+++ b/web/modules/google_analytics/js/google_analytics.js
@@ -161,8 +161,8 @@
    * Extract the relative internal URL from an absolute internal URL.
    *
    * Examples:
-   * - http://mydomain.com/node/1 -> /node/1
-   * - http://example.com/foo/bar -> http://example.com/foo/bar
+   * - https://mydomain.com/node/1 -> /node/1
+   * - https://example.com/foo/bar -> https://example.com/foo/bar
    *
    * @param {string} url
    *   The web url to check.
diff --git a/web/modules/google_analytics/migration_templates/d6_google_analytics_settings.yml b/web/modules/google_analytics/migrations/d6_google_analytics_settings.yml
similarity index 98%
rename from web/modules/google_analytics/migration_templates/d6_google_analytics_settings.yml
rename to web/modules/google_analytics/migrations/d6_google_analytics_settings.yml
index ad2be93ff2856076e4fbdcac4616cb7f961e1e24..70f6762b81375c1d99cfe9181582ad595ae4399c 100644
--- a/web/modules/google_analytics/migration_templates/d6_google_analytics_settings.yml
+++ b/web/modules/google_analytics/migrations/d6_google_analytics_settings.yml
@@ -2,6 +2,7 @@ id: d6_google_analytics_settings
 label: Google Analytics 6 configuration
 migration_tags:
   - Drupal 6
+  - Configuration
 source:
   plugin: variable
   variables:
@@ -32,6 +33,7 @@ source:
     - googleanalytics_translation_set
     - googleanalytics_visibility
     - googleanalytics_visibility_roles
+  source_module: googleanalytics    
 process:
   account: googleanalytics_account
   cache: googleanalytics_cache
diff --git a/web/modules/google_analytics/migration_templates/d6_google_analytics_user_settings.yml b/web/modules/google_analytics/migrations/d6_google_analytics_user_settings.yml
similarity index 71%
rename from web/modules/google_analytics/migration_templates/d6_google_analytics_user_settings.yml
rename to web/modules/google_analytics/migrations/d6_google_analytics_user_settings.yml
index a6dfa7600439a2cddfd567552f11d607e587bf45..98d3c236881b3e3b0bb4078c120a25f7a375e420 100644
--- a/web/modules/google_analytics/migration_templates/d6_google_analytics_user_settings.yml
+++ b/web/modules/google_analytics/migrations/d6_google_analytics_user_settings.yml
@@ -12,11 +12,9 @@ process:
   key: 'constants/key'
   module: 'constants/module'
   settings:
-    # Based on skip_row_if_not_set
-    plugin: google_analytics_skip_row_if_not_set
-    key: custom
-    module: googleanalytics
-    source: data
+    plugin: skip_row_if_not_set
+    index: 'custom'
+    source: data/google_analytics
 destination:
   plugin: user_data
 migration_dependencies:
diff --git a/web/modules/google_analytics/migration_templates/d7_google_analytics_settings.yml b/web/modules/google_analytics/migrations/d7_google_analytics_settings.yml
similarity index 98%
rename from web/modules/google_analytics/migration_templates/d7_google_analytics_settings.yml
rename to web/modules/google_analytics/migrations/d7_google_analytics_settings.yml
index ab3beece9f103d73f3ac57b058297dadcc51db81..30d18f827de155e85f91cbd67a0184b7d433aba2 100644
--- a/web/modules/google_analytics/migration_templates/d7_google_analytics_settings.yml
+++ b/web/modules/google_analytics/migrations/d7_google_analytics_settings.yml
@@ -2,6 +2,7 @@ id: d7_google_analytics_settings
 label: Google Analytics 7 configuration
 migration_tags:
   - Drupal 7
+  - Configuration
 source:
   plugin: variable
   variables:
@@ -34,6 +35,7 @@ source:
     - googleanalytics_translation_set
     - googleanalytics_visibility_pages
     - googleanalytics_visibility_roles
+  source_module: googleanalytics
 process:
   account: googleanalytics_account
   premium: googleanalytics_premium
diff --git a/web/modules/google_analytics/migration_templates/d7_google_analytics_user_settings.yml b/web/modules/google_analytics/migrations/d7_google_analytics_user_settings.yml
similarity index 71%
rename from web/modules/google_analytics/migration_templates/d7_google_analytics_user_settings.yml
rename to web/modules/google_analytics/migrations/d7_google_analytics_user_settings.yml
index 6d4e21719efa4077fbe7f843c4161f5d5f2df6f5..428c0d2725db7059f30f9f2f4ca57649aa7c3324 100644
--- a/web/modules/google_analytics/migration_templates/d7_google_analytics_user_settings.yml
+++ b/web/modules/google_analytics/migrations/d7_google_analytics_user_settings.yml
@@ -12,11 +12,9 @@ process:
   key: 'constants/key'
   module: 'constants/module'
   settings:
-    # Based on skip_row_if_not_set
-    plugin: google_analytics_skip_row_if_not_set
-    key: custom
-    module: googleanalytics
-    source: data
+    plugin: skip_row_if_not_set
+    index: 'custom'
+    source: data/google_analytics
 destination:
   plugin: user_data
 migration_dependencies:
diff --git a/web/modules/google_analytics/src/Form/GoogleAnalyticsAdminSettingsForm.php b/web/modules/google_analytics/src/Form/GoogleAnalyticsAdminSettingsForm.php
index 197f0275c60abdbd281ccc792ee2ecf04a613121..639184b4def8ab591bd692d5a749a4754b702ef8 100644
--- a/web/modules/google_analytics/src/Form/GoogleAnalyticsAdminSettingsForm.php
+++ b/web/modules/google_analytics/src/Form/GoogleAnalyticsAdminSettingsForm.php
@@ -3,15 +3,33 @@
 namespace Drupal\google_analytics\Form;
 
 use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Extension\ModuleHandler;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\google_analytics\GoogleAnalitycsInterface;
 
 /**
  * Configure Google_Analytics settings for this site.
  */
 class GoogleAnalyticsAdminSettingsForm extends ConfigFormBase {
 
+  protected $moduleHandler;
+
+  protected $currentUser;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(ConfigFactoryInterface $config_factory, AccountInterface $currentUser, ModuleHandler $moduleHandler) {
+    parent::__construct($config_factory);
+    $this->currentUser = $currentUser;
+    $this->moduleHandler = $moduleHandler;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -40,7 +58,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     $form['general']['google_analytics_account'] = [
       '#default_value' => $config->get('account'),
-      '#description' => $this->t('This ID is unique to each site you want to track separately, and is in the form of UA-xxxxxxx-yy. To get a Web Property ID, <a href=":analytics">register your site with Google Analytics</a>, or if you already have registered your site, go to your Google Analytics Settings page to see the ID next to every site profile. <a href=":webpropertyid">Find more information in the documentation</a>.', [':analytics' => 'http://www.google.com/analytics/', ':webpropertyid' => Url::fromUri('https://developers.google.com/analytics/resources/concepts/gaConceptsAccounts', ['fragment' => 'webProperty'])->toString()]),
+      '#description' => $this->t('This ID is unique to each site you want to track separately, and is in the form of UA-xxxxxxx-yy. To get a Web Property ID, <a href=":analytics">register your site with Google Analytics</a>, or if you already have registered your site, go to your Google Analytics Settings page to see the ID next to every site profile. <a href=":webpropertyid">Find more information in the documentation</a>.', [':analytics' => 'https://marketingplatform.google.com/about/analytics/', ':webpropertyid' => Url::fromUri('https://developers.google.com/analytics/resources/concepts/gaConceptsAccounts', ['fragment' => 'webProperty'])->toString()]),
       '#maxlength' => 20,
       '#placeholder' => 'UA-',
       '#required' => TRUE,
@@ -133,7 +151,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     ];
 
     // Page specific visibility configurations.
-    $account = \Drupal::currentUser();
+    $account = $this->currentUser;
     $php_access = $account->hasPermission('use PHP for google analytics tracking visibility');
     $visibility_request_path_pages = $config->get('visibility.request_path_pages');
 
@@ -150,18 +168,18 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     }
     else {
       $options = [
-        t('Every page except the listed pages'),
-        t('The listed pages only'),
+        $this->t('Every page except the listed pages'),
+        $this->t('The listed pages only'),
       ];
-      $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", ['%blog' => '/blog', '%blog-wildcard' => '/blog/*', '%front' => '<front>']);
+      $description = $this->t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", ['%blog' => '/blog', '%blog-wildcard' => '/blog/*', '%front' => '<front>']);
 
-      if (\Drupal::moduleHandler()->moduleExists('php') && $php_access) {
-        $options[] = t('Pages on which this PHP code returns <code>TRUE</code> (experts only)');
-        $title = t('Pages or PHP code');
-        $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', ['%php' => '<?php ?>']);
+      if ($this->moduleHandler->moduleExists('php') && $php_access) {
+        $options[] = $this->t('Pages on which this PHP code returns <code>TRUE</code> (experts only)');
+        $title = $this->t('Pages or PHP code');
+        $description .= ' ' . $this->t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', ['%php' => '<?php ?>']);
       }
       else {
-        $title = t('Pages');
+        $title = $this->t('Pages');
       }
       $form['tracking']['page_visibility_settings']['google_analytics_visibility_request_path_mode'] = [
         '#type' => 'radios',
@@ -192,8 +210,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'radios',
       '#title' => $this->t('Add tracking for specific roles'),
       '#options' => [
-        t('Add to the selected roles only'),
-        t('Add to every role except the selected ones'),
+        $this->t('Add to the selected roles only'),
+        $this->t('Add to every role except the selected ones'),
       ],
       '#default_value' => $config->get('visibility.user_role_mode'),
     ];
@@ -213,14 +231,14 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Users'),
       '#group' => 'tracking_scope',
     ];
-    $t_permission = ['%permission' => $this->t('opt-in or out of tracking')];
+    $t_permission = ['%permission' => $this->t('Opt-in or out of tracking')];
     $form['tracking']['user_visibility_settings']['google_analytics_visibility_user_account_mode'] = [
       '#type' => 'radios',
       '#title' => $this->t('Allow users to customize tracking on their account page'),
       '#options' => [
-        t('No customization allowed'),
-        t('Tracking on by default, users with %permission permission can opt out', $t_permission),
-        t('Tracking off by default, users with %permission permission can opt in', $t_permission),
+        $this->t('No customization allowed'),
+        $this->t('Tracking on by default, users with %permission permission can opt out', $t_permission),
+        $this->t('Tracking off by default, users with %permission permission can opt in', $t_permission),
       ],
       '#default_value' => !empty($visibility_user_account_mode) ? $visibility_user_account_mode : 0,
     ];
@@ -257,7 +275,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title_display' => 'invisible',
       '#type' => 'textfield',
       '#default_value' => $config->get('track.files_extensions'),
-      '#description' => $this->t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: @extensions', ['@extensions' => GOOGLE_ANALYTICS_TRACKFILES_EXTENSIONS]),
+      '#description' => $this->t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: @extensions', ['@extensions' => GoogleAnalitycsInterface::GOOGLE_ANALYTICS_TRACKFILES_EXTENSIONS]),
       '#maxlength' => 500,
       '#states' => [
         'enabled' => [
@@ -271,7 +289,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     ];
 
     $colorbox_dependencies = '<div class="admin-requirements">';
-    $colorbox_dependencies .= t('Requires: @module-list', ['@module-list' => (\Drupal::moduleHandler()->moduleExists('colorbox') ? t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Colorbox']) : t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Colorbox']))]);
+    $colorbox_dependencies .= $this->t('Requires: @module-list', ['@module-list' => ($this->moduleHandler->moduleExists('colorbox') ? $this->t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Colorbox']) : $this->t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Colorbox']))]);
     $colorbox_dependencies .= '</div>';
 
     $form['tracking']['linktracking']['google_analytics_trackcolorbox'] = [
@@ -279,7 +297,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Track content in colorbox modal dialogs'),
       '#description' => $this->t('Enable to track the content shown in colorbox modal windows.') . $colorbox_dependencies,
       '#default_value' => $config->get('track.colorbox'),
-      '#disabled' => (\Drupal::moduleHandler()->moduleExists('colorbox') ? FALSE : TRUE),
+      '#disabled' => ($this->moduleHandler->moduleExists('colorbox') ? FALSE : TRUE),
     ];
 
     $form['tracking']['linktracking']['google_analytics_tracklinkid'] = [
@@ -321,7 +339,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     ];
 
     $site_search_dependencies = '<div class="admin-requirements">';
-    $site_search_dependencies .= t('Requires: @module-list', ['@module-list' => (\Drupal::moduleHandler()->moduleExists('search') ? t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Search']) : t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Search']))]);
+    $site_search_dependencies .= $this->t('Requires: @module-list', ['@module-list' => ($this->moduleHandler->moduleExists('search') ? $this->t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Search']) : $this->t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Search']))]);
     $site_search_dependencies .= '</div>';
 
     $form['tracking']['search_and_advertising']['google_analytics_site_search'] = [
@@ -329,7 +347,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Track internal search'),
       '#description' => $this->t('If checked, internal search keywords are tracked. You must configure your Google account to use the internal query parameter <strong>search</strong>. For more information see <a href=":url">Setting Up Site Search for a Profile</a>.', [':url' => 'https://support.google.com/analytics/answer/1012264']) . $site_search_dependencies,
       '#default_value' => $config->get('track.site_search'),
-      '#disabled' => (\Drupal::moduleHandler()->moduleExists('search') ? FALSE : TRUE),
+      '#disabled' => ($this->moduleHandler->moduleExists('search') ? FALSE : TRUE),
     ];
     $form['tracking']['search_and_advertising']['google_analytics_trackadsense'] = [
       '#type' => 'checkbox',
@@ -398,16 +416,16 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         '#element_validate' => [[get_class($this), 'tokenElementValidate']],
         '#token_types' => ['node'],
       ];
-      if (\Drupal::moduleHandler()->moduleExists('token')) {
+      if ($this->moduleHandler->moduleExists('token')) {
         $form['google_analytics_custom_dimension']['indexes'][$i]['value']['#element_validate'][] = 'token_element_validate';
       }
     }
 
     $form['google_analytics_custom_dimension']['google_analytics_description'] = [
       '#type' => 'item',
-      '#description' => $this->t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom dimensions. Section 7 of the <a href=":ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', [':ga_tos' => 'http://www.google.com/analytics/terms/gb.html']),
+      '#description' => $this->t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom dimensions. Section 7 of the <a href=":ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', [':ga_tos' => 'https://www.google.com/analytics/terms/gb.html']),
     ];
-    if (\Drupal::moduleHandler()->moduleExists('token')) {
+    if ($this->moduleHandler->moduleExists('token')) {
       $form['google_analytics_custom_dimension']['google_analytics_token_tree'] = [
         '#theme' => 'token_tree_link',
         '#token_types' => ['node'],
@@ -454,16 +472,16 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         '#element_validate' => [[get_class($this), 'tokenElementValidate']],
         '#token_types' => ['node'],
       ];
-      if (\Drupal::moduleHandler()->moduleExists('token')) {
+      if ($this->moduleHandler->moduleExists('token')) {
         $form['google_analytics_custom_metric']['indexes'][$i]['value']['#element_validate'][] = 'token_element_validate';
       }
     }
 
     $form['google_analytics_custom_metric']['google_analytics_description'] = [
       '#type' => 'item',
-      '#description' => $this->t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom metrics. Section 7 of the <a href=":ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', [':ga_tos' => 'http://www.google.com/analytics/terms/gb.html']),
+      '#description' => $this->t('You can supplement Google Analytics\' basic IP address tracking of visitors by segmenting users based on custom metrics. Section 7 of the <a href=":ga_tos">Google Analytics terms of service</a> requires that You will not (and will not allow any third party to) use the Service to track, collect or upload any data that personally identifies an individual (such as a name, userid, email address or billing information), or other data which can be reasonably linked to such information by Google. You will have and abide by an appropriate Privacy Policy and will comply with all applicable laws and regulations relating to the collection of information from Visitors. You must post a Privacy Policy and that Privacy Policy must provide notice of Your use of cookies that are used to collect traffic data, and You must not circumvent any privacy features (e.g., an opt-out) that are part of the Service.', [':ga_tos' => 'https://www.google.com/analytics/terms/gb.html']),
     ];
-    if (\Drupal::moduleHandler()->moduleExists('token')) {
+    if ($this->moduleHandler->moduleExists('token')) {
       $form['google_analytics_custom_metric']['google_analytics_token_tree'] = [
         '#theme' => 'token_tree_link',
         '#token_types' => ['node'],
@@ -485,7 +503,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     ];
 
     // Allow for tracking of the originating node when viewing translation sets.
-    if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
+    if ($this->moduleHandler->moduleExists('content_translation')) {
       $form['advanced']['google_analytics_translation_set'] = [
         '#type' => 'checkbox',
         '#title' => $this->t('Track translation sets as one unit'),
@@ -500,7 +518,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'details',
       '#title' => $this->t('Custom JavaScript code'),
       '#open' => TRUE,
-      '#description' => $this->t('You can add custom Google Analytics <a href=":snippets">code snippets</a> here. These will be added every time tracking is in effect. Before you add your custom code, you should read the <a href=":ga_concepts_overview">Google Analytics Tracking Code - Functional Overview</a> and the <a href=":ga_js_api">Google Analytics Tracking API</a> documentation. <strong>Do not include the &lt;script&gt; tags</strong>, and always end your code with a semicolon (;).', [':snippets' => 'http://drupal.org/node/248699', ':ga_concepts_overview' => 'https://developers.google.com/analytics/resources/concepts/gaConceptsTrackingOverview', ':ga_js_api' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference']),
+      '#description' => $this->t('You can add custom Google Analytics <a href=":snippets">code snippets</a> here. These will be added every time tracking is in effect. Before you add your custom code, you should read the <a href=":ga_concepts_overview">Google Analytics Tracking Code - Functional Overview</a> and the <a href=":ga_js_api">Google Analytics Tracking API</a> documentation. <strong>Do not include the &lt;script&gt; tags</strong>, and always end your code with a semicolon (;).', [':snippets' => 'https://drupal.org/node/248699', ':ga_concepts_overview' => 'https://developers.google.com/analytics/resources/concepts/gaConceptsTrackingOverview', ':ga_js_api' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference']),
     ];
     $form['advanced']['codesnippet']['google_analytics_codesnippet_create'] = [
       '#type' => 'textarea',
@@ -575,13 +593,13 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $form_state->setValue('google_analytics_account', str_replace(['–', '—', '−'], '-', $form_state->getValue('google_analytics_account')));
 
     if (!preg_match('/^UA-\d+-\d+$/', $form_state->getValue('google_analytics_account'))) {
-      $form_state->setErrorByName('google_analytics_account', t('A valid Google Analytics Web Property ID is case sensitive and formatted like UA-xxxxxxx-yy.'));
+      $form_state->setErrorByName('google_analytics_account', $this->t('A valid Google Analytics Web Property ID is case sensitive and formatted like UA-xxxxxxx-yy.'));
     }
 
     // If multiple top-level domains has been selected, a domain names list is
     // required.
     if ($form_state->getValue('google_analytics_domain_mode') == 2 && $form_state->isValueEmpty('google_analytics_cross_domains')) {
-      $form_state->setErrorByName('google_analytics_cross_domains', t('A list of top-level domains is required if <em>Multiple top-level domains</em> has been selected.'));
+      $form_state->setErrorByName('google_analytics_cross_domains', $this->t('A list of top-level domains is required if <em>Multiple top-level domains</em> has been selected.'));
     }
     // Clear the domain list if cross domains are disabled.
     if ($form_state->getValue('google_analytics_domain_mode') != 2) {
@@ -589,12 +607,12 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     }
 
     // Verify that every path is prefixed with a slash, but don't check PHP
-    // code snippets.
-    if ($form_state->getValue('google_analytics_visibility_request_path_mode') != 2) {
+    // code snippets and do not check for slashes if no paths configured.
+    if ($form_state->getValue('google_analytics_visibility_request_path_mode') != 2 && !empty($form_state->getValue('google_analytics_visibility_request_path_pages'))) {
       $pages = preg_split('/(\r\n?|\n)/', $form_state->getValue('google_analytics_visibility_request_path_pages'));
       foreach ($pages as $page) {
         if (strpos($page, '/') !== 0 && $page !== '<front>') {
-          $form_state->setErrorByName('google_analytics_visibility_request_path_pages', t('Path "@page" not prefixed with slash.', ['@page' => $page]));
+          $form_state->setErrorByName('google_analytics_visibility_request_path_pages', $this->t('Path "@page" not prefixed with slash.', ['@page' => $page]));
           // Drupal forms show one error only.
           break;
         }
@@ -603,7 +621,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
 
     // Disallow empty list of download file extensions.
     if ($form_state->getValue('google_analytics_trackfiles') && $form_state->isValueEmpty('google_analytics_trackfiles_extensions')) {
-      $form_state->setErrorByName('google_analytics_trackfiles_extensions', t('List of download file extensions cannot empty.'));
+      $form_state->setErrorByName('google_analytics_trackfiles_extensions', $this->t('List of download file extensions cannot empty.'));
     }
     // Clear obsolete local cache if cache has been disabled.
     if ($form_state->isValueEmpty('google_analytics_cache') && $form['advanced']['google_analytics_cache']['#default_value']) {
@@ -612,16 +630,16 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
 
     // This is for the Newbie's who cannot read a text area description.
     if (stristr($form_state->getValue('google_analytics_codesnippet_before'), 'google-analytics.com/analytics.js')) {
-      $form_state->setErrorByName('google_analytics_codesnippet_before', t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
+      $form_state->setErrorByName('google_analytics_codesnippet_before', $this->t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
     }
     if (stristr($form_state->getValue('google_analytics_codesnippet_after'), 'google-analytics.com/analytics.js')) {
-      $form_state->setErrorByName('google_analytics_codesnippet_after', t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
+      $form_state->setErrorByName('google_analytics_codesnippet_after', $this->t('Do not add the tracker code provided by Google into the javascript code snippets! This module already builds the tracker code based on your Google Analytics account number and settings.'));
     }
     if (preg_match('/(.*)<\/?script(.*)>(.*)/i', $form_state->getValue('google_analytics_codesnippet_before'))) {
-      $form_state->setErrorByName('google_analytics_codesnippet_before', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
+      $form_state->setErrorByName('google_analytics_codesnippet_before', $this->t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
     }
     if (preg_match('/(.*)<\/?script(.*)>(.*)/i', $form_state->getValue('google_analytics_codesnippet_after'))) {
-      $form_state->setErrorByName('google_analytics_codesnippet_after', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
+      $form_state->setErrorByName('google_analytics_codesnippet_after', $this->t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
     }
   }
 
@@ -879,14 +897,17 @@ protected static function validateCreateFieldName($name) {
       'sampleRate',
       'siteSpeedSampleRate',
       'storage',
-      'userId',
+      'useAmpClientId',
     ];
 
     if ($name == 'name') {
       return t('Create only field name %name is a disallowed field name. Changing the <em>Tracker Name</em> is currently not supported.', ['%name' => $name]);
     }
     if ($name == 'allowLinker') {
-      return t('Create only field name %name is a disallowed field name. Please select <em>Multiple top-level domains</em> under <em>What are you tracking</em> to enable cross domain tracking.', ['%name' => $name]);
+      return t('Create only field name %name is a disallowed field name. Please select <em>Multiple top-level domains</em> under <em>Tracking scope > Domains</em> to enable cross domain tracking.', ['%name' => $name]);
+    }
+    if ($name == 'userId') {
+      return t('Create only field name %name is a disallowed field name. Please enable <em>Track User ID</em> under <em>Tracking scope > Users</em>.', ['%name' => $name]);
     }
     if (!in_array($name, $create_only_fields)) {
       return t('Create only field name %name is an unknown field name. Field names are case sensitive. Please see <a href=":url">create only fields</a> documentation for supported field names.', ['%name' => $name, ':url' => 'https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create']);
@@ -979,4 +1000,16 @@ protected static function convertFormValueDataTypes(array $values) {
     return $values;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      // Load the service required to construct this class.
+      $container->get('config.factory'),
+      $container->get('current_user'),
+      $container->get('module_handler')
+    );
+  }
+
 }
diff --git a/web/modules/google_analytics/src/GoogleAnalitycsInterface.php b/web/modules/google_analytics/src/GoogleAnalitycsInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c982903286afc6e99b1569ae1d5d8bace10d67c
--- /dev/null
+++ b/web/modules/google_analytics/src/GoogleAnalitycsInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\google_analytics;
+
+/**
+ * Provides an interface.
+ */
+interface GoogleAnalitycsInterface {
+
+  /**
+   * Define the default file extension list that should be tracked as download.
+   */
+  const GOOGLE_ANALYTICS_TRACKFILES_EXTENSIONS = '7z|aac|arc|arj|asf|asx|avi|bin|csv|doc(x|m)?|dot(x|m)?|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|msi|msp|pdf|phps|png|ppt(x|m)?|pot(x|m)?|pps(x|m)?|ppam|sld(x|m)?|thmx|qtm?|ra(m|r)?|sea|sit|tar|tgz|torrent|txt|wav|wma|wmv|wpd|xls(x|m|b)?|xlt(x|m)|xlam|xml|z|zip';
+
+}
diff --git a/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsSkipRowIfNotSet.php b/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsSkipRowIfNotSet.php
deleted file mode 100644
index 089d68519e20ca6aede4933e4ab0c03c3a43c833..0000000000000000000000000000000000000000
--- a/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsSkipRowIfNotSet.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace Drupal\google_analytics\Plugin\migrate\process;
-
-use Drupal\migrate\ProcessPluginBase;
-use Drupal\migrate\MigrateExecutableInterface;
-use Drupal\migrate\Row;
-use Drupal\migrate\MigrateSkipRowException;
-
-/**
- * If the source evaluates to empty, we skip the current row.
- *
- * @MigrateProcessPlugin(
- *   id = "google_analytics_skip_row_if_not_set",
- *   handle_multiples = TRUE
- * )
- */
-class GoogleAnalyticsSkipRowIfNotSet extends ProcessPluginBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
-    if (!isset($value[$this->configuration['module']][$this->configuration['key']])) {
-      throw new MigrateSkipRowException();
-    }
-    return $value[$this->configuration['module']][$this->configuration['key']];
-  }
-
-}
diff --git a/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityPages.php b/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityPages.php
index f7986db9cec5384ea403670b0b4b82435c66e1b4..8374c5520de9b148d398823236e0537578fa92c7 100644
--- a/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityPages.php
+++ b/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityPages.php
@@ -29,6 +29,8 @@ class GoogleAnalyticsVisibilityPages extends ProcessPluginBase implements Contai
   protected $moduleHandler;
 
   /**
+   * The migration process plugin.
+   *
    * The migration process plugin, configured for lookups in the d6_user_role
    * and d7_user_role migrations.
    *
diff --git a/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityRoles.php b/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityRoles.php
index 6d6dab7f4f59a8ee3e0d700dfc66287d55c4c9c7..2fe62b405c0d010808d543113e7285fabeb725f7 100644
--- a/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityRoles.php
+++ b/web/modules/google_analytics/src/Plugin/migrate/process/GoogleAnalyticsVisibilityRoles.php
@@ -28,6 +28,8 @@ class GoogleAnalyticsVisibilityRoles extends ProcessPluginBase implements Contai
   protected $moduleHandler;
 
   /**
+   * The migration process plugin.
+   *
    * The migration process plugin, configured for lookups in the d6_user_role
    * and d7_user_role migrations.
    *
diff --git a/web/modules/google_analytics/src/Tests/GoogleAnalyticsCustomUrls.php b/web/modules/google_analytics/src/Tests/GoogleAnalyticsCustomUrls.php
index cbf14a7841b5d715f1c1ba81e5a303b34bca80fc..da9c6558b94a4cd4b9c46bdbeded3ac4f38e35e3 100644
--- a/web/modules/google_analytics/src/Tests/GoogleAnalyticsCustomUrls.php
+++ b/web/modules/google_analytics/src/Tests/GoogleAnalyticsCustomUrls.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\google_analytics\Tests;
 
-use Drupal\Core\Session\AccountInterface;
 use Drupal\simpletest\WebTestBase;
 
 /**
diff --git a/web/modules/google_analytics/src/Tests/GoogleAnalyticsJavaScriptTest.js b/web/modules/google_analytics/src/Tests/GoogleAnalyticsJavaScriptTest.js
index ded59bf5c9d9a434eb1e90bca418b97c68b1e6d5..45f8d52a4761161af5c57ea8f66e1dedfd7581ad 100644
--- a/web/modules/google_analytics/src/Tests/GoogleAnalyticsJavaScriptTest.js
+++ b/web/modules/google_analytics/src/Tests/GoogleAnalyticsJavaScriptTest.js
@@ -81,7 +81,7 @@
   Drupal.google_analytics.test.assertTrue(Drupal.google_analytics.isInternal(base_url + drupalSettings.path.baseUrl + 'node/1?foo=bar'), "Link '" + base_url + drupalSettings.path.baseUrl + "node/1?foo=bar' has been detected as internal link.");
   Drupal.google_analytics.test.assertTrue(Drupal.google_analytics.isInternal(base_url + drupalSettings.path.baseUrl + 'node/1?foo=bar#foo'), "Link '" + base_url + drupalSettings.path.baseUrl + "node/1?foo=bar#foo' has been detected as internal link.");
   Drupal.google_analytics.test.assertTrue(Drupal.google_analytics.isInternal(base_url + drupalSettings.path.baseUrl + 'go/foo'), "Link '" + base_url + drupalSettings.path.baseUrl + "go/foo' has been detected as internal link.");
-  Drupal.google_analytics.test.assertFalse(Drupal.google_analytics.isInternal('http://example.com/node/3'), "Link 'http://example.com/node/3' has been detected as external link.");
+  Drupal.google_analytics.test.assertFalse(Drupal.google_analytics.isInternal('https://example.com/node/3'), "Link 'https://example.com/node/3' has been detected as external link.");
   console.groupEnd();
 
   console.group("Test 'isInternalSpecial':");
@@ -90,9 +90,11 @@
   console.groupEnd();
 
   console.group("Test 'getPageUrl':");
-  Drupal.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(base_url + drupalSettings.path.baseUrl + 'node/1'), "Absolute internal URL '" + drupalSettings.path.baseUrl + "node/1' has been extracted from full qualified url '" + base_url + base_path + "'.");
-  Drupal.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(drupalSettings.path.baseUrl + 'node/1'), "Absolute internal URL '" + drupalSettings.path.baseUrl + "node/1' has been extracted from absolute url '" + base_path + "'.");
-  Drupal.google_analytics.test.assertSame('http://example.com/node/2', Drupal.google_analytics.getPageUrl('http://example.com/node/2'), "Full qualified external url 'http://example.com/node/2' has been extracted.");
+  Drupal.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(window.location.href), "Absolute internal URL '" + base_path + "' has been extracted from full qualified url '" + window.location.href + "'.");
+  Drupal.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(base_path), "Absolute internal URL '" + base_path + "' has been extracted from absolute url '" + base_path + "'.");
+  //Drupal.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(base_url + drupalSettings.path.baseUrl + 'node/1'), "Absolute internal URL '" + drupalSettings.path.baseUrl + "node/1' has been extracted from full qualified url '" + base_url + base_path + "'.");
+  //Drupal.google_analytics.test.assertSame(base_path, Drupal.google_analytics.getPageUrl(drupalSettings.path.baseUrl + 'node/1'), "Absolute internal URL '" + drupalSettings.path.baseUrl + "node/1' has been extracted from absolute url '" + base_path + "'.");
+  Drupal.google_analytics.test.assertSame('https://example.com/node/2', Drupal.google_analytics.getPageUrl('https://example.com/node/2'), "Full qualified external url 'https://example.com/node/2' has been extracted.");
   Drupal.google_analytics.test.assertSame('//example.com/node/2', Drupal.google_analytics.getPageUrl('//example.com/node/2'), "Full qualified external url '//example.com/node/2' has been extracted.");
   console.groupEnd();
 
@@ -109,9 +111,9 @@
   if (drupalSettings.google_analytics.trackCrossDomains) {
     console.dir(drupalSettings.google_analytics.trackCrossDomains);
     Drupal.google_analytics.test.assertTrue(Drupal.google_analytics.isCrossDomain('example.com', drupalSettings.google_analytics.trackCrossDomains), "URL 'example.com' has been found in cross domain list.");
-    Drupal.google_analytics.test.assertTrue(Drupal.google_analytics.isCrossDomain('example.net', drupalSettings.google_analytics.trackCrossDomains), "URL 'example.com' has been found in cross domain list.");
+    Drupal.google_analytics.test.assertTrue(Drupal.google_analytics.isCrossDomain('example.net', drupalSettings.google_analytics.trackCrossDomains), "URL 'example.net' has been found in cross domain list.");
     Drupal.google_analytics.test.assertFalse(Drupal.google_analytics.isCrossDomain('www.example.com', drupalSettings.google_analytics.trackCrossDomains), "URL 'www.example.com' not found in cross domain list.");
-    Drupal.google_analytics.test.assertFalse(Drupal.google_analytics.isCrossDomain('www.example.net', drupalSettings.google_analytics.trackCrossDomains), "URL 'www.example.com' not found in cross domain list.");
+    Drupal.google_analytics.test.assertFalse(Drupal.google_analytics.isCrossDomain('www.example.net', drupalSettings.google_analytics.trackCrossDomains), "URL 'www.example.net' not found in cross domain list.");
   }
   else {
     console.warn('Cross domain tracking is not enabled. Tests skipped.');
diff --git a/web/modules/google_analytics/src/Tests/GoogleAnalyticsSearchTest.php b/web/modules/google_analytics/src/Tests/GoogleAnalyticsSearchTest.php
index ec6af115b426bdd46d1373eee519db13e056ec1a..898ecd0e3bcd44523bdaf7847dc0265e07fcbe36 100644
--- a/web/modules/google_analytics/src/Tests/GoogleAnalyticsSearchTest.php
+++ b/web/modules/google_analytics/src/Tests/GoogleAnalyticsSearchTest.php
@@ -61,7 +61,6 @@ public function testGoogleAnalyticsSearchTracking() {
     $search['keys'] = $this->randomMachineName(8);
 
     // Create a node to search for.
-    // Create a node.
     $edit = [];
     $edit['title[0][value]'] = 'This is a test title';
     $edit['body[0][value]'] = 'This test content contains ' . $search['keys'] . ' string.';
diff --git a/web/modules/google_analytics/src/Tests/GoogleAnalyticsStatusMessagesTest.php b/web/modules/google_analytics/src/Tests/GoogleAnalyticsStatusMessagesTest.php
index 2082fccc326bf752fd4938bc415839a0e34c73cb..2e0488a4c57814535ccb7d2340f415853f2f68b6 100644
--- a/web/modules/google_analytics/src/Tests/GoogleAnalyticsStatusMessagesTest.php
+++ b/web/modules/google_analytics/src/Tests/GoogleAnalyticsStatusMessagesTest.php
@@ -48,16 +48,20 @@ public function testGoogleAnalyticsStatusMessages() {
     $this->assertRaw('ga("send", "event", "Messages", "Error message", "Password field is required.");', '[testGoogleAnalyticsStatusMessages]: Event message "Password field is required." is shown.');
 
     // Testing this drupal_set_message() requires an extra test module.
-    $this->drupalGet('google-analytics-test/drupal-set-message');
+    $this->drupalGet('google-analytics-test/drupal-messenger-add-message');
     $this->assertNoRaw('ga("send", "event", "Messages", "Status message", "Example status message.");', '[testGoogleAnalyticsStatusMessages]: Example status message is not enabled for tracking.');
     $this->assertNoRaw('ga("send", "event", "Messages", "Warning message", "Example warning message.");', '[testGoogleAnalyticsStatusMessages]: Example warning message is not enabled for tracking.');
     $this->assertRaw('ga("send", "event", "Messages", "Error message", "Example error message.");', '[testGoogleAnalyticsStatusMessages]: Example error message is shown.');
     $this->assertRaw('ga("send", "event", "Messages", "Error message", "Example error message with html tags and link.");', '[testGoogleAnalyticsStatusMessages]: HTML has been stripped successful from Example error message with html tags and link.');
 
     // Enable logging of status, warnings and errors.
-    $this->config('google_analytics.settings')->set('track.messages', ['status' => 'status', 'warning' => 'warning', 'error' => 'error'])->save();
+    $this->config('google_analytics.settings')->set('track.messages', [
+      'status' => 'status',
+      'warning' => 'warning',
+      'error' => 'error',
+    ])->save();
 
-    $this->drupalGet('google-analytics-test/drupal-set-message');
+    $this->drupalGet('google-analytics-test/drupal-messenger-add-message');
     $this->assertRaw('ga("send", "event", "Messages", "Status message", "Example status message.");', '[testGoogleAnalyticsStatusMessages]: Example status message is enabled for tracking.');
     $this->assertRaw('ga("send", "event", "Messages", "Warning message", "Example warning message.");', '[testGoogleAnalyticsStatusMessages]: Example warning message is enabled for tracking.');
     $this->assertRaw('ga("send", "event", "Messages", "Error message", "Example error message.");', '[testGoogleAnalyticsStatusMessages]: Example error message is shown.');
diff --git a/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.info.yml b/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.info.yml
index 7399b11b6ae6f5e5729e4daee393c9d438edf774..533669e45bb91ed68415173d288e738fb6967f46 100644
--- a/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.info.yml
+++ b/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.info.yml
@@ -4,8 +4,8 @@ description: 'Support module for Google Analytics testing.'
 package: Testing
 # core: 8.x
 
-# Information added by Drupal.org packaging script on 2017-09-25
-version: '8.x-2.2'
+# Information added by Drupal.org packaging script on 2019-01-31
+version: '8.x-2.4'
 core: '8.x'
 project: 'google_analytics'
-datestamp: 1506372866
+datestamp: 1548968592
diff --git a/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.routing.yml b/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.routing.yml
index 8b7b092da3945b6fa45df31a37a972b7c662df74..dd12ce3fd65be2de4c526dc60a662ad89e658f15 100644
--- a/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.routing.yml
+++ b/web/modules/google_analytics/tests/modules/google_analytics_test/google_analytics_test.routing.yml
@@ -1,7 +1,7 @@
-google_analytics_test.drupal_set_message:
-  path: '/google-analytics-test/drupal-set-message'
+google_analytics_test.drupal_messenger_add_message:
+  path: '/google-analytics-test/drupal-messenger-add-message'
   defaults:
-    _title: 'Set messages with drupal_set_message()'
-    _controller: '\Drupal\google_analytics_test\Controller\GoogleAnalyticsTestController::drupalSetMessageTest'
+    _title: 'Set messages with Drupal::messenger()'
+    _controller: '\Drupal\google_analytics_test\Controller\GoogleAnalyticsTestController::drupalAddMessageTest'
   requirements:
     _access: 'TRUE'
diff --git a/web/modules/google_analytics/tests/modules/google_analytics_test/src/Controller/GoogleAnalyticsTestController.php b/web/modules/google_analytics/tests/modules/google_analytics_test/src/Controller/GoogleAnalyticsTestController.php
index 074049cb97a0139cdfdf86e2a152fdabad5aaa5b..7a260d6bd69ebbfb371734bdf548c84d4d00e8ce 100644
--- a/web/modules/google_analytics/tests/modules/google_analytics_test/src/Controller/GoogleAnalyticsTestController.php
+++ b/web/modules/google_analytics/tests/modules/google_analytics_test/src/Controller/GoogleAnalyticsTestController.php
@@ -12,15 +12,15 @@ class GoogleAnalyticsTestController extends ControllerBase {
   /**
    * Tests setting messages and removing one before it is displayed.
    *
-   * @return string
-   *   Empty string, we just test the setting of messages.
+   * @return array
+   *   Empty array, we just test the setting of messages.
    */
-  public function drupalSetMessageTest() {
+  public function drupalAddMessageTest() {
     // Set some messages.
-    drupal_set_message('Example status message.', 'status');
-    drupal_set_message('Example warning message.', 'warning');
-    drupal_set_message('Example error message.', 'error');
-    drupal_set_message('Example error <em>message</em> with html tags and <a href="http://example.com/">link</a>.', 'error');
+    $this->messenger()->addMessage($this->t('Example status message.'), 'status');
+    $this->messenger()->addMessage($this->t('Example warning message.'), 'warning');
+    $this->messenger()->addMessage($this->t('Example error message.'), 'error');
+    $this->messenger()->addMessage($this->t('Example error <em>message</em> with html tags and <a href="http://example.com/">link</a>.'), 'error');
 
     return [];
   }