<?php
namespace App\Controller;
use App\Elastica\ReviewSearch;
use App\Entity\Review;
use App\Entity\ReviewImage;
use App\Entity\User;
use App\Entity\AgencyCode;
use App\Form\ReviewSearchForm;
use App\Service\FileUploader;
use App\Service\GeocodingService;
use App\Service\MailSender;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Cocur\Slugify\SlugifyInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Translation\TranslatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class ReviewController extends AbstractController
{
/**
* @var MailSender
*/
private $mailSender;
/**
* @var TranslatorInterface
*/
private $translator;
private $parameterBag;
public function __construct(MailSender $mailSender , TranslatorInterface $translator,ParameterBagInterface $parameterBag)
{
$this->mailSender = $mailSender;
$this->translator = $translator;
$this->parameterBag = $parameterBag;
}
/**
* Show review list
* @param Request $request
* @param ReviewSearch $reviewSearch
* @return Response
* @Route("/review/list/{type}", options={"expose"=true}, name="review_list")
*/
public function listAction($type,Request $request, ReviewSearch $reviewSearch)
{
$paramsTerm = $request->query->all();
if(array_key_exists("department",$paramsTerm) && $paramsTerm['department']!="" && array_key_exists("region",$paramsTerm) && $paramsTerm['region']!=""){
$paramsTerm['publisherType'] = intval($type);
$reviewResults = $reviewSearch->searchPaginated($paramsTerm);
return $this->render('review/list.html.twig', [
'total' => $reviewResults->getTotalItemCount(),
'reviews' => $reviewResults,
'urlQuery' => http_build_query($paramsTerm),
'paramsTerm' => $paramsTerm,
]);
}
$this->addFlash('warning', 'Cette page n\'existe pas ou a été supprimé!');
return $this->redirect($this->generateUrl('advertisement_search',$paramsTerm));
}
/**
* Show Review
* @param Request $request
* @return Response
* @Route("/review/details/{id}/{slug}", name="review_show")
*/
public function show(Review $review, $slug,SlugifyInterface $slugify,Request $request)
{
if ($slug !== $slugify->slugify($review->getSlug())) {
throw new NotFoundHttpException();
}
if($review->getStatus()!= Review::STATUS_VALIDATE){
throw new NotFoundHttpException();
}
$referer = $request->headers->get('referer');
return $this->render('review/show.html.twig', [
'review' => $review,
'referer' => $referer
]);
}
/**
* Add new review
* @return Response
* @Route("/review/new", name="review_new")
*/
public function newAction()
{
$securityContext = $this->container->get('security.authorization_checker');
if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
$user = $this->getUser();
if (in_array('ROLE_USER',$user->getRoles()) && $user->getUsername()=='' ) {
$this->addFlash('error',"Compléter votre profil pour accéder à toutes les fonctionnalités du site!");
return $this->redirectToRoute('user_account');
}
if (in_array('ROLE_PRO', $user->getRoles())) {
if($user->getAgency() == null){
$this->addFlash('error', "Compléter votre profil pour accéder à toutes les fonctionnalités du site!");
return $this->redirectToRoute('complete_profil');
}else{
$this->addFlash('error', "Vous n'êtes pas autorisé à poster des avis!");
return $this->redirectToRoute('homepage');
}
}
}
return $this->render('review/new.html.twig',[]);
}
/**
* Publish new review
* @return Response
* @Route("/review/publish", name="review_publish")
*/
public function publishedMessageAction()
{
return $this->render('review/finish.html.twig',[]);
}
/**
* Remove review
* @param Review $review
* @return JsonResponse
* @Route("/review/remove/{id}", name="remove_review")
*/
public function removeReview(Review $review)
{
$user = $this->getUser();
if ($user->getId() !== $review->getUser()->getId()) {
$message = "Opération non autorisée!";
$error = true;
} else {
$em = $this->getDoctrine()->getManager();
$review->setStatus(Review::STATUS_INACTIVE);
$em->flush();
$message = "Avis supprimé avec succès!";
$error = false;
}
return new JsonResponse(['error' => $error, "message" => $message]);
}
/**
* Save review appreciation
* @param Request $request
* @return JsonResponse
* @Route("/review/helpful/save/{id}", name="save_helpful")
*/
public function saveHelpfulAction(Review $review,Request $request)
{
$user = $this->getUser();
$em = $this->getDoctrine()->getManager();
if (!$user->hasHelpfulReviews($review)) {
$review->setHelpfulCount($review->getHelpfulCount()+1);
$user->addHelpfulReviews($review);
$em->flush();
} else {
if($review->getHelpfulCount()>1){
$review->setHelpfulCount($review->getHelpfulCount()-1);
}else{
$review->setHelpfulCount(0);
}
$user->removeHelpfulReviews($review);
$em->flush();
}
return new JsonResponse();
}
/**
* Save a review
* @param Request $request
* @param FileUploader $uploader
* @return Response
* @Route("/review/save", name="save_review")
*/
public function saveReview(Request $request, FileUploader $uploader)
{
try{
$message = 'Nouvel avis publié !';
$message_type = 'success';
$em = $this->getDoctrine()->getManager();
$securityContext = $this->container->get('security.authorization_checker');
$is_logged = true;
if (!$securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
$user_email = $em->getRepository('App\Entity\User')->findOneBy(['email' => $request->get('email')]);
if($user_email!=null){
$this->addFlash('error', 'Cette adresse email est déjà enregistré! Veuillez-vous connecter à votre compte pour poster un avis!');
return $this->redirectToRoute('security_login');
}
$user = new User();
$user->setRoles(['ROLE_USER']);
$user->setEmail($request->get('email'));
$user->setPlainPassword($request->get('plainPassword'));
$user->setFirstname($request->get('firstname'));
$user->setLastname($request->get('lastname'));
$user->setCreatedAt(new \DateTime());
$user->setUsername($request->get('username'));
$ip = $request->getClientIp();
$user->setIpAddress($ip);
$token = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
$user->setValidationToken($token);
$user->setStatus(User::STATUS_INACTIVE);
$user->setIsPublisher(true);
$em->persist($user);
$em->flush();
$this->mailSender->sendActivationCode($user);
$message = "Vous allez recevoir un e-mail de confirmation à l'adresse que vous avez saisie";
$message_type = 'report';
$is_logged = false;
} else {
$user = $this->getUser();
}
$review = new Review();
$geocodingService = new GeocodingService($_ENV['GEOCODING_API_KEY'],$em);
$address = $request->get('address');
$city = $geocodingService->decodeAddress($address);
if($city==null){
$this->addFlash('warning', 'L\'adresse renseigné est incorrecte!');
return $this->redirectToRoute('review_new');
}
$review->setAddress($address);
$review->setPostalCode($city->getPostalCode());
$review->setCity($city->getCity());
$review->setDepartment($city->getDepartment()->getShortName());
$review->setRegion($city->getDepartment()->getRegion()->getLongName());
$review->setLongitude(floatval($city->getLongitude()));
$review->setLatitude(floatval($city->getLatitude()));
$review->setUser($user);
$review->setPublicationDate(new \DateTime());
$review->setPublisherType(1);
$pictures = $request->files->get('pictures');
if ($pictures) {
foreach ($pictures as $image) {
if ($image instanceof UploadedFile && in_array($image->getMimeType(), ['image/png', 'image/jpg','image/jpeg'])) {
$imageName = $uploader->uploadImage($image);
$file = new ReviewImage();
$file->setPath($imageName);
$file->setName($image->getClientOriginalName());
if (!$image->isFile()) {
continue;
}
$file->setSize($image->getClientSize());
$file->setReview($review);
$review->addImage($file);
}
}
}
//Step 4
$life = $this->checkRatingField($request->get('life'));
$security = $this->checkRatingField($request->get('security'));
$transports = $this->checkRatingField($request->get('transports'));
$greenArea = $this->checkRatingField($request->get('greenArea'));
$shops = $this->checkRatingField($request->get('shops'));
$leisure = $this->checkRatingField($request->get('leisure'));
$global = $this->checkRatingField($request->get('globalRanking'));
$water = $this->checkRatingField($request->get('water'));
$electricity = $this->checkRatingField($request->get('electricity'));
$review->setGlobal($global);
$review->setLife($life);
$review->setSecurity($security);
$review->setTransports($transports);
$review->setGreenArea($greenArea);
$review->setShops($shops);
$review->setSportsLeisure($leisure);
$review->setWater($water);
$review->setElectricity($electricity);
$reviewDescription = $request->get('review');
$review->setReview(trim($reviewDescription));
$deal = $request->get('deal');
if(isset($deal)){
$review->setDeal(trim($deal));
}
$improvements = $request->get('improvements');
if(isset($improvements) && is_array($improvements)){
$review->setImprovements(implode(",",$improvements));
}
$improvements_suggestion = $request->get('improvements_suggestion');
if(isset($improvements_suggestion)){
$review->setImprovementsSuggestion($improvements_suggestion);
}
$agency_code = $request->get('agency_code');
if(isset($agency_code) && $agency_code!=''){
$review->setAgencyCode($agency_code);
}
if($is_logged){
$review->setStatus(Review::STATUS_VALIDATE);
}else{
$review->setStatus(Review::STATUS_DISABLE);
}
$agencyCode = $em->getRepository(AgencyCode::class)->findOneBy(['agencyCode' => $agency_code]);
if($agencyCode){
$agencyCode->setCount($agencyCode->getCount() + 1);
$em->persist($agencyCode);
}
$em->persist($review);
$em->flush();
$this->addFlash($message_type, $message);
if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('review_publish');
}else{
return $this->redirectToRoute('homepage');
}
}catch(\Exception $ex){
$this->addFlash('error', 'Oup! Une erreur est survenue! Veuillez réessayer plus tard!');
echo $ex->getMessage();
return $this->redirectToRoute('homepage');
}
}
private function createUsername(User $user){
$em = $this->getDoctrine();
$firstname = explode( ' ',trim($user->getFirstname()));
$lastname = explode( ' ',trim($user->getLastname()));
$firstname = $firstname[0];
$lastname = $lastname[0];
$username = strtolower( $firstname . '.' . $lastname );
$list = $em->getEntityManager()->getRepository( User::class )->findBy(['username'=>$username]);
$length = sizeof($list);
if($length>0){
$username = $username.".";
$list = $em->getEntityManager()->getRepository( User::class )->getUserByUsername($username);
$length = sizeof($list);
if($length == 0){
$username = $username."1";
}else{
$username = $username.($length+1);
}
}
$user->setUsername($username);
}
private function checkRatingField($field){
$field = intval($field);
if($field<0){
$field = 1;
}
if($field>5){
$field = 5;
}
return $field;
}
}