Skip to content

Commit

Permalink
fix /image route
Browse files Browse the repository at this point in the history
  • Loading branch information
krkabol committed Jan 30, 2025
1 parent 13b3946 commit 9bc1682
Showing 1 changed file with 60 additions and 50 deletions.
110 changes: 60 additions & 50 deletions htdocs/src/Controller/Front/SearchFormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,20 @@

namespace App\Controller\Front;

use App\Entity\User;
use App\Enum\CoreObjectsEnum;
use App\Enum\TimeIntervalEnum;
use App\Facade\SearchFormFacade;
use App\Service\CollectionService;
use App\Service\DjatokaService;
use App\Service\ExcelService;
use App\Service\ImageService;
use App\Service\InstitutionService;
use App\Service\KmlService;
use App\Service\Rest\DevelopersService;
use App\Service\Rest\StatisticsService;
use App\Service\SearchFormSessionService;
use App\Service\SpecimenService;
use PhpOffice\PhpSpreadsheet\Writer\Csv;
use PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
use Symfony\Component\Routing\Attribute\Route;
Expand All @@ -35,9 +26,9 @@ class SearchFormController extends AbstractController
public const array RECORDS_PER_PAGE = array(10, 30, 50, 100);

//TODO the name of taxon is not part of the query now, hard to sort
public const array SORT = ["taxon"=> '', 'collector'=>'s.collector'];
public const array SORT = ["taxon" => '', 'collector' => 's.collector'];

public function __construct( protected readonly CollectionService $collectionService, protected readonly InstitutionService $herbariumService, protected readonly SearchFormFacade $searchFormFacade, protected readonly SearchFormSessionService $sessionService, protected readonly ImageService $imageService, protected readonly SpecimenService $specimenService, protected readonly ExcelService $excelService)
public function __construct(protected readonly CollectionService $collectionService, protected readonly InstitutionService $herbariumService, protected readonly SearchFormFacade $searchFormFacade, protected readonly SearchFormSessionService $sessionService, protected readonly ImageService $imageService, protected readonly SpecimenService $specimenService, protected readonly ExcelService $excelService)
{
}

Expand Down Expand Up @@ -103,88 +94,104 @@ public function collectionsSelectOptions(#[MapQueryParameter] string $herbariumI
}

