Untitled

mail@pastecode.io avatar
unknown
php
2 years ago
15 kB
2
Indexable
Never
<?php

namespace App\Entity;

use App\Entity\Tag\Category;
use App\Entity\Tag\Tag;
use App\Repository\EventRepository;
use CodeLabs\Listing\Searching\Attribute\Searchable;
use CodeLabs\Listing\Filtering\Attribute\Filterable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Constraints\LessThanOrEqual;

/**
 * @ORM\Entity(repositoryClass=EventRepository::class)
 * @ORM\HasLifecycleCallbacks()
 */
class Event implements \JsonSerializable
{
    const ALIAS = 'event';

    public function __construct(
        /**
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="UUID")
         * @ORM\Column(type="guid")
         */
        private ?string $id = null,
        
        /**
         * @ORM\Column(type="string", length=255)
         */
        #[Searchable]
        private ?string $title = null,
    
        /**
         * @ORM\Column(type="string", length=255, unique=true, nullable=true)
         */
        private ?string $slug = null,

        /**
         * @ORM\Column(type="text", nullable=true)
         */
        #[Searchable]
        private ?string $description = null,
    
        /**
         * @ORM\Column(type="decimal", precision="8", scale="2", nullable=true)
         */
        #[Assert\GreaterThanOrEqual(0, message: 'price.GreaterThanOrEqual')]
        private ?string $price = null,
    
        /**
         * @ORM\Column(type="string", length=255, nullable=true)
         */
        private ?string $place = null,
    
        /**
         * @ORM\Column(type="integer", nullable=true)
         */
        #[Assert\GreaterThanOrEqual(0, message: 'preferredAgeGroupFrom.GreaterThanOrEqual')]
        private ?int $preferredAgeGroupFrom = null,
    
        /**
         * @ORM\Column(type="integer", nullable=true)
         */
        #[Assert\GreaterThanOrEqual(propertyPath: 'preferredAgeGroupFrom', message: 'preferredAgeGroupTo.greater_than_or_equal_preferredAgeGroupFrom')]
        #[Assert\LessThanOrEqual(150)]
        private ?int $preferredAgeGroupTo = null,
        
        /**
         * @ORM\Column(type="boolean", options={"default" : 0}, nullable=true)
         */
        private ?bool $guestsCanInviteFriends = null,
        
        /**
         * @ORM\Column(type="datetime")
         */
        #[Filterable]
        private ?\DateTime $startsAt = null,

        /**
         * @ORM\Column(type="datetime",  nullable=true)
         */
        #[Assert\GreaterThanOrEqual(propertyPath: 'startsAt', message: 'event.ends_at.greater_than_or_equal_starts_at')]
        private ?\DateTime $endsAt = null,

        /**
         * @ORM\ManyToMany(targetEntity=Tag::class, inversedBy="events")
         */
        private ?Collection $tags = null,
    
        /**
         * @ORM\OneToOne(targetEntity=Image::class, fetch="EAGER", cascade={"persist"}, orphanRemoval=true)
         */
        private ?Image $coverImage = null,
    
        /**
         * @ORM\ManyToOne(targetEntity=User::class)
         * @ORM\JoinColumn(name="host_id", referencedColumnName="id")
         */
        private ?User $host = null,
        
        /**
         * @ORM\ManyToMany(targetEntity=User::class)
         * @ORM\JoinTable(name="co_host_event")
         */
        private ?Collection $coHosts = null,
    
        /**
         * @ORM\ManyToMany(targetEntity=Image::class, cascade={"persist"}, orphanRemoval=true)
         * @ORM\JoinTable(name="event_gallery")
         */
        private ?Collection $gallery = null,
    
        /**
         * @ORM\OneToOne(targetEntity=Location::class, cascade={"persist"})
         */
        private ?Location $location = null,

        /**
         * @ORM\OneToMany(targetEntity=EventDistance::class, mappedBy="event", orphanRemoval=true)
         */
        private ?Collection $distances = null,

        /**
         * @ORM\OneToMany(targetEntity=EventMember::class, mappedBy="event", cascade={"persist"}, orphanRemoval=true, fetch="EXTRA_LAZY")
         */
        private ?Collection $eventMembers = null,

        /**
         * @ORM\OneToOne(targetEntity=EventUserStatistic::class, mappedBy="event")
         */
        private ?EventUserStatistic $userStatistic = null,

        /**
         * @ORM\OneToMany(targetEntity=EventSlugHistory::class, mappedBy="event", cascade={"persist"}, orphanRemoval=true)
         */
        private ?Collection $slugsHistory = null,
    )
    {
        $this->tags = new ArrayCollection();
        $this->coHosts = new ArrayCollection();
        $this->gallery = new ArrayCollection();
        $this->distances = new ArrayCollection();
        $this->eventMembers = new ArrayCollection();
        $this->slugsHistory = new ArrayCollection();
    }
    
