- <?php
- namespace App\Controller;
- use App\Entity\Forms;
- use App\Entity\Inspection;
- use App\Repository\FormsRepository;
- use App\Repository\InspectionRepository;
- use DateTimeImmutable;
- use Intervention\Image\ImageManagerStatic as Image;
- use Psr\Log\LoggerInterface;
- use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
- use Symfony\Component\HttpFoundation\JsonResponse;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\Routing\Annotation\Route;
- use Symfony\Component\Serializer\Encoder\JsonEncoder;
- use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
- use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
- use Symfony\Component\Serializer\Serializer;
- /**
-  * @Route("/v2")
-  */
- class V2Controller extends AbstractController
- {
-     /**
-      * @Route("/inspections/", name="v2_list")
-      */
-     public function index()
-     {
-         return $this->render('v2/index.html.twig', []);
-     }
-     /**
-      * @Route("/inspections/form", name="v2_form_new")
-      */
-     public function form_new()
-     {
-         return $this->render('v2/form.html.twig', []);
-     }
-     /**
-      * @Route("/inspections/form/{uuid}", name="v2_form_edit")
-      */
-     public function form_edit($uuid)
-     {
-         return $this->render('v2/form.html.twig', ['uuid'=>$uuid]);
-     }
-     /**
-      * @Route("/inspections/show/{uuid}", name="v2_forms_show", methods={"GET"})
-      */
-     public function show($uuid, InspectionRepository $inspectionRepository): Response
-     {
-         // Get count of all forms
-         $form = $inspectionRepository->findOneBy(['uuid'=>$uuid]);
-         if( $form == null ) {
-             return new Response('Error', 404);
-         }
-         $bedroom_ids = []; $bathroom_ids = [];
-         foreach( $form->getData() as $r => $v ) {
-             if( gettype($r) == "string" ) {
-                 $sp = explode("_", $r);
-                 if (count($sp) == 3 && $sp[0] == "bedroom" && $sp[2] == "name") {
-                     $bedroom_ids[] = $sp[1];
-                 }
-                 if (count($sp) == 3 && $sp[0] == "bathroom" && $sp[2] == "name") {
-                     $bathroom_ids[] = $sp[1];
-                 }
-             }
-         }
-         // TODO: update template
-         return $this->render('v2/show.html.twig', [
-             'f' => $form,
-             'bedrooms' => $bedroom_ids,
-             'bathrooms' => $bathroom_ids,
-         ]);
-     }
-     /**
-      * @Route("/inspections/delete/{uuid}", defaults={"uuid"=""}, name="v2_form_delete")
-      */
-     public function form_delete($uuid, InspectionRepository $inspectionRepository)
-     {
-         $f = $inspectionRepository->findOneBy( ['uuid'=>$uuid] );
-         if( ! $f ) {
-             $f = new Inspection();
-             $f->setUuid($uuid);
-         }
-         return $this->render('v2/delete.html.twig', [
-             "f" => $f
-         ]);
-     }
-     /**
-      * @Route("/delete/confirm", name="v2_form_delete_confirm", methods={"POST"})
-      */
-     public function form_delete_confirm(Request $request, InspectionRepository $inspectionRepository)
-     {
-         if ($this->isCsrfTokenValid('delete', $request->request->get('_token'))) {
-             // Remove server copy
-             $f = $inspectionRepository->findOneBy( ['uuid'=>$request->request->get('uuid')] );
-             if( $f ) {
-                 $entityManager = $this->getDoctrine()->getManager();
-                 // $entityManager->remove($f);
-                 $f->setIsDeleted(true);
-                 $entityManager->flush();
-             }
-         }
-         return $this->redirectToRoute('v2_list');
-     }
-     /**
-      * @Route("/inspections/bedroom", name="v2_form_bedroom")
-      */
-     public function form_bedroom(Request $request)
-     {
-         return $this->render('v2/_bedroom.html.twig', [
-             "id" => $request->query->get('id')
-         ]);
-     }
-     /**
-      * @Route("/inspections/bathroom", name="v2_form_bathroom")
-      */
-     public function form_bathroom(Request $request)
-     {
-         return $this->render('v2/_bathroom.html.twig', [
-             "id" => $request->query->get('id')
-         ]);
-     }
-     /**
-      * @Route("/api/list", name="v2_api_list")
-      */
-     public function api_list(
-         Request $request,
-         InspectionRepository $inspectionRepository,
-         LoggerInterface $logger
-     )
-     {
-         $logger->debug(
-             sprintf(
-                 "%s by %s",
-                 $request->attributes->get('_route'),
-                 $this->getUser()->getUsername()
-             ), $request->query->all()
-         );
-         if( $this->getUser() === null ) {
-             $forms = $this->get('serializer')->serialize([], 'json');
-             $response = new Response();
-             $response->setContent($forms);
-             $response->headers->set('Content-Type', 'application/json');
-             return $response;
-         }
-         $forms = $inspectionRepository->findInspections(
-             1,
-             $request->query->get('brand', 'THC'),
-             $request->query->get('filter', ''),
-             $request->query->get('all_users') == 'true' ? '' : $this->getUser()->getId()
-         );
-         $encoder = new JsonEncoder();
-         $defaultContext = [
-             AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
-                 return $object->getUuid();
-             },
-         ];
-         $normalizer = new ObjectNormalizer(null, null, null, null, null, null, $defaultContext);
-         $serializer = new Serializer([$normalizer], [$encoder]);
-         $forms = $serializer->serialize($forms, 'json');
-         $response = new Response();
-         $response->setContent($forms);
-         $response->headers->set('Content-Type', 'application/json');
-         return $response;
-     }
-     /**
-      * @Route("/api/get/{uuid}", name="v2_api_get", methods={"GET"})
-      */
-     public function api_get(
-         $uuid,
-         Request $request,
-         InspectionRepository $inspectionRepository,
-         LoggerInterface $logger
-     )
-     {
-         $logger->debug(
-             sprintf(
-                 "%s by %s",
-                 $request->attributes->get('_route'),
-                 $this->getUser()->getUsername()
-             ), [$uuid]
-         );
-         $form = $inspectionRepository->findOneBy(['uuid'=>$uuid]);
-         if( $form == null ) {
-             return new JsonResponse(['error'=>'Cannot find inspection'], 404);
-         }
-         $encoder = new JsonEncoder();
-         $defaultContext = [
-             AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
-                 return $object->getUuid();
-             },
-         ];
-         $normalizer = new ObjectNormalizer(null, null, null, null, null, null, $defaultContext);
-         $serializer = new Serializer([$normalizer], [$encoder]);
-         $form = $serializer->serialize($form->getData(), 'json');
-         $response = new Response();
-         $response->setContent($form);
-         $response->headers->set('Content-Type', 'application/json');
-         return $response;
-     }
-     public function handleUploads( $f ) {
-         // return $f;
-         // print "<pre>"; print_r( $_FILES ); print_r( $_POST );
-         foreach( $_FILES as $fieldname => $file ) {
-             $fileName = $file['name'];
-             $fileSize = $file['size'];
-             $fileTmpName  = $file['tmp_name'];
-             $fileType = $file['type'];
-             $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION);
-             $filename = pathinfo($fileName, PATHINFO_FILENAME);
-             // $filename = $filename.'-'.uniqid().'.'.$fileExtension;
-             $filename = $filename.'.'.$fileExtension;
-             $uploadPath = $this->getParameter('upload_directory') . '/' . $f['uuid'] . '/' . $filename;
-             // print $uploadPath; exit;
-             if( !is_dir( $this->getParameter('upload_directory') . '/' . $f['uuid'] ) ) {
-                 mkdir( $this->getParameter('upload_directory') . '/' . $f['uuid'] );
-             }
-             if( !is_dir( $this->getParameter('upload_directory') . '/' . $f['uuid'] . '/_thumb/' ) ) {
-                 mkdir( $this->getParameter('upload_directory') . '/' . $f['uuid'] . '/_thumb/' );
-             }
-             if( !is_dir( $this->getParameter('upload_directory') . '/' . $f['uuid'] . '/_medium/' ) ) {
-                 mkdir( $this->getParameter('upload_directory') . '/' . $f['uuid'] . '/_medium/' );
-             }
-             move_uploaded_file($fileTmpName, $uploadPath);
-             if( file_exists( $uploadPath ) ) {
-                 $allowed = array('gif', 'png', 'jpg', 'jpeg');
-                 if (in_array( strtolower($fileExtension), $allowed) ) {
-                     $img = Image::make( $this->getParameter('upload_directory') . '/' . $f['uuid'] .'/' . $filename )->orientate();
-                     $img->resize(800, 800, function ($constraint) {
-                         $constraint->aspectRatio();
-                         $constraint->upsize();
-                     });
-                     // $img->fit(200, 200);
-                     $img->save( $this->getParameter('upload_directory') . '/' . $f['uuid'] . '/_medium/' . $filename );
-                     // $img = Image::make( $this->getParameter('upload_directory') . '/' . $f['uuid'] .'/' . $filename );
-                     $img->fit(75, 75);
-                     $img->save( $this->getParameter('upload_directory') . '/' . $f['uuid'] . '/_thumb/' . $filename );
-                     $img->destroy();
-                 }
-                 // Add to entity
-                 $f[$fieldname] = $filename;
-             }
-         }
-         // Look for empty image fields and remove them from database
-         $imageFields = [
-             'extpic1', 'extpic2', 'extpic3', 'extpic4',
-             'bedroomspic1', 'bedroomspic2', 'bedroomspic3', 'bedroomspic4',
-             'bathroomspic1', 'bathroomspic2', 'bathroomspic3', 'bathroomspic4',
-             'kitchenpic1', 'kitchenpci2', 'kitchenpic3', 'kitchenpic4',
-             'publicpic1', 'publicpic2', 'publicpic3', 'publicpic4',
-             'safetypic1', 'safetypic2', 'safetypic3', 'safetypic4',
-             'generalpic1', 'generalpic2', 'generalpic3', 'generalpic4',
-         ];
-         foreach( $imageFields as $fieldname ) {
-             if( isset($_POST[$fieldname]) && $_POST[$fieldname] === 'null' ) {
-                 $f[$fieldname] = null;
-             }
-         }
-         return $f;
-     }
-     /**
-      * @Route("/api/post", name="v2_api_post", methods={"POST"})
-      */
-     public function api_post(
-         Request $request,
-         InspectionRepository $inspectionRepository,
-         LoggerInterface $logger
-     ): Response
-     {
-         $logger->debug(
-             sprintf(
-                 "%s by %s",
-                 $request->attributes->get('_route'),
-                 $this->getUser()->getUsername()
-             ), $_POST
-         );
-         if( count($_FILES) ) {
-             $logger->debug(
-                 sprintf(
-                     "%s by %s",
-                     $request->attributes->get('_route'),
-                     $this->getUser()->getUsername()
-                 ), $_FILES
-             );
-         }
-         if( !isset( $_POST['completeness'] ) ) {
-             $logger->error(
-                 sprintf(
-                     "%s by %s: Completeness field missing",
-                     $request->attributes->get('_route'),
-                     $this->getUser()->getUsername()
-                 )
-             );
-             $msg = [ "error" => "Completeness parameter not set. Probably missing some data. Don't sync."];
-             return new JsonResponse($msg, 401);
-         }
- //        $logger->debug( 'API POST', $_POST );
- //        $logger->debug( 'API FILES', $_FILES );
- //         print_r( $_FILES );
- //         print_r( $_POST );
-         $encoder = new JsonEncoder();
-         $defaultContext = [
-             AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function ($object, $format, $context) {
-                 return $object->getUuid();
-             },
-         ];
-         $normalizer = new ObjectNormalizer(null, null, null, null, null, null, $defaultContext);
-         $serializer = new Serializer([$normalizer], [$encoder]);
-         $entityManager = $this->getDoctrine()->getManager();
-         $all = $request->request->all();
-         if( count($all) < 80 ) {
-             $logger->error(
-                 sprintf(
-                     "%s by %s: Number of fields = %d",
-                     $request->attributes->get('_route'),
-                     $this->getUser()->getUsername(),
-                     count($all)
-                 )
-             );
-             $msg = [ "error" => "Number of fields seems too low. Don't sync."];
-             return new JsonResponse($msg, 401);
-         }
-         // Upload and resize images
-         foreach( $_FILES as $fieldname => $file ) {
-             if( $file['error'] > 0 ) {
-                 $logger->error(
-                     sprintf(
-                         "%s by %s: Error uploading file",
-                         $request->attributes->get('_route'),
-                         $this->getUser()->getUsername()
-                     ), $file
-                 );
-                 $msg = [ "error" => "Number of fields seems too low. Don't sync."];
-                 return new JsonResponse($msg, 401);
-             }
-         }
-         $all = $this->handleUploads($all);
-         // TODO: handle 'completeness'
-         // Add inspection to database
-         try {
-             $inspection = $inspectionRepository->findOneBy(['uuid' => $request->request->get('uuid')]);
-             if (!$inspection) {
-                 $inspection = new Inspection();
-                 $inspection->setUserId($this->getUser()->getId());
-             } else {
-                 // Check if the completeness value is less than the saved one - maybe a problem
-                 if( $request->request->getInt('completeness', 0) < $inspection->getCompleteness() ) {
-                     $logger->error(
-                         sprintf(
-                             "%s by %s: Previous completeness %d, New completeness %d",
-                             $request->attributes->get('_route'),
-                             $this->getUser()->getUsername(),
-                             $inspection->getCompleteness(),
-                             $request->request->getInt('completeness', 0)
-                         )
-                     );
-                     $msg = [ "error" => "Completeness parameter is less than currently saved. Don't sync."];
-                     return new JsonResponse($msg, 401);
-                 }
-             }
-             $inspection->setUuid($request->request->get('uuid'));
-             $inspection->setDate(DateTimeImmutable::createFromFormat('Y-m-d', $request->request->get('date')));
-             $inspection->setPropname($request->request->get('propname'));
-             $inspection->setBrand($request->request->get('brand', 'THC'));
-             $inspection->setVersion($request->request->getInt('version', 1));
-             $inspection->setTotalScore($request->request->getInt('totalScore', 0));
-             $inspection->setStars((float)$request->request->get('stars', 0));
-             $inspection->setCompleteness($request->request->getInt('completeness', 0));
-             $inspection->setData($all);
-             if( $inspection->getVersion() == 0 ) {
-                 $inspection->setVersion(1);
-                 $all['version'] = 1;
-             }
- //            return new JsonResponse([], 401);
-             $inspection->setIsDeleted(false);
-             $entityManager->persist($inspection);
-             $entityManager->flush();
-             $all = $serializer->serialize($all, 'json');
-             $response = new Response();
-             $response->setContent($all);
-             $response->headers->set('Content-Type', 'application/json');
-             return $response;
-         } catch( \Exception $e ) {
-             return new JsonResponse(['error'=>$e->getMessage()], 401);
-         }
-         return new JsonResponse([], 401);
-     }
- }
-