From 7b96e587c22c6990523f3a83141bf65f5dd7307c Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Fri, 1 Dec 2017 12:46:09 -0500
Subject: [PATCH] Workaround for operator minification bug. (#1081)

- Resolves VUFIND-1260.
---
 .../VuFind/src/VuFind/Search/QueryAdapter.php |   7 ++++
 .../VuFind/tests/fixtures/searches/operators  | Bin 0 -> 699 bytes
 .../VuFindTest/Search/QueryAdapterTest.php    |  30 ++++++++++++++++++
 3 files changed, 37 insertions(+)
 create mode 100644 module/VuFind/tests/fixtures/searches/operators

diff --git a/module/VuFind/src/VuFind/Search/QueryAdapter.php b/module/VuFind/src/VuFind/Search/QueryAdapter.php
index 689750136fe..2fb6b089af0 100644
--- a/module/VuFind/src/VuFind/Search/QueryAdapter.php
+++ b/module/VuFind/src/VuFind/Search/QueryAdapter.php
@@ -248,6 +248,13 @@ abstract class QueryAdapter
                     'b' => $operator
                 ];
                 if (null !== ($op = $current->getOperator())) {
+                    // Some search forms omit the operator for the first element;
+                    // if we have an operator in a subsequent element, we should
+                    // backfill a blank here for consistency; otherwise, VuFind
+                    // may not construct correct search URLs.
+                    if (isset($retVal[0]['f']) && !isset($retVal[0]['o'])) {
+                        $retVal[0]['o'] = '';
+                    }
                     $currentArr['o'] = $op;
                 }
                 $retVal[] = $currentArr;
diff --git a/module/VuFind/tests/fixtures/searches/operators b/module/VuFind/tests/fixtures/searches/operators
new file mode 100644
index 0000000000000000000000000000000000000000..f6c06e3ddfa1599112b278bda9d61796d1a49f8f
GIT binary patch
literal 699
zcmd6lF%QBZ5QY6MH#*s>F&>kNQKvRq<K%*JDoF#CwnH`kcaPds2OTvs5W?f&z3+%I
z93yPXnKmjR>Gr4XvLshM=DD+F1~|ZLj=>0_)9pA?<(||+8kLd*5eb%pTCy2ASy<l8
zv5zo`rhe6khK{n()-)Bpy5h`FY05!J4DhP4C*ptc({KF@KJx+2>Cp_^G*t^GM+Q4d
z)0w7JaYR1GH!(pUx=ISC&9NbMu=a)26JsQ98UxSd`yO_(?%SJIh6wQryp`}*RxWRG
M)W0f<*X+fQJD>d4IsgCw

literal 0
HcmV?d00001

diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php
index 9ab9c5e3c92..238a939f349 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Search/QueryAdapterTest.php
@@ -65,6 +65,36 @@ class QueryAdapterTest extends TestCase
         }
     }
 
+    /**
+     * Test that when one part of the query contains an operator, ALL parts of the
+     * query contain an operator. (We want to be sure that in cases where the first
+     * part of the query has no operator associated with it, a blank value is filled
+     * in as a placeholder.
+     *
+     * @return void
+     */
+    public function testOperatorDefinedEverywhere()
+    {
+        $fixturePath = realpath(__DIR__ . '/../../../../fixtures/searches') . '/';
+        $q = unserialize(file_get_contents($fixturePath . '/operators'));
+        $minified = QueryAdapter::minify($q);
+
+        // First, check that count of 'o' values matches count of queries in group:
+        $callback = function ($carry, $item) {
+            return $carry + (isset($item['o']) ? 1 : 0);
+        };
+        $this->assertEquals(
+            count($minified[0]['g']),
+            array_reduce($minified[0]['g'], $callback, 0)
+        );
+
+        // Next, confirm that first operator is set to empty (filler) value:
+        $this->assertEquals('', $minified[0]['g'][0]['o']);
+
+        // Finally, make sure that we can round-trip back to the input.
+        $this->assertEquals($q, QueryAdapter::deminify($minified));
+    }
+
     /**
      * Test building an advanced query from a request.
      *
-- 
GitLab