<?php
class SortDirection {
const Ascending = 1;
const Descending = -1;
}
interface Filter {
public function filter($item);
}
interface Comparator {
public function compare($a, $b);
}
class MultipleKeyValueFilter implements Filter {
protected $kvPairs;
public function __construct($kvPairs) {
$this->kvPairs = $kvPairs;
}
public function filter($item) {
$result = true;
foreach ($this->kvPairs as $key => $value) {
if ($item[$key] !== $value)
$result &= false;
}
return $result;
}
}
class KeyComparator implements Comparator {
protected $direction;
protected $transform;
protected $key;
public function __construct($key, $direction = SortDirection::Ascending, $transform = null) {
$this->direction = $direction;
$this->transform = $transform;
}
public function compare($a, $b) {
if ($this->transform) {
$a = $this->transform($a);
$b = $this->transform($b);
}
return $a === $b ? 0 : (($a > $b ? 1 : -1) * $this->direction);
}
}
class MultipleKeyComparator implements Comparator {
protected $keys;
public function __construct($keys) {
$this->keys = $keys;
}
public function compare($a, $b) {
$result = 0;
foreach ($this->keys as $comparator) {
if ($comparator instanceof KeyComparator) {
$result = $comparator->compare($a, $b);
if ($result !== 0) return $result;
}
}
return $result;
}
}
'1' => array ('type' => 'blah2', 'category' => 'cat2', 'exp_range' => 'this_week' ), '2' => array ('type' => 'blah1', 'category' => 'cat1', 'exp_range' => 'this_week' ), '3' => array ('type' => 'blah1', 'category' => 'cat2', 'exp_range' => 'next_week' ), '4' => array ('type' => 'blah1', 'category' => 'cat1', 'exp_range' => 'next_week' ) );
$comparator = new MultipleKeyComparator
(array( new KeyComparator('type'),
new KeyComparator('exp_range')
));
echo "Sorted by multiple fields\n";
$filter = new MultipleKeyValueFilter
(array( 'type' => 'blah1'
));
echo "Filtered by multiple fields\n";
PD9waHAKCmNsYXNzIFNvcnREaXJlY3Rpb24gewoJY29uc3QgQXNjZW5kaW5nID0gMTsKCWNvbnN0IERlc2NlbmRpbmcgPSAtMTsKfQoKaW50ZXJmYWNlIEZpbHRlciB7CglwdWJsaWMgZnVuY3Rpb24gZmlsdGVyKCRpdGVtKTsKfQoKaW50ZXJmYWNlIENvbXBhcmF0b3IgewoJcHVibGljIGZ1bmN0aW9uIGNvbXBhcmUoJGEsICRiKTsKfQoKY2xhc3MgTXVsdGlwbGVLZXlWYWx1ZUZpbHRlciBpbXBsZW1lbnRzIEZpbHRlciB7Cglwcm90ZWN0ZWQgJGt2UGFpcnM7CgkKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgka3ZQYWlycykgewoJCSR0aGlzLT5rdlBhaXJzID0gJGt2UGFpcnM7Cgl9CgkKCXB1YmxpYyBmdW5jdGlvbiBmaWx0ZXIoJGl0ZW0pIHsKCQkkcmVzdWx0ID0gdHJ1ZTsKCQkKCQlmb3JlYWNoICgkdGhpcy0+a3ZQYWlycyBhcyAka2V5ID0+ICR2YWx1ZSkgewoJCQlpZiAoJGl0ZW1bJGtleV0gIT09ICR2YWx1ZSkKCQkJCSRyZXN1bHQgJj0gZmFsc2U7CgkJfQoJCQoJCXJldHVybiAkcmVzdWx0OwoJfQp9CgpjbGFzcyBLZXlDb21wYXJhdG9yIGltcGxlbWVudHMgQ29tcGFyYXRvciB7Cglwcm90ZWN0ZWQgJGRpcmVjdGlvbjsKCXByb3RlY3RlZCAkdHJhbnNmb3JtOwoJcHJvdGVjdGVkICRrZXk7CgkKCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdCgka2V5LCAkZGlyZWN0aW9uID0gU29ydERpcmVjdGlvbjo6QXNjZW5kaW5nLCAkdHJhbnNmb3JtID0gbnVsbCkgewoJCSR0aGlzLT5rZXkgPSAka2V5OwoJCSR0aGlzLT5kaXJlY3Rpb24gPSAkZGlyZWN0aW9uOwoJCSR0aGlzLT50cmFuc2Zvcm0gPSAkdHJhbnNmb3JtOwoJfQoJCglwdWJsaWMgZnVuY3Rpb24gY29tcGFyZSgkYSwgJGIpIHsKCQkkYSA9ICRhWyR0aGlzLT5rZXldOwoJCSRiID0gJGJbJHRoaXMtPmtleV07CgkJCgkJaWYgKCR0aGlzLT50cmFuc2Zvcm0pIHsKCQkJJGEgPSAkdGhpcy0+dHJhbnNmb3JtKCRhKTsKCQkJJGIgPSAkdGhpcy0+dHJhbnNmb3JtKCRiKTsKCQl9CgkJCgkJcmV0dXJuICRhID09PSAkYiA/IDAgOiAoKCRhID4gJGIgPyAxIDogLTEpICogJHRoaXMtPmRpcmVjdGlvbik7Cgl9Cn0KCmNsYXNzIE11bHRpcGxlS2V5Q29tcGFyYXRvciBpbXBsZW1lbnRzIENvbXBhcmF0b3IgewoJcHJvdGVjdGVkICRrZXlzOwoJCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJGtleXMpIHsKCQkkdGhpcy0+a2V5cyA9ICRrZXlzOwoJfQoJCglwdWJsaWMgZnVuY3Rpb24gY29tcGFyZSgkYSwgJGIpIHsKCQkkcmVzdWx0ID0gMDsKCQkKCQlmb3JlYWNoICgkdGhpcy0+a2V5cyBhcyAkY29tcGFyYXRvcikgewoJCQlpZiAoJGNvbXBhcmF0b3IgaW5zdGFuY2VvZiBLZXlDb21wYXJhdG9yKSB7CgkJCQkkcmVzdWx0ID0gJGNvbXBhcmF0b3ItPmNvbXBhcmUoJGEsICRiKTsKCQkJCQoJCQkJaWYgKCRyZXN1bHQgIT09IDApIHJldHVybiAkcmVzdWx0OwoJCQl9CgkJfQoJCQoJCXJldHVybiAkcmVzdWx0OwoJfQp9CgoKJGFycmF5ID0gYXJyYXkgKAoJJzEnID0+IGFycmF5ICgndHlwZScgPT4gJ2JsYWgyJywgJ2NhdGVnb3J5JyA9PiAnY2F0MicsICdleHBfcmFuZ2UnID0+ICd0aGlzX3dlZWsnICksCiAgICAnMicgPT4gYXJyYXkgKCd0eXBlJyA9PiAnYmxhaDEnLCAnY2F0ZWdvcnknID0+ICdjYXQxJywgJ2V4cF9yYW5nZScgPT4gJ3RoaXNfd2VlaycgKSwKICAgICczJyA9PiBhcnJheSAoJ3R5cGUnID0+ICdibGFoMScsICdjYXRlZ29yeScgPT4gJ2NhdDInLCAnZXhwX3JhbmdlJyA9PiAnbmV4dF93ZWVrJyApLAogICAgJzQnID0+IGFycmF5ICgndHlwZScgPT4gJ2JsYWgxJywgJ2NhdGVnb3J5JyA9PiAnY2F0MScsICdleHBfcmFuZ2UnID0+ICduZXh0X3dlZWsnICkKKTsKCiRjb21wYXJhdG9yID0gbmV3IE11bHRpcGxlS2V5Q29tcGFyYXRvcihhcnJheSgKCW5ldyBLZXlDb21wYXJhdG9yKCd0eXBlJyksCgluZXcgS2V5Q29tcGFyYXRvcignZXhwX3JhbmdlJykKKSk7Cgp1c29ydCgkYXJyYXksIGFycmF5KCRjb21wYXJhdG9yLCAnY29tcGFyZScpKTsKCmVjaG8gIlNvcnRlZCBieSBtdWx0aXBsZSBmaWVsZHNcbiI7CnByaW50X3IoJGFycmF5KTsKCiRmaWx0ZXIgPSBuZXcgTXVsdGlwbGVLZXlWYWx1ZUZpbHRlcihhcnJheSgKCSd0eXBlJyA9PiAnYmxhaDEnCikpOwoKZWNobyAiRmlsdGVyZWQgYnkgbXVsdGlwbGUgZmllbGRzXG4iOwpwcmludF9yKGFycmF5X2ZpbHRlcigkYXJyYXksIGFycmF5KCRmaWx0ZXIsICdmaWx0ZXInKSkpOw==