<?phpnamespace App\Domain\Entity\PointOfInterest;use ApiPlatform\Metadata\ApiProperty;use ApiPlatform\Metadata\ApiResource;use ApiPlatform\Metadata\Delete;use ApiPlatform\Metadata\Get;use ApiPlatform\Metadata\GetCollection;use ApiPlatform\Metadata\Post;use ApiPlatform\Metadata\Put;use App\Application\ApiResources\State\Processor\RevisionCreateProcessor;use App\Application\ApiResources\State\Processor\RevisionPutProcessor;use App\Application\ApiResources\State\Processor\RevisionValidateProcessor;use App\Application\ApiResources\State\Provider\Revision\GetLatestMainWithPicturesProvider;use App\Application\ApiResources\State\Provider\Revision\GetLatestMainWithPicturesValidatedProvider;use App\Application\ApiResources\State\Provider\Revision\GetMainWithPicturesProvider;use App\Application\ApiResources\State\Provider\Revision\RevisionProvider;use App\Application\Controller\Api\LogUserSearch\LogUserSearchAction;use App\Application\Controller\Api\Revision\GetLatestFavoritesAction;use App\Application\Controller\Api\Revision\GetNearbyAction;use App\Application\Controller\Api\Revision\GetPdfAction;use App\Application\Controller\Api\Revision\GetSelectAction;use App\Application\Controller\Api\Revision\GetStructuredDataAction;use App\Application\Controller\Api\Revision\RevisionFavoriteDataController;use App\Application\Controller\Api\Revision\RevisionIncrementAction;use App\Application\Controller\Api\Revision\RevisionIncrementClickCounterController;use App\Application\Controller\Api\Revision\RevisionIncrementDetailViewCounterController;use App\Application\Controller\Api\Revision\RevisionSuggestionController;use App\Application\Controller\Api\Revision\SearchAction;use App\Application\Controller\Api\Revision\SendMessageAction;use App\Application\Controller\Api\Revision\ShareEmailAction;use App\Application\Dto\PointOfInterest\RevisionSearchOutput;use App\Application\Dto\SendMessageInput;use App\Application\Dto\ShareInput;use App\Domain\Entity\Address;use App\Domain\Entity\Behavior\Identifiable;use App\Domain\Entity\Enumeration\CurrencyType;use App\Domain\Entity\Enumeration\FloorQuality;use App\Domain\Entity\Enumeration\FloorType;use App\Domain\Entity\Enumeration\Label;use App\Domain\Entity\Enumeration\Network;use App\Domain\Entity\Enumeration\ParkingTime;use App\Domain\Entity\Enumeration\ParkingType;use App\Domain\Entity\Enumeration\PaymentType;use App\Domain\Entity\Enumeration\PointOfInterestType;use App\Domain\Entity\Person;use App\Domain\Entity\PointOfInterest;use App\Domain\Entity\Region;use App\Domain\Entity\Translation\RevisionTranslation;use Doctrine\Common\Collections\ArrayCollection;use Doctrine\Common\Collections\Collection;use Gedmo\SoftDeleteable\Traits\SoftDeleteable;use Gedmo\Timestampable\Traits\Timestampable;use Locastic\ApiPlatformTranslationBundle\Model\AbstractTranslatable;/** * Class Revision * * @package App\Domain\Entity\Revision */#[ApiResource( operations: [ new GetCollection( filters: [ 'revision.search_filter', 'revision.query_filter', 'revision.order_filter', 'revision.type_filter', 'revision.service_filter', 'revision.notation_filter', 'revision.minimum_height_filter', 'revision.minimum_width_filter', 'revision.exists_filter', 'soft_delete_filter', ], ), new GetCollection( uriTemplate: 'revisions_location', normalizationContext: ['groups' => ['revision_location_read']], filters: [ 'revision.search_filter', 'revision.query_filter', 'revision.order_filter', 'revision.type_filter', 'revision.service_filter', 'revision.notation_filter', 'revision.minimum_height_filter', 'revision.minimum_width_filter', 'revision.exists_filter', 'soft_delete_filter', ], ), new GetCollection( uriTemplate: '/main_revisions', controller: SearchAction::class, openapiContext: [ 'summary' => 'Get main revision list', 'parameters' => [ [ 'name' => 'filters[type.uuid]', 'in' => 'query', 'schema' => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], 'description' => 'Filter by Point of Interest Type uuid', 'required' => false, 'example' => [ "cbb9076d-a63d-47a1-b2db-86dd6ef15b4e", ], ], [ 'name' => 'filters[attributesDetail]', 'in' => 'query', 'schema' => [ 'type' => 'array', 'items' => [ 'type' => 'integer', ], ], 'description' => 'Filter by price range [ min, max, Show price if unknown ]', 'required' => false, 'example' => [ 0, 200, 1, ], ], [ 'name' => 'filters[firstAverageGrade]', 'in' => 'query', 'schema' => [ 'type' => 'boolean', ], 'description' => 'Filter by average grade > 4.5', 'required' => false, 'example' => true, ], [ 'name' => 'filters[secondAverageGrade]', 'in' => 'query', 'schema' => [ 'type' => 'boolean', ], 'description' => 'Filter by average grade > 4', 'required' => false, 'example' => true, ], [ 'name' => 'filters[thirdAverageGrade]', 'in' => 'query', 'schema' => [ 'type' => 'boolean', ], 'description' => 'Filter by average grade > 3.5', 'required' => false, 'example' => true, ], [ 'name' => 'filters[fourthAverageGrade]', 'in' => 'query', 'schema' => [ 'type' => 'boolean', ], 'description' => 'Filter by average grade > 5', 'required' => false, 'example' => true, ], [ 'name' => 'filters[minimumHeight]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Filter by minimum height', 'required' => false, 'example' => 1.8, ], [ 'name' => 'filters[minimumWidth]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Filter by minimum width', 'required' => false, 'example' => 1.8, ], [ 'name' => 'filters[minimumLength]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Filter by minimum width', 'required' => false, 'example' => 1.8, ], [ 'name' => 'filters[openingDate]', 'in' => 'query', 'schema' => [ 'type' => 'string', 'format' => 'date', ], 'description' => 'Filter by opening date', 'required' => false, ], [ 'name' => 'filters[range][lat]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Latitude of the center point for the radius filter (in decimal degrees)', 'required' => false, ], [ 'name' => 'filters[range][lng]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Longitude of the center point for the radius filter (in decimal degrees)', 'required' => false, ], [ 'name' => 'filters[range][distance]', 'in' => 'query', 'schema' => [ 'type' => 'string', ], 'description' => 'Distance radius in kilometers or miles (e.g. 200km)', 'required' => false, ], [ 'name' => 'filters[bounds][top]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Northernmost latitude of the bounding box (in decimal degrees)', 'required' => false, ], [ 'name' => 'filters[bounds][bottom]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Southernmost latitude of the bounding box (in decimal degrees)', 'required' => false, ], [ 'name' => 'filters[bounds][left]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Westernmost longitude of the bounding box (in decimal degrees)', 'required' => false, ], [ 'name' => 'filters[bounds][right]', 'in' => 'query', 'schema' => [ 'type' => 'number', ], 'description' => 'Easternmost longitude of the bounding box (in decimal degrees)', 'required' => false, ], [ 'name' => 'filters[search]', 'in' => 'query', 'schema' => [ 'type' => 'string', ], 'description' => 'Search query string to filter by activity name', 'required' => false, ], ], 'responses' => [ '200' => [ 'description' => 'List of main revisions', 'content' => [ 'application/json' => [ 'schema' => [ 'type' => 'object', 'properties' => [ 'lastPage' => [ 'type' => 'integer', ], 'totalItems' => [ 'type' => 'integer', ], 'items' => [ 'type' => 'array', 'items' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'integer', ], 'uuid' => [ 'type' => 'string', ], 'name' => [ 'type' => 'string', ], 'maxLength' => [ 'type' => 'number', ], 'maxHeight' => [ 'type' => 'number', ], 'maxWidth' => [ 'type' => 'number', ], 'attributes' => [ 'type' => 'array', 'items' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'integer', ], 'detail' => [ 'type' => 'string', ], 'attribute' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'integer', ], 'uuid' => [ 'type' => 'string', ], 'type' => [ 'type' => 'string', ], 'category' => [ 'type' => 'object', 'properties' => [ 'code' => [ 'type' => 'string', ], ], ], 'picto' => [ 'type' => 'object', 'properties' => [ 'uuid' => [ 'type' => 'string', ], ], ], ], ], ], ], ], 'type' => [ 'type' => 'object', 'properties' => [ 'code' => [ 'type' => 'string', ], 'uuid' => [ 'type' => 'string', ], 'position' => [ 'type' => 'integer', ], ], ], 'address' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'string', ], 'lat' => [ 'type' => 'integer', ], 'lng' => [ 'type' => 'integer', ], 'cityName' => [ 'type' => 'string', ], 'zipCode' => [ 'type' => 'string', ], 'country' => [ 'type' => 'string', ], 'streetName' => [ 'type' => 'string', ], ], ], 'pointOfInterest' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'integer', ], 'uuid' => [ 'type' => 'string', ], 'averageNotation' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'integer', ], 'uuid' => [ 'type' => 'string', ], 'averageNotation' => [ 'type' => 'number', ], 'mainPicture' => [ 'type' => 'object', 'properties' => [ 'uuid' => [ 'type' => 'string', ], ], ], 'pictures' => [ 'type' => 'object', 'properties' => [ 'media' => [ 'type' => 'object', 'properties' => [ 'uuid' => [ 'type' => 'string', ], ], ], ], ], 'author' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'integer', ], 'name' => [ 'type' => 'string', ], ], ], 'comments' => [ 'type' => 'object', 'properties' => [ 'id' => [ 'type' => 'integer', ], 'notation' => [ 'type' => 'integer', ], ], ], ], ], 'campingInformation' => [ 'type' => 'object', 'properties' => [ 'animal' => [ 'type' => 'boolean', ], 'notation' => [ 'type' => 'integer', ], ], ], ], ], ], ], ], ], ], ], ], ], ], ], validationContext: [], output: RevisionSearchOutput::class, read: false, deserialize: false, write: false, name: 'search_main_revisions', ), new GetCollection( uriTemplate: '/revisions/elastic', controller: SearchAction::class, output: RevisionSearchOutput::class, name: 'elastic_revisions', ), new GetCollection( uriTemplate: '/revisions/latest_main_with_pictures', filters: ['revision.search_filter'], provider: GetLatestMainWithPicturesProvider::class, ), new GetCollection( uriTemplate: '/revisions/latest_main_with_pictures_validated', filters: ['revision.search_filter'], provider: GetLatestMainWithPicturesValidatedProvider::class, ), new GetCollection( uriTemplate: '/revisions/by_department', paginationEnabled: true, filters: [ 'revision.query_filter', 'revision.order_filter', 'revision.search_filter', 'soft_delete_filter', ], provider: RevisionProvider::class, ), new GetCollection( uriTemplate: '/revisions/main_with_pictures', normalizationContext: ['groups' => ['base_revision_read']], provider: GetMainWithPicturesProvider::class, ), new GetCollection( uriTemplate: '/revisions/latest_favorites', controller: GetLatestFavoritesAction::class, name: 'get_latest_favorites', ), new GetCollection( uriTemplate: '/revisions/nearby', controller: GetNearbyAction::class, openapiContext: [ 'parameters' => [ ['name' => 'lat', 'in' => 'query', 'required' => true, 'schema' => ['type' => 'number']], ['name' => 'lng', 'in' => 'query', 'required' => true, 'schema' => ['type' => 'number']], ['name' => 'distance', 'in' => 'query', 'required' => true, 'schema' => ['type' => 'integer']], ['name' => 'limit', 'in' => 'query', 'required' => false, 'schema' => ['type' => 'integer']], ['name' => 'revisionId', 'in' => 'query', 'required' => false, 'schema' => ['type' => 'string']] ], ], ), new Get(name: 'get_revision'), new Get( uriTemplate: '/revisions/{uuid}/favorite_data', controller: RevisionFavoriteDataController::class, name: 'get_favorite_data', ), new Get( uriTemplate: '/revisions/{uuid}/select', controller: GetSelectAction::class, security: "is_granted('ROLE_ADMIN')", ), new Get( uriTemplate: '/revisions/{uuid}/pdf', controller: GetPdfAction::class, ), new Get( uriTemplate: '/revisions/{uuid}/structured_data', controller: GetStructuredDataAction::class, name: 'get_revision_structured_data', ), new Get( uriTemplate: '/revisions/{uuid}/select', controller: GetSelectAction::class, security: "is_granted('ROLE_ADMIN')", ), new Post(processor: RevisionCreateProcessor::class), new Post( uriTemplate: '/revisions/{uuid}/share_email', controller: ShareEmailAction::class, input: ShareInput::class, read: false, deserialize: false, ), new Post( uriTemplate: '/revisions/{uuid}/message', controller: SendMessageAction::class, input: SendMessageInput::class, read: false, deserialize: false, ), new Put( processor: RevisionPutProcessor::class, ), new Post( uriTemplate: '/revisions/increment', controller: RevisionIncrementAction::class, security: "is_granted('ROLE_USER')", ), new Put( uriTemplate: '/revisions/{uuid}/validate', security: "is_granted('ROLE_ADMIN')", processor: RevisionValidateProcessor::class, ), new Delete(security: "is_granted('ROLE_ADMIN')"), new Post( uriTemplate: '/revisions/{uuid}/increment_detail_view_counter', controller: RevisionIncrementDetailViewCounterController::class ), new Post( uriTemplate: '/revisions/{uuid}/increment_click_counter', controller: RevisionIncrementClickCounterController::class, ), new Post( uriTemplate: '/revisions/{uuid}/suggestion', controller: RevisionSuggestionController::class, ) ], normalizationContext: ['groups' => ['revision_read']], denormalizationContext: ['groups' => ['revision_write']])]class Revision extends AbstractTranslatable{ use Identifiable; use SoftDeleteable; use Timestampable; /** @var Collection<RevisionAttribute> */ public Collection $attributes; /** @var Collection<Label> */ public Collection $labels; /** @var Collection<OpeningDate> */ public Collection $openingDates; /** @var Collection<OpeningHour> */ public Collection $openingHours; /** @var Collection<PaymentType> */ public Collection $paymentTypes; public ?string $remoteId = null; public const SERVICE_PARKING_FIELD = 'parking'; public const SERVICE_PARKING_SERVICE_FIELD = 'parkingService'; public const SERVICE_PARKING_ELECTRICITY = 'parkingElectricity'; public const SERVICE_PARKING_WATER = 'parkingWater'; public const SERVICE_PACKAGE_CAMPER_VAN_FIELD = 'packageCamperVan'; public const SERVICE_PACKAGE_CARAVAN_FIELD = 'packageCaravan'; public const SLEEP = 'sleep'; /** * @param Address $address * @param CampingInformation $campingInformation * @param string $name * @param PointOfInterest $pointOfInterest * @param PointOfInterestType $type * @param bool $certified * @param bool $gpsCertified * @param bool $main * @param Person|null $certifiedBy * @param ContactInformation|null $contactInformation * @param CurrencyType|null $currency * @param FloorQuality|null $floorQuality * @param FloorType|null $floorType * @param string|null $internalNote * @param float|null $maxLength * @param float|null $maxHeight * @param float|null $maxWidth * @param Network|null $network * @param int|null $nbCarPlace * @param int|null $nbChargingPoint * @param int|null $number * @param string|null $openingDescription * @param ParkingTime|null $parkingTime * @param ParkingType|null $parkingType * @param Region|null $region * @param float|null $parking * @param float|null $parkingService * @param float|null $packageCamperVan * @param float|null $packageCaravan * @param bool|null $isTemporaryClosed * @param string|null $temporaryClosedReason * @param array $translations * @param string|null $createdFrom * */ public function __construct( #[ApiProperty(openapiContext: ['nullable' => false])] public Address $address, #[ApiProperty(openapiContext: ['nullable' => false])] public CampingInformation $campingInformation, #[ApiProperty(openapiContext: ['nullable' => false])] public string $name, #[ApiProperty(openapiContext: ['nullable' => false])] public PointOfInterest $pointOfInterest, #[ApiProperty(openapiContext: ['nullable' => false])] public PointOfInterestType $type, #[ApiProperty(openapiContext: ['nullable' => false])] public bool $certified = false, #[ApiProperty(openapiContext: ['nullable' => false])] public bool $gpsCertified = false, #[ApiProperty(openapiContext: ['nullable' => false])] public bool $main = false, public ?Person $certifiedBy = null, public ?ContactInformation $contactInformation = null, public ?CurrencyType $currency = null, public ?FloorQuality $floorQuality = null, public ?FloorType $floorType = null, public ?string $internalNote = null, public ?float $maxLength = null, public ?float $maxHeight = null, public ?float $maxWidth = null, public ?Network $network = null, public ?int $nbCarPlace = null, public ?int $nbChargingPoint = null, public ?int $number = 0, public ?string $openingDescription = null, public ?ParkingTime $parkingTime = null, public ?ParkingType $parkingType = null, public ?Region $region = null, public ?float $parking = null, public ?float $parkingService = null, public ?float $packageCamperVan = null, public ?float $packageCaravan = null, public ?bool $isTemporaryClosed = null, public ?string $temporaryClosedReason = null, public ?string $createdFrom = null, ) { $this->attributes = new ArrayCollection(); $this->labels = new ArrayCollection(); $this->openingDates = new ArrayCollection(); $this->openingHours = new ArrayCollection(); $this->paymentTypes = new ArrayCollection(); $this->translations = new ArrayCollection(); } public function __clone() { $this->id = null; $this->uuid = null; $this->createdAt = null; $this->updatedAt = null; $this->main = false; $cCampingInformation = clone $this->campingInformation; $cCampingInformation->id = null; $cCampingInformation->uuid = null; $this->campingInformation = $cCampingInformation; $cAddress = clone $this->address; $cAddress->id = null; $cAddress->uuid = null; $this->address = $cAddress; $cContactInformation = clone $this->contactInformation; $cContactInformation->id = null; $cContactInformation->uuid = null; $this->contactInformation = $cContactInformation; $this->paymentTypes = new ArrayCollection(); $this->labels = new ArrayCollection(); } /** * @return int */ public function getId(): int { return $this->id; } /** * @param RevisionAttribute $revisionAttribute * * @return self */ public function addAttribute(RevisionAttribute $revisionAttribute): self { if (!$this->attributes->contains($revisionAttribute)) { $this->attributes->add($revisionAttribute); } return $this; } public function addOpeningDate(OpeningDate $openingDate): self { $this->openingDates->add($openingDate); return $this; } public function addOpeningHour(OpeningHour $openingHour): self { $this->openingHours->add($openingHour); return $this; } public function addPaymentType(PaymentType $paymentType): self { $this->paymentTypes->add($paymentType); return $this; } public function getFormattedUpdatedAt(): string { return $this->updatedAt->format('d/m/Y'); } public function isElasticSearchPublishable(): bool { return $this->main && $this->deletedAt === null; } public function removeAttribute(RevisionAttribute $revisionAttribute): self { $this->attributes->removeElement($revisionAttribute); return $this; } public function removeOpeningDate(OpeningDate $openingDate): self { $this->openingDates->removeElement($openingDate); return $this; } public function removeOpeningHour(OpeningHour $openingHour): self { $this->openingHours->removeElement($openingHour); return $this; } public function removePaymentType(PaymentType $paymentType): self { $this->paymentTypes->removeElement($paymentType); return $this; } /** * @return Collection */ public function getLabels(): Collection { return $this->labels; } /** * @param Collection $labels */ public function setLabels(Collection $labels): void { $this->labels = $labels; } public function addLabel(Label $label): self { $this->labels->add($label); return $this; } public function removeLabel(Label $label): self { $this->labels->removeElement($label); return $this; } /** * @return Collection */ public function getPaymentTypes(): Collection { return $this->paymentTypes; } /** * @param Collection $paymentTypes */ public function setPaymentTypes(Collection $paymentTypes): void { $this->paymentTypes = $paymentTypes; } /** * @return Address */ public function getAddress(): Address { return $this->address; } /** * @return Collection */ public function getAttributes(): Collection { return $this->attributes; } /** * @return PointOfInterestType */ public function getType(): PointOfInterestType { return $this->type; } public function createTranslation(): RevisionTranslation { return new RevisionTranslation(); } public function getDescription(): ?string { return $this->getTranslationType()->getDescription(); } public function setDescription(?string $value): void { $this->getTranslationType()->setDescription($value); } public function getTranslationType(?string $locale = null): RevisionTranslation { return $this->getTranslation($locale); }}