src/Service/AnimalService.php line 564
<?php
namespace App\Service;
use App\Entity\Animal;
use App\Entity\AnimalSearch;
use App\Entity\File;
use App\Entity\Species;
use App\Entity\UserLoyaltyPoint;
use App\Entity\UserLoyaltyPointBid;
use App\Form\AnimalSearchForm;
use App\Repository\AnimalRepository;
use App\Repository\AnimalSearchRepository;
use App\Repository\FileRepository;
use App\Repository\UserLoyaltyPointBidRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
use Dompdf\Dompdf;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Twig\Environment;
/**
* Bag of useful animal methods
*
* @author Michał Zbieranek <michal.zbieranek@kansi.pl>
*/
class AnimalService
{
const PDF_VOUCHER_FILE_PATH = 'pdf_voucher';
/** @var ManagerRegistry */
private ManagerRegistry $entityManager;
/** @var AuthorizationCheckerInterface */
private $authorizationChecker;
/** @var FileRepository */
private $fileRepository;
/** @var AnimalRepository */
private $animalRepository;
/** @var Router */
private $router;
/** @var TokenStorage */
private $tokenStorage;
/** @var SortService */
private $sortService;
/** @var FormFactory */
private $formFactory;
/** @var AnimalSearchRepository */
private $animalSearchRepository;
/** @var UserService */
private $userService;
/** @var UserLoyaltyPointBidRepository */
private $userLoyaltyPointBidRepository;
/** @var bool */
private $vouchersSending;
/** @var array */
private $vouchersAddEmails;
/** @var DomPdf */
private $pdf;
/** @var RequestStack */
private $requestStack;
/**
* @var MailerInterface
*/
private MailerInterface $mailer;
public function __construct(
UserService $userService,
SortService $sortService,
ManagerRegistry $entityManager,
TokenStorageInterface $tokenStorage,
UserLoyaltyPointBidRepository $userLoyaltyPointBidRepository,
AuthorizationCheckerInterface $authorizationChecker,
Environment $templating,
MailerInterface $mailer
) {
$this->userService = $userService;
$this->sortService = $sortService;
$this->entityManager = $entityManager;
$this->tokenStorage = $tokenStorage;
$this->userLoyaltyPointBidRepository = $userLoyaltyPointBidRepository;
$this->authorizationChecker = $authorizationChecker;
$this->templating = $templating;
$this->mailer = $mailer;
}
/**
* @param array $params
* @return array
*/
public function prepareSortURLs($params)
{
return $this->sortService->prepareSortURLs($params);
}
/**
* Add animal and clear pictures session
* @param Request $request
* @param Animal $animal
* @param Form $form
* @return void
*/
public function addAnimal(Request $request, Animal $animal, Form $form)
{
$this->addPicturesFromSession($animal, $request);
$this->setFeaturedImage($animal, $form);
$this->entityManager->getManager()->persist($animal);
$this->entityManager->getManager()->flush();
$request->getSession()->set('animalPictures', new ArrayCollection());
$this->sentVoucher(
$animal,
[
$animal->getTemporaryHouse()->getEmail()
]
);
if ($this->vouchersSending) {
//When adding voucher is always sent
$animal->setIsVoucherDTSent(true);
}
}
private function sendInfoToTempHouse($animal)
{
$email = (new TemplatedEmail())
->from('no-reply@adopciaki.pl')
->to(new Address($animal->getTemporaryHouse()->getEmail()))
->subject('Gratulacje')
->htmlTemplate('front/animal/emails/publishedAnimal.html.twig')
->context([
'animal' => $animal,
]);
try {
$this->mailer->send($email);
} catch (TransportExceptionInterface $e) {
return $e->getMessage();
}
return true;
}
/**
* @param Animal $animal
* @param array $email [email => name]
* @return bool
*/
public function sentVoucher(Animal $animal, array $email)
{
if (!$this->vouchersSending) {
if (empty($email)) {
$email = (new TemplatedEmail())
->from('no-reply@adopciaki.pl')
->to($this->vouchersAddEmails)
->subject('Nie udało się wysłać vouchera')
->htmlTemplate('admin/animal/no_voucher.html.twig')
->context([
'animal' => $animal,
]);
try {
$this->mailer->send($email);
} catch (TransportExceptionInterface $e) {
return $e->getMessage();
}
} else {
$emails = $email;
$pdfFile = $this->prepareVoucherPdf($animal);
$email = (new TemplatedEmail())
->from('no-reply@adopciaki.pl')
->to(...$emails)
->addPart(new DataPart($pdfFile, 'voucher.pdf', 'application/pdf'))
->subject('Voucher!')
->htmlTemplate('front/animal/emails/pdf_voucher.html.twig')
->context([
'animal' => $animal,
]);
try {
$this->mailer->send($email);
} catch (TransportExceptionInterface $e) {
return $e->getMessage();
}
}
}
$this->vouchersSending = true;
return true;
}
/**
* @param Animal $animal
* @param array $email [email => name]
* @return bool
*/
public function sentTestVoucher(Animal $animal)
{
$testEmail = 'develop.kostenko@gmail.com';
$pdfFile = $this->prepareVoucherPdf($animal);
$email = (new TemplatedEmail())
->from('no-reply@adopciaki.pl')
->to($testEmail)
->addPart(new DataPart($pdfFile, 'voucher.pdf', 'application/pdf'))
->subject('Voucher!')
->htmlTemplate('front/animal/emails/pdf_voucher.html.twig')
->context([
'animal' => $animal,
]);
try {
$this->mailer->send($email);
} catch (TransportExceptionInterface $e) {
return $e->getMessage();
}
return true;
}
/**
* @param Animal $animal
* @return string path to PDF file
*/
private function prepareVoucherPdf(Animal $animal)
{
$html = $this->templating->render('admin/animal/voucher_pdf.html.twig', ['animal' => $animal]);
$pdf = new Dompdf();
$pdf->loadHtml($html);
$options = new \Dompdf\Options();
$options->set('isFontSubsettingEnabled', true);
$options->set('isRemoteEnabled', true);
$pdf->setOptions($options);
$customPaper = array(0,0,1050,1450);
$pdf->setPaper($customPaper);
$pdf->render();
return $pdf->output();
}
/**
* Add animal and clear pictures session
* @param Request $request
* @param Animal $animal
* @param Form $form
* @return void
*/
public function editAnimal(Request $request, Animal $animal, Form $form)
{
//if adoption date is just set, send voucher
$animalDBData = $this->entityManager->getManager()->getUnitOfWork()->getOriginalEntityData($animal);
if (empty($animalDBData['ownerEmail']) && !empty($animal->getOwnerEmail())) {
$this->sentVoucher($animal, [$animal->getOwnerEmail()]);
$animal->setIsVoucherDSSent(true);
}
$animal->setPictures(new ArrayCollection());
$this->addPicturesFromSession($animal, $request);
$this->userService->changeAnimalOwnerRole($animal, $form);
$this->setFeaturedImage($animal, $form);
//if points not added check if post is published and add points
$pointsAdded = $animal->getIsPointAdded();
if (!$pointsAdded) {
$isPublished = $form->getData()->getIsPublished();
if ($isPublished) {
$this->addLoyaltyPoints($animal);
$form->getData()->setIsPointAdded(true);
}
}
//if is publishing
if (!$animalDBData['isPublished']) {
if ($form->getData()->getIsPublished()) {
$this->sendInfoToTempHouse($animal);
}
}
$this->entityManager->getManager()->flush();
return true;
}
/**
* Return AdvancedSearchedForm with AnimalSearched entity
* @return Form
*/
public function prepareAdvancedSearchedForm()
{
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
$isAuth = true;
} else {
$isAuth = false;
}
$user = $this->tokenStorage->getToken()->getUser();
if ($isAuth) {
$animalSearch = $this->animalSearchRepository->findOneBy(['user' => $user]);
}
if (empty($animalSearch)) {
$animalSearch = new AnimalSearch();
if ($isAuth) {
$animalSearch->setUser($user);
}
}
$searchForm = $this->formFactory->create(AnimalSearchForm::class, $animalSearch, ['isAuth' => $isAuth]);
return $searchForm;
}
/**
* @param Request $request
* @param array $search = []
* @param type $notPublished = false
* @param type $notOnFb = false
* @param type $isPublished = false
* @param type $adopted = null
* @param type $olx = null
* @return QueryBuilder
*/
public function prepareIndexQB(
Request $request,
array $search,
$notPublished = false,
$notOnFb = false,
$isPublished = false,
$adopted = null,
$olx = null
) {
if (
$this->tokenStorage->getToken() &&
$this->authorizationChecker->isGranted('ROLE_HOME_TEMPORARY') &&
!$this->authorizationChecker->isGranted('ROLE_MODERATOR_HOME_TEMPORARY')
) {
$homeTemporary = $this->tokenStorage->getToken()->getUser();
} else {
$homeTemporary = null;
}
$order = $request->get('o', 'DESC');
$sortField = $request->get('s', 'id');
$animalsQb = $this->entityManager->getRepository(Animal::class)->findAllqb(
$sortField,
$order,
$homeTemporary,
$search,
$notPublished,
$notOnFb,
$isPublished,
$adopted,
$olx
);
return $animalsQb;
}
/**
* @param Request $request
* @param $homeTemporary
* @param $search
* @return QueryBuilder
*/
public function prepareHomeTemporaryQB(Request $request, $homeTemporary, $search)
{
$order = $request->get('o', 'DESC');
$sortField = $request->get('s', 'id');
$animalsQb = $this->entityManager->getRepository(Animal::class)->findAllqb(
$sortField,
$order,
$homeTemporary,
$search,
false,
false,
false
);
return $animalsQb;
}
/**
*
* Prepare advanced search criteria for frontend part
* @param AnimalSearch $animalSearch
* @return array
*/
public function prepareAdvancedSearchCriteria(AnimalSearch $animalSearch)
{
$searchCriteria = [];
if (!empty($animalSearch->getSpecies())) {
$searchCriteria['species'] = $animalSearch->getSpecies()->getId();
}
$sex = $animalSearch->getSex();
if ($sex->isEmpty() === false) {
$searchCriteria['sex'] = [];
foreach ($sex as $item) {
$searchCriteria['sex'][] = $item->getId();
}
}
$age = $animalSearch->getAge();
if ($age->isEmpty() === false) {
$searchCriteria['age'] = [];
foreach ($age as $item) {
$searchCriteria['age'][] = $item;
}
}
$weight = $animalSearch->getWeight();
if ($weight->isEmpty() === false) {
$searchCriteria['weight'] = [];
foreach ($weight as $item) {
$searchCriteria['weight'][] = $item;
}
}
$size = $animalSearch->getSize();
if ($size->isEmpty() === false) {
$searchCriteria['size'] = [];
foreach ($size as $item) {
$searchCriteria['size'][] = $item;
}
}
if (!empty($animalSearch->getLifeStyle())) {
$searchCriteria['lifeStyle'] = $animalSearch->getLifeStyle()->getId();
}
$kidAcceptances = $animalSearch->getKidAcceptances();
if ($kidAcceptances->isEmpty() === false) {
$searchCriteria['kidAcceptances'] = [];
foreach ($kidAcceptances as $kidAcceptance) {
$searchCriteria['kidAcceptances'][] = $kidAcceptance;
}
}
$animalAcceptances = $animalSearch->getAnimalAcceptances();
if ($animalAcceptances->isEmpty() === false) {
$searchCriteria['notAcceptings'] = [];
foreach ($animalAcceptances as $animalAcceptance) {
$searchCriteria['notAcceptings'][] = $animalAcceptance;
}
}
$preferableLives = $animalSearch->getPreferableLives();
if ($preferableLives->isEmpty() === false) {
$searchCriteria['preferableLives'] = [];
foreach ($preferableLives as $preferableLive) {
$searchCriteria['preferableLives'][] = $preferableLive->getId();
}
}
if (!empty($animalSearch->getTimeCareNeeded())) {
$searchCriteria['timeCareNeeded'] = $animalSearch->getTimeCareNeeded()->getId();
}
$searchCriteria['isPublished'] = true;
return $searchCriteria;
}
/**
* Copy pictures from session to entity collection
* @param Animal $animal
* @param Request $request
* @return void
*/
private function addPicturesFromSession(Animal $animal, Request $request)
{
$pictures = $request->getSession()->get('animalPictures');
if (!$pictures->isEmpty()) {
foreach ($pictures as $picture) {
if($picture) {
$file = $this->entityManager->getRepository(File::class)->find($picture->getId());
$animal->addPicture($file);
}
}
}
$request->getSession()->set('animalPictures', new ArrayCollection());
}
public function getSimilarAnimals(Animal $animal) {
$criteria = [
'species' => $animal->getSpecies(),
'sex' => $animal->getSex(),
'size' => $animal->getSize(),
'isPublished' => true,
'adoptionDate' => null
];
return $this->entityManager->getRepository(Animal::class)->findBy($criteria, [], 6);
}
/**
* @param type $id
* @return Animal
*/
public function getSingleAnimal($id, $checkRole = true)
{
$criteria = ['id' => $id];
if ($checkRole) {
if ($this->authorizationChecker->isGranted(
'ROLE_HOME_TEMPORARY'
) && !$this->authorizationChecker->isGranted('ROLE_MODERATOR_HOME_TEMPORARY')) {
$author = $this->tokenStorage->getToken()->getUser();
$criteria['temporaryHouse'] = $author;
}
}
$animal = $this->entityManager->getRepository(Animal::class)->findOneBy($criteria);
if (empty($animal)) {
throw new Exception('Zwierzak '.$id.' nie istnieje');
}
return $animal;
}
/**
* @param Animal $animal
* @param Form $form
*/
private function setFeaturedImage(Animal $animal, Form $form)
{
$_featuredImageId = $form->get('_featuredImageId')->getData();
if (!empty($_featuredImageId) && count($animal->getPictures()) > 0) {
//chose featured image from animal pictures collection
$properImage = $animal->getPictures()->filter(
function (File $file) use ($_featuredImageId) {
if ($_featuredImageId == $file->getId()) {
return true;
} else {
return false;
}
}
)->current();
$animal->setFeaturedImage($properImage);
}
}
/**
*
*/
private function addLoyaltyPoints(Animal $animal)
{
$user = $animal->getTemporaryHouse();
if ($user->hasRole('ROLE_HOME_TEMPORARY')) {
//different types for different species
$bidType = UserLoyaltyPointBid::TYPE_ADDING_ANIMAL;
if ($animal->getSpecies()->getType() == Species::TYPE_DOG) {
$bidType = UserLoyaltyPointBid::TYPE_ADDING_ANIMAL_DOG;
}
$bid = $this->userLoyaltyPointBidRepository->findOneBy(['type' => $bidType]);
$loyaltyPoint = new UserLoyaltyPoint();
$loyaltyPoint->setUser($user);
$loyaltyPoint->setName($bid->getName());
$loyaltyPoint->setType($bid->getType());
$loyaltyPoint->setValue($bid->getValue());
$user->addLoyaltyPoint($loyaltyPoint);
$this->entityManager->getManager()->flush();
}
}
}