     1:  2:  3:  4:  5:  6:  7:  8:  9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83:

    <?php

    /*
     * This file is part of the affilinet Product Data PHP SDK.
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */

    namespace Affilinet\ProductData\Requests\Helper;

    /**
     * Class QueryBuilderTrait
     *
     * The keyword(s) you want the products to match. Can be any
     * length. The following search operators are supported:
     *      - AND (both query tokens must be contained in the product, but not necessarily next to one another)
     *      - OR (any of the query tokens must be contained in the product)
     *      - NOT (e.g. with “ipod AND NOT nano”, you will get products, which match the query “ipod”, but at the same time don’t match “nano”)
     *      - "(phrase match: all query tokens inclosed with double quotes must be contained in the found products in that order)
     *      - () Parentheses, to group expressions So you can formulate a query like this: "apple ipod" ((touch OR classic) NOT nano) AND "32  GB"
     *
     * SearchProducts supports the wildcard ‘*’ for suffix matching, that
     * is: a query ‘bott*’ will match for products, which contain the word
     * “bottle” or the word “bottom”.
     * Search operators “AND”, “OR” and “NOT” must be in capital
     * letters.
     *
     *  */
    class Query implements QueryInterface
    {

        private $query = '';

        /**
         * @return string
         */
        public function getQuery()
        {
           return $this->query;
        }

        /**
         * @param  Expression     $expression
         * @return QueryInterface
         */
        public function where(Expression $expression, $operator = 'AND')
        {
            if ($this->query != '') {
                $this->query .= ' '. $operator . ' ';
            }
            $this->query .=  ' (' . $expression->getExpression() . ' ) ';

            return $this;
        }

        /**
         * @param  Expression     $expression
         * @return QueryInterface
         */
        public function andWhere(Expression $expression)
        {
            return $this->where($expression, 'AND');

        }

        /**
         * @param  Expression     $expression
         * @return QueryInterface
         */
        public function orWhere(Expression $expression)
        {
            return $this->where($expression, 'OR');

        }

        public function expr()
        {
            return new Expression();
        }

    }