Turba_Driver::makeSearch PHP Method

makeSearch() public method

Takes a hash of Turba key => search value and return a (possibly nested) array, using backend attribute names, that can be turned into a search by the driver. The translation is based on the contents of $this->map, and includes nested OR searches for composite fields.
public makeSearch ( array $criteria, string $search_type, array $strict, boolean $match_begin = false, array $custom_strict = [] ) : array
$criteria array Hash of criteria using Turba keys.
$search_type string OR search or AND search?
$strict array Fields that must be matched exactly.
$match_begin boolean Whether to match only at beginning of words.
$custom_strict array Custom set of fields that are to matched exactly, but are glued using $search_type and 'AND' together with $strict fields. Allows an 'OR' search pm a custom set of $strict fields.
return array An array of search criteria.
    public function makeSearch($criteria, $search_type, array $strict, $match_begin = false, array $custom_strict = array())
    {
        $search = $search_terms = $subsearch = $strict_search = array();
        $glue = $temp = '';
        $lastChar = '\\"';
        $blobs = $this->getBlobs();
        foreach ($criteria as $key => $val) {
            if (!isset($this->map[$key])) {
                continue;
            }
            if (is_array($this->map[$key])) {
                /* Composite field, break out the search terms. */
                $parts = explode(' ', $val);
                if (count($parts) > 1) {
                    /* Only parse if there was more than 1 search term and
                     * 'AND' the cumulative subsearches. */
                    for ($i = 0; $i < count($parts); ++$i) {
                        $term = $parts[$i];
                        $firstChar = substr($term, 0, 1);
                        if ($firstChar == '"') {
                            $temp = substr($term, 1, strlen($term) - 1);
                            $done = false;
                            while (!$done && $i < count($parts) - 1) {
                                $lastChar = substr($parts[$i + 1], -1);
                                if ($lastChar == '"') {
                                    $temp .= ' ' . substr($parts[$i + 1], 0, -1);
                                    $done = true;
                                } else {
                                    $temp .= ' ' . $parts[$i + 1];
                                }
                                ++$i;
                            }
                            $search_terms[] = $temp;
                        } else {
                            $search_terms[] = $term;
                        }
                    }
                    $glue = 'AND';
                } else {
                    /* If only one search term, use original input and
                       'OR' the searces since we're only looking for 1
                       term in any of the composite fields. */
                    $search_terms[0] = $val;
                    $glue = 'OR';
                }
                foreach ($this->map[$key]['fields'] as $field) {
                    if (!empty($blobs[$field])) {
                        continue;
                    }
                    $field = $this->toDriver($field);
                    if (!empty($strict[$field])) {
                        /* For strict matches, use the original search
                         * vals. */
                        $strict_search[] = array('field' => $field, 'op' => '=', 'test' => $val);
                    } elseif (!empty($custom_strict[$field])) {
                        $search[] = array('field' => $field, 'op' => '=', 'test' => $val);
                    } else {
                        /* Create a subsearch for each individual search
                         * term. */
                        if (count($search_terms) > 1) {
                            /* Build the 'OR' search for each search term
                             * on this field. */
                            $atomsearch = array();
                            for ($i = 0; $i < count($search_terms); ++$i) {
                                $atomsearch[] = array('field' => $field, 'op' => 'LIKE', 'test' => $search_terms[$i], 'begin' => $match_begin, 'approximate' => !empty($this->approximate[$field]));
                            }
                            $atomsearch[] = array('field' => $field, 'op' => '=', 'test' => '', 'begin' => $match_begin, 'approximate' => !empty($this->approximate[$field]));
                            $subsearch[] = array('OR' => $atomsearch);
                            unset($atomsearch);
                            $glue = 'AND';
                        } else {
                            /* $parts may have more than one element, but
                             * if they are all quoted we will only have 1
                             * $subsearch. */
                            $subsearch[] = array('field' => $field, 'op' => 'LIKE', 'test' => $search_terms[0], 'begin' => $match_begin, 'approximate' => !empty($this->approximate[$field]));
                            $glue = 'OR';
                        }
                    }
                }
                if (count($subsearch)) {
                    $search[] = array($glue => $subsearch);
                }
            } else {
                /* Not a composite field. */
                if (!empty($blobs[$key])) {
                    continue;
                }
                if (!empty($strict[$this->map[$key]])) {
                    $strict_search[] = array('field' => $this->map[$key], 'op' => '=', 'test' => $val);
                } elseif (!empty($custom_strict[$this->map[$key]])) {
                    $search[] = array('field' => $this->map[$key], 'op' => '=', 'test' => $val);
                } else {
                    $search[] = array('field' => $this->map[$key], 'op' => 'LIKE', 'test' => $val, 'begin' => $match_begin, 'approximate' => !empty($this->approximate[$this->map[$key]]));
                }
            }
        }
        if (count($strict_search) && count($search)) {
            return array('AND' => array($search_type => $strict_search, array($search_type => $search)));
        } elseif (count($strict_search)) {
            return array($search_type => $strict_search);
        } elseif (count($search)) {
            return array($search_type => $search);
        }
        return array();
    }