src/FMT/Domain/Service/Manager/UserManager.php line 177

Open in your IDE?
  1. <?php
  2. namespace FMT\Domain\Service\Manager;
  3. use Doctrine\Common\Collections\ArrayCollection;
  4. use Doctrine\ORM\QueryBuilder;
  5. use FMT\Data\Entity\User;
  6. use FMT\Data\Entity\UserContact;
  7. use FMT\Data\Entity\UserMajor;
  8. use FMT\Data\Entity\UserProfile;
  9. use FMT\Data\Entity\UserSchool;
  10. use FMT\Data\Model\BaseFilterOptions;
  11. use FMT\Data\Repository\UserContactRepository;
  12. use FMT\Domain\Event\UserEvent;
  13. use FMT\Domain\Repository\UserRepositoryInterface;
  14. use FMT\Domain\Service\CampaignManagerInterface;
  15. use FMT\Domain\Service\Synchronizer\MajorSynchronizer;
  16. use FMT\Domain\Service\Synchronizer\SchoolSynchronizer;
  17. use FMT\Domain\Service\UserManagerInterface;
  18. use FMT\Infrastructure\Helper\LogHelper;
  19. use FOS\UserBundle\Doctrine\UserManager as FOSUserManager;
  20. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  21. use FOS\UserBundle\Model\UserInterface;
  22. use FOS\UserBundle\Util\TokenGeneratorInterface;
  23. use RuntimeException;
  24. /**
  25.  * Class UserManager
  26.  * @package FMT\Domain\Service\Security
  27.  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  28.  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  29.  */
  30. class UserManager extends EventBasedManager implements UserManagerInterface
  31. {
  32.     /** @var FOSUserManager */
  33.     private $manager;
  34.     /** @var MajorSynchronizer */
  35.     private MajorSynchronizer $majorSynchronizer;
  36.     /** @var SchoolSynchronizer */
  37.     private $schoolSynchronizer;
  38.     /** @var UserRepositoryInterface */
  39.     private $userRepository;
  40.     /** @var CampaignManagerInterface */
  41.     private $campaignManager;
  42.     /**
  43.      * @var TokenStorageInterface|null
  44.      */
  45.     private $tokenStorage;
  46.     /** @var TokenGeneratorInterface */
  47.     private $tokenGenerator;
  48.     /** @var UserContactRepository */
  49.     private $userContactRepository;
  50.     /**
  51.      * UserManager constructor.
  52.      * @param FOSUserManager $manager
  53.      */
  54.     public function __construct(FOSUserManager $managerMajorSynchronizer $synchronizer)
  55.     {
  56.         $this->manager $manager;
  57.         $this->majorSynchronizer $synchronizer;
  58.     }
  59.     /**
  60.      * @param UserRepositoryInterface $repository
  61.      * @required
  62.      */
  63.     public function setUserRepository(UserRepositoryInterface $repository)
  64.     {
  65.         $this->userRepository $repository;
  66.     }
  67.     /**
  68.      * @param CampaignManagerInterface $manager
  69.      * @required
  70.      */
  71.     public function setCampaignManager(CampaignManagerInterface $manager)
  72.     {
  73.         $this->campaignManager $manager;
  74.     }
  75.     /**
  76.      * @param SchoolSynchronizer $synchronizer
  77.      * @required
  78.      */
  79.     public function setSchoolSynchronizer(SchoolSynchronizer $synchronizer)
  80.     {
  81.         $this->schoolSynchronizer $synchronizer;
  82.     }
  83.     /**
  84.      * @param TokenStorageInterface $tokenStorage
  85.      * @required
  86.      */
  87.     public function setTokenStorage(TokenStorageInterface $tokenStorage)
  88.     {
  89.         $this->tokenStorage $tokenStorage;
  90.     }
  91.     /**
  92.      * @param TokenGeneratorInterface $generator
  93.      * @required
  94.      */
  95.     public function setTokenGenerator(TokenGeneratorInterface $generator)
  96.     {
  97.         $this->tokenGenerator $generator;
  98.     }
  99.     /**
  100.      * @param UserContactRepository $userContactRepository
  101.      * @required
  102.      */
  103.     public function setUserContactRepository(UserContactRepository $userContactRepository)
  104.     {
  105.         $this->userContactRepository $userContactRepository;
  106.     }
  107.     /**
  108.      * Returns active student by student ID
  109.      *
  110.      * @param int $id
  111.      * @return User
  112.      */
  113.     public function getActiveStudent($id)
  114.     {
  115.         /** @var User $result */
  116.         $result $this->manager->findUserBy(["id" => $id]);
  117.         if (empty($result) || !$result->isActiveStudent()) {
  118.             return null;
  119.         }
  120.         return $result;
  121.     }
  122.     /**
  123.      * @param User $user
  124.      * @throws \Exception
  125.      */
  126.     public function confirm(User $user)
  127.     {
  128.         $event = new UserEvent($user);
  129.         $this->dispatch(UserEvent::CONFIRMATION_RECEIVED$event);
  130.         try {
  131.             if ($user->getId() === null) {
  132.                 // TODO: Replace with domain-based exception of corresponding type
  133.                 throw new \Exception("Unable to confirm user that is not exist yet");
  134.             }
  135.             $user
  136.                 ->setEnabled(true)
  137.                 ->setConfirmationToken(null);
  138.             $this->dispatch(UserEvent::CONFIRMATION_SUCCESS$event);
  139.             $this->manager->updateUser($user);
  140.         } catch (\Exception $exception) {
  141.             $this->dispatch(UserEvent::CONFIRMATION_FAILED$event);
  142.             throw $exception;
  143.         }
  144.     }
  145.     /**
  146.      * @param User $user
  147.      * @return User
  148.      * @throws RuntimeException
  149.      */
  150.     public function create(User $user)
  151.     {
  152.         $event = new UserEvent($user);
  153.         $this->dispatch(UserEvent::SIGNUP_STARTED$event);
  154.         try {
  155.             if ($user->getId() !== null) {
  156.                 // TODO: Replace with domain-based exception of corresponding type
  157.                 throw new RuntimeException("This user already registered");
  158.             }
  159.             $user->setPassword(base64_encode(uniqid(''true)));
  160.             $this->manager->updateUser($user);
  161.         } catch (RuntimeException $exception) {
  162.             $this->dispatch(UserEvent::SIGNUP_FAILED$event);
  163.             throw $exception;
  164.         }
  165.         $this->dispatch(UserEvent::SIGNUP_SUCCESS$event);
  166.         return $user;
  167.     }
  168.     /**
  169.      * @param UserInterface $user
  170.      * @return UserInterface
  171.      */
  172.     public function findOrCreateDonorAsContact(UserInterface $user)
  173.     {
  174.         if ($existingDonor $this->manager->findUserByEmail($user->getEmail())) {
  175.             return $existingDonor;
  176.         }
  177.         $event = new UserEvent($user);
  178.         $this->dispatch(UserEvent::CONTACT_SIGNUP_INITIATED$event);
  179.         try {
  180.             if ($user->getId() !== null) {
  181.                 throw new RuntimeException('This user is already exist');
  182.             }
  183.             $user->setPassword(base64_encode(uniqid(''true)));
  184.             $user->setConfirmationToken($this->tokenGenerator->generateToken());
  185.             $this->manager->updateUser($user);
  186.         } catch (RuntimeException $exception) {
  187.             $this->dispatch(UserEvent::SIGNUP_FAILED$event);
  188.             throw $exception;
  189.         }
  190.         return $user;
  191.     }
  192.     /**
  193.      * @param User $user
  194.      * @param bool $allowNotEnabled
  195.      * @throws \Exception
  196.      */
  197.     public function update(User $userbool $allowNotEnabled false)
  198.     {
  199.         $event = new UserEvent($user);
  200.         try {
  201.             if (!$user->isEnabled() && !$allowNotEnabled) {
  202.                 throw new \Exception("You can't change password. User is disabled.");
  203.             }
  204.             $this->dispatch(UserEvent::USER_UPDATED$event);
  205.             $this->dispatch(UserEvent::USER_PROFILE_UPDATED$event);
  206.             $this->manager->updateUser($user);
  207.         } catch (\Exception $exception) {
  208.             $this->dispatch(UserEvent::SIGNUP_FAILED$event);
  209.             throw $exception;
  210.         }
  211.     }
  212.     /**
  213.      * @param bool $forActiveCampaign
  214.      * @return UserMajor[]|ArrayCollection
  215.      * @codeCoverageIgnore
  216.      */
  217.     public function getMajors($forActiveCampaign false)
  218.     {
  219.         /** @var User $user */
  220.         $user $this->tokenStorage->getToken()->getUser();
  221.         $schoolId $user->getProfile()->getSchool()->getId();
  222.         return $this->majorSynchronizer
  223.             ->setForActiveCampaign($forActiveCampaign)
  224.             ->setVisibilityData(
  225.                 $this->getVisibilityData()
  226.             )
  227.             ->synchronizeBySchool($schoolId);
  228.     }
  229.     /**
  230.      * @return UserSchool[]|array
  231.      * @codeCoverageIgnore
  232.      */
  233.     public function getSchools()
  234.     {
  235.         return $this->schoolSynchronizer->synchronize();
  236.     }
  237.     /**
  238.      * @param User $user
  239.      * @return User
  240.      */
  241.     public function createOrUpdateUser(User $user)
  242.     {
  243.         $result $this->manager->findUserBy(["login" => $user->getLogin()]);
  244.         if (empty($result)) {
  245.             LogHelper::info("User %s is not found - creating new one"$user->getLogin());
  246.             $result $user;
  247.             $result->setEnabled(false);
  248.             $this->manager->updateUser($result);
  249.         } else {
  250.             LogHelper::info("User %s already exists"$user->getLogin());
  251.         }
  252.         return $result;
  253.     }
  254.     /**
  255.      * @param User $student
  256.      * @param User $contact
  257.      * @param bool $assignToCampaign
  258.      * @return UserContact
  259.      */
  260.     public function addContact(User $studentUser $contact$assignToCampaign false)
  261.     {
  262.         if (!$student->isActiveStudent()) {
  263.             throw new \RuntimeException("This user could not attach contacts");
  264.         }
  265.         LogHelper::debug(
  266.             "Creating contact %s %s (%s) for student #%d",
  267.             $contact->getProfile()->getFirstName(),
  268.             $contact->getProfile()->getLastName(),
  269.             $contact->getLogin(),
  270.             $student->getId()
  271.         );
  272.         /** @var User $donor */
  273.         $donor $this->findOrCreateDonorAsContact($contact);
  274.         $isNew = !($userContact $student->findContact($donor));
  275.         if ($isNew) {
  276.             $userContact $student->addContact($donor);
  277.         }
  278.         $userContact->setFirstName($contact->getProfile()->getFirstName());
  279.         $userContact->setLastName($contact->getProfile()->getLastName());
  280.         $this->manager->updateUser($donor);
  281.         if ($isNew) {
  282.             $this->dispatch(UserEvent::USER_CONTACT_ADDED, new UserEvent($student));
  283.         } else {
  284.             $userContact->setContactWasDeleted(false);
  285.             $this->userContactRepository->save($userContact);
  286.         }
  287.         if ($assignToCampaign && ($campaign $student->getUnfinishedCampaign())) {
  288.             LogHelper::debug("Adding contact to the campaign #%d"$campaign->getId());
  289.             $campaignContact $this->campaignManager->assignContact($campaign$userContact);
  290.             $userContact->addCampaignContact($campaignContact);
  291.             $this->userRepository->save($userContact);
  292.         }
  293.         return $userContact;
  294.     }
  295.     /**
  296.      * @param $email
  297.      * @return null|object|User
  298.      * @codeCoverageIgnore
  299.      */
  300.     public function getUserByEmail($email)
  301.     {
  302.         return $this->manager->findUserByEmail($email);
  303.     }
  304.     /**
  305.      * @return User
  306.      */
  307.     public function makeDonor()
  308.     {
  309.         $user = new User();
  310.         $user->setRoles([User::ROLE_INCOMPLETE_DONOR]);
  311.         $user->getProfile()->setVisible(UserProfile::VISIBILITY_NON);
  312.         return $user;
  313.     }
  314.     /**
  315.      * @return User
  316.      */
  317.     public function makeStudent()
  318.     {
  319.         $user = new User();
  320.         $user->setRoles([User::ROLE_INCOMPLETE_STUDENT]);
  321.         return $user;
  322.     }
  323.     /**
  324.      * @param User $user
  325.      * @return User
  326.      */
  327.     public function completeUser(User $user)
  328.     {
  329.         if ($user->isIncompleteDonor()) {
  330.             $user->setRoles([User::ROLE_DONOR]);
  331.         } elseif ($user->isIncompleteStudent()) {
  332.             $user->setRoles([User::ROLE_STUDENT]);
  333.         }
  334.         return $user;
  335.     }
  336.     /**
  337.      * @param BaseFilterOptions $formFilterParams
  338.      * @return QueryBuilder
  339.      */
  340.     public function getDonatedStudentsFiltered(BaseFilterOptions $formFilterParams)
  341.     {
  342.         $user $this->tokenStorage->getToken()->getUser();
  343.         return $this->userRepository->getDonatedStudentsFiltered($formFilterParams$user);
  344.     }
  345.     /**
  346.      * @param UserInterface $user
  347.      */
  348.     public function disableAccount(UserInterface $user)
  349.     {
  350.         $newLogin sprintf('%s%s%s'$user->getEmail(), User::DELETED_USER_DELIMITER_MARKtime());
  351.         $user->setLogin($newLogin);
  352.         $user->setEnabled(false);
  353.         if($user->isStudent()) {
  354.             $campaign $user->hasUnfinishedCampaign()
  355.                 ? $user->getUnfinishedCampaign()
  356.                 : $this->campaignManager->getLastFinishedCampaign($user);
  357.             if ($campaign) {
  358.                 $campaign->setPaused(true);
  359.                 $this->campaignManager->update($campaign);
  360.             }
  361.         }
  362.         $this->manager->updateUser($user);
  363.     }
  364.     /**
  365.      * @return array
  366.      */
  367.     protected function getVisibilityData()
  368.     {
  369.         $visibility = [UserProfile::VISIBILITY_ALL];
  370.         $token $this->tokenStorage->getToken();
  371.         if (null !== $token && $token->getUser() instanceof User) {
  372.             $visibility[] = UserProfile::VISIBILITY_REGISTRED;
  373.         }
  374.         return $visibility;
  375.     }
  376. }