Covivo/mobicoop

View on GitHub
api/src/Event/Service/EventManager.php

Summary

Maintainability
B
4 hrs
Test Coverage
<?php

/**
 * Copyright (c) 2021, MOBICOOP. All rights reserved.
 * This project is dual licensed under AGPL and proprietary licence.
 ***************************
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License as
 *    published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <gnu.org/licenses>.
 ***************************
 *    Licence MOBICOOP described in the file
 *    LICENSE
 */

namespace App\Event\Service;

use App\App\Repository\AppRepository;
use App\DataProvider\Entity\ApidaeProvider;
use App\DataProvider\Entity\TourinsoftProvider;
use App\Event\Entity\Event;
use App\Event\Event\EventCreatedEvent;
use App\Event\Repository\EventRepository;
use App\Geography\Service\AddressManager;
use App\Geography\Service\GeoTools;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Event manager.
 *
 * This service contains methods related to event manipulations.
 *
 * @author Sylvain Briat <sylvain.briat@mobicoop.org>
 * @author Remi Wortemann <remi.wortemann@mobicoop.org>
 */
class EventManager
{
    public const EVENT_PROVIDER_APIDAE = 'apidae';
    public const EVENT_PROVIDER_TOURINSOFT = 'tourinsoft';
    public const APP_ID = 1;
    private $eventRepository;
    private $dispatcher;
    private $entityManager;
    private $geoTools;
    private $provider;
    private $appRepository;
    private $addressManager;
    private $eventProvider;
    private $eventProviderApiKey;
    private $eventProviderProjectId;
    private $eventProviderSelectionId;
    private $eventProviderServerUrl;

    /**
     * Constructor.
     */
    public function __construct(
        EntityManagerInterface $entityManager,
        EventRepository $eventRepository,
        EventDispatcherInterface $dispatcher,
        GeoTools $geoTools,
        AppRepository $appRepository,
        AddressManager $addressManager,
        string $eventProvider,
        string $eventProviderApiKey,
        string $eventProviderProjectId,
        string $eventProviderSelectionId,
        string $eventProviderServerUrl
    ) {
        $this->entityManager = $entityManager;
        $this->eventRepository = $eventRepository;
        $this->dispatcher = $dispatcher;
        $this->geoTools = $geoTools;
        $this->eventProvider = $eventProvider;
        $this->eventProviderApiKey = $eventProviderApiKey;
        $this->eventProviderProjectId = $eventProviderProjectId;
        $this->eventProviderSelectionId = $eventProviderSelectionId;
        $this->eventProviderServerUrl = $eventProviderServerUrl;
        $this->appRepository = $appRepository;
        $this->addressManager = $addressManager;

        switch ($eventProvider) {
            case self::EVENT_PROVIDER_APIDAE:
                $this->provider = new ApidaeProvider($this->eventProviderApiKey, $this->eventProviderProjectId, $this->eventProviderSelectionId);

                break;

            case self::EVENT_PROVIDER_TOURINSOFT:
                $this->provider = new TourinsoftProvider($this->eventProviderServerUrl);

                break;
        }
    }

    /**
     * Create an event.
     *
     * @param Event $event The event to create
     *
     * @return Event The event created
     */
    public function createEvent(Event $event)
    {
        if (is_null($event->getUser()) && is_null($event->getApp())) {
            throw new \Exception('User or App are mandatory', 1);
        }
        $this->entityManager->persist($event);
        $this->entityManager->flush();

        // We set the displayLabel of the event's address
        $event->getAddress()->setDisplayLabel($this->geoTools->getDisplayLabel($event->getAddress()));
        $event->getAddress()->setName($event->getName());
        // we set the urlKey
        $event->setUrlKey($this->generateUrlKey($event));

        $eventEvent = new EventCreatedEvent($event);
        $this->dispatcher->dispatch($eventEvent, EventCreatedEvent::NAME);

        return $event;
    }

