src/Controller/DefaultController.php line 41

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