-
-
Notifications
You must be signed in to change notification settings - Fork 932
#530 ~ Add behat test and change behavior of ItemDataProvider for uuid #533
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
Conversation
55aa7d1
to
67e1333
Compare
ping @dunglas. |
features/composite.feature
Outdated
@createSchema | ||
@dropSchema | ||
Scenario: Get collection with composite identifiers | ||
Scenario: Get a compisite item with composite identifiers |
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.
typo
$placeholder = 'id_'.$propertyName; | ||
$whereExpr[$i] = $queryBuilder->expr()->eq('o.'.$propertyName, ':'.$placeholder); | ||
|
||
if ($i <= 0) { |
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 use an iterator here instead
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.
Ill look at it
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.
foreach ($identifiers as $propertyName => $value) {
$placeholder = 'id_'.$propertyName;
$whereExpr[] = $queryBuilder->expr()->eq('o.'.$propertyName, ':'.$placeholder);
$whereExprObj = new \ArrayObject($whereExpr);
var_dump($whereExprObj);
$whereIterator = $whereExprObj->getIterator();
var_dump($whereIterator->key());
if ($whereIterator->key() <= 0) {
$queryBuilder
->where($whereIterator->current());
} else {
$queryBuilder
->andWhere($whereIterator->current());
}
$queryBuilder->setParameter($placeholder, $value);
$whereIterator->next();
}
I can't make it working since the array is populated at the same time that I test it keys.
Do you see something wrong in what i've tried to achieve ?
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 of an interator on $identifiers
rather
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've missunderstand that comment line ;(
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.
no worries :)
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.
Like this ?
1996b64
to
f67ceca
Compare
->setParameter($placeholder, $value); | ||
++$i; | ||
$identifiersObjIterator->next(); | ||
} |
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 point of the iterator is to get rid of $i
. You can easily have something more readable by putting that into a private function:
$this->processIdentifiers($identifiers, $queryBuilder);
private function processIdentifiers(array $identifiers, QueryBuilder $queryBuilder)
{
if (0 === count($identifiers)) {
return;
}
$iterator = (new \ArrayObject($identifiers))->getIterator();
$queryBuilder->where(
$queryBuilder->expr()->eq(
'o.'.$identifiersObjIterator->key(),
':id_'.$identifiersObjIterator->key()
)
);
$queryBuilder->setParameter($'id_'.$identifiersObjIterator->key(), $identifiersObjIterator->current());
$iterator->next();
while($iterator->valid()) {
$queryBuilder->andWhere(
$queryBuilder->expr()->eq(
'o.'.$identifiersObjIterator->key(),
':id_'.$identifiersObjIterator->key()
)
);
$queryBuilder->setParameter('id_'.$identifiersObjIterator->key(), $identifiersObjIterator->current());
$iterator->next();
}
}
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.
but to be fair, you could have another version where you check just if you're on the first property or not:
private function processIdentifiers(array $identifiers, QueryBuilder $queryBuilder)
{
if (0 === count($identifiers)) {
return;
}
$firstIdentifier = reset($identifiers);
foreach($identifiers as $identifier => $value) {
$placeholder = ':id_'.$identifier;
$expression = $queryBuilder->expr()->eq(
'o.'.$identifier,
':'.$placeholder
);
if ($firstIdentifier === $identifier) {
$queryBuilder->where($expression);
} else {
$queryBuilder->andWhere($expression);
}
$queryBuilder->setParameter($placeholder, $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.
I will prefer the iterator version, it's readable and fun to use ;).
WDYT ?
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.
It's a fun case to play with the iterator which is why I mentioned it, but I must admit I find the second version more readable and accessible.
b0a9590
to
6ed35e7
Compare
Thanks for the help @theofidry ! |
I didn't looked into the code but this patch is working on my project 👍 |
} | ||
|
||
$identifierValues = explode('-', $id); | ||
$identifierValues = (array) $id; |
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.
Casting to an array is useless IIRC.
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.
We use it as an array later in the code. Do we have to cast it in a other way ?
L130
$firstIdentifier = reset($identifiers);
foreach ($identifiers as $identifier => $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.
I'd be happy if this whole identifiers business can be moved into a separate method:
$identifiers = $this->normalizeIdentifiers($id);
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.
In the same class ?
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 a first step, yes. We could certainly extract it out later if that makes sense...
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.
It's ok like this ?
9812b8a
to
69e9988
Compare
* @param array $identifiers | ||
* @param QueryBuilder $queryBuilder | ||
* | ||
* Populate the query with where when needed. |
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.
This is not valid PHPDoc. It assume you forgot to clean up here.
Anyway, I suggest to rephrase it like this:
Add WHERE conditions to the query for one or more identifiers (simple or composite).
ddf2461
to
e2ab7cc
Compare
|
||
if ($propertyMetadata->isIdentifier()) { | ||
$identifierValues[] = $this->propertyAccessor->getValue($item, $propertyName); | ||
$identifierValuesComposite[] = $propertyName.'='.$this->propertyAccessor->getValue($item, $propertyName); |
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.
THIS, feels like a hack.
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.
Just change the above line to:
$identifiers[$propertyName] = $this->propertyAccessor->getValue($item, $propertyName);
Then do this after the loop:
if (1 === count($identifiers)) {
$identifiers = array_map(function ($identifierValue) {
return rawurlencode($identifierValue);
}, $identifiers);
} else {
$identifiers = array_map(function ($identifierName, $identifierValue) {
return sprintf('%s=%s', $identifierName, rawurlencode($identifierValue));
}, array_keys($identifiers), $identifiers);
}
And finally:
return $this->router->generate($routeName, ['id' => implode(',', $identifiers)], $referenceType);
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.
Thanks for the help ! Ill modify that asap
…g uuid feature. and fix composite
ec18af3
to
aabd844
Compare
public function getId() | ||
{ | ||
return sprintf('%s-%s', $this->compositeItem->getId(), $this->compositeLabel->getId()); | ||
return sprintf('%s;%s', $this->compositeItem->getId(), $this->compositeLabel->getId()); |
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.
What is the purpose of this method? I don't see it being used anywhere...
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.
My mistake, I think this is some leftovers from my tests with api-platform 1.x ref #282 (comment)
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 asked myself too, but :
If we remove that :
{
"@id": "\/composite_relations\/compositeItem=1;compositeLabel=1",
"@type": "CompositeRelation",
"id": null,
"value": "somefoobardummy"
}
Where id is null, but when this exist, the ID is correct :
"id": "1;1"
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.
A separate id
property? Where does it come from when there's no getId
method?
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 don't understand, there is one, we are talking about that method no ?
public function getId() {
...
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.
Yes, is it still a problem if we remove this method from CompositeRelation
(and from the related tests too, of course)?
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 agree, it's useless
Thank you @Simperfit |
api-platform#530 ~ Add behat test and change behavior of ItemDataProvider for uuid
This is WIP
Edit : This is ok for review