Selaa lähdekoodia

Merge branch 'develop' of gitlab.2iopenservice.com:opentalent/ap2i into develop

Olivier Massot 1 vuosi sitten
vanhempi
commit
e9ce3afa7f

+ 1 - 0
.gitignore

@@ -50,6 +50,7 @@ public/phpstorm_index.php
 
 ###> phpstan/phpstan ###
 phpstan.neon
+phpstan.json
 ###< phpstan/phpstan ###
 
 ###> liip/imagine-bundle ###

+ 2 - 2
old/Entity/Awin/Product.php

@@ -153,14 +153,14 @@ class Product
      *
      *
      */
-    #[ORM\Column(name: 'price_mini', type: 'float', nullable: true)]
+    #[ORM\Column(name: 'priceMini', type: 'float', nullable: true)]
     protected $priceMini;
     /**
      * @var float
      *
      *
      */
-    #[ORM\Column(name: 'price_maxi', type: 'float', nullable: true)]
+    #[ORM\Column(name: 'priceMaxi', type: 'float', nullable: true)]
     protected $priceMaxi;
     /**
      * @var string

+ 0 - 24
phpstan.json

@@ -1,24 +0,0 @@
-[
-    {
-        "description": "PHPDoc tag @param references unknown parameter: $price_min",
-        "fingerprint": "a01fcf3b22321902df6137f7c06fa593d7b805397a90357e55ea87d53b3fbb02",
-        "severity": "major",
-        "location": {
-            "path": "src/Entity/Public/PublicEvent.php",
-            "lines": {
-                "begin": 523
-            }
-        }
-    },
-    {
-        "description": "PHPDoc tag @param references unknown parameter: $price_max",
-        "fingerprint": "16c23a8222383c8eab1118fa7cd936e1b023cc8af2118927cf67f7fc72e7e4a1",
-        "severity": "major",
-        "location": {
-            "path": "src/Entity/Public/PublicEvent.php",
-            "lines": {
-                "begin": 541
-            }
-        }
-    }
-]

+ 6 - 6
sql/schema-extensions/001-view_public_events.sql

@@ -8,8 +8,8 @@ AS
         b.url, 
         b.datetimeStart, 
         b.datetimeEnd, 
-        null as price_mini, 
-        null as price_maxi, 
+        null as priceMini, 
+        null as priceMaxi, 
         null as categoryCode,
         p.name AS placeName, 
         p.description AS placeDescription, 
@@ -54,9 +54,9 @@ UNION
         aw.deepLink AS url, 
         aw.datetimeStart, 
         aw.datetimeEnd, 
-        aw.price_mini, 
-        aw.price_maxi, 
-        aw.categoryCode,
+        aw.priceMini, 
+        aw.priceMaxi, 
+        aw.subCategory AS categoryCode,
         aw.place AS placeName, 
         NULL AS placeDescription, 
         NULL AS placeFloorSize, 
@@ -73,7 +73,7 @@ UNION
         NULL AS roomFloorSize,
         aw.largeimage AS imageUrl, 
         aw.mediumimage as thumbnailUrl, 
-        aw.categories AS categories, 
+        aw.categoryCode AS categories, 
         'awin' as origin, 
         aw.id as entityId
     FROM AwinProduct as aw

+ 0 - 0
src/ApiResource/.gitignore


+ 20 - 18
src/Entity/Public/PublicEvent.php

@@ -3,18 +3,19 @@ declare (strict_types=1);
 
 namespace App\Entity\Public;
 
-use ApiPlatform\Metadata\GetCollection;
 use ApiPlatform\Metadata\Get;
+use Doctrine\ORM\Mapping as ORM;
+use ApiPlatform\Metadata\ApiFilter;
 use ApiPlatform\Metadata\ApiResource;
-use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
+use ApiPlatform\Metadata\GetCollection;
 use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
-use ApiPlatform\Doctrine\Orm\Filter\NumericFilter;
+use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
 use ApiPlatform\Doctrine\Orm\Filter\RangeFilter;
-use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
-use ApiPlatform\Metadata\ApiFilter;
 use App\Filter\ApiPlatform\Utils\DistanceFilter;
 use App\Repository\Public\PublicEventRepository;
-use Doctrine\ORM\Mapping as ORM;
+use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
+use ApiPlatform\Doctrine\Orm\Filter\NumericFilter;
+use App\Filter\ApiPlatform\Utils\ArrayFieldFilter;
 
 /**
  * Évènements publics tels que publiés sur l'agenda du site opentalent ou les sites des structures
@@ -35,11 +36,12 @@ use Doctrine\ORM\Mapping as ORM;
 #[ORM\Entity(repositoryClass: PublicEventRepository::class, readOnly: true)]
 #[ORM\Table(name: "view_public_events")]
 #[ApiFilter(filterClass: SearchFilter::class, properties: ['name' => 'partial', 'city' => 'exact', 'categoryCode' => 'exact', 'origin' => 'exact'])]
-#[ApiFilter(filterClass: NumericFilter::class, properties: ['organizationId', 'price_mini', 'price_maxi'])]
+#[ApiFilter(filterClass: NumericFilter::class, properties: ['organizationId', 'priceMini', 'price_maxi'])]
 #[ApiFilter(filterClass: DateFilter::class, properties: ['datetimeStart', 'datetimeEnd'])]
 #[ApiFilter(filterClass: DistanceFilter::class)]
 #[ApiFilter(filterClass: OrderFilter::class, properties: ['datetimeStart', 'datetimeEnd'], arguments: ['orderParameterName' => 'order'])]
-#[ApiFilter(filterClass: RangeFilter::class, properties: ['price_mini', 'price_maxi'])]
+#[ApiFilter(filterClass: RangeFilter::class, properties: ['priceMini', 'priceMaxi'])]
+#[ApiFilter(filterClass: ArrayFieldFilter::class, properties: ['categories'])]
 
 class PublicEvent
 {
@@ -112,10 +114,10 @@ class PublicEvent
     private int $entityId;
 
     #[ORM\Column]
-    private int $price_mini;
+    private int $priceMini;
 
     #[ORM\Column]
-    private int $price_maxi;
+    private int $priceMaxi;
 
     // categoryCode 
     #[ORM\Column]
@@ -522,16 +524,16 @@ class PublicEvent
      */
     public function getPriceMini(): int
     {
-        return $this->price_mini;
+        return $this->priceMini;
     }
 
     /**
-     * @param int $price_mini
+     * @param int $priceMini
      * @return PublicEvent
      */
