From 789895fdbed72990f3b5b8be46d8df195106d325 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Fri, 8 Oct 2021 13:38:41 +0100
Subject: [PATCH] Issue #3241280 by alexpott, Lendude: Fix PHP 8.1 deprecations
 caused by views code

---
 .../views/src/Plugin/views/HandlerBase.php    |  3 ++
 .../Plugin/views/display/PathPluginBase.php   | 41 +++++++++++--------
 .../src/Plugin/views/field/NumericField.php   |  2 +
 .../tests/src/Kernel/QueryGroupByTest.php     |  4 +-
 4 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/core/modules/views/src/Plugin/views/HandlerBase.php b/core/modules/views/src/Plugin/views/HandlerBase.php
index ef76b5736995..311c98550fca 100644
--- a/core/modules/views/src/Plugin/views/HandlerBase.php
+++ b/core/modules/views/src/Plugin/views/HandlerBase.php
@@ -193,6 +193,9 @@ public function getField($field = NULL) {
    * {@inheritdoc}
    */
   public function sanitizeValue($value, $type = NULL) {
+    if ($value === NULL) {
+      return '';
+    }
     switch ($type) {
       case 'xss':
         $value = Xss::filter($value);
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index 646ddcd549e0..a6d6b81a933d 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -133,7 +133,8 @@ protected function getRoute($view_id, $display_id) {
     ];
 
     // @todo How do we apply argument validation?
-    $bits = explode('/', $this->getOption('path'));
+    $path = $this->getOption('path');
+
     // @todo Figure out validation/argument loading.
     // Replace % with %views_arg for menu autoloading and add to the
     // page arguments so the argument actually comes through.
@@ -144,23 +145,27 @@ protected function getRoute($view_id, $display_id) {
 
     $argument_map = [];
 
-    // Replace arguments in the views UI (defined via %) with parameters in
-    // routes (defined via {}). As a name for the parameter use arg_$key, so
-    // it can be pulled in the views controller from the request.
-    foreach ($bits as $pos => $bit) {
-      if ($bit == '%') {
-        // Generate the name of the parameter using the key of the argument
-        // handler.
-        $arg_id = 'arg_' . $arg_counter++;
-        $bits[$pos] = '{' . $arg_id . '}';
-        $argument_map[$arg_id] = $arg_id;
-      }
-      elseif (strpos($bit, '%') === 0) {
-        // Use the name defined in the path.
-        $parameter_name = substr($bit, 1);
-        $arg_id = 'arg_' . $arg_counter++;
-        $argument_map[$arg_id] = $parameter_name;
-        $bits[$pos] = '{' . $parameter_name . '}';
+    $bits = [];
+    if (is_string($path)) {
+      $bits = explode('/', $path);
+      // Replace arguments in the views UI (defined via %) with parameters in
+      // routes (defined via {}). As a name for the parameter use arg_$key, so
+      // it can be pulled in the views controller from the request.
+      foreach ($bits as $pos => $bit) {
+        if ($bit == '%') {
+          // Generate the name of the parameter using the key of the argument
+          // handler.
+          $arg_id = 'arg_' . $arg_counter++;
+          $bits[$pos] = '{' . $arg_id . '}';
+          $argument_map[$arg_id] = $arg_id;
+        }
+        elseif (strpos($bit, '%') === 0) {
+          // Use the name defined in the path.
+          $parameter_name = substr($bit, 1);
+          $arg_id = 'arg_' . $arg_counter++;
+          $argument_map[$arg_id] = $parameter_name;
+          $bits[$pos] = '{' . $parameter_name . '}';
+        }
       }
     }
 
diff --git a/core/modules/views/src/Plugin/views/field/NumericField.php b/core/modules/views/src/Plugin/views/field/NumericField.php
index 19bd477b9b6c..83d6dee7f653 100644
--- a/core/modules/views/src/Plugin/views/field/NumericField.php
+++ b/core/modules/views/src/Plugin/views/field/NumericField.php
@@ -157,6 +157,8 @@ public function render(ResultRow $values) {
       return '';
     }
 
+    // After the hide_empty check NULL values should be treated as a 0 value.
+    $value = $value ?? 0;
     if (!empty($this->options['set_precision'])) {
       $precision = $this->options['precision'];
     }
diff --git a/core/modules/views/tests/src/Kernel/QueryGroupByTest.php b/core/modules/views/tests/src/Kernel/QueryGroupByTest.php
index abedcf916bac..62be526db265 100644
--- a/core/modules/views/tests/src/Kernel/QueryGroupByTest.php
+++ b/core/modules/views/tests/src/Kernel/QueryGroupByTest.php
@@ -111,8 +111,8 @@ public function groupByTestHelper($aggregation_function, $values) {
     foreach ($view->result as $item) {
       $results[$item->entity_test_name] = $item->id;
     }
-    $this->assertEquals($values[0], $results['name1'], new FormattableMarkup('Aggregation with @aggregation_function and groupby name: name1 returned the expected amount of results', ['@aggregation_function' => $aggregation_function]));
-    $this->assertEquals($values[1], $results['name2'], new FormattableMarkup('Aggregation with @aggregation_function and groupby name: name2 returned the expected amount of results', ['@aggregation_function' => $aggregation_function]));
+    $this->assertEquals($values[0], $results['name1'], new FormattableMarkup('Aggregation with @aggregation_function and groupby name: name1 returned the expected amount of results', ['@aggregation_function' => $aggregation_function ?? 'NULL']));
+    $this->assertEquals($values[1], $results['name2'], new FormattableMarkup('Aggregation with @aggregation_function and groupby name: name2 returned the expected amount of results', ['@aggregation_function' => $aggregation_function ?? 'NULL']));
   }
 
   /**
-- 
GitLab