diff --git a/spec/Doctrine/Orm/Filter/AttributeFilterSpec.php b/spec/Doctrine/Orm/Filter/AttributeFilterSpec.php
new file mode 100644
index 00000000..3d0519a3
--- /dev/null
+++ b/spec/Doctrine/Orm/Filter/AttributeFilterSpec.php
@@ -0,0 +1,272 @@
+iriConverter = $iriConverter;
+ }
+
+ /**
+ * @param mixed $value
+ */
+ protected function filterProperty(
+ string $property,
+ $value,
+ QueryBuilder $queryBuilder,
+ QueryNameGeneratorInterface $queryNameGenerator,
+ string $resourceClass,
+ string $operationName = null
+ ): void {
+ if (
+ !\is_array($value) ||
+ !$this->isPropertyEnabled($property, $resourceClass)
+ ) {
+ return;
+ }
+
+ $attributeId = $this->getAttributeId($value, $property);
+ $extractedValue = $this->extractValue($value, $property);
+ if (null === $attributeId || null === $extractedValue) {
+ return;
+ }
+
+ $alias = $queryBuilder->getRootAliases()[0];
+
+ if ($this->isPropertyNested($property . '.id', $resourceClass)) {
+ [$alias] = $this->addJoinsForNestedProperty($property . '.id', $alias, $queryBuilder, $queryNameGenerator, $resourceClass);
+ }
+
+ Assert::string($alias);
+
+ $this->addWhere(
+ $queryBuilder,
+ $queryNameGenerator,
+ $alias,
+ $property,
+ $attributeId,
+ $extractedValue
+ );
+ }
+
+ /** @param mixed $value */
+ protected function addWhere(
+ QueryBuilder $queryBuilder,
+ QueryNameGeneratorInterface $queryNameGenerator,
+ string $alias,
+ string $field,
+ string $attributeId,
+ $value,
+ string $operator = self::OPERATOR_EXACT
+ ): void {
+ $valueParameter = $queryNameGenerator->generateParameterName($field);
+
+ /** @var AttributeInterface $attribute */
+ $attribute = $this->iriConverter->getItemFromIri($attributeId);
+ $attributeType = $attribute->getType();
+ Assert::notNull($attributeType);
+ $value = $this->normalizeValue($value, $attributeType);
+
+ switch ($operator) {
+ case self::OPERATOR_EXACT:
+ $queryBuilder
+ ->andWhere(
+ sprintf(
+ '%s.%s = :%s',
+ $alias,
+ $attributeType,
+ $valueParameter
+ )
+ )
+ ->setParameter($valueParameter, $value);
+
+ break;
+ case self::OPERATOR_PARTIAL:
+ if (null === $value) {
+ return;
+ }
+
+ $queryBuilder
+ ->andWhere(sprintf('%s.%s > :%s', $alias, $field, $valueParameter))
+ ->setParameter($valueParameter, $value);
+
+ break;
+ }
+ }
+
+ public function getDescription(string $resourceClass): array
+ {
+ $description = [];
+
+ $properties = $this->getProperties();
+ if (null === $properties) {
+ $properties = array_fill_keys($this->getClassMetadata($resourceClass)->getFieldNames(), null);
+ }
+
+ /** @var string $property */
+ foreach (array_keys($properties) as $property) {
+ $description += $this->getFilterDescription($property, self::ATTRIBUTE_ID);
+ $description += $this->getFilterDescription($property, self::VALUE);
+ }
+
+ return $description;
+ }
+
+ protected function getFilterDescription(string $fieldName, string $operator): array
+ {
+ /** @var string $propertyName */
+ $propertyName = $this->normalizePropertyName($fieldName);
+
+ return [
+ sprintf('%s[%s]', $propertyName, $operator) => [
+ 'property' => $propertyName,
+ 'type' => 'string',
+ 'required' => false,
+ ],
+ ];
+ }
+
+ private function getAttributeId(array $values, string $property): ?string
+ {
+ if (array_key_exists(self::ATTRIBUTE_ID, $values)) {
+ /** @var string $attributeId */
+ $attributeId = $values[self::ATTRIBUTE_ID];
+ } else {
+ $this->getLogger()->notice('Invalid filter ignored', [
+ 'exception' => new InvalidArgumentException(
+ sprintf(
+ '%s is required for "%s" property',
+ self::ATTRIBUTE_ID,
+ $property
+ )
+ ),
+ ]);
+
+ return null;
+ }
+
+ return $attributeId;
+ }
+
+ private function extractValue(array $values, string $property): ?string
+ {
+ if (array_key_exists(self::VALUE, $values)) {
+ /** @var string $value */
+ $value = $values[self::VALUE];
+ } else {
+ $this->getLogger()->notice('Invalid filter ignored', [
+ 'exception' => new InvalidArgumentException(
+ sprintf(
+ '%s is required for "%s" property',
+ self::VALUE,
+ $property
+ )
+ ),
+ ]);
+
+ return null;
+ }
+
+ return $value;
+ }
+
+ /**
+ * @param ?mixed $value
+ *
+ * @return int|float|string|bool|\DateTime|null
+ *
+ * @throws \Exception
+ */
+ private function normalizeValue($value, string $type)
+ {
+ switch ($type) {
+ case CheckboxAttributeType::TYPE:
+ $value = (bool) $value;
+
+ break;
+ case DateAttributeType::TYPE:
+ case DatetimeAttributeType::TYPE:
+ Assert::string($value);
+ $value = new \DateTime($value);
+
+ break;
+ case IntegerAttributeType::TYPE:
+ $value = (int) $value;
+
+ break;
+ case PercentAttributeType::TYPE:
+ $value = (float) $value;
+
+ break;
+ case SelectAttributeType::TYPE:
+ //assume IRI ?
+ //TODO::
+ $value = (bool) $value;
+
+ break;
+ default:
+ $value = (null !== $value) ? (string) $value : null;
+ }
+
+ return $value;
+ }
+}
diff --git a/src/Behat/Context/GraphqlApiPlatformContext.php b/src/Behat/Context/GraphqlApiPlatformContext.php
index 3d26eef8..ba0841ba 100644
--- a/src/Behat/Context/GraphqlApiPlatformContext.php
+++ b/src/Behat/Context/GraphqlApiPlatformContext.php
@@ -180,7 +180,7 @@ private function castToType($value, string $type = null)
break;
default:
- $value = is_array($value) ? (array) $value: (string) $value;
+ $value = is_array($value) ? $value: (string) $value;
break;
}
diff --git a/src/Doctrine/Orm/Filter/AttributeFilter.php b/src/Doctrine/Orm/Filter/AttributeFilter.php
index b1ac083a..f4106aa0 100644
--- a/src/Doctrine/Orm/Filter/AttributeFilter.php
+++ b/src/Doctrine/Orm/Filter/AttributeFilter.php
@@ -30,9 +30,6 @@
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
use Webmozart\Assert\Assert;
-/**
- * Filters the collection by value of given attribute IRI
- */
class AttributeFilter extends AbstractContextAwareFilter implements FilterInterface
{
use PropertyHelperTrait;
@@ -66,9 +63,7 @@ public function __construct(
$this->iriConverter = $iriConverter;
}
- /**
- * @param mixed $value
- */
+ /** @param mixed $value */
protected function filterProperty(
string $property,
$value,
@@ -77,20 +72,24 @@ protected function filterProperty(
string $resourceClass,
string $operationName = null
): void {
- if (
- !\is_array($value) ||
- !$this->isPropertyEnabled($property, $resourceClass)
- ) {
+ if ($this->isWrongValueOrProperty($value, $property, $resourceClass)) {
return;
}
+ Assert::isArray($value);
+
$attributeId = $this->getAttributeId($value, $property);
$extractedValue = $this->extractValue($value, $property);
if (null === $attributeId || null === $extractedValue) {
return;
}
- $alias = $queryBuilder->getRootAliases()[0];
+ $aliases = $queryBuilder->getRootAliases();
+ if(count($aliases) > 0){
+ $alias = reset($aliases);
+ }else{
+ return;
+ }
if ($this->isPropertyNested($property . '.id', $resourceClass)) {
[$alias] = $this->addJoinsForNestedProperty($property . '.id', $alias, $queryBuilder, $queryNameGenerator, $resourceClass);
@@ -187,10 +186,7 @@ protected function getFilterDescription(string $fieldName, string $operator): ar
private function getAttributeId(array $values, string $property): ?string
{
- if (array_key_exists(self::ATTRIBUTE_ID, $values)) {
- /** @var string $attributeId */
- $attributeId = $values[self::ATTRIBUTE_ID];
- } else {
+ if (!array_key_exists(self::ATTRIBUTE_ID, $values)) {
$this->getLogger()->notice('Invalid filter ignored', [
'exception' => new InvalidArgumentException(
sprintf(
@@ -204,15 +200,12 @@ private function getAttributeId(array $values, string $property): ?string
return null;
}
- return $attributeId;
+ return (string) $values[self::ATTRIBUTE_ID];
}
private function extractValue(array $values, string $property): ?string
{
if (array_key_exists(self::VALUE, $values)) {
- /** @var string $value */
- $value = $values[self::VALUE];
- } else {
$this->getLogger()->notice('Invalid filter ignored', [
'exception' => new InvalidArgumentException(
sprintf(
@@ -226,7 +219,7 @@ private function extractValue(array $values, string $property): ?string
return null;
}
- return $value;
+ return (string) $values[self::VALUE];;
}
/**
@@ -258,9 +251,7 @@ private function normalizeValue($value, string $type)
break;
case SelectAttributeType::TYPE:
- //assume IRI ?
- //TODO::
- $value = (bool) $value;
+ $value = (string) $value;
break;
default:
@@ -269,4 +260,11 @@ private function normalizeValue($value, string $type)
return $value;
}
+
+ /** @param mixed $value */
+ protected function isWrongValueOrProperty($value, string $property, string $resourceClass): bool
+ {
+ return !\is_array($value) ||
+ !$this->isPropertyEnabled($property, $resourceClass);
+ }
}
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index 37904ba2..43bfa98f 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -10,7 +10,7 @@ We are hiring developers from all over the world. Join us and start your new, ex
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
+
diff --git a/src/Resources/services/behat/contexts.xml b/src/Resources/services/behat/contexts.xml
index 29dc746d..4c91a0de 100755
--- a/src/Resources/services/behat/contexts.xml
+++ b/src/Resources/services/behat/contexts.xml
@@ -68,6 +68,5 @@
-
diff --git a/src/Resources/services/doctrine_orm.xml b/src/Resources/services/doctrine_orm.xml
index 180a4d50..e7ed22e7 100644
--- a/src/Resources/services/doctrine_orm.xml
+++ b/src/Resources/services/doctrine_orm.xml
@@ -11,14 +11,18 @@ We are hiring developers from all over the world. Join us and start your new, ex
-
+
null
-
+