    public function getId(): ?string
    {
        return $this->id;
    }
    
    public function getTitle(): ?string
    {
        return $this->title;
    }
    
    public function setTitle(string $title): void
    {
        $this->title = $title;
    }
    
    public function setSlug(?string $slug): void
    {
        $this->slug = $slug;
    }

    public function getSlug(): ?string
    {
        return $this->slug;
    }

    public function isSlugTheSame(string $slug): bool
    {
        return $this->slug===$slug;
    }

    public function getStartsAt(): ?\DateTime
    {
        return $this->startsAt;
    }
    
    public function getEndsAt(): ?\DateTime
    {
        return $this->endsAt;
    }

    public function isUpcoming(): bool
    {
        return $this->startsAt > new \DateTime();
    }

    public function isInProgress(): bool
    {
        $now = new \DateTime();
        return $this->startsAt < $now && $this->endsAt > $now;
    }

    public function isFinished(): bool
    {
        return $this->endsAt < new \DateTime();
    }

    /**
     * Whether user can join or be interested.
     */
    public function canUserEnlist(): bool
    {
        return $this->endsAt > new \DateTime();
    }

    public function setStartsAt(\DateTime $startsAt): void
    {
        $this->startsAt = $startsAt;
    }
    
    public function setEndsAt(?\DateTime $endsAt): void
    {
        $this->endsAt = $endsAt;
    }

    public function setDefaultEndsAt(): void
    {
        if(is_null($this->startsAt)) {
            return;
        }
        $this->endsAt = clone $this->startsAt;
        $this->endsAt->add(new \DateInterval('PT2H'));
    }

    /**
     * @return Collection|Tag[]
     */
    public function getTags(): Collection
    {
        return $this->tags;
    }
    
    public function addTag(Tag $tag): void
    {
        if (!$this->tags->contains($tag)) {
            $this->tags[] = $tag;
        }
    }
    
    public function setTags(Collection $tags): void
    {
        $this->tags = $tags;
    }
    
    public function removeTag(Tag $tag): void
    {
        $this->tags->removeElement($tag);
    }
    
    public function getTagsIdsByCategoryIdHumanReadable(string $idHumanReadable): array
    {
        $tagsIds = $this->tags->map(function(Tag $tag) use($idHumanReadable) {
            return $tag->getCategory()->getIdHumanReadable()===$idHumanReadable ? $tag->getId() : null;
        })->toArray();
        return array_values(array_filter($tagsIds));
    }

    private function getTagsByCategoryIdHumanReadable(string $categoryIdHumanReadable): ?Collection
    {
        return $this->tags->filter(function(Tag $tag) use($categoryIdHumanReadable) {
            return $tag->getCategory()?->getIdHumanReadable() === $categoryIdHumanReadable;
        });
    }

    public function getTagsValues(): ?Collection
    {
        return $this->getTagsByCategoryIdHumanReadable(Category::ID_HUMAN_READABLE_VALUES);
    }

    public function getTagsInterests(): ?Collection
    {
        return $this->getTagsByCategoryIdHumanReadable(Category::ID_HUMAN_READABLE_INTERESTS);
    }

    public function getTagsMyPersonality(): ?Collection
    {
        return $this->getTagsByCategoryIdHumanReadable(Category::ID_HUMAN_READABLE_MY_PERSONALITY);
    }

    public function getCoverImage(): ?Image
    {
        return $this->coverImage;
    }
    
    public function setCoverImage(?Image $coverImage): void
    {
        $this->coverImage = $coverImage;
    }
    
    public function setHost(?User $host): void
    {
        $this->host = $host;
    }
    
    public function getHost(): ?User
    {
        return $this->host;
    }
    
    public function getHostId(): ?string
    {
        return $this->host instanceof User ? $this->host->getId() : null;
    }
    
    public function getCoHosts(): ?Collection
    {
        return $this->coHosts;
    }
    
    public function getCoHostsIds(): array
    {
        return $this->coHosts->map(function(User $host) {
            return $host->getId();
        })->toArray();
    }
    
    public function addCoHost(User $user): void
    {
        if (!$this->coHosts->contains($user)) {
            $this->coHosts[] = $user;
        }
    }
    
    public function setCoHosts(?Collection $coHosts): void
    {
        $this->coHosts = $coHosts;
    }
    
    public function getDescription(): ?string
    {
        return $this->description;
    }
    
    public function getPrice(): ?string
    {
        return $this->price;
    }
    
    public function getPlace(): ?string
    {
        return $this->place;
    }
    
    public function getPreferredAgeGroupFrom(): ?int
    {
        return $this->preferredAgeGroupFrom;
    }
    
    public function getPreferredAgeGroupTo(): ?int
    {
        return $this->preferredAgeGroupTo;
    }
    
    public function getGuestsCanInviteFriends(): ?bool
    {
        return $this->guestsCanInviteFriends;
    }
    
