Skip to content

Commit

Permalink
Allows to unset path for websites with single store
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-kl1 committed Mar 22, 2024
1 parent 9114294 commit 463b97a
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 25 deletions.
19 changes: 12 additions & 7 deletions Model/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

use Magento\Directory\Helper\Data;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ScopeInterface as AppScopeInterface;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Model\ScopeInterface;
Expand All @@ -17,8 +16,9 @@

class Config
{
private const CONFIG_PATH_USE_STORE_PATH = 'web/url/use_store_path';
private const CONFIG_PATH_STORE_PATH_URL = 'web/url/store_path_url';
private const CONFIG_PATH_CUSTOM_PATH_MAPPER = 'web/url/custom_path_mapper';
private const CONFIG_PATH_UNSET_SINGLE_STORE_PATH = 'web/url/unset_single_store_path';

private ?array $customPathMapper = null;

Expand All @@ -35,24 +35,29 @@ public function isEnabled(): bool

public function getStorePathType(): PathType
{
return PathType::from($this->scopeConfig->getValue(self::CONFIG_PATH_USE_STORE_PATH));
return PathType::from($this->scopeConfig->getValue(self::CONFIG_PATH_STORE_PATH_URL));
}

public function getCountry(AppScopeInterface|StoreInterface $scope): string
public function isUnsetSingleStorePath(): bool
{
return $this->scopeConfig->isSetFlag(self::CONFIG_PATH_UNSET_SINGLE_STORE_PATH);
}

public function getCountry(StoreInterface $store): string
{
return (string)$this->scopeConfig->getValue(
Data::XML_PATH_DEFAULT_COUNTRY,
ScopeInterface::SCOPE_STORE,
$scope->getId()
$store->getId()
);
}

public function getLocale(AppScopeInterface|StoreInterface $scope): string
public function getLocale(StoreInterface $store): string
{
return (string)$this->scopeConfig->getValue(
Data::XML_PATH_DEFAULT_LOCALE,
ScopeInterface::SCOPE_STORE,
$scope->getId()
$store->getId()
);
}

Expand Down
3 changes: 2 additions & 1 deletion Plugin/Url/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use Magento\Framework\Url\ScopeInterface;
use Magento\Framework\UrlInterface;
use Magento\Store\Api\Data\StoreInterface;
use Opengento\StorePathUrl\Model\Config;
use Opengento\StorePathUrl\Service\UriUtils;

Expand All @@ -24,7 +25,7 @@ public function afterGetBaseUrl(
string $type = UrlInterface::URL_TYPE_LINK,
?bool $secure = null
): string {
return $type === UrlInterface::URL_TYPE_LINK && $this->config->isEnabled()
return $type === UrlInterface::URL_TYPE_LINK && $subject instanceof StoreInterface && $this->config->isEnabled()
? $this->uriUtils->replaceScopeCode($baseUrl, $subject)
: $baseUrl;
}
Expand Down
30 changes: 22 additions & 8 deletions Service/PathResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

namespace Opengento\StorePathUrl\Service;

use Magento\Framework\App\ScopeInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Model\Store;
use Opengento\StorePathUrl\Model\Config;
use Opengento\StorePathUrl\Model\Config\PathType;

Expand All @@ -19,15 +20,28 @@ class PathResolver
{
public function __construct(private Config $config) {}

public function resolve(ScopeInterface|StoreInterface $scope): string
public function resolve(StoreInterface $store): string
{
if ($store instanceof Store && $this->isSingleStore($store) && $this->config->isUnsetSingleStorePath()) {
return '';
}

return strtolower(match ($this->config->getStorePathType()) {
PathType::StoreCode => $scope->getCode(),
PathType::CountryCode => $this->config->getCountry($scope),
PathType::LanguageCode => strtok($this->config->getLocale($scope), '_'),
PathType::LocaleUnderscore => $this->config->getLocale($scope),
PathType::LocaleHyphen => str_replace('_', '-', $this->config->getLocale($scope)),
PathType::Custom => $this->config->getCustomPathMapper()[(int)$scope->getId()] ?? $scope->getCode(),
PathType::StoreCode => $store->getCode(),
PathType::CountryCode => $this->config->getCountry($store),
PathType::LanguageCode => strtok($this->config->getLocale($store), '_'),
PathType::LocaleUnderscore => $this->config->getLocale($store),
PathType::LocaleHyphen => str_replace('_', '-', $this->config->getLocale($store)),
PathType::Custom => $this->config->getCustomPathMapper()[(int)$store->getId()] ?? '',
});
}

private function isSingleStore(Store $store): bool
{
try {
return $store->getWebsiteId() && $store->getWebsite()->getStoresCount() === 1;
} catch (NoSuchEntityException) {
return true;
}
}
}
12 changes: 8 additions & 4 deletions Service/UriUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

namespace Opengento\StorePathUrl\Service;

use Magento\Framework\App\ScopeInterface;
use Magento\Store\Api\Data\StoreInterface;

use function ltrim;
Expand All @@ -22,12 +21,12 @@ class UriUtils
{
public function __construct(private PathResolver $pathResolver) {}

public function replaceScopeCode(string $url, ScopeInterface|StoreInterface $scope): string
public function replaceScopeCode(string $url, StoreInterface $scope): string
{
return $this->replaceLeadingPath($scope->getCode(), $this->pathResolver->resolve($scope), $url);
}

public function replacePathCode(string $url, ScopeInterface|StoreInterface $scope): string
public function replacePathCode(string $url, StoreInterface $scope): string
{
return $this->replaceLeadingPath($this->pathResolver->resolve($scope), $scope->getCode(), $url);
}
Expand All @@ -37,7 +36,12 @@ private function replaceLeadingPath(string $search, string $replace, string $uri
$path = parse_url($uri, PHP_URL_PATH) ?? '/';

return $path !== '/' && str_starts_with(ltrim($path, '/'), ltrim($search, '/'))
? str_replace($path, substr_replace($path, $replace, (int)str_starts_with($path, '/'), strlen($search)), $uri)
? str_replace($path, $this->replacePath($search, $replace, $path), $uri)
: $uri;
}

private function replacePath(string $search, string $replace, string $path): string
{
return str_replace('//', '/', substr_replace($path, $replace, (int)str_starts_with($path, '/'), strlen($search)));
}
}
24 changes: 20 additions & 4 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
<system>
<section id="web">
<group id="url">
<field id="use_store_path" type="select" translate="label comment" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="15" canRestore="1">
<label>Custom Store Path Url</label>
<field id="use_store" translate="label comment">
<label>Add Store Path to Urls</label>
<comment>
<![CDATA[<strong class="colorRed">Warning!</strong> When using Store Path in URLs, in some cases system may not work properly if URLs without Store Path are specified in the third-party services (e.g. PayPal etc.).]]>
</comment>
</field>
<field id="store_path_url" type="select" translate="label" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="15" canRestore="1">
<label>Store Path Url</label>
<source_model>Opengento\StorePathUrl\Model\Config\Source\PathTypes</source_model>
<config_path>web/url/use_store_path</config_path>
<config_path>web/url/store_path_url</config_path>
<depends>
<field id="use_store">1</field>
</depends>
Expand All @@ -24,8 +30,18 @@
<config_path>web/url/custom_path_mapper</config_path>
<depends>
<field id="use_store">1</field>
<field id="use_store_path">custom</field>
<field id="store_path_url">custom</field>
</depends>
</field>
<field id="unset_single_store_path" type="select" translate="label comment" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="15" canRestore="1">
<label>Unset Path for Single Store</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>web/url/unset_single_store_path</config_path>
<depends>
<field id="use_store">1</field>
<field id="store_path_url" negative="1">custom</field>
</depends>
<comment>When enabled, websites with a single store won't use the Store Path in URLs.</comment>
</field>
</group>
</section>
Expand Down
3 changes: 2 additions & 1 deletion etc/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
<default>
<web>
<url>
<use_store_path>store_code</use_store_path>
<store_path_url>store_code</store_path_url>
<unset_single_store_path>1</unset_single_store_path>
</url>
</web>
</default>
Expand Down

0 comments on commit 463b97a

Please sign in to comment.