<?php
/** @noinspection SqlResolve */
/** @noinspection SqlNoDataSourceInspection */
namespace App\Controller\JSON;
use App\Common\API\APICommon;
use App\Common\Resize;
use App\Common\SyncCommon;
use PDO;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Class MediaController
*
* @package App\Controller\JSON
*/
#[Route(path: '/api/media')]
class MediaController extends CommonController
{
/**
* Common static function to generate URL items for media related API elements.
*
* @param $mediaData
*/
public static function buildMediaPaths($mediaData, AbstractController $controller): array
{
if (!array_key_exists("MediaID", $mediaData) || !array_key_exists("FileExt", $mediaData)) {
// Missing required keys
return ["Invalid media data"];
}
$paths = [
'normal' => $controller->generateUrl(
'JSON_API.media',
[
'media' => $mediaData['MediaID'],
],
UrlGeneratorInterface::ABSOLUTE_URL
),
];
if ($mediaData['ext'] == 'jpg' || $mediaData['ext'] == 'jpeg' || $mediaData['ext'] == 'gif' || $mediaData['ext'] == 'png') {
// Media is an image, include additional paths
$paths['full-size'] = $controller->generateUrl(
'JSON_API.media.fullsize',
[
'media' => $mediaData['MediaID'],
],
UrlGeneratorInterface::ABSOLUTE_URL
);
$paths['thumbnail'] = $controller->generateUrl(
'JSON_API.media.thumbnail',
[
'media' => $mediaData['MediaID'],
],
UrlGeneratorInterface::ABSOLUTE_URL
);
}
return $paths;
}
/**
* Return media object. If it is an image, max resolution of 512px x 512px
*
*
* @param $media
* @return string
*/
#[Route(path: '/{media}', name: 'JSON_API.media')]
public function media($media)
{
$mediaData = $this->getMediaAsset($media);
if (!array_key_exists('path', $mediaData)) {
// Asset not found. Kill process.
throw new NotFoundHttpException('Object not found.');
}
$remoteAsset = APICommon::getAssetPath($mediaData['path'], $mediaData['name'], $mediaData['ext']);
if (!file_exists($remoteAsset) || filesize($remoteAsset) <= 0) {
// Asset not found. Kill process.
throw new NotFoundHttpException('Asset not found.');
}
// Get last modified time.
$lastModified = filemtime($remoteAsset);
// Getting headers sent by the client.
$headers = getallheaders();
// Checking if the client is validating its cache and if it is current.
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == $lastModified)) {
// Client's cache IS current, so we just respond '304 Not Modified'.
header("Last-Modified: " . gmdate('D, d M Y H:i:s', $lastModified) . " GMT", true, 304);
exit;
}
if ($mediaData['ext'] == 'jpg' || $mediaData['ext'] == 'jpeg' || $mediaData['ext'] == 'gif' || $mediaData['ext'] == 'png') {
$resizeObj = new Resize();
$resizeObj->build($remoteAsset);
$resizeObj->resizeImage(512, 512);
$response = new Response();
$response->headers->set('Content-Type', $resizeObj->getContentType());
$response->sendHeaders();
$resizeObj->getImage();
return $response;
} else {
$response = new BinaryFileResponse($remoteAsset);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);
$response->headers->add(["Last-Modified" => gmdate('D, d M Y H:i:s', $lastModified) . " GMT"]);
return $response;
}
}
/**
* Get array containing media data
*
* @param $mediaID
*/
protected function getMediaAsset($mediaID): array
{
// Connect to MSSQL
$this->makeConnection();
$fullQuery = "
SELECT Multimedia.MulId AS MediaID,
Multimedia.MulDateiS AS LinkID,
Multimedia.MulPfadS AS FilePath,
Multimedia.MulDateiS AS FileName,
Multimedia.MulExtentS AS FileExt,
Multimedia.MulTypS AS FileType
FROM Multimedia
WHERE Multimedia.MulId = %d";
// Fire query
$query = sqlsrv_query(
$this->getConnection(),
sprintf($fullQuery, $mediaID) . SyncCommon::GENERAL_MEDIA_FILTERS . ";"
);
$data = [];
// Loop through result set
while ($row = sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC)) {
$data = [
'path' => $row['FilePath'],
'name' => $row['FileName'],
'ext' => $row['FileExt'],
];
}
$this->closeConnection();
return $data;
}
/**
* Get image at its full size
*
*
* @param $media
* @return string
*/
#[Route(path: '/{media}/full', name: 'JSON_API.media.fullsize')]
public function full($media)
{
$mediaData = $this->getMediaAsset($media);
if (!array_key_exists('path', $mediaData) ||
!($mediaData['ext'] == 'jpg' || $mediaData['ext'] == 'jpeg' || $mediaData['ext'] == 'gif' || $mediaData['ext'] == 'png')) {
// Asset not found. Kill process.
throw new NotFoundHttpException('Object not found.');
}
$remoteAsset = APICommon::getAssetPath($mediaData['path'], $mediaData['name'], $mediaData['ext']);
if (!file_exists($remoteAsset) || filesize($remoteAsset) <= 0) {
// Asset not found. Kill process.
throw new NotFoundHttpException('Asset not found.');
}
// Get last modified time.
$lastModified = filemtime($remoteAsset);
// Getting headers sent by the client.
$headers = getallheaders();
// Checking if the client is validating its cache and if it is current.
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == $lastModified)) {
// Client's cache IS current, so we just respond '304 Not Modified'.
header("Last-Modified: " . gmdate('D, d M Y H:i:s', $lastModified) . " GMT", true, 304);
exit;
}
$response = new BinaryFileResponse($remoteAsset);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);
$response->headers->add(["Last-Modified" => gmdate('D, d M Y H:i:s', $lastModified) . " GMT"]);
return $response;
}
/**
* Get image at 38x56
*
*
* @param $media
* @return string
*/
#[Route(path: '/{media}/thumbnail', name: 'JSON_API.media.thumbnail')]
public function thumbnail($media)
{
$mediaData = $this->getMediaAsset($media);
if (!array_key_exists('path', $mediaData) ||
!($mediaData['ext'] == 'jpg' || $mediaData['ext'] == 'jpeg' || $mediaData['ext'] == 'gif' || $mediaData['ext'] == 'png')) {
// Asset not found. Kill process.
throw new NotFoundHttpException('Object not found.');
}
$remoteAsset = APICommon::getAssetPath($mediaData['path'], $mediaData['name'], $mediaData['ext']);
if (!file_exists($remoteAsset) || filesize($remoteAsset) <= 0) {
// Asset not found. Kill process.
throw new NotFoundHttpException('Asset not found.');
}
// Get last modified time.
$lastModified = filemtime($remoteAsset);
// Getting headers sent by the client.
$headers = getallheaders();
// Checking if the client is validating its cache and if it is current.
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == $lastModified)) {
// Client's cache IS current, so we just respond '304 Not Modified'.
header("Last-Modified: " . gmdate('D, d M Y H:i:s', $lastModified) . " GMT", true, 304);
exit;
}
$resizeObj = new Resize();
$resizeObj->build($remoteAsset);
$resizeObj->resizeImage(38, 56);
$response = new Response();
$response->headers->set('Content-Type', $resizeObj->getContentType());
$response->sendHeaders();
$resizeObj->getImage();
return $response;
}
}