-    public function setPriceMini(int $price_mini): PublicEvent
+    public function setPriceMini(int $priceMini): PublicEvent
     {
-        $this->price_mini = $price_mini;
+        $this->priceMini = $priceMini;
         return $this;
     }
 
@@ -540,16 +542,16 @@ class PublicEvent
      */
     public function getPriceMaxi(): int
     {
-        return $this->price_maxi;
+        return $this->priceMaxi;
     }
 
     /**
-     * @param int $price_maxi
+     * @param int $priceMaxi
      * @return PublicEvent
      */
-    public function setPriceMaxi(int $price_maxi): PublicEvent
+    public function setPriceMaxi(int $priceMaxi): PublicEvent
     {
-        $this->price_maxi = $price_maxi;
+        $this->priceMaxi = $priceMaxi;
         return $this;
     }
 

+ 86 - 0
src/Filter/ApiPlatform/Utils/ArrayFieldFilter.php

@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Filter\ApiPlatform\Utils;
+
+use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
+use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
+use Doctrine\ORM\QueryBuilder;
+use ApiPlatform\Metadata\Operation;
+
+/**
+ * Cette classe est un filtre personnalisé pour les champs de type array
+ * Elle recherche des correspondances partielles dans un champ de type array JSON
+ * 
+ * différences avec le filtre InFilter:
+ * - ArrayFieldFilter recherche des correspondances partielles
+ * - InFilter utilise la clause SQL IN pour rechercher des correspondances exactes
+ * - Format est différent : pour ArrayFieldFilter, le format est un tableau JSON,
+ *  pour InFilter, le format est une liste CSV
+ */
+class ArrayFieldFilter extends AbstractFilter
+{
+    /**
+     * @param string $property
+     * @param mixed $value
+     * @param QueryBuilder $queryBuilder
+     * @param QueryNameGeneratorInterface $queryNameGenerator
+     * @param string $resourceClass
+     * @param Operation|null $operation
+     * @param array<mixed> $context
+     */
+    protected function filterProperty(
+        string $property,
+        $value,
+        QueryBuilder $queryBuilder,
+        QueryNameGeneratorInterface $queryNameGenerator,
+        string $resourceClass,
+        ?Operation $operation = null,
+        array $context = []
+    ): void {
+        if (!$this->isPropertyEnabled($property, $resourceClass)) {
+            return;
+        }
+
+        $parameterName = $queryNameGenerator->generateParameterName($property);
+        $valueArray = json_decode($value, true);
+
+        if (is_array($valueArray)) {
+            $queryBuilder->andWhere($queryBuilder->expr()->orX(
+                ...array_map(function ($val) use ($queryBuilder, $property, $parameterName) {
+                    return $queryBuilder->expr()->like(sprintf('o.%s', $property), ':' . $parameterName);
+                }, $valueArray)
+            ));
+            foreach ($valueArray as $key => $val) {
+                $queryBuilder->setParameter($parameterName, '%' . $val . '%');
+            }
+        } else {
+            $queryBuilder->andWhere(sprintf('o.%s LIKE :%s', $property, $parameterName))
+                ->setParameter($parameterName, '%' . $value . '%');
+        }
+    }
+
+    /**
+     * @param string $resourceClass
+     * @return array<string, mixed>
+     */
+    public function getDescription(string $resourceClass): array
+    {
+        if (!$this->properties) {
+            return [];
+        }
+
+        $description = [];
+        foreach ($this->properties as $property => $strategy) {
+            $description[$property] = [
+                'property' => $property,
+                'type' => 'array',
+                'required' => false,
+                'swagger' => ['description' => "Filter by $property"],
+            ];
+        }
+
+        return $description;
+    }
+}