src/Entity/Affiliation.php line 81

  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM,
  4.     Doctrine\DBAL\Types\Types,
  5.     Doctrine\Common\Collections\Collection,
  6.     Doctrine\Common\Collections\ArrayCollection;
  7. use Symfony\Component\Serializer\Annotation\Groups,
  8.     Symfony\Component\Validator\Constraints as Assert;
  9. use ApiPlatform\Metadata\ApiResource,
  10.     ApiPlatform\Metadata\ApiProperty,
  11.     ApiPlatform\Metadata\Get,
  12.     ApiPlatform\Metadata\GetCollection,
  13.     ApiPlatform\Metadata\Post,
  14.     ApiPlatform\Metadata\Put,
  15.     ApiPlatform\Metadata\Delete,
  16.     ApiPlatform\Metadata\ApiFilter,
  17.     ApiPlatform\Doctrine\Orm\Filter\SearchFilter,
  18.     ApiPlatform\Doctrine\Orm\Filter\ExistsFilter,
  19.     ApiPlatform\Doctrine\Orm\Filter\BooleanFilter,
  20.     ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
  21. use App\Entity\Trait\IdTrait,
  22.     App\Entity\Trait\UuidTrait,
  23.     App\Entity\Trait\OrdStatTrait,
  24.     App\Entity\Trait\TimestampableTrait,
  25.     App\Entity\Trait\TranslatableTrait,
  26.     App\Entity\Trait\Languages\SiteLanguagesTrait,
  27.     App\Entity\Trait\DepthTrait,
  28.     App\Entity\Trait\ImportIdTrait,
  29.     App\Entity\Interface\TranslatableInterface,
  30.     App\Entity\Interface\OrdStatableInterface,
  31.     App\Entity\Interface\ParentableInterface,
  32.     App\Entity\Interface\LanguageableInterface,
  33.     App\Repository\AffiliationRepository,
  34.     App\Enum\Country,
  35.     App\Enum\Language,
  36.     App\Filter\IriFilter;
  37. use App\Attribute\DenormalizationPriority,
  38.     App\Doctrine\DBAL\Types\LanguagesType;
  39. use App\Validator\Constraints as CustomAssert;
  40. #[ApiResource(
  41.     description'Affiliations',
  42.     normalizationContext: ['groups' => [
  43.         'read',
  44.         'read:' self::class,
  45.         'read:' self::class . 'Translation',
  46.         'single:read:' self::class ,
  47.     ]],
  48.     denormalizationContext: ['groups' => ['write']],
  49.     security'is_granted("' self::class . '")',
  50.     order: ['ord' => 'desc'],
  51.     operations: [
  52.         new GetCollection(paginationMaximumItemsPerPage500normalizationContext: ['groups' => [
  53.             'read',
  54.             'read:' self::class,
  55.             'read:' self::class . 'Translation'
  56.         ]]),
  57.         new Post(denormalizationContext: ['groups' => ['write''post']]),
  58.         new Get(),
  59.         new Put(),
  60.         new Delete(),
  61.     ],
  62.     extraProperties: ['standard_put' => false],
  63. )]
  64. #[ApiFilter(SearchFilter::class, properties: [
  65.     'translations.title' => 'partial',
  66.     'nativeTitle' => 'partial',
  67.     'ror' => 'partial'
  68. ])]
  69. #[ApiFilter(ExistsFilter::class, properties: ['parent''country'])]
  70. #[ApiFilter(IriFilter::class, properties: ['parent''country'])]
  71. #[ApiFilter(BooleanFilter::class, properties: ['stat'])]
  72. #[ApiFilter(OrderFilter::class, properties: ['nativeTitle''ord'])]
  73. #[ORM\Entity(repositoryClassAffiliationRepository::class)]
  74. class Affiliation implements TranslatableInterfaceOrdStatableInterfaceParentableInterfaceLanguageableInterface
  75. {
  76.     use IdTrait,
  77.         UuidTrait,
  78.         OrdStatTrait,
  79.         TimestampableTrait,
  80.         TranslatableTrait,
  81.         SiteLanguagesTrait,
  82.         DepthTrait,
  83.         ImportIdTrait;
  84.     #[ApiProperty(description'Parent affiliation'readableLinkfalsewritableLinkfalse)]
  85.     #[Groups(['read:' self::class, 'write'])]
  86.     #[CustomAssert\Depth(max3)]
  87.     #[ORM\ManyToOne(targetEntityself::class, inversedBy'children')]
  88.     #[ORM\JoinColumn(onDelete'cascade')]
  89.     private ?self $parent null;
  90.     #[ApiProperty(description'Root affiliation'readableLinktrue)]
  91.     #[Groups(['read:' self::class])]
  92.     #[ORM\ManyToOne(targetEntityself::class)]
  93.     #[ORM\JoinColumn(onDelete'cascade'nullabletrue)]
  94.     private ?self $root;
  95.     #[ApiProperty(description'Address')]
  96.     #[Groups(['single:read:' self::class, 'write'])]
  97.     #[ORM\Column(typeTypes::TEXTnullabletrue)]
  98.     private ?string $address null;
  99.     #[ApiProperty(description'Website')]
  100.     #[Groups(['read:' self::class, 'write'])]
  101.     #[ORM\Column(typeTypes::STRINGnullabletrue)]
  102.     private ?string $website null;
  103.     #[ApiProperty(description'E-mail')]
  104.     #[Groups(['read:' self::class, 'write'])]
  105.     #[Assert\Email]
  106.     #[ORM\Column(typeTypes::STRINGnullabletrue)]
  107.     private ?string $email null;
  108.     #[ApiProperty(description'ROR')]
  109.     #[Groups(['read:' self::class, 'write:depth:0'])]
  110.     #[ORM\Column(typeTypes::STRINGnullabletrue)]
  111.     private ?string $ror null;
  112.     #[ApiProperty(description'GRID')]
  113.     #[Groups(['read:' self::class, 'write:depth:0'])]
  114.     #[ORM\Column(typeTypes::STRINGnullabletrue)]
  115.     private ?string $grid null;
  116.     #[ApiProperty(description'ISNI')]
  117.     #[Groups(['read:' self::class, 'write:depth:0'])]
  118.     #[ORM\Column(typeTypes::STRINGnullabletrue)]
  119.     private ?string $isni null;
  120.     #[ApiProperty(description'Country'writableLinkfalse)]
  121.     #[Groups(['read:' self::class, 'read:stats''write:depth:0'])]
  122.     #[ORM\Column(typeTypes::STRINGenumTypeCountry::class, length255nullabletrue)]
  123.     private ?Country $country null;
  124.     #[ApiProperty(description'Type of affiliation'writableLinkfalse)]
  125.     #[Groups(['read:' self::class, 'write:depth:0'])]
  126.     #[ORM\ManyToOne(targetEntityAffiliationType::class, inversedBy'affiliations')]
  127.     #[ORM\JoinColumn(onDelete'set null')]
  128.     private ?AffiliationType $type null;
  129.     #[ApiProperty(description'Children affiliations'writableLinkfalse)]
  130.     #[Groups(['read:' self::class])]
  131.     #[ORM\OneToMany(targetEntityself::class, mappedBy'parent')]
  132.     #[ORM\OrderBy(['ord' => 'desc'])]
  133.     private Collection $children;
  134.     #[ApiProperty(description'Languages'writableLinkfalse)]
  135.     #[Groups(['single:read:' self::class, 'write'])]
  136.     #[Assert\Choice(callback: [Language::class, 'cases'], multipletrue)]
  137.     #[Assert\Unique]
  138.     #[Assert\Count(min2)]
  139.     #[CustomAssert\DefaultLanguagesRequired(requiredLanguage::DEFAULT_SITE)]
  140.     #[DenormalizationPriority(DenormalizationPriority::TOP)]
  141.     #[ORM\Column(typeLanguagesType::NAME)]
  142.     protected array $languages = [];
  143.     #[ApiProperty(description'BPN')]
  144.     #[Groups(['read:' self::class, 'write:depth:0'])]
  145.     #[ORM\Column(typeTypes::STRINGnullabletrue)]
  146.     private ?string $bpn null;
  147.     #[ApiProperty(description'Funder id')]
  148.     #[Groups(['read:' self::class, 'write:depth:0'])]
  149.     #[ORM\Column(typeTypes::STRINGnullabletrue)]
  150.     private ?string $funderId null;
  151.     public function __construct(?Affiliation $parent, ?array $languages)
  152.     {
  153.         $this->setUuid();
  154.         $this->parent $parent;
  155.         $this->root $this->getRootFrom($this);
  156.         $this->translations = new ArrayCollection();
  157.         $this->children = new ArrayCollection();
  158.         $this->setLanguages($languages ?? Language::DEFAULT_SITE);
  159.         $this->createdAt = new \DateTimeImmutable();
  160.         $this->updatedAt = new \DateTimeImmutable();
  161.         $parent?->addChild($this);
  162.     }
  163.     public function getParent(): ?self
  164.     {
  165.         return $this->parent;
  166.     }
  167.     public function setParent(?Affiliation $parent): self
  168.     {
  169.         $this->parent $parent;
  170.         $this->root $this->getRootFrom($this);
  171.         return $this;
  172.     }
  173.     public function getRoot(): self
  174.     {
  175.         return $this->root;
  176.     }
  177.     public function getRootFrom(Affiliation $current): Affiliation
  178.     {
  179.         if (! $current->getParent()) {
  180.             return $current;
  181.         }
  182.         return $this->getRootFrom($current->getParent());
  183.     }
  184.     public function getAddress(): ?string
  185.     {
  186.         return $this->address;
  187.     }
  188.     public function setAddress(?string $address): self
  189.     {
  190.         $this->address $address;
  191.         return $this;
  192.     }
  193.     public function getWebsite(): ?string
  194.     {
  195.         return $this->website;
  196.     }
  197.     public function setWebsite(?string $website): self
  198.     {
  199.         $this->website $website;
  200.         return $this;
  201.     }
  202.     public function getEmail(): ?string
  203.     {
  204.         return $this->email;
  205.     }
  206.     public function setEmail(?string $email): self
  207.     {
  208.         $this->email $email;
  209.         return $this;
  210.     }
  211.     public function getRor(): ?string
  212.     {
  213.         return $this->ror;
  214.     }
  215.     public function setRor(?string $ror): self
  216.     {
  217.         $this->ror $ror;
  218.         return $this;
  219.     }
  220.     public function getGrid(): ?string
  221.     {
  222.         return $this->grid;
  223.     }
  224.     public function setGrid(?string $grid): self
  225.     {
  226.         $this->grid $grid;
  227.         return $this;
  228.     }
  229.     public function getIsni(): ?string
  230.     {
  231.         return $this->isni;
  232.     }
  233.     public function setIsni(?string $isni): self
  234.     {
  235.         $this->isni $isni;
  236.         return $this;
  237.     }
  238.     public function getCountry(): ?Country
  239.     {
  240.         return $this->country;
  241.     }
  242.     public function setCountry(?Country $country): self
  243.     {
  244.         $this->country $country;
  245.         return $this;
  246.     }
  247.     public function getType(): ?AffiliationType
  248.     {
  249.         return $this->type;
  250.     }
  251.     public function setType(?AffiliationType $type): self
  252.     {
  253.         $this->type $type;
  254.         return $this;
  255.     }
  256.     /**
  257.      * @return Collection|Affiliation[]
  258.      */
  259.     public function getChildren(): Collection
  260.     {
  261.         return $this->children;
  262.     }
  263.     public function addChild(self $child): self
  264.     {
  265.         if ($this->children->contains($child)) {
  266.             return $this;
  267.         }
  268.         $this->children[] = $child;
  269.         return $this;
  270.     }
  271.     public function removeChild(self $child): self
  272.     {
  273.         $this->children->removeElement($child);
  274.         return $this;
  275.     }
  276.     public function getClosestTree(int $reach 4): array
  277.     {
  278.         if ($reach 1) {
  279.             return [$this];
  280.         }
  281.         if (! $this->getParent()) {
  282.             return [$this];
  283.         }
  284.         return [$this, ...$this->getParent()->getClosestTree($reach 1)];
  285.     }
  286.     public function getBpn(): ?string
  287.     {
  288.         return $this->bpn;
  289.     }
  290.     public function setBpn(?string $bpn): self
  291.     {
  292.         $this->bpn $bpn;
  293.         return $this;
  294.     }
  295.     public function getFunderId(): ?string
  296.     {
  297.         return $this->funderId;
  298.     }
  299.     public function setFunderId(?string $funderId): self
  300.     {
  301.         $this->funderId $funderId;
  302.         return $this;
  303.     }
  304. }