Commit de4d5be2 authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

Amélioration de la définition des filtres.

BC: les paramètres multiples (foo[]) s'appellent désormais foos au lieu de foo.
parent 5f752a45
......@@ -296,11 +296,8 @@ final class MetadataFactory implements MetadataFactoryInterface
continue;
}
/** @var FilterInterface $filter */
$filter = $this->filterLocator->get($filterId);
foreach ($filter->getDescription($class->getFullName()) as $name => $filterParameter) {
$filters[$name] = $filterParameter;
}
$filters[] = $this->filterLocator->get($filterId);
}
return $filters;
......
......@@ -30,12 +30,15 @@ use Irstea\NgModelGeneratorBundle\Metadata\ResourceMetadata;
use Irstea\NgModelGeneratorBundle\Models\ClassName;
use Irstea\NgModelGeneratorBundle\Models\Declaration;
use Irstea\NgModelGeneratorBundle\Models\PHPClass;
use Irstea\NgModelGeneratorBundle\Models\Types\Alias;
use Irstea\NgModelGeneratorBundle\Models\Types\BuiltinType;
use Irstea\NgModelGeneratorBundle\Models\Types\Objects\InterfaceType;
use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property;
use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Repository;
use Irstea\NgModelGeneratorBundle\Models\Types\Resources\UUID;
use Irstea\NgModelGeneratorBundle\Models\Types\StringConst;
use Irstea\NgModelGeneratorBundle\Models\Types\Type;
use Irstea\NgModelGeneratorBundle\Models\Types\Union;
use Irstea\NgModelGeneratorBundle\Writers\MultiFileWriter;
use Irstea\NgModelGeneratorBundle\Writers\Writer;
use Symfony\Component\PropertyInfo\Type as PHPType;
......@@ -198,6 +201,7 @@ final class ModelGenerator
$factory->add('UUID', UUID::get());
$factory->add('CommonFilters', $this->createCommonFilters('CommonFilters'));
$factory->add('Ordering', $this->createOrdering());
foreach ([
PHPType::BUILTIN_TYPE_ARRAY => 'Array',
......@@ -240,6 +244,15 @@ final class ModelGenerator
return new InterfaceType($name, null, $properties);
}
/**
* @return Type
*/
private function createOrdering(): Type
{
return new Alias('Ordering', Union::create([StringConst::get('asc'), StringConst::get('desc')]), 'Allowed values for ordering parameters');
}
/**
* Retourne un iterateur sur les métadonnées des ressources.
*
......
......@@ -22,10 +22,13 @@
namespace Irstea\NgModelGeneratorBundle;
use Doctrine\Common\Inflector\Inflector;
use Irstea\NgModelGeneratorBundle\Exceptions\InvalidArgumentException;
use Irstea\NgModelGeneratorBundle\Metadata\OperationMetadata;
use Irstea\NgModelGeneratorBundle\Metadata\SerializationMetadata;
use Irstea\NgModelGeneratorBundle\Models\PHPClass;
use Irstea\NgModelGeneratorBundle\Models\Types\ArrayType;
use Irstea\NgModelGeneratorBundle\Models\Types\BuiltinType;
use Irstea\NgModelGeneratorBundle\Models\Types\Objects\AnonymousObject;
use Irstea\NgModelGeneratorBundle\Models\Types\Objects\InterfaceType;
use Irstea\NgModelGeneratorBundle\Models\Types\Objects\Property;
use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Operation;
......@@ -34,6 +37,8 @@ use Irstea\NgModelGeneratorBundle\Models\Types\Operations\Path;
use Irstea\NgModelGeneratorBundle\Models\Types\Placeholder;
use Irstea\NgModelGeneratorBundle\Models\Types\Resources\Collection;
use Irstea\NgModelGeneratorBundle\Models\Types\Resources\IRI;
use Irstea\NgModelGeneratorBundle\Models\Types\Resources\Representation;
use Irstea\NgModelGeneratorBundle\Models\Types\StringConst;
use Irstea\NgModelGeneratorBundle\Models\Types\Type;
use Irstea\NgModelGeneratorBundle\Models\Types\Union;
......@@ -221,42 +226,116 @@ final class OperationMapper
*/
private function getFilterProperties(): array
{
$parameters = [];
/** @var Property[] $properties */
$properties = [];
$pagination = $this->operation->getPagination();
if ($pagination && $pagination->isEnabled()) {
$intType = BuiltinType::get('number');
$parameters[$pagination->getPageParameterName()] = $intType;
$pageName = $pagination->getPageParameterName();
$properties[] = new Property($pageName, 'Requested page', $intType, false, true, false, $pageName);
if ($pagination->isClientItemsPerPage()) {
$parameters[$pagination->getItemsPerPageParameterName()] = $intType;
$pageSizeName = $pagination->getItemsPerPageParameterName();
$properties[] = new Property($pageSizeName, 'Page size', $intType, false, true, false, $pageSizeName);
}
}
foreach ($this->operation->getFilters() as $name => $filter) {
$parameters[$name] = $this->typeFactory->get($filter['type']);
}
$rootClass = $this->operation->getClassName();
/** @var array<string,Property> $properties */
$properties = [];
foreach ($parameters as $name => $type) {
$l = \strlen($name);
foreach ($this->operation->getFilters() as $filter) {
$filterType = PHPClass::get(get_class($filter))->getBaseName();
foreach ($filter->getDescription($this->operation->getResource()->getFullName()) as $name => $filterDesc) {
$type = $this->typeFactory->get($filterDesc['type']);
if (isset($filterDesc['property']) && is_string($filterDesc['property'])) {
$propType = $this->resolvePropertyType($rootClass, $filterDesc['property']);
if ($propType) {
$type = $propType;
}
}
$type = $this->resolveFilterType($filterType, $type);
if (substr($name, $l - 2) === '[]') {
$name = substr($name, 0, $l - 2);
$type = new ArrayType($type);
$propName = Inflector::camelize(preg_replace('/\W+/', '_', $name));
if (isset($filterDesc['is_collection']) && $filterDesc['is_collection']) {
$type = new ArrayType($type);
$propName = Inflector::pluralize($propName);
}
if (isset($properties[$propName])) {
$type = Union::create([$type, $properties[$propName]->getType()]);
}
$properties[$propName] = new Property($propName, '', $type, false, true, false, $name);
}
$simplerName = Inflector::camelize(preg_replace('/\W+/', '_', $name));
}
if (isset($properties[$simplerName])) {
$type = Union::create([$type, $properties[$simplerName]->getType()]);
/** @var Property[] $propDict */
$propDict = [];
foreach ($properties as $property) {
$name = $property->getName();
if (isset($propDict[$name])) {
if ($propDict[$name]->getOriginalName() !== $property->getOriginalName()) {
throw new InvalidArgumentException(sprintf("filter property conflict: $name"));
}
$mergedeType = Union::create([$propDict[$name]->getType(), $property->getType()]);
$mergedNullable = $propDict[$name]->isNullable() || $property->isNullable();
$propDict[$name] = new Property($name, '', $mergedeType, false, $mergedNullable, false, $property->getOriginalName());
} else {
$propDict[$name] = $property;
}
}
return $propDict;
}
$properties[$simplerName] = new Property($simplerName, '', $type, false, true, false, $name);
/**
* @param string $class
* @param string $property
*
* @return Type|null
*/
private function resolvePropertyType(string $class, string $property): ?Type
{
/** @var AnonymousObject|null $type */
$type = $this->typeFactory->get($class)->findType(AnonymousObject::class);
if (!$type || !$type->hasProperty($property)) {
return null;
}
return $properties;
return $type->getProperty($property)->getType();
}
/**
* @param string $filterType
* @param Type $baseType
*
* @return Type
*/
private function resolveFilterType(string $filterType, Type $baseType): Type
{
switch ($filterType) {
case 'DateFilter':
return BuiltinType::get('Date');
case 'NumericFilter':
return BuiltinType::get('number');
break;
case 'OrderFilter':
return $this->typeFactory->get('Ordering');
case 'BooleanFilter':
case 'ExistFilter':
return BuiltinType::get('boolean');
}
return $baseType;
}
/**
......@@ -284,7 +363,7 @@ final class OperationMapper
);
$this->typeFactory->add($filterName, $filterType);
$body[] = "if (filters && typeof filters === 'object') {";
$body = ["if (filters && typeof filters === 'object') {"];
$body[] = " if (!$varName) {";
$body[] = " $varName = {};";
$body[] = ' }';
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment