| @@ -365,6 +365,18 @@ paths: | |||
| style: form | |||
| explode: true | |||
| allowReserved: false | |||
| - | |||
| name: partnerProduct.product.name | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| deprecated: false | |||
| post: | |||
| operationId: api_contact_partner_products_post | |||
| @@ -4534,6 +4546,10 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| partnerProduct: | |||
| readOnly: true | |||
| description: '?PartnerProduct' | |||
| $ref: '#/components/schemas/PartnerProduct' | |||
| product: | |||
| readOnly: true | |||
| description: '?ProductApi' | |||
| @@ -4576,6 +4592,10 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| partnerProduct: | |||
| readOnly: true | |||
| description: '?PartnerProduct' | |||
| $ref: '#/components/schemas/PartnerProduct.jsonhal' | |||
| product: | |||
| readOnly: true | |||
| description: '?ProductApi' | |||
| @@ -4632,6 +4652,10 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| partnerProduct: | |||
| readOnly: true | |||
| description: '?PartnerProduct' | |||
| $ref: '#/components/schemas/PartnerProduct.jsonld' | |||
| product: | |||
| readOnly: true | |||
| description: '?ProductApi' | |||
| @@ -5418,6 +5442,7 @@ components: | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| product: | |||
| readOnly: true | |||
| description: '?ProductApi' | |||
| 'owl:maxCardinality': 1 | |||
| $ref: '#/components/schemas/Product' | |||
| @@ -5464,6 +5489,7 @@ components: | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| product: | |||
| readOnly: true | |||
| description: '?ProductApi' | |||
| 'owl:maxCardinality': 1 | |||
| $ref: '#/components/schemas/Product.jsonhal' | |||
| @@ -5524,6 +5550,7 @@ components: | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| product: | |||
| readOnly: true | |||
| description: '?ProductApi' | |||
| 'owl:maxCardinality': 1 | |||
| $ref: '#/components/schemas/Product.jsonld' | |||
| @@ -5613,6 +5640,7 @@ components: | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| numComments: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| @@ -5761,6 +5789,7 @@ components: | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| numComments: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| @@ -5916,6 +5945,7 @@ components: | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| numComments: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| @@ -6505,6 +6535,11 @@ components: | |||
| type: | |||
| - boolean | |||
| - 'null' | |||
| numTaskNotes: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| createdAt: | |||
| readOnly: true | |||
| type: | |||
| @@ -6609,6 +6644,11 @@ components: | |||
| type: | |||
| - boolean | |||
| - 'null' | |||
| numTaskNotes: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| createdAt: | |||
| readOnly: true | |||
| type: | |||
| @@ -6727,6 +6767,11 @@ components: | |||
| type: | |||
| - boolean | |||
| - 'null' | |||
| numTaskNotes: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| createdAt: | |||
| readOnly: true | |||
| type: | |||
| @@ -45,6 +45,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| // security: 'is_granted("ROLE_ADMIN")', | |||
| // ) | |||
| ], | |||
| order: ['createdAt' => 'DESC'], | |||
| security: 'is_granted("ROLE_USER")', | |||
| provider: EntityToDtoStateProvider::class, | |||
| processor: EntityClassDtoStateProcessor::class, | |||
| @@ -13,6 +13,7 @@ use ApiPlatform\Metadata\ApiFilter; | |||
| use ApiPlatform\Metadata\ApiProperty; | |||
| use ApiPlatform\Metadata\ApiResource; | |||
| use App\Entity\ContactPartnerProduct; | |||
| use App\Entity\PartnerProduct; | |||
| use App\State\EntityClassDtoStateProcessor; | |||
| use App\State\EntityToDtoStateProvider; | |||
| use ApiPlatform\Metadata\Delete; | |||
| @@ -43,7 +44,10 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| processor: EntityClassDtoStateProcessor::class, | |||
| stateOptions: new Options(entityClass: ContactPartnerProduct::class), | |||
| )] | |||
| #[ApiFilter(SearchFilter::class, properties: ['contact' => 'exact'])] | |||
| #[ApiFilter(SearchFilter::class, properties: [ | |||
| 'contact' => 'exact', | |||
| 'partnerProduct.product.name' => 'ipartial', | |||
| ])] | |||
| class ContactPartnerProductApi | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| @@ -55,6 +59,22 @@ class ContactPartnerProductApi | |||
| #[NotBlank] | |||
| public ?PartnerProductApi $partnerProductIri = null; | |||
| /** | |||
| * @var $product ?PartnerProduct | |||
| */ | |||
| #[ApiProperty( | |||
| writable: false, | |||
| readableLink: true, | |||
| writableLink: false, | |||
| builtinTypes: [ | |||
| new Type( | |||
| 'object', | |||
| class: PartnerProductApi::class, | |||
| ) | |||
| ] | |||
| )] | |||
| public ?PartnerProductApi $partnerProduct = null; | |||
| /** | |||
| * @var $product ?ProductApi | |||
| */ | |||
| @@ -71,15 +71,16 @@ class PartnerProductApi | |||
| public ?PartnerApi $partner = null; | |||
| #[NotBlank] | |||
| #[ApiProperty(writable: true)] | |||
| public ?PartnerApi $partnerIri = null; | |||
| /** | |||
| * @var $product ?ProductApi | |||
| */ | |||
| #[ApiProperty( | |||
| writable: true, | |||
| writable: false, | |||
| readableLink: true, | |||
| writableLink: true, | |||
| writableLink: false, | |||
| builtinTypes: [ | |||
| new Type( | |||
| 'object', | |||
| @@ -90,6 +91,7 @@ class PartnerProductApi | |||
| public ?ProductApi $product = null; | |||
| #[NotBlank] | |||
| #[ApiProperty(writable: true)] | |||
| public ?ProductApi $productIri = null; | |||
| #[ApiProperty(writable: false)] | |||
| @@ -173,6 +173,7 @@ class PostingApi implements OwnerInterface | |||
| #[Groups(['posting:create'])] | |||
| public ?SaleApi $saleIri = null; | |||
| #[ApiProperty(writable: false)] | |||
| public ?int $numComments = null; | |||
| #[ApiProperty(writable: false)] | |||
| @@ -167,6 +167,9 @@ class TaskApi | |||
| #[Assert\NotNull] | |||
| public ?bool $completed = null; | |||
| #[ApiProperty(writable: false)] | |||
| public ?int $numTaskNotes = null; | |||
| #[ApiProperty(writable: false)] | |||
| public ?\DateTimeImmutable $createdAt = null; | |||
| @@ -41,6 +41,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||
| // security: 'is_granted("ROLE_ADMIN")', | |||
| // ) | |||
| ], | |||
| order: ['createdAt' => 'DESC'], | |||
| security: 'is_granted("ROLE_USER")', | |||
| provider: EntityToDtoStateProvider::class, | |||
| processor: EntityClassDtoStateProcessor::class, | |||
| @@ -53,7 +53,7 @@ class ContactPartnerProductApiToEntityMapper implements MapperInterface | |||
| assert($contact instanceof Contact); | |||
| assert($partnerProduct instanceof PartnerProduct); | |||
| $entity = new PartnerProduct($contact, $partnerProduct); | |||
| $entity = new ContactPartnerProduct($contact, $partnerProduct); | |||
| } | |||
| if (!$entity) { | |||
| @@ -66,9 +66,9 @@ class ContactPartnerProductApiToEntityMapper implements MapperInterface | |||
| public function populate(object $from, object $to, array $context): object | |||
| { | |||
| $dto = $from; | |||
| assert($dto instanceof PartnerProductApi); | |||
| assert($dto instanceof ContactPartnerProductApi); | |||
| $entity = $to; | |||
| assert($entity instanceof PartnerProduct); | |||
| assert($entity instanceof ContactPartnerProduct); | |||
| return $entity; | |||
| } | |||
| } | |||
| @@ -47,6 +47,13 @@ class ContactPartnerProductEntityToApiMapper implements MapperInterface | |||
| MicroMapperInterface::MAX_DEPTH => 1, | |||
| ]); | |||
| $dto->partnerProduct = null; | |||
| if ($entity->getPartnerProduct() !== null) { | |||
| $dto->partnerProduct = $this->microMapper->map($entity->getPartnerProduct(), PartnerProductApi::class, [ | |||
| MicroMapperInterface::MAX_DEPTH => 1, | |||
| ]); | |||
| } | |||
| $dto->product = null; | |||
| if ($entity->getPartnerProduct() !== null && $entity->getPartnerProduct()->getProduct() !== null) { | |||
| $dto->product = $this->microMapper->map($entity->getPartnerProduct()->getProduct(), ProductApi::class, [ | |||
| @@ -34,7 +34,7 @@ class PartnerFollowApiToEntityMapper implements MapperInterface | |||
| } else { | |||
| $user = $this->security->getUser(); | |||
| assert($user instanceof User); | |||
| if ($dto->partner === null) { | |||
| if ($dto->partnerIri === null) { | |||
| throw new \Exception('Partner missing'); | |||
| } | |||
| $partner = $this->microMapper->map($dto->partnerIri, Partner::class, [ | |||
| @@ -83,6 +83,8 @@ class TaskEntityToApiMapper implements MapperInterface | |||
| MicroMapperInterface::MAX_DEPTH => 1, | |||
| ]); | |||
| $dto->numTaskNotes = count($entity->getTaskNotes()); | |||
| $dto->prio = $entity->getPrio(); | |||
| $dto->completed = $entity->getCompleted(); | |||
| $dto->createdAt = $entity->getCreatedAt(); | |||
| @@ -28,12 +28,14 @@ class EntityToDtoStateProvider implements ProviderInterface | |||
| $resourceClass = $operation->getClass(); | |||
| if ($operation instanceof CollectionOperationInterface) { | |||
| $entities = $this->collectionProvider->provide($operation, $uriVariables, $context); | |||
| assert($entities instanceof Paginator); | |||
| $dtos = []; | |||
| foreach ($entities as $entity) { | |||
| $dtos[] = $this->mapEntityToDto($entity, $resourceClass); | |||
| } | |||
| return $dtos; | |||
| return new TraversablePaginator( | |||
| new \ArrayIterator($dtos), | |||