From 58f04cd0e205f1ffa55816029ee6c9c34f46dbcd Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Fri, 11 Oct 2013 08:34:11 -0400
Subject: [PATCH] Added "selective capitalization" feature. - Progress on
 VUFIND-915.

---
 .../Backend/Solr/QueryBuilder.php             | 20 +++++++++---
 .../Backend/Solr/QueryBuilderTest.php         | 31 +++++++++++++++++++
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php
index 77f8ef8b291..292ca290d34 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/QueryBuilder.php
@@ -607,19 +607,31 @@ class QueryBuilder implements QueryBuilderInterface
      * Capitalize boolean operators.
      *
      * @param string $string Search string
+     * @param array  $bools  Which booleans to capitalize (default = all)
      *
      * @return string
      */
-    public function capitalizeBooleans($string)
+    public function capitalizeBooleans($string, $bools = array('AND', 'OR', 'NOT'))
     {
         // Load the "inside quotes" lookahead so we can use it to prevent
         // switching case of Boolean reserved words inside quotes, since
         // that can cause problems in case-sensitive fields when the reserved
         // words are actually used as search terms.
         $lookahead = self::$insideQuotes;
-        $regs = array("/\s+AND\s+{$lookahead}/i", "/\s+OR\s+{$lookahead}/i",
-                "/(\s+NOT\s+|^NOT\s+){$lookahead}/i", "/\(NOT\s+{$lookahead}/i");
-        $replace = array(' AND ', ' OR ', ' NOT ', '(NOT ');
+
+        // Create standard conversions:
+        $regs = $replace = array();
+        foreach ($bools as $bool) {
+            $regs[] = "/\s+{$bool}\s+{$lookahead}/i";
+            $replace[] = ' ' . $bool . ' ';
+        }
+
+        // Special extra case for NOT:
+        if (in_array('NOT', $bools)) {
+            $regs[] = "/\(NOT\s+{$lookahead}/i";
+            $replace[] = '(NOT ';
+        }
+
         return trim(preg_replace($regs, $replace, $string));
     }
 
diff --git a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php
index 22d20f1ebb2..bcc5632fa54 100644
--- a/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php
+++ b/module/VuFindSearch/tests/unit-tests/src/VuFindTest/Backend/Solr/QueryBuilderTest.php
@@ -81,6 +81,37 @@ class QueryBuilderTest extends PHPUnit_Framework_TestCase
         }
     }
 
+    /**
+     * Test the selective capitalization functionality of capitalizeBooleans.
+     *
+     * @return void
+     */
+    public function testSelectiveBooleanCapitalization()
+    {
+        $qb = new QueryBuilder();
+        $in = 'this or that and the other not everything else (not me)';
+        $this->assertEquals(
+            'this OR that AND the other NOT everything else (NOT me)',
+            $qb->capitalizeBooleans($in, array('AND', 'OR', 'NOT'))
+        );
+        $this->assertEquals(
+            'this OR that and the other NOT everything else (NOT me)',
+            $qb->capitalizeBooleans($in, array('OR', 'NOT'))
+        );
+        $this->assertEquals(
+            'this or that and the other NOT everything else (NOT me)',
+            $qb->capitalizeBooleans($in, array('NOT'))
+        );
+        $this->assertEquals(
+            'this or that AND the other not everything else (not me)',
+            $qb->capitalizeBooleans($in, array('AND'))
+        );
+        $this->assertEquals(
+            'this OR that and the other not everything else (not me)',
+            $qb->capitalizeBooleans($in, array('OR'))
+        );
+    }
+
     /**
      * Test capitalizeRanges functionality.
      *
-- 
GitLab