Skip to content

Commit

Permalink
test: fail ci
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Nov 7, 2021
1 parent 2decc7b commit 972e12d
Show file tree
Hide file tree
Showing 17 changed files with 712 additions and 136 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,6 @@ jobs:
run: |
mkdir -p build/logs/behat
vendor/bin/behat --out=std --format=progress --format=junit --out=build/logs/behat/junit --profile=default --no-interaction
continue-on-error: true
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v1
Expand Down
8 changes: 4 additions & 4 deletions docs/adr/0003-uri-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ We will use a POPO to define URI variables, for now these options are available:
uriVariables: [
'companyId' => new UriVariable(
targetClass: Company::class,
inverseProperty: null,
targetProperty: null,
property: 'company'
identifiers: ['id'],
compositeIdentifier: true,
Expand All @@ -53,7 +53,7 @@ Where `uriVariables` keys are the URI template's variable names. Its value is a

- `targetClass` is the PHP FQDN of the class this value belongs to
- `property` represents the property, the URI Variable is mapped to in the current class
- `inverseProperty` represents the property, the URI Variable is mapped to in the related class and is not available in the current class
- `targetProperty` represents the property, the URI Variable is mapped to in the related class and is not available in the current class
- `identifiers` are the properties of the targetClass to which we map the URI variable
- `compositeIdentifier` is used to match a single variable to multiple identifiers (`ida=1;idb=2` to `class::ida` and `class::idb`)

Expand Down Expand Up @@ -122,7 +122,7 @@ class Company {
}
```

Note that the above is a shortcut for: `new UriVariable(targetClass: Employee::class, inverseProperty: 'company')`
Note that the above is a shortcut for: `new UriVariable(targetClass: Employee::class, targetProperty: 'company')`

Corresponding DQL:

Expand Down Expand Up @@ -259,7 +259,7 @@ class Employee {
#[ApiResource("/employees/{employeeId}/company", uriVariables: [
'employeeId' => new UriVariable(
targetClass: Employee::class,
inverseProperty: 'company'
targetProperty: 'company'
property: null,
identifiers: ['id'],
compositeIdentifier: true
Expand Down
2 changes: 2 additions & 0 deletions features/main/subresource.feature
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,9 @@ Feature: Subresource support
}
"""

@createSchema
Scenario: Get the subresource relation item
Given there is a dummy object with a fourth level relation
When I send a "GET" request to "/dummies/1/related_dummies/2"
Then the response status code should be 200
And the response should be in JSON
Expand Down
8 changes: 4 additions & 4 deletions src/Api/IdentifiersExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ private function getIdentifierValue($item, string $class, string $property, stri
continue;
}

if ($type->getClassName() === $class) {
return $this->resolveIdentifierValue($this->propertyAccessor->getValue($item, "$propertyName.$property"), $parameterName);
}

if ($type->isCollection() && ($collectionValueType = $type->getCollectionValueType()) && $collectionValueType->getClassName() === $class) {
return $this->resolveIdentifierValue($this->propertyAccessor->getValue($item, sprintf('%s[0].%s', $propertyName, $property)), $parameterName);
}

if ($type->getClassName() === $class) {
return $this->resolveIdentifierValue($this->propertyAccessor->getValue($item, "$propertyName.$property"), $parameterName);
}
}

throw new RuntimeException('Not able to retrieve identifiers.');
Expand Down
6 changes: 4 additions & 2 deletions src/Api/UriVariablesConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace ApiPlatform\Api;

use ApiPlatform\Exception\InvalidUriVariableException;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
use Symfony\Component\PropertyInfo\Type;
Expand Down Expand Up @@ -46,10 +47,11 @@ public function convert(array $uriVariables, string $class, array $context = [])
{
$operation = $context['operation'] ?? $this->resourceMetadataCollectionFactory->create($class)->getOperation();
$context = $context + ['operation' => $operation];
$uriVariablesDefinition = $operation->getUriVariables() ?? [];
$uriVariablesDefinitions = $operation->getUriVariables() ?? [];

foreach ($uriVariables as $parameterName => $value) {
if ([] === $types = $this->getIdentifierTypes($uriVariablesDefinition[$parameterName]->getFromClass() ?? $class, $uriVariablesDefinition[$parameterName]->getIdentifiers() ?? [$parameterName])) {
$uriVariableDefinition = $uriVariablesDefinitions[$parameterName] ?? $uriVariablesDefinitions['id'] ?? new Link();
if ([] === $types = $this->getIdentifierTypes($uriVariableDefinition->getFromClass() ?? $class, $uriVariableDefinition->getIdentifiers() ?? [$parameterName])) {
continue;
}

Expand Down
1 change: 1 addition & 0 deletions src/Bridge/Doctrine/Orm/State/CollectionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public function provide(string $resourceClass, array $identifiers = [], ?string

$this->handleLinks($queryBuilder, $identifiers, $queryNameGenerator, $context, $resourceClass, $operationName);

// dd($queryBuilder->getQuery());
foreach ($this->collectionExtensions as $extension) {
$extension->applyToCollection($queryBuilder, $queryNameGenerator, $resourceClass, $operationName, $context);

Expand Down
3 changes: 3 additions & 0 deletions src/Bridge/Doctrine/Orm/State/ItemProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
use ApiPlatform\State\ProviderInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
Expand Down Expand Up @@ -56,6 +57,7 @@ public function provide(string $resourceClass, array $identifiers = [], ?string
return $manager->getReference($resourceClass, $identifiers);
}

/** @var EntityRepository $repository */
$repository = $manager->getRepository($resourceClass);
if (!method_exists($repository, 'createQueryBuilder')) {
throw new RuntimeException('The repository class must have a "createQueryBuilder" method.');
Expand All @@ -66,6 +68,7 @@ public function provide(string $resourceClass, array $identifiers = [], ?string

$this->handleLinks($queryBuilder, $identifiers, $queryNameGenerator, $context, $resourceClass, $operationName);

dd($queryBuilder->getDQL());
foreach ($this->itemExtensions as $extension) {
$extension->applyToItem($queryBuilder, $queryNameGenerator, $resourceClass, $identifiers, $operationName, $context);

Expand Down
113 changes: 72 additions & 41 deletions src/Bridge/Doctrine/Orm/State/LinksHandlerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
namespace ApiPlatform\Bridge\Doctrine\Orm\State;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
use ApiPlatform\Exception\RuntimeException;
use ApiPlatform\Metadata\GraphQl\Operation as GraphQlOperation;
use ApiPlatform\Metadata\Link;
use Doctrine\ORM\QueryBuilder;
Expand All @@ -33,62 +32,93 @@ private function handleLinks(QueryBuilder $queryBuilder, array $identifiers, Que

if ($linkClass = $context['linkClass'] ?? false) {
foreach ($links as $link) {
if ($linkClass === $link->getFromClass()) {
if ($linkClass === $link->getTargetClass()) {
foreach ($identifiers as $identifier => $value) {
$this->applyLink($queryBuilder, $queryNameGenerator, $doctrineClassMetadata, $alias, $link, $identifier, $value);
}

return;
}
}
}

$operation = $this->resourceMetadataCollectionFactory->create($linkClass)->getOperation($operationName);
$links = $operation instanceof GraphQlOperation ? $operation->getLinks() : $operation->getUriVariables();
foreach ($links as $link) {
if ($resourceClass === $link->getFromClass()) {
$link = $link->withFromProperty($link->getToProperty())->withFromClass($linkClass);
foreach ($identifiers as $identifier => $value) {
$this->applyLink($queryBuilder, $queryNameGenerator, $doctrineClassMetadata, $alias, $link, $identifier, $value);
}
if (null === $links) {
return;
}

return;
}
dd($links)
dump($operation->getUriTemplate());
$aliases = [];
$previousContext = [];
$conditions = [];
foreach ($links as $parameterName => $link) {
$identifier = $link->getIdentifiers()[0];
if (!isset($aliases[$link->getTargetClass()])) {
$aliases[$link->getTargetClass()] = $link->getTargetClass() === $operation->getClass() ? $alias : $queryNameGenerator->generateJoinAlias($alias);
}

throw new RuntimeException(sprintf('The class "%s" cannot be retrieved from "%s".', $resourceClass, $linkClass));
}
$currentAlias = $aliases[$link->getTargetClass()];
$placeholder = $queryNameGenerator->generateParameterName($parameterName);
// inverse == prop de la targetClass
if (!$link->getInverseProperty() && !$link->getProperty() && !$link->getExpandedValue()) {
$conditions[] = $aliases[$link->getTargetClass()] . ".$identifier = :$placeholder";
$previousContext = ['alias' => $currentAlias, 'identifier' => $identifier];
continue;
}

if (!$links) {
return;
}

foreach ($identifiers as $identifier => $value) {
$link = $links[$identifier] ?? $links['id'];
if ($inverseProperty = $link->getInverseProperty()) {
$joinAlias = $queryNameGenerator->generateJoinAlias($alias);
$inverseAlias = $queryNameGenerator->generateJoinAlias($alias);
$conditions[] = "{$previousContext['alias']}.{$previousContext['identifier']} IN (SELECT $inverseAlias.$identifier FROM {$link->getTargetClass()} $joinAlias JOIN $joinAlias.$inverseProperty $inverseAlias WHERE $joinAlias.$identifier = $placeholder)";
$previousContext = ['alias' => $currentAlias, 'identifier' => $identifier];
continue;
}

dump($conditions);
dd($link);
// dd($link);
// if ($link->getExpandedValue()) {
// dd($queryBuilder->getDQL());
// dd('test');
// continue;
// }

$this->applyLink($queryBuilder, $queryNameGenerator, $doctrineClassMetadata, $alias, $link, $identifier, $value);
// $this->applyLink($queryBuilder, $queryNameGenerator, $doctrineClassMetadata, $alias, $link, $identifiers[$parameterName] ?? null);
}
}

private function applyLink(QueryBuilder $queryBuilder, QueryNameGenerator $queryNameGenerator, ClassMetadata $doctrineClassMetadata, string $alias, Link $link, string $identifier, $value)
private function applyLink(QueryBuilder $queryBuilder, QueryNameGenerator $queryNameGenerator, ClassMetadata $doctrineClassMetadata, string $alias, Link $link, $value = null)
{
$placeholder = ':id_'.$identifier;
if ($fromProperty = $link->getFromProperty()) {
$propertyIdentifier = $link->getIdentifiers()[0];
$joinAlias = $queryNameGenerator->generateJoinAlias($fromProperty);

$queryBuilder->join(
$link->getFromClass(),
$joinAlias,
'with',
"$alias.$propertyIdentifier = $joinAlias.$fromProperty"
);

$expression = $queryBuilder->expr()->eq(
"{$joinAlias}.{$propertyIdentifier}",
$placeholder
);
} elseif ($property = $link->getToProperty()) {
$propertyIdentifier = $link->getIdentifiers()[0];
$propertyIdentifier = $link->getIdentifiers()[0];
$placeholder = ':' . $queryNameGenerator->generateParameterName($propertyIdentifier);
if ($inverseProperty = $link->getInverseProperty()) {
$joinAlias = $queryNameGenerator->generateJoinAlias($alias);
$inverseAlias = $queryNameGenerator->generateJoinAlias($alias);

// SELECT o FROM ApiPlatform\Tests\Fixtures\TestBundle\Entity\ThirdLevel o
// WHERE o.id IN (
// SELECT o_a3.id FROM
// ApiPlatform\Tests\Fixtures\TestBundle\Entity\Dummy o_a1
// JOIN o_a1.relatedDummies o_a2
// JOIN o_a2.thirdLevel o_a3
// WHERE o_a1.id = :id_id
// ) AND o.id = :id_id

// $queryBuilder->join(
// $link->getTargetClass(),
// $joinAlias,
// 'with',
// "$alias.$propertyIdentifier = $joinAlias.$inverseProperty"
// );

$expression = "$alias.$propertyIdentifier IN (SELECT $inverseAlias.$propertyIdentifier FROM {$link->getTargetClass()} $joinAlias JOIN $joinAlias.$inverseProperty $inverseAlias WHERE $joinAlias.$propertyIdentifier = $placeholder)";

// $expression = $queryBuilder->expr()->eq(
// "{$joinAlias}.{$propertyIdentifier}",
// $placeholder
// );
} elseif ($property = $link->getProperty()) {
$joinAlias = $queryNameGenerator->generateJoinAlias($property);

$queryBuilder->join(
Expand All @@ -102,10 +132,11 @@ private function applyLink(QueryBuilder $queryBuilder, QueryNameGenerator $query
);
} else {
$expression = $queryBuilder->expr()->eq(
"{$alias}.{$identifier}", $placeholder
"{$alias}.{$propertyIdentifier}", $placeholder
);
}

$queryBuilder->andWhere($expression);
$queryBuilder->setParameter($placeholder, $value, $doctrineClassMetadata->getTypeOfField($identifier));
$queryBuilder->setParameter($placeholder, $value, $doctrineClassMetadata->getTypeOfField($propertyIdentifier));
}
}
Loading

0 comments on commit 972e12d

Please sign in to comment.