From 7572b41d35636b6d1fc583c3f4b5b3b04aa148ef Mon Sep 17 00:00:00 2001
From: Sergei Shilko <contact@sshilko.com>
Date: Wed, 16 Jan 2019 11:46:18 +0100
Subject: [PATCH] Helper functions for match

Prevent boilerplace code for constructing comples (A AND (B OR C)) queries and enforce parenthesis by

- wrapping multiple matches into another match (enforces "( many matches )") via matchAndMatch()
- helper for field IN selector to build match code for "@field A | B | C", to get rid of boilerplace everytime (cant do orMatch, must first ->match)

Feel free to rename the functions, i find them usefull in my project to prevent boilerplace

```
 $matches = [];
 $matches[] = $sphql->matchFieldIN('field_a', [1,2,3]);
 $matches[] = $sphql->matchFieldIN('field_b', [4,5,6]);
 $sphql->resetMatch()->match($sphql->matchAndMatch($matches));
//generates ("(@field_a 1 | 2 | 3) (@field_b 4 | 5 | 6)") without boilerplate

// (A1 AND (B2 OR C3)) still needs boilerplace like this
                    $mymatch  = (new Match($sphql))->match($mymatch1)
                                                   ->orMatch()
                                                   ->match((new Match($sphql))->match($mymatch2)->orMatch($mymatch3));

```
---
 src/SphinxQL.php | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/src/SphinxQL.php b/src/SphinxQL.php
index 2b11bb80..018dd203 100644
--- a/src/SphinxQL.php
+++ b/src/SphinxQL.php
@@ -964,6 +964,48 @@ public function from($array = null)
 
         return $this;
     }
+    
+    /**
+     * MATCH field IN (values)
+     *
+     * @param string $field  The field
+     * @param array  $values Values for IN clause
+     *
+     * @return Match
+     */
+    public function matchFieldIN(string $field, array $values) : Match {
+        $match = (new Match($this))->field($field);
+
+        /**
+         * Reindex array
+         */
+        $values = array_values(array_unique($values));
+
+        $count  = count($values);
+        for ($n = 0; $n < $count; $n++) {
+            if (!$n) {
+                $match->match($values[$n]);
+            } else {
+                $match->orMatch($values[$n]);
+            }
+        }
+        return $match;
+    }
+
+    /**
+     * Wrap match into another match helper to build complex (A OR (B AND C)) matches
+     *
+     * @param Match[] $matches Matches to group up with AND
+     *
+     * @return Match
+     */    
+    public function matchAndMatch(array $matches) {
+        $match = new Match($this);
+        foreach ($matches as $m) {
+            $match->match($m);
+        }
+        return $match;
+    }
 
     /**
      * MATCH clause (Sphinx-specific)