【问题标题】:Get collection without deleted resources API-Platform获取不删除资源的集合 API-Platform
【发布时间】:2021-08-03 08:38:25
【问题描述】:

如何在不使用 API-Platform 删除相关资源的情况下选择资源? 我有这种关系 Don ManyTOOne Donateur。在 Don 资源中,我将 $isDeleted 作为字段。当它的值为 true 并尝试从 Donateur 中选择一个项目时,我明白了。 在此处显示:

// The GET operation http://localhost:8000/api/donateurs/3
{
  "@context": "\/api\/contexts\/Donateur",
  "@id": "\/api\/donateurs\/3",
  "@type": "Donateur",
  "id": 3,
  "nom": "Yazid Ibn Amr",
  "solde": 135000,
  "isDeleted": false,
  "dons": [
    {
      "@id": "\/api\/dons\/1",
      "@type": "Don",
      "id": 1,
      "date": "2021-07-26T00:00:00+00:00",
      "montant": 35000,
      "isDeleted": true
    },
    {
      "@id": "\/api\/dons\/2",
      "@type": "Don",
      "id": 2,
      "date": "2021-07-28T00:00:00+00:00",
      "montant": 60000,
      "isDeleted": false
    },
    {
      "@id": "\/api\/dons\/3",
      "@type": "Don",
      "id": 3,
      "date": "2021-07-28T00:00:00+00:00",
      "montant": 75000,
      "isDeleted": false
    }
  ]
}

在获取 Donateur 项目时,我不需要在此返回的 Don 集合中删除资源。

这是我的代码

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use App\Repository\DonRepository;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;

/**
 * @ApiResource(
 *      normalizationContext={
 *          "groups"={
 *              "read:Don:item",
 *              "read:Don:collection"
 *          }
 *      },
 *      denormalizationContext={
 *          "groups"={
 *              "write:Don"
 *          }
 *      },
 *      collectionOperations={
 *          "get", "post"
 *      },
 *      itemOperations={
 *          "get"={
 *              "normalization_context"={
 *                  "groups"={
 *                      "read:Don:item",
 *                      "read:Don:collection"
 *                  }
 *              }
 *          }, 
 *          "patch", "delete"
 *      }
 * )
 * @ORM\Entity(repositoryClass=DonRepository::class)
 */
class Don
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @Groups({"read:Donateur:item"})
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity=Donateur::class, inversedBy="dons")
     * @ORM\JoinColumn(nullable=false)
     * @Groups({"read:Don:collection", "write:Don"})
     */
    private $donateur;

    /**
     * @ORM\Column(type="date", nullable=true)
     * @Groups({"read:Don:collection", "write:Don", "read:Donateur:item"})
     */
    private $date;

    /**
     * @ORM\Column(type="float")
     * @Groups({"read:Don:collection", "write:Don", "read:Donateur:item"})
     */
    private $montant;

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\DonateurRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;

/**
 * @ApiResource(
 *      normalizationContext={
 *          "groups"={
 *              "read:Donateur:item",
 *              "read:Donateur:collection"
 *          }
 *      },
 *      denormalizationContext={
 *          "groups"={
 *              "write:Donateur"
 *          }
 *      },
 *      collectionOperations={
 *          "get", "post"
 *      },
 *      itemOperations={
 *          "get", "patch", "delete"
 *      }
 * )
 * @ORM\Entity(repositoryClass=DonateurRepository::class)
 */
class Donateur
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @Groups("read:Donateur:collection")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Groups({"read:Donateur:collection", "write:Donateur"})
     */
    private $nom;

    /**
     * @ORM\Column(type="text", nullable=true)
     * @Groups({"read:Donateur:collection", "write:Donateur"})
     */
    private $presentation;


    /**
     * @ORM\Column(type="float")
     * @Groups({"read:Donateur:collection", "write:Don"})
     */
    private $solde;

    /**
     * @ORM\Column(type="boolean")
     * @Groups("read:Donateur:collection")
     */
    private $isDeleted;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $createdAt;

    /**
     * @ORM\ManyToOne(targetEntity=User::class)
     */
    private $createdBy;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $updatedAt;

    /**
     * @ORM\ManyToOne(targetEntity=User::class)
     */
    private $updatedBy;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $deletedAt;

    /**
     * @ORM\ManyToOne(targetEntity=User::class)
     */
    private $deletedBy;

    /**
     * @ORM\OneToMany(targetEntity=Don::class, mappedBy="donateur")
     * @Groups({"read:Donateur:item"})
     */
    private $dons;

