-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EZP-26780 Implement DateMetadata criterion parser in REST #1861
Conversation
ping @andrerom @bdunogier |
} | ||
$target = $data['DateMetadataCriterion']['Target']; | ||
|
||
$reflector = new ReflectionClass('eZ\Publish\API\Repository\Values\Content\Query\Criterion\Operator'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be good to not have to use reflection
ping @andrerom |
/** | ||
* @return array | ||
*/ | ||
public static function getAvaliableOperators() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaik this does not have any meaning in the PHP API, as operators are never referred to by string names like "EQ" and so on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation referes to those names:
https://doc.ez.no/display/EZP/Criteria+reference
It does not say to use "=", ">=", etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I read that doc it refers to the constants, but it is indeed hard to tell on this page as it does not have any examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this is what I referred to above, you don't use the API by passing in string values EQ
and so on, or =
for that matter, you use constants.
|
||
if (!isset($data['DateMetadataCriterion']['Operator'])) { | ||
$data['DateMetadataCriterion']['Operator'] = 'EQ'; | ||
} elseif (!in_array($data['DateMetadataCriterion']['Operator'], array_keys(Operator::getAvaliableOperators()))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can move the method to this class as private function getAvaliableDateMetadateRESTOperators()
, and it can return plain array with the available operators.
3c13554
to
d5aaf4e
Compare
@andrerom Changed. |
08bde8d
to
f049fb4
Compare
|
||
/** | ||
* Parser for ViewInput Criterion. | ||
*/ | ||
class DateMetadata extends BaseParser | ||
{ | ||
/** @var array */ | ||
public $availableOperators = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
privat?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about changing this value or inheritance, but after rethink it can be changed I guess
@bdunogier looks ok to me now besides comment, but unsure about the whole OperatorCriterion as I'm not aware how this is done in other criteria. |
@andrerom AFAIK there're no operators in other criteria or they are not implemented. |
ok, somewhat clear. note to self/other-reviewers then: check spec and try to get how operators were intended to work, now that PR changed values from string versions of constants (EQ, LIKE, ..), to the actual values which afaik are supposed to be internal, hence the use of constants. |
@andrerom @kamilmusial switch ($data['DateMetadataCriterion']['Operator']) {
case 'IN':
$operator = Operator::IN;
break:
case 'GTE':
$operator = Operator::GTE;
break:
case 'BETWEEN':
$operator = Operator::BETWEEN;
break:
...
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks okay.
After thinking about it for quite a bit, I'm wondering if we should move this up one level... we could conceal the whole operator debate by abstracting the criterion like this:
"ModifiedSince": <timestamp>
"PublishedAfter": <timestamp>
"ModifiedBetween": [<timestamp1>, <timestamp2>]
It would be much easier to use for REST consumers, and much more semantic/readable.
It is a bit more work for us to parse, but if we make this logic part of the parser dispatcher, it shouldn't be that complicated. Instead of a 1:1 match of the criterion's name, we could first detect this "operator suffix", and pass it to the parser when it gets invoked ? That way, we can keep the structs simple, and it also works for any criterion that needs an operator.
The main drawback that I can see is the non handling of the "than or equal" (e.g. GT
vs GTE
). But I'm kind of thinking that this case isn't that frequent, and it can always be formulated in other ways.
Please let me know what you think.
$target = $data['DateMetadataCriterion']['Target']; | ||
|
||
if (!isset($data['DateMetadataCriterion']['Operator'])) { | ||
$data['DateMetadataCriterion']['Operator'] = '='; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could skip this completely, and set a $operator
to null
. The Criterion's constructor will set it either to EQ
or IN
depending on the value.
} | ||
$value = $data['DateMetadataCriterion']['Value']; | ||
|
||
return new DateMetadataCriterion($target, $data['DateMetadataCriterion']['Operator'], $value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small consistency remark: why set a local variable for Value and not for Operator ? I'd probably be consistent here, and also set a $operator
after the checks above.
['DateMetadataCriterion' => ['Target' => 'created', 'Operator' => '=', 'Value' => 1033920830]], | ||
new DateMetadataCriterion('created', '=', 1033920830), | ||
], | ||
]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a test case where the operator isn't set ?
* @expectedException \eZ\Publish\Core\REST\Common\Exceptions\Parser | ||
* @expectedExceptionMessage Invalid <DateMetadataCriterion> format | ||
*/ | ||
public function testParseExceptionOnInvalidCriterionFormat() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that you have multiple error tests, you could use a dataProvider for them as well, since you use one for valid cases.
REST implementation has been moved to eZ Platform REST Bundle. We'll have to implement it there. Closing this one. |
JIRA: https://jira.ez.no/browse/EZP-26780
Currently there's no
OperatorCriterion
, so there's no easy way to set$operator
forDateMetadataCriterion
like it's done in other parsers.That could be done by simply passing a string value to criterion constructor, but that'd omit a specification whitelist. So there's quick check in an array of abstract class reflection constants to validate an operator input before return a criterion object.
Another approach could be to implement an
OperatorCriterion
parser, but that should be another issue(?)