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: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236:
<?php
namespace Apptus\ESales\Connector;
use Apptus\ESales\Connector\Filters\AndFilter;
use Apptus\ESales\Connector\Filters\AttributeFilter;
use Apptus\ESales\Connector\Filters\EmptyFilter;
use Apptus\ESales\Connector\Filters\IncrementalFilter;
use Apptus\ESales\Connector\Filters\NotFilter;
use Apptus\ESales\Connector\Filters\OrFilter;
use Apptus\ESales\Connector\Filters\RangeFilter;
use Apptus\ESales\Connector\Filters\StringFilter;
use Apptus\ESales\Connector\Filters\UniverseFilter;
/**
* A set of static methods for building a filter.<br/>
*
* The FilterBuilder class is a utility that is intended to be used to create filters for eSales queries.
* The methods in this class are all static and return some kind of {@see Filter} limiting your search.
*
* Example:<br/>
* <code>
* // Create some simple attribute filters
* $a = FilterBuilder::attribute('artist', 'Presley');
* $b = FilterBuilder::attribute('song', 'Jumpin\' Jack Flash');
* $c = FilterBuilder::attribute('description', 'Rock nostalgia');
*
* echo 'Created some attribute filters:' . PHP_EOL;
* echo $a . PHP_EOL;
* echo $b . PHP_EOL;
* echo $c . PHP_EOL;
*
* echo PHP_EOL;
*
* // Let's combine them
* $kingOfRock = FilterBuilder::andFilter($a, $c);
* echo $kingOfRock . PHP_EOL;
* $classic = FilterBuilder::andFilter(b, c);
* echo $classic . PHP_EOL;
* $justCool = FilterBuilder::orFilter(a, b);
* echo $justCool . PHP_EOL;
* $coolOldie = FilterBuilder::andFilter(justCool, c);
* echo $coolOldie . PHP_EOL;
*
* echo PHP_EOL;
*
* // Let's add some more stuff into the mix
* $lamers = FilterBuilder::attributeFilter('artist', 'Sofarock');
* $lamers = FilterBuilder::orFilter($lamers, FilterBuilder::attributeFilter('artist', 'amazonics'));
* $noLamers = FilterBuilder::notFilter($lamers);
* echo $noLamers . PHP_EOL;
*
* // Combine more than 2 filters at once by simply supplying them all
* $theOriginal = FilterBuilder::andFilter($classic, $noLamers, $c);
* echo $theOriginal . PHP_EOL;
* </code>
*/
class FilterBuilder {
/** @internal */
public static $EMPTY = 'EMPTY';
/** @internal */
public static $UNIVERSE = 'UNIVERSE';
// filter constants
private static $UNIVERSE_FILTER = null;
private static $EMPTY_FILTER = null;
private final function __construct() {
// prevent instantiation and sub-classing
}
/**
* Create a new NOT filter matching every result that the given operand doesn't match.
*
* @param Filter
* The operand to negate.
* @return Filter
* A NOT filter
*/
public static function notFilter(Filter $operand) {
return new NotFilter($operand);
}
/**
* Create a new AND filter to match the intersection of the results that all the given filters would return.
*
* @param Filter...
* Operands.
* @return Filter
* An AND filter
*/
public static function andFilter() { // todo (fli) not sure if this will work as in java/c#
$filters = self::removeNullFilters(func_get_args());
if (sizeof($filters) == 0) {
throw new \InvalidArgumentException('Invalid argument to AND filter, and operation requires at least 1 valid filter');
}
if (sizeof($filters) == 1) {
return $filters[0];
}
return new AndFilter($filters);
}
/**
* Create a new OR filter to match the union of the results that all the given filters would return.
*
* @param Filter...
* Operands.
* @return Filter
* An OR filter.
*/
public static function orFilter() { // todo (fli) not sure if this will work as in java/c#
$filters = self::removeNullFilters(func_get_args()); // TODO!
if (sizeof($filters) == 0) {
throw new \InvalidArgumentException('Invalid argument to OR filter, or operation requires at least 1 valid filter');
}
if (sizeof($filters) == 1) {
return $filters[0];
}
return new OrFilter($filters);
}
private static function removeNullFilters() {
$args = func_get_args();
$filters = array();
array_walk_recursive($args, function ($current) use (&$filters) {
if ($current !== null) {
if ($current instanceof Filter) {
$filters[] = $current;
} else {
$type = gettype($current) === 'object' ? get_class($current) : gettype($current);
throw new \InvalidArgumentException('Invalid argument to OR filter, expected Filter, got: ' . $type);
}
}
});
return $filters;
}
/**
* Create a new attribute filter, limiting results to products where all processed parts (after tokenization and
* normalization) of the specified <code>$value</code> are present within any of the given <code>$attributes</code>.
*
* @param string|array
* A single attribute or an array of attributes to search within.
* @param string
* The value to match.
* @return Filter
* An attribute filter.
*/
public static function attributeFilter($attributes, $value) {
return new AttributeFilter($attributes, $value);
}
/**
* Create a new filter from a string representation of a filter.
*
* @param string
* The string representation of the filter to match.
* @param boolean
* True if parentheses is needed when this filter is part of a composite filter.
* @return Filter
* A string filter.
*/
public static function fromString($filter, $needsParentheses = true) {
return new StringFilter($filter, !$needsParentheses);
}
/**
* Create a new INCREMENTAL filter, limiting the result to products where all processed parts (after tokenization and
* normalization) of the specified <code>$value</code> are present within any of the given <code>$attributes</code>. The last
* value token matches if any attribute contains a value to which it is a prefix (after tokenization).
*
* @param string|array
* A single attribute or a list of attributes to search within.
* @param string
* The value to match.
* @return Filter
* An incremental filter.
*/
public static function incrementalFilter($attributes, $value) {
if (is_string($attributes)) {
$attributes = array ($attributes);
}
return new IncrementalFilter($attributes, $value);
}
/**
* Create a new range filter limiting results to values between <code>$from</code> and <code>$to</code>, for any of the
* specified <code>$attributes</code>. Whether or not the bounds should be considered inclusive or exclusive is determined by
* the specified <code>$fromInc</code> and <code>$toInc</code> parameters.
*
* @param string|array
* A single attribute or a list of attributes.
* @param string
* The lower bound.
* @param string
* The upper bound.
* @param boolean
* If the lower bound is to be considered inclusive.
* @param boolean
* If the upper bound is to be considered inclusive.
* @return Filter
* A range filter as described above.
*/
public static function rangeFilter($attributes, $from, $to, $fromInc = true, $toInc = false) {
if (is_string($attributes)) {
$attributes = array ($attributes);
}
return new RangeFilter($attributes, $from, $to, $fromInc, $toInc);
}
/**
* Return a universe filter representing all results.
*
* @return Filter
* The universe filter.
*/
public static function universeFilter() {
if (self::$UNIVERSE_FILTER === null) {
self::$UNIVERSE_FILTER = new UniverseFilter();
}
return self::$UNIVERSE_FILTER;
}
/**
* Return a empty filter representing no results.
*
* @return Filter
* The empty filter.
*/
public static function emptyFilter() {
if (self::$EMPTY_FILTER === null) {
self::$EMPTY_FILTER = new EmptyFilter();
}
return self::$EMPTY_FILTER;
}
}