还有这个

<?php

namespace App\Doctrine;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryItemExtensionInterface;
use Doctrine\ORM\QueryBuilder;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use App\Entity\Don;
use App\Entity\Donateur;
use App\Entity\TypeOeuvre;

class NoneDeletedResources implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
{
    public function addWhere(QueryBuilder $queryBuilder, string $resourceClass)
    {
        if($resourceClass === TypeOeuvre::class or $resourceClass === Don::class or $resourceClass === Donateur::class){
            $rootAlias = $queryBuilder->getRootAliases()[0];
            $queryBuilder->andWhere("$rootAlias.isDeleted = :isDeleted");
            $queryBuilder->orderBy("$rootAlias.id", "DESC");
            $queryBuilder->setParameter("isDeleted", false);
        }
    }

    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?string $operationName = null)
    {
        $this->addWhere($queryBuilder, $resourceClass);
    }
    
    public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, ?string $operationName = null, array $context = [])
    {
        // dd($context);
        $this->addWhere($queryBuilder, $resourceClass);
    }
}

感谢您的帮助

【问题讨论】:

  • 我的回答对您有帮助吗?如果没有,请告诉我如何改进我的答案。
  • 它适用于这种关系。但是当我尝试执行另一个时它不起作用并且我得到一个错误。
  • 当然,我没有写你所有的查询;)但很高兴听到它对你有帮助。

标签: symfony doctrine-orm doctrine api-platform.com


【解决方案1】:
$queryBuilder->andWhere("$rootAlias.isDeleted = :isDeleted");

使用此代码,您只过滤根别名,而不是它的关系。您应该修改您的代码,使其也能过滤这些关系。

public function addWhere(QueryBuilder $queryBuilder, string $resourceClass)
{
    if($resourceClass === Donateur::class) {
        $rootAlias = $queryBuilder->getRootAliases()[0];
        $queryBuilder->andWhere("$rootAlias.isDeleted = :isDeleted");
        $queryBuilder->orderBy("$rootAlias.id", "DESC");
        $queryBuilder->setParameter("isDeleted", false);

        // add something like this:
        $queryBuilder->andWhere("dons.isDeleted = :isDeleted");
    }
}

别名的确切名称(我以dons 为例)取决于您的用例。也许你应该先加入Don,然后才能使用它。

我希望您可以使用我的建议来解决您的问题。如果没有,请告诉我;我会帮忙添加一些实现细节。

