<?php
namespace App\Domain\Entity;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use App\Application\ApiResources\State\Processor\Person\FcmUpdateProcessor;
use App\Application\ApiResources\State\Processor\Person\PersonLocaleUpdateProcessor;
use App\Application\ApiResources\State\Processor\Person\PersonUpdateProcessor;
use App\Application\ApiResources\State\Provider\MyCamperVanProvider;
use App\Application\ApiResources\State\Provider\Person\PersonStatisticsCurrentMonthProvider;
use App\Application\ApiResources\State\Provider\Person\PersonStatisticsProvider;
use App\Application\ApiResources\State\Provider\Person\RandomPersonProvider;
use App\Application\ApiResources\State\Provider\Person\RankProvider;
use App\Application\ApiResources\State\Provider\Person\SubstitutePersonProvider;
use App\Application\ApiResources\State\Provider\PersonStartedAtProvider;
use App\Application\ApiResources\State\Provider\PremiumCheckProvider;
use App\Application\Controller\Api\Person\AddGoToLogAction;
use App\Application\Controller\Api\Person\AdminDeletePersonAction;
use App\Application\Controller\Api\Person\DeletePersonAction;
use App\Application\Controller\Api\Person\GetCurrentPersonAction;
use App\Application\Controller\Api\Person\GetFavoriteBooleanAction;
use App\Application\Controller\Api\Person\GetFavoriteController;
use App\Application\Controller\Api\Person\GetFavoriteListController;
use App\Application\Controller\Api\Person\GetFavoriteNewController;
use App\Application\Controller\Api\Person\SubscriptionCheckAction;
use App\Application\Controller\Api\Person\SubstituteAction;
use App\Application\Dto\Person\DeletePersonInput;
use App\Application\Dto\Person\FcmInput;
use App\Application\Dto\Person\PersonLocaleInput;
use App\Application\Dto\Person\PersonStatisticsOutput;
use App\Application\Dto\Person\RankOutput;
use App\Application\Service\Notification\Model\EmailableInterface;
use App\Domain\Entity\Behavior\Actionable;
use App\Domain\Entity\Enumeration\VehicleType;
use Athome\UserBundle\Entity\User;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gedmo\SoftDeleteable\Traits\SoftDeleteable;
use Gedmo\Timestampable\Traits\Timestampable;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* Class Person
*
* @package App\Domain\Entity
*/
#[UniqueEntity(fields: ['email'], message: 'There is already an account with this email')]
#[ApiResource(
operations: [
new Delete(
controller: AdminDeletePersonAction::class,
security: "is_granted('ROLE_ADMIN') or object.id == user.id"
),
new GetCollection(
uriTemplate: '/people/export',
formats: ['csv' => ['text/csv']],
paginationEnabled: false,
normalizationContext: ['groups' => ['person_export'], 'csv_delimiter' => ';'],
filters: [
'member.query_filter',
'person.order_filter',
'id_search_filter',
'soft_delete_filter',
]
),
new GetCollection(
uriTemplate: '/people/random',
normalizationContext: ['groups' => ['trombinoscope']],
provider: RandomPersonProvider::class,
),
new GetCollection(
normalizationContext: ['groups' => ['person_list']],
filters: [
'member.query_filter',
'person.order_filter',
'id_search_filter',
'soft_delete_filter',
'person.enabled.search_filter',
'person_no_admin_filter',
],
),
new GetCollection(
uriTemplate: '/people/substitute',
normalizationContext: ['groups' => ['person_list']],
security: 'is_granted("ROLE_ADMIN")',
filters: ['member.query_filter'],
provider: SubstitutePersonProvider::class,
),
new GetCollection(
uriTemplate: '/me',
controller: GetCurrentPersonAction::class,
normalizationContext: ['groups' => ['person_read', 'self_person_read']],
name: 'current'
),
new GetCollection(
uriTemplate: '/people/favorites',
controller: GetFavoriteController::class
),
new GetCollection(
uriTemplate: '/people/favorites_list',
controller: GetFavoriteListController::class,
),
new GetCollection(
uriTemplate: '/people/favorites_new',
controller: GetFavoriteNewController::class
),
new GetCollection(
uriTemplate: '/people/favorites_boolean',
controller: GetFavoriteBooleanAction::class,
),
new Get(),
new Get(
uriTemplate: '/people/{uuid}/substitute',
controller: SubstituteAction::class,
security: 'is_granted("ROLE_ADMIN")'
),
new Get(uriTemplate: '/people/{uuid}/rank', output: RankOutput::class, provider: RankProvider::class),
new Get(
uriTemplate: '/people/{uuid}/statistics',
normalizationContext: ['groups' => ['person_statistics:read']],
output: PersonStatisticsOutput::class,
provider: PersonStatisticsProvider::class
),
new Get(
uriTemplate: '/people/{uuid}/statistics/current_month',
normalizationContext: ['groups' => ['person_statistics:read']],
output: PersonStatisticsOutput::class,
provider: PersonStatisticsCurrentMonthProvider::class
),
new Get('/premium_check', provider: PremiumCheckProvider::class),
new Get('/my_camper_van', security: "is_granted('ROLE_USER')", provider: MyCamperVanProvider::class),
new Get('/started_at', security: "is_granted('ROLE_USER')", provider: PersonStartedAtProvider::class),
new Post(
uriTemplate: '/me/delete_account',
controller: DeletePersonAction::class,
denormalizationContext: ['groups' => ["delete_person_input_write"]],
input: DeletePersonInput::class,
),
new Post(
uriTemplate: '/subscription_check',
controller: SubscriptionCheckAction::class,
),
new Post(
uriTemplate: '/add_goto_log',
controller: AddGoToLogAction::class,
),
new Patch(security: "is_granted('ROLE_ADMIN') or object.id == user.id"),
new Put(
security: "is_granted('ROLE_ADMIN') or object.id == user.id",
processor: PersonUpdateProcessor::class,
validationContext: ['groups' => ['person_write']],
),
new Put(
uriTemplate: '/people/{uuid}/locale',
denormalizationContext: ['groups' => ["person_locale_input_write"]],
security: "is_granted('ROLE_ADMIN') or object.id == user.id",
input: PersonLocaleInput::class,
processor: PersonLocaleUpdateProcessor::class,
),
new Put(
uriTemplate: '/people/{uuid}/fcm',
denormalizationContext: ['groups' => ['person_fcm_input_write']],
security: "is_granted('ROLE_ADMIN') or object.id == user.id",
input: FcmInput::class,
processor: FcmUpdateProcessor::class
),
],
normalizationContext: ['groups' => ['person_read']],
denormalizationContext: ['groups' => ['person_write']],
order: ['id' => 'ASC']
)]
class Person extends User implements EmailableInterface
{
use Actionable;
use SoftDeleteable;
use Timestampable;
public const AMOUNT_PREMIUM = 17.99;
private Collection $favorites;
/** @var Collection<PointOfInterest> */
private Collection $references;
/** @var Collection<PointOfInterest> */
private Collection $activities;
/** @var Collection<Payment> */
private Collection $payments;
#[ApiProperty(identifier: true)]
public string $uuid;
public mixed $newToken = null;
/**
* @param Address|null $address
* @param Media|null $avatar
* @param DateTime|null $birthDate
* @param int $caras
* @param CamperVan|null $camperVan
* @param string|null $civility
* @param Media|null $coverPicture
* @param int|null $coverPosition
* @param DateTime|null $startPremiumDate
* @param DateTime|null $endPremiumDate
* @param string|null $description
* @param string|null $dtype
* @param string|null $facebook
* @param string|null $facebookId
* @param string|null $familyName
* @param string|null $givenName
* @param string|null $googleId
* @param string|null $instagram
* @param Newsletter|null $newsletter
* @param bool $privateFacebook
* @param bool $privateInstagram
* @param string|null $publicUrl
* @param string|null $rate
* @param string|null $referrer
* @param string|null $registeredFrom
* @param DateTime|null $startedAt
* @param string|null $source
* @param bool $translator
* @param string|null $telephone
* @param array $providers
* @param string|null $terminal
* @param string|null $trips
* @param VehicleType|null $vehicleType
* @param bool $validator
* @param int|null $contactId
* @param string $locale
* @param string|null $fcmId
* @param string|null $remoteId
* @param DateTime|null $zhistUpdate
* @param int|null $aiOffTopicFlagCounter
* @param int|null $aiInappropriateFlagCounter
* @param bool|null $isPremiumSubscriptionActive
*/
public function __construct(
public ?Address $address = null,
public ?Media $avatar = null,
public ?DateTime $birthDate = null,
public int $caras = 0,
public ?CamperVan $camperVan = null,
public ?string $civility = null,
public ?Media $coverPicture = null,
public ?int $coverPosition = null,
public ?DateTime $startPremiumDate = null,
public ?DateTime $endPremiumDate = null,
public ?string $description = null,
public ?string $dtype = null,
public ?string $facebook = null,
public ?string $facebookId = null,
public ?string $familyName = null,
public ?string $givenName = null,
public ?string $googleId = null,
public ?string $instagram = null,
public ?Newsletter $newsletter = new Newsletter(),
public bool $privateFacebook = false,
public bool $privateInstagram = false,
public ?string $publicUrl = null,
public ?string $rate = null,
public ?string $referrer = null,
public ?string $registeredFrom = null,
public ?DateTime $startedAt = null,
public ?string $source = 'web',
public bool $translator = false,
public ?string $telephone = null,
public array $providers = [],
public ?string $terminal = null,
public ?string $trips = null,
public ?VehicleType $vehicleType = null,
public bool $validator = false,
public ?int $contactId = null,
public string $locale = 'fr',
public ?string $fcmId = null,
public ?string $remoteId = null,
public ?DateTime $zhistUpdate = null,
public ?string $oldPassword = null,
public ?string $macifMemberCode = null,
public ?int $aiOffTopicFlagCounter = 0,
public ?int $aiInappropriateFlagCounter = 0,
public ?bool $isPremiumSubscriptionActive = false,
public ?bool $hasMonthlySubscription = false,
) {
parent::__construct();
$this->favorites = new ArrayCollection();
$this->references = new ArrayCollection();
$this->activities = new ArrayCollection();
$this->payments = new ArrayCollection();
}
public function getActive(): bool
{
return $this->endPremiumDate && $this->endPremiumDate >= new DateTime();
}
public function getFavorites(): Collection
{
return $this->favorites;
}
public function getFullname(): string
{
return ($this->givenName ?: '') . ' ' . ($this->familyName ? $this->familyName[0] . '.' : '');
}
/**
* @return Collection<PointOfInterest>
*/
public function getReferences(): Collection
{
return $this->references;
}
/**
* @return Collection<Payment>
*/
public function getPayments(): Collection
{
return $this->payments;
}
/**
* @return Collection<Activity>
*/
public function getActivities(): Collection
{
return $this->activities;
}
#[ApiProperty]
public function getFirstReference(): ?PointOfInterest
{
//return the first reference not deleted
foreach ($this->references as $reference) {
if (!$reference->isDeleted()) {
return $reference;
}
}
return null;
}
public function getCamperVan(): ?CamperVan
{
return $this->camperVan;
}
public function getStartedAt(): ?DateTime
{
return $this->startedAt;
}
public function setOffTopicFlagCounter(int $aiOffTopicFlagCounter): void
{
$this->aiOffTopicFlagCounter = $aiOffTopicFlagCounter;
}
public function getOffTopicFlagCounter(): ?int
{
return $this->aiOffTopicFlagCounter;
}
public function setInappropriateFlagCounter(int $aiInappropriateFlagCounter): void
{
$this->aiInappropriateFlagCounter = $aiInappropriateFlagCounter;
}
public function getInappropriateFlagCounter(): ?int
{
return $this->aiInappropriateFlagCounter;
}
public function setPremiumSubscriptionActive(bool $isPremiumSubscriptionActive): void
{
$this->isPremiumSubscriptionActive = $isPremiumSubscriptionActive;
}
public function getPremiumSubscriptionActive(): ?bool
{
return $this->isPremiumSubscriptionActive;
}
public function getNewToken(): mixed
{
return $this->newToken;
}
public function setNewToken($data): void
{
$this->newToken = $data;
}
public function getHasMonthlySubscription(): ?bool
{
return $this->hasMonthlySubscription;
}
public function setHasMonthlySubscription(bool $hasMonthlySubscription): void
{
$this->hasMonthlySubscription = $hasMonthlySubscription;
}
/**
* Retourne true si le user est premium aujourd'
* @return bool
*/
public function isPremium(): bool
{
$today = new DateTime();
return $this->endPremiumDate && $this->endPremiumDate >= $today;
}
/**
* Retourne true si le user est inscrit plus de 24 heures et moins de 7 jours
* @return bool
*/
public function isNewSubscriber(): bool
{
$yesterday = new DateTime('yesterday');
$aWeekAgo = new DateTime('7 days ago');
return $this->createdAt &&
$this->createdAt <= $yesterday &&
$this->createdAt >= $aWeekAgo;
}
/**
* Retourne true si le user est inscrit depuis plus de 90 jours et moins de 97 jours
* @return bool
*/
public function isOldSubscriber(): bool
{
$minDate = new DateTime('-90 days');
$maxDate = new DateTime('-97 days');
return $this->endPremiumDate &&
$this->endPremiumDate <= $minDate &&
$this->endPremiumDate >= $maxDate;
}
}