Segelparade / www / symfonyproject / src / Controller / DownloadController.php
DownloadController.php
Raw
<?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;

    }
}