    public function setDescription(?string $description): void
    {
        $this->description = $description;
    }
    
    public function setPrice(?string $price): void
    {
        $this->price = $price;
    }
    
    public function setPlace(?string $place): void
    {
        $this->place = $place;
    }
    
    public function setPreferredAgeGroupFrom(?int $preferredAgeGroupFrom): void
    {
        $this->preferredAgeGroupFrom = $preferredAgeGroupFrom;
    }
    
    public function setPreferredAgeGroupTo(?int $preferredAgeGroupTo): void
    {
        $this->preferredAgeGroupTo = $preferredAgeGroupTo;
    }
    
    public function setGuestsCanInviteFriends(?bool $guestsCanInviteFriends): void
    {
        $this->guestsCanInviteFriends = $guestsCanInviteFriends;
    }
    
    public function getGallery(): ?Collection
    {
        return $this->gallery;
    }
    
    public function addGalleryImage(Image $image): void
    {
        if (!$this->gallery->contains($image)) {
            $this->gallery[] = $image;
        }
    }
    
    public function removeGalleryImage(Image $image): void
    {
        $this->gallery->removeElement($image);
    }
    
    public function setGallery(?Collection $gallery): void
    {
        $this->gallery = $gallery;
    }
    
    public function getLocation(): ?Location
    {
        return $this->location;
    }
    
    public function setLocation(?Location $location): void
    {
        $this->location = $location;
    }

    public function clearDistances(): void
    {
        $this->distances->clear();
    }

    public function getDistances(): ?Collection
    {
        return $this->distances;
    }

    public function getDistanceByPlaceId(string $placeId): ?EventDistance
    {
        $criteria = Criteria::create()
            ->andWhere(Criteria::expr()->eq('place_id', $placeId))
        ;
        $result = $this->distances->matching($criteria)->current();
        return $result instanceof EventDistance ? $result : null;
    }

    public function getEventMembers(): ?Collection
    {
        return $this->eventMembers;
    }

    public function addEventMember(EventMember $eventMember): void
    {
        if ($this->eventMembers->contains($eventMember)) {
            return;
        }

        $this->eventMembers->add($eventMember);
    }

    public function getEventMemberByUser(User $user): ?EventMember
    {
        return $this->eventMembers->filter(function (EventMember $eventMember) use ($user) {
            return $eventMember->getUser()->getId() === $user->getId();
        })->first() ?: null;
    }

    public function getJoinedEventMembers(): Collection
    {
        return $this->eventMembers->filter(function(EventMember $eventMember) { return $eventMember->isJoined(); });
    }

    public function getInterestedEventMembers(): Collection
    {
        return $this->eventMembers->filter(function(EventMember $eventMember) { return $eventMember->isInterested(); });
    }

    public function getJoinRequestEventMembers(): Collection
    {
        return $this->eventMembers->filter(function(EventMember $eventMember) { return $eventMember->isJoinRequest(); });
    }
<<<<<<< HEAD

=======
    
>>>>>>> feature/HAN-64-event-sharing
    public function getUserStatistic(): ?EventUserStatistic
    {
        return $this->userStatistic;
    }

    public function getSlugsHistory(): ?Collection
    {
        return $this->slugsHistory;
    }

    public function addSlugToHistory(string $slug): void
    {
        foreach($this->slugsHistory as $slugHistory) {
            if($slugHistory->getSlug()===$slug) {
                return;
            }
        }
        $eventSlugHistory = new EventSlugHistory($this, $slug);
        $this->slugsHistory->add($eventSlugHistory);
    }
<<<<<<< HEAD

=======
    
>>>>>>> feature/HAN-64-event-sharing
    public function jsonSerialize(): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'slug' => $this->slug,
            'description' => $this->description,
            'price' => $this->price,
            'place' => $this->place,
            'preferredAgeGroupFrom' => $this->preferredAgeGroupFrom,
            'preferredAgeGroupTo' => $this->preferredAgeGroupTo,
            'guestsCanInviteFriends' => $this->guestsCanInviteFriends,
            'startsAt' => $this->startsAt?->format('Y-m-d H:i:s'),
            'endsAt' => $this->endsAt?->format('Y-m-d H:i:s'),
            'coverImage' => $this->coverImage,
            'host' => $this->host,
            'coHosts' => $this->getCoHosts()->toArray(),
            'gallery' => $this->getGallery()->toArray(),
            'location' => $this->location,
            'tagsValues' => array_values($this->getTagsValues()->toArray()),
            'tagsInterests' => array_values($this->getTagsInterests()->toArray()),
            'tagsMyPersonality' => array_values($this->getTagsMyPersonality()->toArray()),
        ];
    }

    /**
     * @ORM\PreFlush
     */
    public function preFlush(): void
    {
        if(is_null($this->endsAt)) {
            $this->setDefaultEndsAt();
        }
    }
}