<?php
namespace App\Service;
use App\DTO\Request\UserEmailUpdateMMAZ;
use App\DTO\Response\MMAZResponse;
use App\Entity\Notifications\Notification;
use App\Entity\User\User;
use App\Entity\User\UserProfile;
use App\Enums\Constants;
use App\Event\User\UserCreatedEvent;
use App\Event\User\UserRevokeEvent;
use App\Event\User\UserUpdatedEvent;
use App\Repository\App\CountryRepository;
use App\Repository\App\LanguageRepository;
use App\Repository\Notifications\NotificationRepository;
use App\Repository\User\UserProfileRepository;
use App\Repository\User\UserRepository;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class UserService
{
/** @var RequestDataExtractorService */
private $requestDataExtractorService;
/** @var EventDispatcherInterface */
private $eventDispatcher;
/** @var UserRepository **/
private $userRepository;
/** @var UserProfileRepository */
private $userProfileRepository;
/** @var CountryRepository */
private $countryRepository;
/** @var LanguageRepository */
private $languageRepository;
/** @var NotificationRepository */
private $notificationRepository;
/**
* @param RequestDataExtractorService $requestDataExtractorService
* @param EventDispatcherInterface $eventDispatcher
* @param UserRepository $userRepository
* @param UserProfileRepository $userProfileRepository
* @param CountryRepository $countryRepository
* @param LanguageRepository $languageRepository
* @param LanguageRepository $notificationRepository
*/
public function __construct(
RequestDataExtractorService $requestDataExtractorService,
EventDispatcherInterface $eventDispatcher,
UserRepository $userRepository,
UserProfileRepository $userProfileRepository,
CountryRepository $countryRepository,
LanguageRepository $languageRepository,
NotificationRepository $notificationRepository
)
{
$this->requestDataExtractorService = $requestDataExtractorService;
$this->eventDispatcher = $eventDispatcher;
$this->userRepository = $userRepository;
$this->userProfileRepository = $userProfileRepository;
$this->countryRepository = $countryRepository;
$this->languageRepository = $languageRepository;
$this->notificationRepository = $notificationRepository;
}
/**
* @param string $email
* @return object|null
*/
public function findUserByEmail(string $email)
{
return $this->userRepository->findOneBy(['email' => $email]);
}
/**
* @param array $data
* @return User
*/
public function createUserFromMMAZ(array $data)
{
$data = $this->checkDataFromMMAZ($data);
$entityUser = (new User)
->setEmail($data['email'])
->setEnabled(true)
->setTwoFactorAuthenticationEnabled($data['two_factor_authentication_enabled'])
->setStatus(Constants::USER_CREATED);
$this->userRepository->save($entityUser);
/** @var UserProfile $entityUserProfile */
$entityUserProfile = (new UserProfile())
->setFirstName($data['user_profile_first_name'])
->setLastName($data['user_profile_last_name'])
->setCountry($this->countryRepository->findOneBy(['country' => $data['user_profile_country_name']]))
->setLanguage($this->languageRepository->findOneBy(['code' => $data['user_profile_language_code']]))
->setApplications($data['applications'])
->setUser($entityUser);
$this->userProfileRepository->save($entityUserProfile);
$this->eventDispatcher->dispatch(new UserCreatedEvent($entityUser, Constants::MMAZ_REFERER));
return $entityUser;
}
/**
* @param User $entityUser
* @param array $data
* @return User
*/
public function updateUserFromMMAZ(User $entityUser, array $data)
{
$data = $this->checkDataFromMMAZ($data);
$entityUser->setEmail($data['email']);
$entityUser->setEnabled(true);
$entityUser->setTwoFactorAuthenticationEnabled($data['two_factor_authentication_enabled']);
$this->userRepository->flush($entityUser);
/** @var UserProfile $entityUserProfile */
$entityUserProfile = $entityUser->getUserProfile();
$entityUserProfile->setFirstName($data['user_profile_first_name']);
$entityUserProfile->setLastName($data['user_profile_last_name']);
$entityUserProfile->setCountry($this->countryRepository->findOneBy(['country' => $data['user_profile_country_name']]));
$entityUserProfile->setLanguage($this->languageRepository->findOneBy(['code' => $data['user_profile_language_code']]));
$entityUserProfile->setApplications($data['applications']);
$this->userProfileRepository->flush($entityUserProfile);
$this->eventDispatcher->dispatch(new UserUpdatedEvent($entityUser, Constants::MMAZ_REFERER));
return $entityUser;
}
/**
* @param UserEmailUpdateMMAZ $emailUpdateMMAZ
* @return MMAZResponse
*/
public function updateJustEmailFromMMAZ(UserEmailUpdateMMAZ $emailUpdateMMAZ)
{
$response = new MMAZResponse();
/** @var User $entityUserOld */
$entityUserOld = $this->findUserByEmail($emailUpdateMMAZ->getOldEmail());
if(is_null($entityUserOld)){
$response->setStatus("error")
->setMessage("Failed to update email. Reason: this email ({$emailUpdateMMAZ->getOldEmail()}) does not exist");
}
/** @var User $entityUserNew */
$entityUserNew = $this->findUserByEmail($emailUpdateMMAZ->getNewEmail());
if(!is_null($entityUserNew)){
$response->setStatus("error")
->setMessage("Failed to update email. Reason: this email ({$emailUpdateMMAZ->getNewEmail()}) already exist");
}
if($response->getStatus() == "error"){
return $response;
}
$entityUserOld->setEmail($emailUpdateMMAZ->getNewEmail());
$this->userRepository->flush($entityUserOld);
$response->setStatus("success")
->setMessage("Email updated successfully in MMPZ.");
return $response;
}
/**
* @param User $entityUser
* @param array $data
* @return void
*/
public function revokeAccess(User $entityUser, array $data)
{
$data = $this->requestDataExtractorService->extractDataFromAnArray([
'email',
'enabled',
'status',
'applications'
], $data);
$status = ((int)$data['status'] === 0) ? Constants::USER_SUSPEND : Constants::USER_CREATED;
$entityUser->setStatus($status);
$entityUser->setEnabled($data['enabled']);
$this->userRepository->flush($entityUser);
/** @var UserProfile $entityUserProfile */
$entityUserProfile = $entityUser->getUserProfile();
$entityUserProfile->setApplications($data['applications']);
$this->userProfileRepository->flush($entityUserProfile);
$this->eventDispatcher->dispatch(new UserRevokeEvent($entityUser, Constants::MMAZ_REFERER));
}
/**
* @param User $user
* @param $page
* @param $limit
* @return Paginator
*/
public function notificationInMeEndpoint(User $user, $page = 1, $limit = 5): Paginator
{
if($_ENV['CWR_ENVIROMENT'] === "local"){
$user = $this->findUserByEmail($_ENV['ADMIN_EMAIL']);
}
$queryBuilder = $this->notificationRepository->createQueryBuilder('notification')
->where('notification.user = :user')
->setParameter('user', $user)
->orderBy('notification.createdAt', 'DESC')
->setFirstResult(($page - 1) * $limit)
->setMaxResults($limit);
$query = $queryBuilder->getQuery();
return new Paginator($query);
}
/**
* @param array $data
* @return array
*/
private function checkDataFromMMAZ(array $data)
{
$dataChecked = $this->requestDataExtractorService->extractDataFromAnArray([
'email',
'enabled',
'status',
//'currency_code',
//'created_at',
'two_factor_authentication_enabled',
//'signed_up_to_mailing_list',
'user_profile_first_name',
'user_profile_last_name',
'user_profile_email_gc',
'user_profile_country_name',
//'user_profile_timezone',
'user_profile_language_code',
], $data);
return $dataChecked;
}
}