183 lines
4.8 KiB
PHP
183 lines
4.8 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun3d\LanguageUrlStoreResolver\Model;
|
|
|
|
use Magento\Framework\UrlInterface;
|
|
use Magento\Store\Model\StoreManagerInterface;
|
|
|
|
class UrlPathConverter
|
|
{
|
|
/**
|
|
* @var Config
|
|
*/
|
|
private $config;
|
|
|
|
/**
|
|
* @var StoreCodeMapper
|
|
*/
|
|
private $storeCodeMapper;
|
|
|
|
/**
|
|
* @var StoreViewRegistry
|
|
*/
|
|
private $storeViewRegistry;
|
|
|
|
/**
|
|
* @var StoreManagerInterface
|
|
*/
|
|
private $storeManager;
|
|
|
|
public function __construct(
|
|
Config $config,
|
|
StoreCodeMapper $storeCodeMapper,
|
|
StoreViewRegistry $storeViewRegistry,
|
|
StoreManagerInterface $storeManager
|
|
) {
|
|
$this->config = $config;
|
|
$this->storeCodeMapper = $storeCodeMapper;
|
|
$this->storeViewRegistry = $storeViewRegistry;
|
|
$this->storeManager = $storeManager;
|
|
}
|
|
|
|
public function toLanguageUrl(string $url, string $language): string
|
|
{
|
|
$parts = parse_url($url);
|
|
if ($parts === false) {
|
|
return $url;
|
|
}
|
|
|
|
if ($this->isExternalUrl($parts)) {
|
|
return $url;
|
|
}
|
|
|
|
$path = $parts['path'] ?? '/';
|
|
$path = $path === '' ? '/' : $path;
|
|
$basePath = $this->getBasePath();
|
|
$relativePath = $this->stripBasePath($path, $basePath);
|
|
|
|
if ($this->config->shouldSkipPath($relativePath)) {
|
|
return $url;
|
|
}
|
|
|
|
$parts['path'] = $this->prependBasePath(
|
|
$basePath,
|
|
$this->convertRelativePath($relativePath, strtolower($language))
|
|
);
|
|
|
|
return $this->buildUrl($parts);
|
|
}
|
|
|
|
/**
|
|
* @param mixed[] $parts
|
|
*/
|
|
private function isExternalUrl(array $parts): bool
|
|
{
|
|
if (!isset($parts['host'])) {
|
|
return false;
|
|
}
|
|
|
|
$baseParts = parse_url($this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_WEB));
|
|
$baseHost = isset($baseParts['host']) ? strtolower($baseParts['host']) : '';
|
|
|
|
return strtolower((string)$parts['host']) !== $baseHost;
|
|
}
|
|
|
|
private function convertRelativePath(string $path, string $language): string
|
|
{
|
|
$path = '/' . ltrim($path, '/');
|
|
$segments = explode('/', trim($path, '/'), 2);
|
|
$firstSegment = $segments[0] ?? '';
|
|
$remainingPath = $segments[1] ?? '';
|
|
|
|
if ($this->storeCodeMapper->isRealStoreCodeInScope($firstSegment)) {
|
|
$language = $this->storeCodeMapper->languageFromStoreCode($firstSegment) ?? $language;
|
|
$path = $remainingPath === '' ? '/' : '/' . ltrim($remainingPath, '/');
|
|
}
|
|
|
|
if ($this->storeCodeMapper->isLanguageAllowed(strtolower($firstSegment))) {
|
|
$path = $remainingPath === '' ? '/' : '/' . ltrim($remainingPath, '/');
|
|
}
|
|
|
|
if ($this->storeCodeMapper->isDefaultLanguage($language)) {
|
|
return $path;
|
|
}
|
|
|
|
return $path === '/' ? '/' . $language . '/' : '/' . $language . $path;
|
|
}
|
|
|
|
private function getBasePath(): string
|
|
{
|
|
$baseParts = parse_url($this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_WEB));
|
|
$basePath = isset($baseParts['path']) ? rtrim($baseParts['path'], '/') : '';
|
|
|
|
return $basePath !== '' ? $basePath : '/';
|
|
}
|
|
|
|
private function stripBasePath(string $path, string $basePath): string
|
|
{
|
|
if ($basePath === '/' || $basePath === '') {
|
|
return '/' . ltrim($path, '/');
|
|
}
|
|
|
|
if ($path === $basePath) {
|
|
return '/';
|
|
}
|
|
|
|
if (strpos($path, $basePath . '/') === 0) {
|
|
return '/' . ltrim(substr($path, strlen($basePath)), '/');
|
|
}
|
|
|
|
return '/' . ltrim($path, '/');
|
|
}
|
|
|
|
private function prependBasePath(string $basePath, string $path): string
|
|
{
|
|
$path = '/' . ltrim($path, '/');
|
|
|
|
if ($basePath === '/' || $basePath === '') {
|
|
return $path;
|
|
}
|
|
|
|
return rtrim($basePath, '/') . $path;
|
|
}
|
|
|
|
/**
|
|
* @param mixed[] $parts
|
|
*/
|
|
private function buildUrl(array $parts): string
|
|
{
|
|
$url = '';
|
|
|
|
if (isset($parts['host'])) {
|
|
$url .= isset($parts['scheme']) ? $parts['scheme'] . '://' : '//';
|
|
|
|
if (isset($parts['user'])) {
|
|
$url .= $parts['user'];
|
|
if (isset($parts['pass'])) {
|
|
$url .= ':' . $parts['pass'];
|
|
}
|
|
$url .= '@';
|
|
}
|
|
|
|
$url .= $parts['host'];
|
|
|
|
if (isset($parts['port'])) {
|
|
$url .= ':' . $parts['port'];
|
|
}
|
|
}
|
|
|
|
$url .= $parts['path'] ?? '/';
|
|
|
|
if (isset($parts['query']) && $parts['query'] !== '') {
|
|
$url .= '?' . $parts['query'];
|
|
}
|
|
|
|
if (isset($parts['fragment']) && $parts['fragment'] !== '') {
|
|
$url .= '#' . $parts['fragment'];
|
|
}
|
|
|
|
return $url;
|
|
}
|
|
}
|