mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-18 07:23:13 +00:00
Convert dates to date ranges on timestamp keys
This commit is contained in:
@@ -20,22 +20,22 @@ class RangeExpression extends Node
|
|||||||
|
|
||||||
public static function lessThan(Key $key, $bound)
|
public static function lessThan(Key $key, $bound)
|
||||||
{
|
{
|
||||||
return new self($key, $bound, false);
|
return new self($key, null, false, $bound, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function lessThanOrEqual(Key $key, $bound)
|
public static function lessThanOrEqual(Key $key, $bound)
|
||||||
{
|
{
|
||||||
return new self($key, $bound, true);
|
return new self($key, null, false, $bound, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function greaterThan(Key $key, $bound)
|
public static function greaterThan(Key $key, $bound)
|
||||||
{
|
{
|
||||||
return new self($key, null, false, $bound, false);
|
return new self($key, $bound, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function greaterThanOrEqual(Key $key, $bound)
|
public static function greaterThanOrEqual(Key $key, $bound)
|
||||||
{
|
{
|
||||||
return new self($key, null, false, $bound, true);
|
return new self($key, $bound, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct(Key $key, $lb, $li = false, $hb = null, $hi = false)
|
public function __construct(Key $key, $lb, $li = false, $hb = null, $hi = false)
|
||||||
@@ -57,17 +57,17 @@ class RangeExpression extends Node
|
|||||||
if ($this->lower_bound !== null) {
|
if ($this->lower_bound !== null) {
|
||||||
$this->assertValueCompatible($this->lower_bound, $context);
|
$this->assertValueCompatible($this->lower_bound, $context);
|
||||||
if ($this->lower_inclusive) {
|
if ($this->lower_inclusive) {
|
||||||
$params['lte'] = $this->lower_bound;
|
$params['gte'] = $this->lower_bound;
|
||||||
} else {
|
} else {
|
||||||
$params['lt'] = $this->lower_bound;
|
$params['gt'] = $this->lower_bound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->higher_bound !== null) {
|
if ($this->higher_bound !== null) {
|
||||||
$this->assertValueCompatible($this->higher_bound, $context);
|
$this->assertValueCompatible($this->higher_bound, $context);
|
||||||
if ($this->higher_inclusive) {
|
if ($this->higher_inclusive) {
|
||||||
$params['gte'] = $this->higher_bound;
|
$params['lte'] = $this->higher_bound;
|
||||||
} else {
|
} else {
|
||||||
$params['gt'] = $this->higher_bound;
|
$params['lt'] = $this->higher_bound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,16 +98,16 @@ class RangeExpression extends Node
|
|||||||
$string = '';
|
$string = '';
|
||||||
if ($this->lower_bound !== null) {
|
if ($this->lower_bound !== null) {
|
||||||
if ($this->lower_inclusive) {
|
if ($this->lower_inclusive) {
|
||||||
$string .= sprintf(' lte="%s"', $this->lower_bound);
|
$string .= sprintf(' gte="%s"', $this->lower_bound);
|
||||||
} else {
|
} else {
|
||||||
$string .= sprintf(' lt="%s"', $this->lower_bound);
|
$string .= sprintf(' gt="%s"', $this->lower_bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->higher_bound !== null) {
|
if ($this->higher_bound !== null) {
|
||||||
if ($this->higher_inclusive) {
|
if ($this->higher_inclusive) {
|
||||||
$string .= sprintf(' gte="%s"', $this->higher_bound);
|
$string .= sprintf(' lte="%s"', $this->higher_bound);
|
||||||
} else {
|
} else {
|
||||||
$string .= sprintf(' gt="%s"', $this->higher_bound);
|
$string .= sprintf(' lt="%s"', $this->higher_bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Mapping;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Structure\Field;
|
||||||
|
|
||||||
class QueryHelper
|
class QueryHelper
|
||||||
@@ -107,4 +108,42 @@ class QueryHelper
|
|||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getRangeFromDateString($string)
|
||||||
|
{
|
||||||
|
$formats = ['Y/m/d', 'Y/m', 'Y'];
|
||||||
|
$deltas = ['+1 day', '+1 month', '+1 year'];
|
||||||
|
$to = null;
|
||||||
|
while ($format = array_pop($formats)) {
|
||||||
|
$delta = array_pop($deltas);
|
||||||
|
$from = date_create_from_format($format, $string);
|
||||||
|
if ($from !== false) {
|
||||||
|
// Rewind to start of range
|
||||||
|
$month = 1;
|
||||||
|
$day = 1;
|
||||||
|
switch ($format) {
|
||||||
|
case 'Y/m/d':
|
||||||
|
$day = (int) $from->format('d');
|
||||||
|
case 'Y/m':
|
||||||
|
$month = (int) $from->format('m');
|
||||||
|
case 'Y':
|
||||||
|
$year = (int) $from->format('Y');
|
||||||
|
}
|
||||||
|
date_date_set($from, $year, $month, $day);
|
||||||
|
date_time_set($from, 0, 0, 0);
|
||||||
|
// Create end of the the range
|
||||||
|
$to = date_modify(clone $from, $delta);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$from || !$to) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Invalid date "%s".', $string));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'from' => $from->format(Mapping::DATE_FORMAT_CAPTION_PHP),
|
||||||
|
'to' => $to->format(Mapping::DATE_FORMAT_CAPTION_PHP)
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ namespace Alchemy\Phrasea\SearchEngine\Elastic\Search;
|
|||||||
|
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
use Alchemy\Phrasea\SearchEngine\Elastic\AST;
|
||||||
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\Exception;
|
use Alchemy\Phrasea\SearchEngine\Elastic\Exception\Exception;
|
||||||
|
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryHelper;
|
||||||
use Hoa\Compiler\Llk\TreeNode;
|
use Hoa\Compiler\Llk\TreeNode;
|
||||||
use Hoa\Visitor\Element;
|
use Hoa\Visitor\Element;
|
||||||
use Hoa\Visitor\Visit;
|
use Hoa\Visitor\Visit;
|
||||||
@@ -176,10 +177,29 @@ class QueryVisitor implements Visit
|
|||||||
private function visitEqualNode(TreeNode $node)
|
private function visitEqualNode(TreeNode $node)
|
||||||
{
|
{
|
||||||
return $this->handleBinaryExpression($node, function($left, $right) {
|
return $this->handleBinaryExpression($node, function($left, $right) {
|
||||||
|
if ($this->isDateKey($left)) {
|
||||||
|
try {
|
||||||
|
// Try to create a range for incomplete dates
|
||||||
|
$range = QueryHelper::getRangeFromDateString($right);
|
||||||
|
return new AST\KeyValue\RangeExpression(
|
||||||
|
$left,
|
||||||
|
$range['from'], true,
|
||||||
|
$range['to'], false
|
||||||
|
);
|
||||||
|
} catch (\InvalidArgumentException $e) {
|
||||||
|
// Fall back to equal expression
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new AST\KeyValue\EqualExpression($left, $right);
|
return new AST\KeyValue\EqualExpression($left, $right);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function isDateKey(AST\KeyValue\Key $key)
|
||||||
|
{
|
||||||
|
return $key instanceof AST\KeyValue\TimestampKey;
|
||||||
|
}
|
||||||
|
|
||||||
private function visitTerm(Element $element)
|
private function visitTerm(Element $element)
|
||||||
{
|
{
|
||||||
$words = array();
|
$words = array();
|
||||||
|
Reference in New Issue
Block a user