【讨论】:

    【解决方案2】:
    public function addWhere(QueryBuilder $queryBuilder, string $resourceClass)
        {
            if($resourceClass === TypeOeuvre::class or $resourceClass === Don::class or $resourceClass === Donateur::class or $resourceClass === Oeuvre::class or $resourceClass === DonOeuvre::class){
                $rootAlias = $queryBuilder->getRootAliases()[0];
                if($resourceClass === Donateur::class) {
                    $queryBuilder->join("$rootAlias.dons", "d");
                    $queryBuilder->andWhere("d.isDeleted = :isDeleted");
                }
    
                if($resourceClass === Oeuvre::class or $resourceClass === Don::class) {
                    $queryBuilder->join("$rootAlias.donOeuvres", "d");
                    $queryBuilder->andWhere("d.isDeleted = :isDeleted");
                    // dd($queryBuilder);
                }
                $queryBuilder->andWhere("$rootAlias.isDeleted = :isDeleted");
                $queryBuilder->orderBy("$rootAlias.id", "DESC");
                $queryBuilder->setParameter("isDeleted", false);
            }
        }
    

    第一个 if 工作正常。但不是第二个 这是我的资源代码:

    Don.php

    <?php
    
    namespace App\Entity;
    
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;
    use Doctrine\ORM\Mapping as ORM;
    use App\Repository\DonRepository;
    use ApiPlatform\Core\Annotation\ApiResource;
    use Symfony\Component\Serializer\Annotation\Groups;
    
    /**
     * @ApiResource(
     *      normalizationContext={
     *          "groups"={
     *              "read:Don:item",
     *              "read:Don:collection"
     *          }
     *      },
     *      denormalizationContext={
     *          "groups"={
     *              "write:Don"
     *          }
     *      },
     *      collectionOperations={
     *          "get", "post"
     *      },
     *      itemOperations={
     *          "get"={
     *              "normalization_context"={
     *                  "groups"={
     *                      "read:Don:item",
     *                      "read:Don:collection"
     *                  }
     *              }
     *          }, 
     *          "utilisation_don" = {
     *              "path" = "/{id}/utilisation-don,
     *              "controller" =
     *          }
     *          "patch", "delete"
     *      }
     * )
     * @ORM\Entity(repositoryClass=DonRepository::class)
     */
    class Don
    {
        /**
         * @ORM\Id
         * @ORM\GeneratedValue
         * @ORM\Column(type="integer")
         * @Groups({"read:Donateur:item"})
         */
        private $id;
    
        ...
    
        /**
         * @ORM\OneToMany(targetEntity=DonOeuvre::class, mappedBy="don")
         */
        private $donOeuvres;
    

    Oeuvre.php

    <?php
    
    namespace App\Entity;
    
    use ApiPlatform\Core\Annotation\ApiResource;
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;
    use Symfony\Component\Serializer\Annotation\Groups;
    use App\Repository\OeuvreRepository;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ApiResource(
     *      normalizationContext={
     *          "groups"={
     *              "read:Oeuvre:collection"
     *          }
     *      },
     *      denormalizationContext={
     *          "groups"={
     *              "write:Oeuvre"
     *          }
     *      },
     *      collectionOperations={
     *          "get", 
     *          "post" = {
     *              "denormalization_context"={
     *                  "groups"={
     *                      "write:Oeuvre"
     *                  }
    *               }
     *          }
     *      },
     *      itemOperations={
     *          "get", 
     *          "patch" = {
     *              "denormalization_context"={
     *                  "groups"={
     *                      "update:Oeuvre:patch"
     *                  }
    *               }
     *          }, 
     *          "delete"
     *      }
     * )
     * @ORM\Entity(repositoryClass=OeuvreRepository::class)
     */
    class Oeuvre
    {
        /**
         * @ORM\Id
         * @ORM\GeneratedValue
         * @ORM\Column(type="integer")
         * @Groups("read:Oeuvre:collection")
         */
        private $id;
    
        ...
    
        /**
         * @ORM\OneToMany(targetEntity=DonOeuvre::class, mappedBy="oeuvre")
         * @Groups({"write:Oeuvre"})
         */
        private $donOeuvres;
    

    和 DonOeuvre.php

    <?php
    
    namespace App\Entity;
    
    use ApiPlatform\Core\Annotation\ApiResource;
    use App\Repository\DonOeuvreRepository;
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Serializer\Annotation\Groups;
    
    /**
     * @ApiResource(
     *      normalizationContext={
     *          "groups"={
     *              "read:DonOeuvre:collection"
     *          }
     *      },
     *      denormalizationContext={
     *          "groups"={
     *              "write:DonOeuvre"
     *          }
     *      },
     *      collectionOperations={
     *          "get", "post"
     *      },
     *      itemOperations={
     *          "get", "patch", "delete"
     *      }
     * )
     * @ORM\Entity(repositoryClass=DonOeuvreRepository::class)
     */
    class DonOeuvre
    {
        /**
         * @ORM\Id
         * @ORM\GeneratedValue
         * @ORM\Column(type="integer")
         * @Groups({"read:DonOeuvre:collection", "read:Don:item"})
         */
        private $id;
    
        /**
         * @ORM\ManyToOne(targetEntity=Don::class, inversedBy="donOeuvres")
         * @ORM\JoinColumn(nullable=false)
         * @Groups({"read:DonOeuvre:collection", "write:DonOeuvre", "write:Oeuvre"})
         */
        private $don;
    
        /**
         * @ORM\ManyToOne(targetEntity=Oeuvre::class, inversedBy="donOeuvres", cascade={"persist"})
         * @ORM\JoinColumn(nullable=false)
         * @Groups({"read:DonOeuvre:collection", "write:DonOeuvre", "read:Don:item"})
         */
        private $oeuvre;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-05
      • 1970-01-01
      • 2023-03-12
      • 2020-06-25
      • 2020-07-04
      • 2020-03-30
      • 2020-12-23
      • 1970-01-01
      相关资源
      最近更新 更多