    public function updateEvent(Event $event)
    {
        $this->entityManager->persist($event);
        $this->entityManager->flush();

        // We set the displayLabel of the event's address
        $event->getAddress()->setDisplayLabel($this->geoTools->getDisplayLabel($event->getAddress()));
        $event->getAddress()->setName($event->getName());
        // we set the urlKey
        $event->setUrlKey($this->generateUrlKey($event));

        return $event;
    }

    /**
     * Get an event by its id.
     *
     * @return null|Event
     */
    public function getEvent(int $eventId)
    {
        return $this->eventRepository->find($eventId);
    }

    // very useful method :-|
    public function canReport()
    {
        // EVERYONE CAN REPORT EVENT
        return true;
    }

    /**
     * retrive events created by a user.
     */
    public function getCreatedEvents(int $userId)
    {
        return $this->eventRepository->getCreatedEvents($userId);
    }

    public function getEvents(): QueryBuilder
    {
        return $this->eventRepository->getEvents();
    }

    /**
     * Generate the UrlKey of an Event.
     *
     * @return string The url key
     */
    public function generateUrlKey(Event $event): string
    {
        $urlKey = $event->getName();
        $urlKey = str_replace(' ', '-', $urlKey);
        $urlKey = str_replace("'", '-', $urlKey);
        $urlKey = strtr(utf8_decode($urlKey), utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'), 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
        $urlKey = preg_replace('/[^A-Za-z0-9\-]/', '', $urlKey);

        // We don't want to finish with a single "-"
        if ('-' == substr($urlKey, -1)) {
            $urlKey = substr($urlKey, 0, strlen($urlKey) - 1);
        }

        return $urlKey;
    }

    /**
     * method to import external events.
     */
    public function importEvents()
    {
        $eventsToImport = $this->provider->getEvents();

        foreach ($eventsToImport as $eventToImport) {
            $event = $this->eventRepository->findOneBy(['externalId' => $eventToImport->getExternalId(), 'externalSource' => $eventToImport->getExternalSource()]);
            if (isset($event) && !is_null($event)) {
                $event->setName($eventToImport->getName());
                $event->setFromDate($eventToImport->getFromDate());
                $event->setToDate($eventToImport->getToDate());
                $event->setDescription($eventToImport->getDescription());
                $event->setFullDescription($eventToImport->getFullDescription());
                $event->setAddress($eventToImport->getAddress());
                $event->setUrl($eventToImport->getUrl());
                $event->setExternalImageUrl($eventToImport->getExternalImageUrl());
            } else {
                $event = new Event();
                $event->setExternalId($eventToImport->getExternalId());
                $event->setExternalSource($eventToImport->getExternalSource());
                $event->setName($eventToImport->getName());
                $event->setFromDate($eventToImport->getFromDate());
                $event->setToDate($eventToImport->getToDate());
                $event->setDescription($eventToImport->getDescription());
                $event->setFullDescription($eventToImport->getFullDescription());
                $event->setAddress($eventToImport->getAddress());
                $event->setUrl($eventToImport->getUrl());
                $event->setExternalImageUrl($eventToImport->getExternalImageUrl());
                $event->setStatus(1);
                $event->setPrivate(0);
                $event->setUseTime(0);
                $event->setApp($this->appRepository->find(self::APP_ID));
            }
            if (is_null($event->getUser()) && is_null($event->getApp())) {
                throw new \Exception('User or App are mandatory', 1);
            }
            $this->entityManager->persist($event);
            $this->entityManager->flush();
        }
    }

    public function getEventsByCommunity(int $communityId)
    {
        return $this->eventRepository->getEventsByCommunity($communityId);
    }

    public function getEventByExternalId(int $externalId)
    {
        return $this->eventRepository->findOneBy(['externalId' => $externalId]);
    }

    public function getEventsWithAnExternalId()
    {
        return $this->eventRepository->getEventsWithAnExternalId();
    }

    /**
     * Delete an event.
     *
     * @param Event $event The event to delete
     */
    public function deleteEvent(Event $event)
    {
        $this->entityManager->remove($event);
        $this->entityManager->flush();
    }
}