src/Controller/DefaultController.php line 102

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\AccountTransactions;
  4. use App\Entity\Auctions;
  5. use App\Entity\AuctionVehicleBids;
  6. use App\Entity\AuctionVehicles;
  7. use App\Entity\ContentPages;
  8. use App\Entity\VehicleClients;
  9. use App\Entity\VehicleMakers;
  10. use App\Entity\VehicleModels;
  11. use App\Entity\Vehicles;
  12. use App\Service\VehicleHelper;
  13. use Doctrine\ORM\Query\Expr\Math;
  14. use DoctrineExtensions\Query\Mysql\Date;
  15. use Knp\Component\Pager\PaginatorInterface;
  16. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  17. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  18. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  19. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  20. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  21. use Symfony\Component\Form\Extension\Core\Type\TextType;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  24. use Symfony\Component\Security\Core\User\UserInterface;
  25. use Symfony\Contracts\Translation\TranslatorInterface;
  26. /**
  27.  * Class DefaultController
  28.  * @package App\Controller
  29.  */
  30. class DefaultController extends AbstractController
  31. {
  32.     /**
  33.      * @param Request $request
  34.      *
  35.      * @Route("/", name="homepage")
  36.      * @Method("GET")
  37.      *
  38.      * @return \Symfony\Component\HttpFoundation\Response
  39.      * @throws \Doctrine\ORM\NonUniqueResultException
  40.      */
  41.     public function indexAction(Request $requestPaginatorInterface $paginator)
  42.     {
  43.         $em     $this->getDoctrine()->getManager();
  44.         //the video to show with auction info
  45.         $video $em->getRepository(ContentPages::class)->findOneBy(['keyword' => 'video']);
  46.         $locale $request->getLocale();
  47.         $session $request->getSession();
  48.         $data $this->getOngoingAuctionVehicles($request$paginator);
  49.         // to set init before load page and jq
  50.         $countDown = [];
  51.         $checkNoMinus true;
  52.         $auctionFinished false;
  53.          if($data['endDate']){
  54.              // set default timezone
  55.              date_default_timezone_set('Asia/Riyadh'); // CDT
  56.              $datetime1 = new \DateTime();
  57.              $datetime2 $data['endDate'];
  58.              $interval $datetime1->diff($datetime2);
  59.              $days$interval->format('%a');
  60.              $hours =$interval->format('%h') ;
  61.              $mins $interval->format('%i');
  62.               if($datetime2 $datetime1 ){
  63.                  $checkNoMinus false;
  64.                  if($days <= 5){
  65.                      $auctionFinished true;
  66.                  }
  67.              }else{
  68.                  $countDown['days'] = $days ;
  69.                  $countDown['hours'] = $hours ;
  70.                  $countDown['mins'] = $mins ;
  71.              }
  72.          }
  73.         // index.html.twig will be used if there is an ongoing auction. Otherwise: index-without-auction.html.twig
  74.         $homepageTemplate $this->getParameter('homepage_template');
  75.         
  76.         $auctionTermsContent $em->getRepository(ContentPages::class)->findOneBy(['keyword' => 'auction_terms']);
  77.         // replace this example code with whatever you need
  78.         return $this->render($homepageTemplate, [
  79.             'searchForm'      => $data['searchForm']->createView(),
  80.             'auctionVehicles' => $data['auctionVehicles'],
  81.             'locale'          => $locale,
  82.             'imageRealPath'   => $data['imageRealPath'],
  83.             'totalResult'     => $data['totalResult'],
  84.             'loggedUser'      => $this->getUser(),
  85.             'endDate'         => $data['endDate'],
  86.             'auctionStatus'   => $data['auctionStatus'],
  87.             'countDown'       => $countDown,
  88.             'checkNoMinus'    => $checkNoMinus,
  89.             'auctionFinished' => $auctionFinished,
  90.             'auction' => $data['auction'],
  91.             'video' => $video,
  92.             'auctionTermsContent' => $auctionTermsContent
  93. /*            'homepage'        => $this->getParameter('homepage')*/
  94.         ]);
  95.     }
  96.     /**
  97.      * @param Request $request
  98.      *
  99.      * @Route("/auctionVehicles", name="auction_vehicles")
  100.      * @Method("GET")
  101.      *
  102.      * @return \Symfony\Component\HttpFoundation\Response
  103.      * @throws \Doctrine\ORM\NonUniqueResultException
  104.      */
  105.     public function auctionVehicles(Request $request)
  106.     {
  107.         $data $this->getOngoingAuctionVehicles($request'auctionVehicles');
  108.         return $this->render('default/auction_vehicles.html.twig', [
  109.             'searchForm'      => $data['searchForm']->createView(),
  110.             'auctionVehicles' => $data['auctionVehicles'],
  111.             'locale'          => $data['locale'],
  112.             'imageRealPath'   => $data['imageRealPath'],
  113.             'totalResult'     => $data['totalResult']
  114.         ]);
  115.     }
  116.     /**
  117.      * @param $vehicleId
  118.      * @param Request $request
  119.      * @param UserInterface $user
  120.      *
  121.      * @Route("/vehicleDetails/{vehicleId}", name="vehicle_details")
  122.      * @Method({"GET", "POST"})
  123.      *
  124.      * @return \Symfony\Component\HttpFoundation\Response
  125.      * @throws \Doctrine\DBAL\ConnectionException
  126.      * @throws \Doctrine\ORM\NonUniqueResultException
  127.      * @throws \Doctrine\ORM\ORMException
  128.      * @throws \Doctrine\ORM\OptimisticLockException
  129.      */
  130.     public function vehicleDetailsAction($vehicleIdRequest $requestTranslatorInterface $translatorAuthorizationCheckerInterface $authUserInterface $user null)
  131.     {
  132.         // if the user was not logged in and press the login url in this action page we redirect him to this action and send login parameter equal 1 with the url
  133.         $requireLogin $request->get('login');
  134.         $loggedinUser $auth->isGranted(['IS_AUTHENTICATED_FULLY''IS_AUTHENTICATED_REMEMBERED']);
  135.         if ($requireLogin && !$loggedinUser) {
  136.             throw $this->createAccessDeniedException();
  137.         } elseif ($requireLogin && $loggedinUser) { // after redirect the logged in user we remove the parameter login
  138.             $request->query->remove('login');
  139.             return $this->redirectToRoute('vehicle_details', array('vehicleId' => $vehicleId));
  140.         }
  141.         $em            $this->getDoctrine()->getManager();
  142.         $locale        $request->getLocale();
  143.         $vehicle       $em->getRepository(Vehicles::class)->find($vehicleId);
  144.         $imageRealPath $this->getParameter('vehicle_uploaded_files') . '/';
  145.         if ($user) {
  146.             $auctionVehicle    $em->getRepository(Auctions::class)->getAuctionVehicleAtOngoingAuction($vehicleId);
  147.             $auctionVehicleId  $auctionVehicle->getAuctionVehicleId();
  148.             $auctionVehicleBid $em->getRepository(AuctionVehicleBids::class)->findOneBy(['auctionVehicle' => $auctionVehicleId'bidder' => $user->getUserId()]);
  149.             if (!$auctionVehicleBid) {
  150.                 $auctionVehicleBid = new AuctionVehicleBids();
  151.             }
  152.         } else {
  153.             $auctionVehicleBid = new AuctionVehicleBids();
  154.         }
  155.         $bidForm $this->createFormBuilder($auctionVehicleBid)
  156.             ->setMethod('POST')
  157.             ->add('bidValue'TextType::class, array(
  158.                 'required'           => false,
  159.                 'label'              => 'add your bid',
  160.                 'translation_domain' => 'vehicles',
  161.                 'data'               => $auctionVehicleBid->getBidValue()
  162.             ))
  163.             ->getForm();
  164.         $bidForm->handleRequest($request);
  165.         if ($bidForm->isSubmitted()) {
  166.             //a default success flash message
  167.             $session $request->getSession();
  168.             $vehicleClient $em->getRepository(VehicleClients::class)->find($user->getUserId());
  169.             //[1.1] suspend auto-commit until ensuring that balance funds covers all auction security locks
  170.             $em->getConnection()->beginTransaction();
  171.             //[1.2] insert\update\delete bids according user data entries
  172.             $transactionsRepo =  $this->getDoctrine()->getManager()->getRepository(AccountTransactions::class);
  173.             //if a new bid and its value is entered then prepare it for saving
  174.             if (!$auctionVehicleBid->getBiddingId() && $auctionVehicleBid->getBidValue()) {
  175.                 $auctionVehicleBid->setBidder($vehicleClient);
  176.                 $auctionVehicle->addAuctionVehicleBid($auctionVehicleBid);
  177.                 $this->getDoctrine()->getManager()->persist($auctionVehicleBid);
  178.                 $this->getDoctrine()->getManager()->flush($auctionVehicleBid);
  179.                 $transactionsRepo->createAucSecTrans($auctionVehicleBid$user$user);
  180.             }
  181.             //if a new bid but no bid value entered then remove the bid object
  182.             elseif (!$auctionVehicleBid->getBiddingId() && !$auctionVehicleBid->getBidValue()) {
  183.                 $auctionVehicleBid->setAuctionVehicle(null);
  184.                 $auctionVehicle->removeAuctionVehicleBid($auctionVehicleBid);
  185.             }
  186.             //if an existing bid but no bid value entered then remove the bid from DB
  187.             elseif ($auctionVehicleBid->getBiddingId() && !$auctionVehicleBid->getBidValue()) {
  188.                 //unlock the auction security locking transaction and update user locked security amount
  189.                 $transactionsRepo->deleteBidTrans($auctionVehicleBid->getAuctionSecTransaction(), $this->getUser());
  190.                 $this->getDoctrine()->getManager()->remove($auctionVehicleBid);
  191.                 $this->getDoctrine()->getManager()->flush($auctionVehicleBid);
  192.             }
  193.             //if none of the above, then it is a existing bid value editing operation
  194.             else {
  195.                 $this->getDoctrine()->getManager()->flush($auctionVehicleBid);
  196.             }
  197.             //[1.3] calculate unrestricted funds after applying user bids
  198.             $balance            = (float)$user->getBalance();
  199.             $lockedOtSec        $user->getLockedOtSecurity();
  200.             $balanceAfterAction $balance -$lockedOtSec;
  201.             //[1.4] decide whether rollback or commit changes
  202.             if ($balanceAfterAction 0
  203.                 &&
  204.                 ($balance || $lockedOtSec ) ) {
  205.                 //[1.4.1] prevent either negative balance or negative security locks even if valid remaining funds. This odd case
  206.                 //might happen due to wrong balance or wrong security locks from the begining
  207.                 $session->getFlashBag()->add('warning',
  208.                     $translator->trans('error! balance cant be negative', array(), 'clients')
  209.                 );
  210.                 $em->getConnection()->rollBack();
  211.             } elseif ( $balanceAfterAction ) {
  212.                 //[1.4.2] the balance funds doesn't cover the requested action transactions
  213.                 $session->getFlashBag()->add('warning',
  214.                     $translator->trans('balance is less than the transaction with this amount', array('%{amount}'=> abs($balanceAfterAction) ), 'clients')
  215.                 );
  216.                 $em->getConnection()->rollBack();
  217.             } else {
  218.                 //[1.4.3] if no errors then commit changes to DB
  219.                 $session->getFlashBag()->add('success',
  220.                     $translator->trans('bids have been saved successfully', array(), 'clients')
  221.                 );
  222.                 $em->getConnection()->commit();
  223.             }
  224.         }
  225.         return $this->render('default/vehicle_details.html.twig', array(
  226.             'vehicle'       => $vehicle,
  227.             'locale'        => $locale,
  228.             'imageRealPath' => $imageRealPath,
  229.             'bidForm'       => $bidForm->createView()
  230.         ));
  231.     }
  232.     /**
  233.      * @param Request $request
  234.       * @return mixed
  235.      * @throws \Doctrine\ORM\NonUniqueResultException
  236.      */
  237.     private function getOngoingAuctionVehicles(Request $requestPaginatorInterface $paginator)
  238.     {
  239.         $em            $this->getDoctrine()->getManager();
  240.         $locale        $request->getLocale();
  241.         $vehicleHelper = new VehicleHelper();
  242.         $searchForm $this->createFormBuilder()
  243.             ->setMethod('GET')
  244.             ->add('maker'EntityType::class, array(
  245.                 'class'              => VehicleMakers::class,
  246.                 'label'              => 'Vehicle Maker',
  247.                 'choice_label'       => 'name' ucfirst($locale),
  248.                 'placeholder'        => 'Please Select',
  249.                 'required'           => false,
  250.                 'translation_domain' => 'vehicles'
  251.             ))
  252.             ->add('model'EntityType::class, array(
  253.                 'required'           => false,
  254.                 'label'              => 'Vehicle Model',
  255.                 'class'              => VehicleModels::class,
  256.                 'choice_label'       => 'name' ucfirst($locale),
  257.                 'placeholder'        => 'Please Select',
  258.                 'attr'               => array('disabled' => 'disabled'),
  259.                 'translation_domain' => 'vehicles'
  260.             ))
  261.             ->add('manufacturingYear'ChoiceType::class, array(
  262.                 'required'           => false,
  263.                 'label'              => 'Made Year',
  264.                 'choices'            => $vehicleHelper->getYears(1990),
  265.                 'placeholder'        => 'Please Select',
  266.                 'translation_domain' => 'vehicles'
  267.             ))
  268.             ->getForm();
  269.         $searchForm->handleRequest($request);
  270.         //$ongoingAuction  = $em->getRepository(Auctions::class)->getOngoingAuction();
  271.         $repository $em->getRepository(Auctions::class);
  272.         //get the ongoing auction. If multiple auctions, only the last one will be returned
  273.         $qb         $repository->createQueryBuilder('Auc')
  274.             ->orderBy('Auc.auctionId''DESC')
  275.             ->setMaxResults(1);
  276.         $ongoingAuction $qb->getQuery()->getOneOrNullResult();
  277.         if ($ongoingAuction->getStatus() != Auctions::AUCTION_STATUSES['upcomming']) {
  278.             $auctionId $ongoingAuction->getAuctionId();
  279.             $repository $em->getRepository(Vehicles::class);
  280.             $qb $repository->createQueryBuilder('V');
  281.             $qb->select('V''VR''AV.lineNumber');
  282.             $qb->join(AuctionVehicles::class, 'AV''with''V.vehicleId = AV.vehicle AND AV.auction = ' $auctionId);
  283.             $qb->leftJoin('V.vehicleRegistrations''VR');
  284.             //if search fields submitted then filter result accordingly
  285.             if ($searchForm->isSubmitted()) {
  286.                 $qb->where('1=1'); //workaround! just initializing the where clause with an always-true condition to freely use andWhere() inside if-else statements regardless of which condition will be true
  287.                 if ($vehicleMaker $searchForm->get('maker')->getData()) {
  288.                     if ($vehicleModel $searchForm->get('model')->getData()) {
  289.                         $qb->andWhere('VR.model = :vehicleModel')
  290.                             ->setParameter('vehicleModel'$vehicleModel);
  291.                     } else {
  292.                         $modelsRepo $this->getDoctrine()
  293.                             ->getRepository(VehicleModels::class);
  294.                         $modelsQuery $modelsRepo->createQueryBuilder('m')
  295.                             ->select('m.modelId')
  296.                             ->where('m.maker = :makerID')
  297.                             ->setParameter('makerID'$vehicleMaker)
  298.                             ->getQuery();
  299.                         $makerModels $modelsQuery->getArrayResult();
  300.                         foreach ($makerModels as $maker) {
  301.                             $makerModelsArr[] = $maker['modelId'];
  302.                         }
  303.                         $qb->andWhere('VR.model IN (:makerModels)')
  304.                             ->setParameter('makerModels'$makerModelsArr);
  305.                     }
  306.                 }
  307.                 if ($manufacturingYear $searchForm->get('manufacturingYear')->getData()) {
  308.                     $qb->andWhere('VR.manufacturingYear = :manufacturingYear')
  309.                         ->setParameter('manufacturingYear'$manufacturingYear);
  310.                 }
  311.             }
  312.             $qb->orderBy('AV.lineNumber''ASC');
  313.             $auctionVehicles   $qb->getQuery()->getResult();
  314.             $totalResult       count($auctionVehicles);
  315.             $auctionVehicles $paginator->paginate(
  316.                 $auctionVehicles,
  317.                 $request->query->getInt('page'1),
  318.                 $request->query->getInt('limit'20)
  319.             );
  320.         } else {
  321.             $auctionVehicles null;
  322.             $totalResult     0;
  323.             $paginator       null;
  324.         }
  325.         $imageRealPath $this->getParameter('vehicle_uploaded_files') . '/';
  326.         $data['searchForm']      = $searchForm;
  327.         $data['locale']          = $locale;
  328.         $data['auctionVehicles'] = $auctionVehicles;
  329.         $data['totalResult']     = $totalResult;
  330.         $data['paginator']       = $paginator;
  331.         $data['imageRealPath']   = $imageRealPath;
  332.         $data['auctionStatus']   = $ongoingAuction->getStatus();
  333.         $data['auction']         = $ongoingAuction;
  334.         $data['endDate']         = ($ongoingAuction &&$ongoingAuction->getEndDate()) ?$ongoingAuction->getEndDate() : false;
  335.         return $data;
  336.     }
  337. }