#[Route('/image', name: 'app_front_image_endpoint', methods: ['GET'])]
public function showImage(#[MapQueryParameter] string $filename,#[MapQueryParameter] ?string $sid,#[MapQueryParameter] string $method,#[MapQueryParameter] ?string $format): Response
public function showImage(#[MapQueryParameter] string $filename, #[MapQueryParameter] ?string $sid, #[MapQueryParameter] string $method, #[MapQueryParameter] ?string $format): Response
{
if ($_SERVER['REMOTE_ADDR'] == '94.177.9.139' && !empty($sid) && $method == 'download' && strrpos($filename, '_') == strpos($filename, '_')) {
// kulturpool is calling...
// Redirect to new location
$this->redirectToRoute("services_rest_images_europeana", ["specimenID"=>$sid], 303);
$this->redirectToRoute("services_rest_images_europeana", ["specimenID" => $sid], 303);
}

//TODO only due Djatoka in the getPicDetails() is needed to have this format, otherwise could be deriobed from the streamed response headers, see bellow
switch ($format) {
case 'jpeg2000':
$mime = 'image/jp2';
$contentType = 'image/jp2';
break;
case'tiff':
$mime = 'image/tiff';
$contentType = 'image/tiff';
break;
default:
$mime = 'image/jpeg';
$contentType = 'image/jpeg';
break;
}

$picDetails = $this->imageService->getPicDetails($filename,$mime, $sid);
$picDetails = $this->imageService->getPicDetails($filename, $contentType, $sid);

if (!empty($picDetails['url'])) {
switch ($method) {
default:
$this->imageService->getSourceUrl($picDetails,$mime, 0);
exit;
$url = $this->imageService->getSourceUrl($picDetails, $contentType, 0);
break;
case 'download': // detail

return new StreamedResponse(function () use ($picDetails, $mime) {
// ignore broken certificates
$context = stream_context_create(array("ssl"=>array("verify_peer" => false,
"verify_peer_name" => false),
"http"=>array('timeout' => 60)));
readfile($url, false, $context);
$this->imageService->getSourceUrl($picDetails,$mime, 0);
});
$url = $this->imageService->getSourceUrl($picDetails, $contentType, 0);
break;
case 'thumb': // detail
return new JsonResponse(['dd' => $this->imageService->getSourceUrl($picDetails,$mime, 1)], 202);

return new StreamedResponse(function () use ($picDetails, $mime) {
$this->imageService->getSourceUrl($picDetails,$mime, 1);
});
$url = $this->imageService->getSourceUrl($picDetails, $contentType, 1);
break;
case 'resized': // create_xml.php
$this->imageService->getSourceUrl($picDetails,$mime, 2);
exit;
$url = $this->imageService->getSourceUrl($picDetails, $contentType, 2);
break;
case 'europeana': // NOTE: not supported on non-djatoka servers (yet)
if (strtolower(substr($picDetails['requestFileName'], 0, 3)) == 'wu_' && $this->imageService->checkPhaidra((int)$picDetails['specimenID'])) {
// Phaidra (only WU)
$picDetails['imgserver_type'] = 'phaidra';
} else {
// Djatoka
$picinfo = $this->imageService->getPicInfo($picDetails);
if (!empty($picinfo['pics'][0]) && !in_array($picDetails['originalFilename'], $picinfo['pics'])) {
if (!empty($picinfo['pics'][0]) && !in_array($picDetails['originalFilename'], $picinfo['pics'])) {
$picDetails['originalFilename'] = $picinfo['pics'][0];
}
}
$this->imageService->getSourceUrl($picDetails,$mime, 3);
exit;
$url = $this->imageService->getSourceUrl($picDetails, $contentType, 3);
break;
case 'nhmwthumb': // NOTE: not supported on legacy image server scripts
$this->imageService->getSourceUrl($picDetails,$mime, 4);
exit;
$url = $this->imageService->getSourceUrl($picDetails, $contentType, 4);
break;
case 'thumbs': // unused
return $this->json($this->imageService->getPicInfo($picDetails));
case 'show': // detail, ajax/results.php
return $this->redirect($this->imageService->doRedirectShowPic($picDetails));
$url = $this->imageService->doRedirectShowPic($picDetails);
break;
}

$streamContext = stream_context_create([
'http' => ['follow_location' => true,
'timeout' => 60],
'ssl' => ["verify_peer" => false,
"verify_peer_name" => false]
]);
$imageStream = @fopen($url, 'rb', false, $streamContext);

$headers = get_headers($url, true);

// $contentType = $headers['Content-Type'] ?? 'image/jpeg'; // Fallback na JPEG
$contentLength = $headers['Content-Length'] ?? null;
$response = new StreamedResponse(function () use ($imageStream) {
fpassthru($imageStream);
fclose($imageStream);
});

$response->headers->set('Content-Type', $contentType);
if ($contentLength) {
$response->headers->set('Content-Length', $contentLength);
}

return $response;

} else {
switch ($method) {
case 'download':
case 'thumb':
$filePath = $this->getParameter('kernel.project_dir') . '/public/recordIcons/404.png';
$filePath = $this->getParameter('kernel.project_dir') . '/public/recordIcons/404.png';

if (!file_exists($filePath) || mime_content_type($filePath) !== 'image/png') {
throw $this->createNotFoundException('Sorry, this image does not exist.');
}
if (!file_exists($filePath) || mime_content_type($filePath) !== 'image/png') {
throw $this->createNotFoundException('Sorry, this image does not exist.');
}

return new Response(file_get_contents($filePath), 200, [
'Content-Type' => 'image/png',
'Content-Length' => filesize($filePath),
]);
return new Response(file_get_contents($filePath), 200, [
'Content-Type' => 'image/png',
'Content-Length' => filesize($filePath),
]);
case 'thumbs':
return new JsonResponse(['error' => 'not found'], 404);
default:
Expand All @@ -197,7 +204,7 @@ public function showImage(#[MapQueryParameter] string $filename,#[MapQueryParame
#[Route('/detail/{specimenId}', name: 'app_front_specimenDetail', methods: ['GET'])]
public function detail(int $specimenId): Response
{
return $this->render('front/home/detail.html.twig', ['specimen'=> $this->specimenService->findAccessibleForPublic($specimenId)]);
return $this->render('front/home/detail.html.twig', ['specimen' => $this->specimenService->findAccessibleForPublic($specimenId)]);
}

#[Route('/exportKml', name: 'app_front_exportKml', methods: ['GET'])]
Expand All @@ -210,6 +217,7 @@ public function exportKml(): Response

return $response;
}

#[Route('/exportExcel', name: 'app_front_exportExcel', methods: ['GET'])]
public function exportExcel(): Response
{
Expand All @@ -227,6 +235,7 @@ public function exportExcel(): Response

return $response;
}

#[Route('/exportCsv', name: 'app_front_exportCsv', methods: ['GET'])]
public function exportCsv(): Response
{
Expand All @@ -244,6 +253,7 @@ public function exportCsv(): Response

return $response;
}

#[Route('/exportOds', name: 'app_front_exportOds', methods: ['GET'])]
public function exportOds(): Response
{
Expand Down

0 comments on commit 9bc1682

Please sign in to comment.