<?php declare(strict_types=1);
namespace Intedia\Imgbolt\Core\Content\Media\Pathname;
use Shopware\Core\Content\Media\Aggregate\MediaThumbnail\MediaThumbnailEntity;
use Shopware\Core\Content\Media\MediaEntity;
use Shopware\Core\Content\Media\Pathname\PathnameStrategy\PathnameStrategyInterface;
use Shopware\Core\Content\Media\Pathname\UrlGeneratorInterface;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\Service\ResetInterface;
class CdnUrlGenerator implements UrlGeneratorInterface, ResetInterface
{
const CONFIG_KEY = 'IntediaImgbolt.config.';
/**
* @var UrlGeneratorInterface
*/
private $originalService;
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var string
*/
private $baseUrl;
/**
* @var array
*/
protected $config;
/**
* @var PathnameStrategyInterface
*/
private $pathnameStrategy;
/**
* @var SystemConfigService
*/
protected $systemConfigService;
/**
* @var array
*/
protected $cdnUrls;
public function __construct(
UrlGeneratorInterface $originalService,
PathnameStrategyInterface $pathnameStrategy,
RequestStack $requestStack,
string $baseUrl,
SystemConfigService $systemConfigService
) {
$this->originalService = $originalService;
$this->pathnameStrategy = $pathnameStrategy;
$this->requestStack = $requestStack;
$this->systemConfigService = $systemConfigService;
$this->config = $this->getConfig();
$this->cdnUrls = $this->getCdnUrls();
$this->baseUrl = $this->normalizeBaseUrl($baseUrl);
}
/**
* {@inheritDoc}
*/
public function getRelativeMediaUrl(MediaEntity $media): string
{
return $this->originalService->getRelativeMediaUrl($media);
}
/**
* {@inheritDoc}
*/
public function getAbsoluteMediaUrl(MediaEntity $media): string
{
return $this->getBaseUrl() . '/' . $this->getRelativeMediaUrl($media);
}
/**
* {@inheritDoc}
*/
public function getRelativeThumbnailUrl(MediaEntity $media, MediaThumbnailEntity $thumbnail): string
{
return $this->originalService->getRelativeThumbnailUrl($media, $thumbnail);
}
/**
* @param MediaEntity $media
* @param MediaThumbnailEntity $thumbnail
* @return string
*/
public function getAbsoluteThumbnailUrl(MediaEntity $media, MediaThumbnailEntity $thumbnail): string
{
return $this->getBaseUrl() . '/' . $this->getRelativeThumbnailUrl($media, $thumbnail);
}
/**
* @return string
*/
private function getBaseUrl(): string
{
if (!$this->baseUrl) {
$this->baseUrl = $this->createFallbackUrl();
}
return $this->baseUrl;
}
/**
* @return string
*/
private function createFallbackUrl(): string
{
$request = $this->requestStack->getMasterRequest();
if ($request) {
$schemeAndHost = empty($this->cdnUrls) ? $request->getSchemeAndHttpHost() : rtrim($this->cdnUrls[array_rand($this->cdnUrls)], '/');
$basePath = $schemeAndHost . $request->getBasePath();
return rtrim($basePath, '/');
}
return $_SERVER['APP_URL'];
}
/**
* @param string|null $baseUrl
* @return string|null
*/
private function normalizeBaseUrl(?string $baseUrl): ?string
{
if ($baseUrl === null) { // The case most of the time
return null;
}
return rtrim($baseUrl, '/');
}
protected function getCdnUrls(): array
{
if ($this->getConfigValue('imCdnEnabled')) {
if ($domainConfig = trim($this->getConfigValue('imCdnDomain'))) {
return array_map('trim', explode(',', $domainConfig));
}
}
return [];
}
/**
* @param $key
* @param null $default
* @return mixed|null
*/
protected function getConfigValue($key, $default = null)
{
if (array_key_exists($key, $this->config)) {
return $this->config[$key];
}
else if (array_key_exists(self::CONFIG_KEY . $key, $this->config)) {
return $this->config[self::CONFIG_KEY . $key];
}
return $default;
}
protected function getConfig(): array
{
$request = $this->requestStack->getMasterRequest();
$salesChannelId = $request ? $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID) : null;
return $this->systemConfigService->getDomain(self::CONFIG_KEY, $salesChannelId, true);
}
public function reset(): void
{
if (method_exists($this->originalService, 'reset')) {
$this->originalService->reset();
}
// TODO: Implement reset() method.
}
}