<?php
namespace App\Controller;
use App\Entity\Image;
use App\Entity\Processing;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\HttpFoundation\StreamedResponse;
class DownloadController extends AbstractController
{
// returning zip||imagefile to download images passed in the $id (ids seperated by +)
// downloading original || processed depending on $type
public function index(EntityManagerInterface $entityManager, $type, $id): Response
{
//setting the root path to fetch the images from
switch ($type) {
case 'original':
$rootpath = $_ENV["UPLOAD_PATH"];
break;
case 'processed':
$rootpath = str_replace("upload","processed",$_ENV["UPLOAD_PATH"]);
break;
}
// creating an array with the images to download
$images = [];
// splitting the id input given to create ids array that we can iterate
$id = explode("+",$id);
foreach ($id as $image) {
$images[] = $entityManager->getRepository(Image::class)->findById($image);
}
//creating an array with the relevant information to the images
/*imagesInfo[
[id, ImageFile, [tag1, tag2]]
]
*/
$imagesInfo = [];
foreach ($images as $entry) {
if (! $entry) {
throw new Exception('Invalid Image passed');
}
$tags = [];
foreach ($entry->getTag() as $tag) {
$tags[] = $tag->getName();
}
$imagesInfo[] = [
$entry->getId(),
$entry->getImageFile(),
$tags,
];
}
// getting todays date to include in the files
$date = date("YmdHis");
/*##################################################################
returning the download for a single file - not creating archive
####################################################################*/
if (count($imagesInfo) == 1) {
$image = $imagesInfo[0];
$imageName = "SegelParade_" . $image[0] . "_" . $date . "_tag";
foreach ($image[2] as $tag) {
$imageName .= "-$tag";
}
//adding the original file extension
$imageName .= "." . pathinfo($rootpath . $image[1], PATHINFO_EXTENSION);
//getting the content type for download and setting header
$contentType = mime_content_type($rootpath . $image[1]);
header('Content-Type: ' . $contentType);
header('Content-Disposition: attachment; filename="' . $imageName . '"');
// download
readfile($rootpath . $image[1]);
}
/*##################################################################
returnung the download for multiple files as zip archive
####################################################################*/
$zipLocation = "/var/www/html/symfonyproject/var/userdownloads/";
$zipFilename = $zipLocation . "$date.zip";
$zip = new \ZipArchive();
if ($zip->open($zipFilename, \ZipArchive::CREATE) === TRUE) {
// adding files to the archive
foreach ($imagesInfo as $image) {
//naming the image SegelParade_id_DATE_tag-TAG1-TAG2
$imageName = "SegelParade_" . $image[0] . "_" . $date . "_tag";
foreach ($image[2] as $tag) {
$imageName .= "-$tag";
}
//adding the original file extension
$imageName .= "." . pathinfo($rootpath . $image[1], PATHINFO_EXTENSION);
// adding the file to the zip
$zip->addFile($rootpath . $image[1], $imageName);
}
// closing the archive
$zip->close();
// download the archive
$downloadName = "Segelparade_Bilder";
foreach ($imagesInfo as $image) {
$downloadName .= "-" . $image[0];
}
$downloadName .= "_" . $date . ".zip";
// sending headers for zip file download
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $downloadName . '"');
header('Content-Length: ' . filesize($zipFilename));
// send the zip file
readfile($zipFilename);
// Delete the archive after downloading
unlink($zipFilename);
}else {
echo 'Fehler beim Erstellen des Bildarchivs';
}
}
public function takeout(EntityManagerInterface $entityManager, SerializerInterface $serializer): Response
{
// this is usually not interesting: $allImages = $entityManager->getRepository(Image::class)->findAll();
// get all images with status read
$allImages = $entityManager->getRepository(Image::class)->findAllByCategory('read');
//construct multidimensional array to format the necessary data
$takeout = [["ID","eMail","Name", "Alter", "Upload-Datum", "Freigabe-Datum", "Tags"]];
//get all the necessary data
foreach ($allImages as $image) {
$id = $image->getId();
$uploaded = $image->getuploaded()->format('d.m.Y');
$email = $entityManager->getRepository(User::class)->find($image->getFkUser())->getEmail();
$name = $image->getName() ? $image->getName() : $entityManager->getRepository(User::class)->find($image->getFkUser())->getName();
$age = $image->getAge() ? $image->getAge() : $entityManager->getRepository(User::class)->find($image->getFkUser())->getAge();
//$age = $image->getAge();
$accepted = $image->getAccepted() ? $image->getAccepted()->format('d.m.Y') : 'nicht freigeschaltet';
$tags = [];
foreach ($image->getTag()->toArray() as $tag) {
$tags[] = $tag->getName();
}
$takeout[] = [
$id,
$email,
$name,
$age,
$uploaded,
$accepted,
implode('-',$tags)
];
}
// Serialize the Image entity with flattened nested data
$csvContent = $serializer->serialize($takeout, 'csv', [
CsvEncoder::NO_HEADERS_KEY => true, // Exclude headers -> header set manually in first row not via key
CsvEncoder::DELIMITER_KEY => ';', // Specify delimiter
]);
$response = new StreamedResponse(function () use ($csvContent) {
echo $csvContent;
});
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename="file.csv"');
return $response;
}
}