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