247 lines
7.5 KiB
PHP
247 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ContentBundle\Util;
|
|
|
|
use KupShop\ComponentsBundle\Entity\Thumbnail;
|
|
use KupShop\ContentBundle\Entity\Image;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
|
use KupShop\KupShopBundle\Util\Contexts;
|
|
use KupShop\KupShopBundle\Util\StringUtil;
|
|
use KupShop\KupShopBundle\Util\System\PathFinder;
|
|
use KupShop\KupShopBundle\Util\System\UrlFinder;
|
|
use Query\Operator;
|
|
use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext;
|
|
|
|
class ImageLocator
|
|
{
|
|
/**
|
|
* @var PathFinder
|
|
*/
|
|
private $pathFinder;
|
|
|
|
/** @var UrlFinder */
|
|
protected $urlFinder;
|
|
|
|
// Default settings
|
|
private $default = [
|
|
'crop' => true,
|
|
'background' => false,
|
|
'watermark' => false,
|
|
'png' => false,
|
|
'svg' => false,
|
|
'upscale' => false,
|
|
'quality' => null,
|
|
'sharpen' => null,
|
|
'contrast' => null,
|
|
];
|
|
|
|
public function __construct(PathFinder $pathFinder)
|
|
{
|
|
$this->pathFinder = $pathFinder;
|
|
}
|
|
|
|
public function getConfig()
|
|
{
|
|
global $cfg;
|
|
|
|
return $cfg['Photo'];
|
|
}
|
|
|
|
public function getThumbnailPath(Thumbnail $thumbnail, string $type, string $size): string
|
|
{
|
|
// TODO: Tady začni generovat cestu bez extension a asi teda i kvůli SEO šovinistům i s názevm souboru :-(
|
|
// TODO: A ideálně nějakou custom URL, co se bude zpracovávat v PHP, ale bude na CDN cachovaná.
|
|
$config = $this->getTypeConfig($type);
|
|
|
|
$lang = null;
|
|
if (!empty($config['lang'])) {
|
|
$lang = Contexts::get(LanguageContext::class)->getActiveId();
|
|
}
|
|
|
|
return $this->getNewPath($thumbnail, $type, $size, $lang);
|
|
}
|
|
|
|
public function getThumbnailUrl(Thumbnail $thumbnail, string $type, string $size)
|
|
{
|
|
$path = $this->getThumbnailPath($thumbnail, $type, $size);
|
|
|
|
if (isFunctionalTests()) {
|
|
$version = '';
|
|
} else {
|
|
$version = is_numeric($thumbnail->version) ? $thumbnail->version : strtotime($thumbnail->version);
|
|
}
|
|
|
|
return $this->urlFinder->staticUrl("{$path}?{$version}");
|
|
}
|
|
|
|
public function getNewPath(Thumbnail $thumbnail, string $type, string $version, ?string $lang = null): string
|
|
{
|
|
$path = "photo/{$type}/{$thumbnail->id}/";
|
|
$path .= empty($thumbnail->title) ? 'photo' : StringUtil::slugify($thumbnail->title);
|
|
$path .= empty($version) ? '' : ".{$version}";
|
|
$path .= empty($lang) ? '' : ".{$lang}";
|
|
|
|
return $this->pathFinder->shopPath($path);
|
|
}
|
|
|
|
public function getPath($id, $type, $ext = 'jpg', $lang = null, ?string $version = null)
|
|
{
|
|
$config = $this->getConfig();
|
|
|
|
if (!is_numeric($type)) {
|
|
if (!isset($config['type_to_id'])) {
|
|
$config['type_to_id'] = array_flip($config['id_to_type']);
|
|
}
|
|
|
|
$type = $config['type_to_id'][$type];
|
|
}
|
|
|
|
$subFolder = $id % 10;
|
|
|
|
if ($lang) {
|
|
$ext = "{$lang}.{$ext}";
|
|
}
|
|
|
|
$versionString = '';
|
|
if ($version && $version !== \Photos::PHOTO_VERSION_DESKTOP && $version !== 'desktop') {
|
|
$versionString = "_{$version}";
|
|
}
|
|
|
|
return $this->pathFinder->tmpPath("{$type}/{$subFolder}/{$id}_{$type}{$versionString}.{$ext}");
|
|
}
|
|
|
|
public function getTypeName($type)
|
|
{
|
|
$config = $this->getConfig();
|
|
if (is_numeric($type)) {
|
|
$type = getVal($type, $config['id_to_type'], $type);
|
|
}
|
|
|
|
if (!isset($config['types'][$type])) {
|
|
throw new \UnexpectedValueException('Neznámý typ obrázku: '.$type);
|
|
}
|
|
|
|
return $type;
|
|
}
|
|
|
|
public function getTypeConfig(&$type)
|
|
{
|
|
$config = $this->getConfig();
|
|
|
|
$type = $this->getTypeName($type);
|
|
|
|
return array_merge($this->default, $config['default'], $config['types'][$type]);
|
|
}
|
|
|
|
public function getImageById(int $id): ?Image
|
|
{
|
|
$photo = sqlQueryBuilder()
|
|
->select('*')
|
|
->from('photos')
|
|
->where(Operator::equals(['id' => $id]))
|
|
->execute()->fetchAssociative();
|
|
|
|
if (!$photo) {
|
|
return null;
|
|
}
|
|
|
|
return $this->getImage($photo);
|
|
}
|
|
|
|
public function getImage(array $photo): Image
|
|
{
|
|
return (new Image())
|
|
->setId((int) $photo['id'])
|
|
->setVideoId($photo['id_video'] ?? null)
|
|
->setDescription($photo['descr'])
|
|
->setSource($photo['source'])
|
|
->setImageDesktop($photo['image_2'])
|
|
->setImageTablet($photo['image_tablet'])
|
|
->setImageMobile($photo['image_mobile'])
|
|
->setDate(!empty($photo['date']) ? new \DateTime($photo['date_update']) : null)
|
|
->setDateUpdated(new \DateTime($photo['date_update']))
|
|
->setData(json_decode($photo['data'] ?? '', true) ?: []);
|
|
}
|
|
|
|
public function getOldImageArray($id, $file, $folder, $type, $desc = '', ?int $dateUpdate = null, ?string $data = null): ?array
|
|
{
|
|
if (empty($id)) {
|
|
return null;
|
|
}
|
|
|
|
$settings = $this->getTypeConfig($type);
|
|
|
|
// All thumbnails now use `jpg` extension
|
|
$ext = 'jpg';
|
|
|
|
$lang = null;
|
|
if (!empty($settings['lang'])) {
|
|
$lang = Contexts::get(LanguageContext::class)->getActiveId();
|
|
}
|
|
|
|
$path_large = $this->getPath($id, 0, $ext, $lang);
|
|
$path_thumbnail = $this->getPath($id, $type, $ext, $lang);
|
|
|
|
$ret = [
|
|
'id' => $id,
|
|
'src' => &$path_thumbnail,
|
|
'source' => &$path_thumbnail,
|
|
'descr' => $desc,
|
|
'width' => $settings['size'][0] ?? 0, // TODO: Revert, responsive types should not be accessed using getOldImageArray
|
|
'height' => $settings['size'][1] ?? 0,
|
|
'src_big' => &$path_large,
|
|
'source_big' => &$path_large,
|
|
'date_update' => $dateUpdate,
|
|
'type' => $this->getTypeName($type),
|
|
];
|
|
|
|
if ($data) {
|
|
$data = json_decode($data, true);
|
|
$ret = array_merge($data, $ret);
|
|
}
|
|
|
|
if (($dateUpdate ?? -1) > 0) {
|
|
$time_thumbnail = $time_large = (isFunctionalTests()) ? '' : $dateUpdate;
|
|
} else {
|
|
if (isLocalDevelopment()) {
|
|
$logger = ServiceContainer::getService('logger');
|
|
$logger->error('getOldImageArray bez data poslední změny '.$type, array_merge($ret, ['exception' => new SilencedErrorContext(1, '', 0, debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 5), 1)]));
|
|
}
|
|
$time_thumbnail = $time_large = '';
|
|
}
|
|
|
|
$imageVersion = '';
|
|
if (!isFunctionalTests()) {
|
|
$imageVersion = '_'.(\Settings::getDefault()->image_version ?? '1');
|
|
}
|
|
|
|
$path_thumbnail .= "?{$time_thumbnail}{$imageVersion}";
|
|
$path_large .= "?{$time_large}{$imageVersion}";
|
|
|
|
$path_thumbnail = $this->urlFinder->staticUrl($path_thumbnail);
|
|
$path_large = $this->urlFinder->staticUrl($path_large);
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public function clearThumbnails($image_id, $version = null)
|
|
{
|
|
foreach ($this->getConfig()['id_to_type'] as $id => $type) {
|
|
foreach (glob($this->getPath($image_id, $id, '', null, $version).'*') as $filename) {
|
|
@unlink($filename);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @required
|
|
*/
|
|
public function setUrlFinder(UrlFinder $urlFinder): void
|
|
{
|
|
$this->urlFinder = $urlFinder;
|
|
}
|
|
}
|