<?php
/**
* Created by PhpStorm.
* User: SUSAN MEDINA
* Date: 28/03/2019
* Time: 06:10 PM
*/
namespace App\EventSubscriber\User;
use App\Exception\GeneralException;
use App\Exception\NotFoundException;
use App\MessageHandler\Message;
use App\Repository\App\TimeSlot\TimeSlotRepository;
use Doctrine\ORM\EntityManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use ApiPlatform\Core\EventListener\EventPriorities;
use Doctrine\ORM\EntityManagerInterface;
use App\Repository\App\VendorRepository;
use App\Repository\App\CompanyRepository;
use App\Services\VendorService;
use App\Services\UserService;
use App\Entity\App\User;
use App\Entity\App\Vendor;
use App\Entity\App\Role;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class UserPostWriteSubscriber implements EventSubscriberInterface
{
private $vendorRepository;
private $userService;
private $vendorService;
private $entityManager;
private $companyRepository;
private $tokenStorage;
private $translator;
private $authorizationChecker;
private $messageBus;
private $timeSlotRepository;
public function __construct(
EntityManagerInterface $entityManager,
CompanyRepository $companyRepository,
VendorRepository $vendorRepository,
VendorService $vendorService,
UserService $userService,
TokenStorageInterface $tokenStorage,
TranslatorInterface $translator,
AuthorizationCheckerInterface $checker,
MessageBusInterface $messageBus,
TimeSlotRepository $timeSlotRepository
) {
$this->entityManager = $entityManager;
$this->vendorRepository = $vendorRepository;
$this->userService = $userService;
$this->vendorService = $vendorService;
$this->companyRepository = $companyRepository;
$this->tokenStorage = $tokenStorage;
$this->translator = $translator;
$this->authorizationChecker = $checker;
$this->messageBus = $messageBus;
$this->timeSlotRepository = $timeSlotRepository;
}
/**
* @param ViewEvent $event
* @throws GeneralException
* @throws NotFoundException
* @throws \Doctrine\Common\Persistence\Mapping\MappingException
* @throws \Doctrine\DBAL\ConnectionException
* @throws \Doctrine\ORM\ORMException
*/
public function onKernelView(ViewEvent $event)
{
$user = $event->getControllerResult();
$request = $event->getRequest();
$route = $request->attributes->get('_route');
if (!($user instanceof User)) {
return;
}
if ($this->tokenStorage->getToken()) {
$userCurrent = $this->tokenStorage->getToken()->getUser();
if (!($userCurrent instanceof User)) {
throw new NotFoundException($this->translator->trans('User current not found'));
}
if (!$this->entityManager->isOpen()) {
$this->entityManager = EntityManager::create(
$this->entityManager->getConnection(),
$this->entityManager->getConfiguration()
);
}
if (false == $this->entityManager->getConnection()->ping()) {
$this->entityManager->getConnection()->close();
$this->entityManager->getConnection()->connect();
}
if ('api_users_post_collection' == $route || 'api_users_put_item' == $route) {
$dataMessage = [];
$this->entityManager->getConnection()->beginTransaction();
try {
$plainPassword = $user->getPlainPassword();
if (!is_null($plainPassword)) {
$this->userService->encodePassword($user, false, false);
}
$mediaContent = $user->getMediaContent();
if ($mediaContent !== null && $mediaContent !== 0) {
$this->userService->addMediaContent(
$user,
$mediaContent,
false,
true,
false);
}
if (is_null($user->getChannelName())) {
$user->setChannelName(md5(uniqid()));
}
if (!is_null($user->getEmail())) {
$user->setUsername($user->getEmail());
} elseif (!is_null($user->getPhonePrefixAndPhone())) {
$user->setUsername($user->getPhonePrefixAndPhone());
} elseif (!is_null($user->getPhoneNumber())) {
$user->setUsername($user->getPhoneNumber());
}
$this->entityManager->persist($user);
$data = json_decode($request->getContent(), true);
$vendor = null;
if (isset($data['vendor'])) {
$vendor = $this->vendorRepository->find($data['vendor']);
}
if ($vendor instanceof Vendor) {
if ('api_users_put_item' == $route) {
if ($this->vendorService->isUserRoleInToVendor(
$vendor,
$userCurrent,
[Role::ROLE_ADMIN]
)) {
$this->updatePassword($user);
} else {
if ($userCurrent === $user || $this->authorizationChecker->isGranted(
'ROLE_SUPERADMIN'
)) {
$this->updatePassword($user);
}
}
}
$vendorStaff = $this->vendorService->findOrCreateVendorStaff($vendor, $user, true);
if (isset($data['company']) && !is_null($data['company'])) {
$company = $this->companyRepository->find($data['company']);
$vendorStaff->setCompany($company);
} else {
$vendorStaff->setCompany(null);
}
if (isset($data['costPerHour'])) {
$vendorStaff->setCostPerHour($data['costPerHour']);
} else {
$vendorStaff->setCostPerHour(0);
}
if (isset($data['enable'])) {
$vendorStaff->setEnable($data['enable']);
}
if (isset($data['timeSlot']['id']) && !is_null($vendorStaff)){
$timeSlotRepository = $this->timeSlotRepository->find($data['timeSlot']['id']);
if(!is_null($timeSlotRepository)) {
$vendorStaff->setCostPerHour($timeSlotRepository->getDefaultCost());
}
}
if(!is_null($vendorStaff)){
$workerBudgets = $vendorStaff->getWorkerBudgets();
foreach ($workerBudgets as $workerBudget){
$workerBudget->setCostHour($vendorStaff->getCostPerHour());
}
}
$this->entityManager->persist($vendorStaff);
$messageResponse = '';
if (isset($data['roles'])) {
$this->vendorService->addRoleStaff(
$vendorStaff,
$data['roles'],
true,
$messageResponse,
false,
true);
}
if (isset($data['locations'])) {
$this->vendorService->addLocationToUser(
$vendorStaff,
$data['locations'],
true,
$messageResponse,
false,
true);
}
if (isset($data['categories'])) {
$this->vendorService->addCategoryToUser(
$vendorStaff,
$data['categories'],
$messageResponse,
false,
true);
}
if ('api_users_post_collection' == $route) {
$dataMessage['user_id'] = $user->getId();
$dataMessage['vendor_id'] = $vendor->getId();
if (!empty($user->getEmail())) {
$this->userService->sendEnterpriseWelcome($user);
}
if (!empty($user->getPhonePrefixAndPhone())) {
$this->userService->sendInvitationSMS($user);
}
}
}
$this->entityManager->flush();
$this->entityManager->getConnection()->commit();
//$this->entityManager->clear();
} catch (\Exception $exception) {
$this->entityManager->getConnection()->rollback();
$this->entityManager->remove($user);
//$this->entityManager->clear();
throw new GeneralException($exception->getMessage());
}
if ('api_users_post_collection' == $route) {
if (!empty($user->getCaptchaToken())) {
if (!empty($user->getEmail())) {
$this->userService->sendEnterpriseWelcome($user);
}
if (!empty($user->getPhonePrefixAndPhone())) {
$this->userService->sendInvitationSMS($user);
}
}
}
if (count($dataMessage) > 0) {
$this->messageBus->dispatch(new Message(Message::NEW_USER, $dataMessage));
}
}
}
}
/**
* @param User $user
* @throws \Doctrine\ORM\ORMException
*/
protected function updatePassword(User $user)
{
$plainPassword = $user->getPlainPassword();
if (!is_null($plainPassword))
$this->userService->encodePassword($user, true, false);
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::POST_WRITE]
];
}
}