<?php
namespace App\Controller;
use App\Entity\Image;
use App\Entity\User;
use App\Entity\Tag;
use App\Entity\Processing;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\HttpFoundation\Request;
use PHPMailer\PHPMailer\PHPMailer;
class UploadController extends AbstractController
{
public function index(EntityManagerInterface $entityManager, Request $request): Response
{
//this function will send a confirmation mail to the adress specified in param
//if none is specified it will default to mail set in env, if not set either no mail is send
function sendMail($mailto = NULL, $message="A new file was uploaded\n")
{
// todo: do not overwrite
$message = $message="A new file was uploaded\n\n".
"user: ". $_POST['username'] . "\n" .
"email: ". $_POST['emailInput'] . "\n" .
"age:". $_POST['age'] . "\n".
"direction: " . $_POST['direction'] . "\n".
"filename:".$_FILES['imageInput']['name']."\n".
"backend: http://www.segelparade.de/backend " . "\n";
$mailto = (isset($_ENV["NOTIFICATION_MAIL"])&&!$mailto) ? $_ENV["NOTIFICATION_MAIL"] : NULL;
//return early if no recipient is specified
if (! $mailto) {
return;
}
$mail = new PHPMailer(true);
try {
// configure SMTP
$mail->isSMTP();
$mail->Host = 'smtp.ionos.de';
$mail->SMTPAuth = true;
$mail->Username = 'testmail@luckyluke.click';
$mail->Password = 'itestmymail';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
$mail->setFrom('testmail@luckyluke.click', 'Luke Kahms');
$mail->addAddress($mailto);
// configure the message
$mail->Subject = 'Segelparade';
$mail->Body = $message;
// send the mail
$mail->send();
} catch (Exception $e) {
// error handling by frontend
}
}
sendMail();
$userInfo = null;
$imageInfo = null;
$maxFileSize = 64 * 1024 * 1024; // 64 MB in Bytes
if($_SERVER["REQUEST_METHOD"] == "POST"){
// setting variables with user form input
$email = ($_POST['emailInput']);
$image = ($_FILES['imageInput']);
$name = ($_POST['username']);
$age = ($_POST['age']);
$allowedtypes = array(
"image/jpeg",
"image/png",
"image/tiff",
"image/heic"
);
if(isset($_POST['content'])) {
$tagsCont = $_POST['content'];
} else {
$tagsCont = [];
}
if(isset($_POST['direction'])) {
$tagsDir = $_POST['direction'];
} else {
$tagsDir = [];
}
// checking user input
if (!empty($email) && !empty($image) && !empty($tagsCont) && !empty($tagsDir) && $image['size'] > 0 && $image['size'] < $maxFileSize) {
// checking file type
if (in_array($image["type"],$allowedtypes)){
// check if email is already set, if not: create new user + persist
// // FS FEEDBACK FRONTEND: TODO duplicate code: The if will be executed AND again if false in the else
// if(!$entityManager->getRepository(User::class)->findByEmailExists($email)){
// $userInfo = new User();
// $userInfo->setEmail($email);
// // todo: after the project is finished for next year: remove the age and name
// $userInfo->setAge($age);
// $userInfo->setName($name);
// $entityManager->persist($userInfo);
// }
// // if it is already set: search for mail in DB and connect it to new upload
// else{
// $userInfo = $entityManager->getRepository(User::class)->FindUserByEmail($email);
// }
// checking if user already exixts, else create new user
$userInfo = $entityManager->getRepository(User::class)->FindUserByEmail($email);
if ($userInfo === null) {
$userInfo = new User();
$userInfo->setEmail($email);
// todo: after the project is finished for next year: remove the age and name
$userInfo->setAge($age);
$userInfo->setName($name);
$entityManager->persist($userInfo);
}
// create new Image object for new upload + persist
$imageInfo = new Image();
// FS FEEDBACK FRONTEND: Keep in mind, but code as it is. here we can get a race condition whre ids get mixed up. Would be better
// to first insert in DB and then get the id, it will be automatically in $lastInsertedId = $imageInfo->getId();
// Caution, then the filename is not set yet, so we need to set it afterwards
// getting last image id from DB and adding 1 for current image id
$imageId = (($entityManager->getRepository(Image::class)->findLastId()) + 1);
// creating new filename (e.g. Bild_1.jpg)
$newFilename = 'Bild_' . $imageId . "." . pathinfo($image['name'], PATHINFO_EXTENSION);
// processing
$process = $entityManager->getRepository(Processing::class)->findByType("new");
$imageInfo->addProcessing($process);
$imageInfo->setImageFile($newFilename);
$imageInfo->setUploaded(new DateTime("now"));
$imageInfo->setFkUser($userInfo);
$imageInfo->setAge($age);
$imageInfo->setName($name);
$entityManager->persist($imageInfo);
if(isset($image)) {
$fileName = $newFilename;
$tempFile = $image['tmp_name'];
$directory = $_ENV["UPLOAD_PATH"]; // directory where image is saved
// moving image to said directory
move_uploaded_file($tempFile, $directory . $fileName);
}
// check if content tags are selected
if(isset($tagsCont)) {
// for each tag in array
foreach($tagsCont as $selectedValue) {
// // FS FEEDBACK FRONTEND: TODO extra file. here are duplicate requests to the DB. Better: store the result in a variable
// // check if tag is already set, if not: create new tag + persist
// if(!$entityManager->getRepository(Tag::class)->findByTagExists($selectedValue)){
// // Done: FS FEEDBACK FRONTEND: TODO, see above. Why do we need it? Dangerous, becuase there will be a lot of tags, if someone missued the form. Better: fixtures
// $tag = new Tag();
// $tag->setName($selectedValue);
// $tag->setType('content');
// $imageInfo->addTag($tag);
// $entityManager->persist($tag);
// }
// // if it is already set: search for tag in DB and connect it
// else{
// $tag = $entityManager->getRepository(Tag::class)->FindTagByName($selectedValue);
// $imageInfo->addTag($tag);
// }
// checking with fixtures which tag is selected and setting variable
$tag = $entityManager->getRepository(Tag::class)->FindTagByName($selectedValue);
// adding tag to image object
$imageInfo->addTag($tag);
// (only for displaying)
$tags[] = $tag;
}
}
else {
$tags = [];
}
// check if direction tags are selected
if(isset($tagsDir)) {
$selectedValue = $tagsDir;
// // check if tag is already set, if not: create new tag + persist
// if(!$entityManager->getRepository(Tag::class)->findByTagExists($selectedValue)){
// // FS FEEDBACK FRONTEND: TODO see above, can be missused
// $tag = new Tag();
// $tag->setName($selectedValue);
// $tag->setType('direction');
// $imageInfo->addTag($tag);
// $entityManager->persist($tag);
// }
// // if it is already set: search for tag in DB and connect it
// else{
// $tag = $entityManager->getRepository(Tag::class)->FindTagByName($selectedValue);
// $imageInfo->addTag($tag);
// }
// checking with fixtures which tag is selected and setting variable
$tag = $entityManager->getRepository(Tag::class)->FindTagByName($selectedValue);
// adding tag to image object
$imageInfo->addTag($tag);
// (only for displaying)
$tags[] = $tag;
}
else {
$tags = [];
}
// flushing to database
$entityManager->flush();
// after sucsess render landing page
return $this->render('upload/upload.html.twig', [
'user' => $userInfo,
'image' => $imageInfo,
'tags' => $tags,
'errorMessage' => ""
]);
}
// error message on homepage when file type is not allowed
else{
$message = "Ihr Dateiformat wird nicht unterstützt. Erlaubt sind: .jpg, .png, .HEIC und .tiff";
return $this->render('frontend/index.html.twig', [
'errorMessage' => $message,
]);
}
}
// error message on homepage if not all the mandatory inputs are given or file is bigger than allowed
else {
$message = "Bitte füllen Sie alle erforderlichen Felder aus und beachten Sie, dass die Bilddatei nicht größer als 64MB sein darf.";
return $this->render('frontend/index.html.twig', [
'errorMessage' => $message,
]);
}
}
// return to index.html.twig if server did not answer to POST request
else{
return $this->render('frontend/index.html.twig', [
]);
}
}
}