| @@ -795,6 +795,58 @@ paths: | |||||
| style: form | style: form | ||||
| explode: false | explode: false | ||||
| allowReserved: false | allowReserved: false | ||||
| - | |||||
| name: partner | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'partner[]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: array | |||||
| items: | |||||
| type: string | |||||
| style: form | |||||
| explode: true | |||||
| allowReserved: false | |||||
| - | |||||
| name: contact | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: string | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | |||||
| name: 'contact[]' | |||||
| in: query | |||||
| description: '' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: true | |||||
| schema: | |||||
| type: array | |||||
| items: | |||||
| type: string | |||||
| style: form | |||||
| explode: true | |||||
| allowReserved: false | |||||
| deprecated: false | deprecated: false | ||||
| post: | post: | ||||
| operationId: api_posts_post | operationId: api_posts_post | ||||
| @@ -1239,6 +1291,7 @@ components: | |||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| imageUrl: | imageUrl: | ||||
| readOnly: true | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| @@ -1304,6 +1357,7 @@ components: | |||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| imageUrl: | imageUrl: | ||||
| readOnly: true | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| @@ -1383,6 +1437,7 @@ components: | |||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| imageUrl: | imageUrl: | ||||
| readOnly: true | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| @@ -1522,6 +1577,7 @@ components: | |||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| logoUrl: | logoUrl: | ||||
| readOnly: true | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| @@ -1593,6 +1649,7 @@ components: | |||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| logoUrl: | logoUrl: | ||||
| readOnly: true | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| @@ -1678,6 +1735,7 @@ components: | |||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| logoUrl: | logoUrl: | ||||
| readOnly: true | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| @@ -1697,8 +1755,13 @@ components: | |||||
| description: '' | description: '' | ||||
| deprecated: false | deprecated: false | ||||
| required: | required: | ||||
| - headline | |||||
| - message | - message | ||||
| properties: | properties: | ||||
| headline: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| message: | message: | ||||
| type: | type: | ||||
| - string | - string | ||||
| @@ -1710,6 +1773,23 @@ components: | |||||
| - 'null' | - 'null' | ||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| ownerName: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| partner: | |||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/Partner' | |||||
| - | |||||
| type: 'null' | |||||
| contact: | |||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/Contact' | |||||
| - | |||||
| type: 'null' | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -1721,6 +1801,7 @@ components: | |||||
| description: '' | description: '' | ||||
| deprecated: false | deprecated: false | ||||
| required: | required: | ||||
| - headline | |||||
| - message | - message | ||||
| properties: | properties: | ||||
| _links: | _links: | ||||
| @@ -1732,6 +1813,10 @@ components: | |||||
| href: | href: | ||||
| type: string | type: string | ||||
| format: iri-reference | format: iri-reference | ||||
| headline: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| message: | message: | ||||
| type: | type: | ||||
| - string | - string | ||||
| @@ -1743,6 +1828,23 @@ components: | |||||
| - 'null' | - 'null' | ||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| ownerName: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| partner: | |||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/Partner.jsonhal' | |||||
| - | |||||
| type: 'null' | |||||
| contact: | |||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/Contact.jsonhal' | |||||
| - | |||||
| type: 'null' | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -1754,6 +1856,7 @@ components: | |||||
| description: '' | description: '' | ||||
| deprecated: false | deprecated: false | ||||
| required: | required: | ||||
| - headline | |||||
| - message | - message | ||||
| properties: | properties: | ||||
| '@context': | '@context': | ||||
| @@ -1779,6 +1882,10 @@ components: | |||||
| '@type': | '@type': | ||||
| readOnly: true | readOnly: true | ||||
| type: string | type: string | ||||
| headline: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| message: | message: | ||||
| type: | type: | ||||
| - string | - string | ||||
| @@ -1790,6 +1897,23 @@ components: | |||||
| - 'null' | - 'null' | ||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| ownerName: | |||||
| readOnly: true | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| partner: | |||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/Partner.jsonld' | |||||
| - | |||||
| type: 'null' | |||||
| contact: | |||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/Contact.jsonld' | |||||
| - | |||||
| type: 'null' | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -64,6 +64,7 @@ class ContactApi | |||||
| public ?MediaObject $image = null; | public ?MediaObject $image = null; | ||||
| #[ApiProperty(writable: false)] | |||||
| public ?string $imageUrl = null; | public ?string $imageUrl = null; | ||||
| public ?string $position = null; | public ?string $position = null; | ||||
| @@ -77,6 +77,7 @@ class PartnerApi | |||||
| public ?MediaObject $logo = null; | public ?MediaObject $logo = null; | ||||
| #[ApiProperty(writable: false)] | |||||
| public ?string $logoUrl = null; | public ?string $logoUrl = null; | ||||
| public ?\DateTimeImmutable $createdAt = null; | public ?\DateTimeImmutable $createdAt = null; | ||||
| @@ -7,11 +7,11 @@ | |||||
| namespace App\ApiResource; | namespace App\ApiResource; | ||||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | |||||
| use ApiPlatform\Doctrine\Orm\State\Options; | use ApiPlatform\Doctrine\Orm\State\Options; | ||||
| use ApiPlatform\Metadata\ApiFilter; | |||||
| use ApiPlatform\Metadata\ApiProperty; | use ApiPlatform\Metadata\ApiProperty; | ||||
| use ApiPlatform\Metadata\ApiResource; | use ApiPlatform\Metadata\ApiResource; | ||||
| use App\Entity\Contact; | |||||
| use App\Entity\Partner; | |||||
| use App\Entity\Posting; | use App\Entity\Posting; | ||||
| use App\State\EntityClassDtoStateProcessor; | use App\State\EntityClassDtoStateProcessor; | ||||
| use App\State\EntityToDtoStateProvider; | use App\State\EntityToDtoStateProvider; | ||||
| @@ -46,20 +46,27 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| processor: EntityClassDtoStateProcessor::class, | processor: EntityClassDtoStateProcessor::class, | ||||
| stateOptions: new Options(entityClass: Posting::class), | stateOptions: new Options(entityClass: Posting::class), | ||||
| )] | )] | ||||
| #[ApiFilter(SearchFilter::class, properties: ['partner' => 'exact', 'contact' => 'exact'])] | |||||
| class PostingApi | class PostingApi | ||||
| { | { | ||||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | #[ApiProperty(readable: false, writable: false, identifier: true)] | ||||
| public ?int $id = null; | public ?int $id = null; | ||||
| #[NotBlank] | |||||
| public ?string $headline = null; | |||||
| #[NotBlank] | #[NotBlank] | ||||
| public ?string $message = null; | public ?string $message = null; | ||||
| #[IsValidOwner] | #[IsValidOwner] | ||||
| public ?UserApi $owner = null; | public ?UserApi $owner = null; | ||||
| public ?Partner $partner = null; | |||||
| #[ApiProperty(writable: false)] | |||||
| public ?string $ownerName = null; | |||||
| public ?PartnerApi $partner = null; | |||||
| public ?Contact $contact = null; | |||||
| public ?ContactApi $contact = null; | |||||
| #[ApiProperty(writable: false)] | #[ApiProperty(writable: false)] | ||||
| public ?\DateTimeImmutable $createdAt = null; | public ?\DateTimeImmutable $createdAt = null; | ||||
| @@ -71,7 +71,7 @@ class AppFixtures extends Fixture | |||||
| }); | }); | ||||
| PostingFactory::createMany(200, function() { | PostingFactory::createMany(200, function() { | ||||
| $randomBoolean = (bool)rand(0, 1); | |||||
| $randomBoolean = (bool)random_int(0, 1); | |||||
| return [ | return [ | ||||
| 'owner' => UserFactory::random(), | 'owner' => UserFactory::random(), | ||||
| 'partner' => PartnerFactory::random(), | 'partner' => PartnerFactory::random(), | ||||
| @@ -14,7 +14,7 @@ class Posting | |||||
| #[ORM\Column] | #[ORM\Column] | ||||
| private ?int $id = null; | private ?int $id = null; | ||||
| #[ORM\Column(length: 255, nullable: true)] | |||||
| #[ORM\Column(length: 255)] | |||||
| private ?string $headline = null; | private ?string $headline = null; | ||||
| #[ORM\Column(type: Types::TEXT)] | #[ORM\Column(type: Types::TEXT)] | ||||
| @@ -46,9 +46,10 @@ final class PostingFactory extends ModelFactory | |||||
| */ | */ | ||||
| protected function getDefaults(): array | protected function getDefaults(): array | ||||
| { | { | ||||
| $randomBoolean = (bool)random_int(0, 1); | |||||
| return [ | return [ | ||||
| 'message' => self::faker()->text(), | |||||
| 'owner' => UserFactory::random(), | |||||
| 'headline' => self::faker()->words(random_int(1, 5), true), | |||||
| 'message' => $randomBoolean ? self::faker()->sentence() : self::faker()->sentences(random_int(1, 3), true), | |||||
| ]; | ]; | ||||
| } | } | ||||
| @@ -2,10 +2,10 @@ | |||||
| namespace App\Mapper; | namespace App\Mapper; | ||||
| use App\ApiResource\DragonTreasureApi; | |||||
| use App\ApiResource\ContactApi; | |||||
| use App\ApiResource\PartnerApi; | |||||
| use App\ApiResource\UserApi; | use App\ApiResource\UserApi; | ||||
| use App\ApiResource\PostingApi; | use App\ApiResource\PostingApi; | ||||
| use App\Entity\DragonTreasure; | |||||
| use App\Entity\Posting; | use App\Entity\Posting; | ||||
| use Symfony\Bundle\SecurityBundle\Security; | use Symfony\Bundle\SecurityBundle\Security; | ||||
| use Symfonycasts\MicroMapper\AsMapper; | use Symfonycasts\MicroMapper\AsMapper; | ||||
| @@ -40,10 +40,21 @@ class PostingEntityToApiMapper implements MapperInterface | |||||
| assert($entity instanceof Posting); | assert($entity instanceof Posting); | ||||
| assert($dto instanceof PostingApi); | assert($dto instanceof PostingApi); | ||||
| $dto->headline = $entity->getHeadline(); | |||||
| $dto->message = $entity->getMessage(); | $dto->message = $entity->getMessage(); | ||||
| $dto->owner = $this->microMapper->map($entity->getOwner(), UserApi::class, [ | $dto->owner = $this->microMapper->map($entity->getOwner(), UserApi::class, [ | ||||
| MicroMapperInterface::MAX_DEPTH => 0, | MicroMapperInterface::MAX_DEPTH => 0, | ||||
| ]); | ]); | ||||
| $dto->ownerName = $entity->getOwner()?->getFirstName()." ".$entity->getOwner()?->getLastName(); | |||||
| $dto->partner = $this->microMapper->map($entity->getPartner(), PartnerApi::class, [ | |||||
| MicroMapperInterface::MAX_DEPTH => 0, | |||||
| ]); | |||||
| $dto->contact = $this->microMapper->map($entity->getContact(), ContactApi::class, [ | |||||
| MicroMapperInterface::MAX_DEPTH => 0, | |||||
| ]); | |||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| return $dto; | return $dto; | ||||