<?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);
}
}