Skip to content

Commit

Permalink
FRW-7936 Allow to provide store name as part of URL path. (#11121)
Browse files Browse the repository at this point in the history
FRW-7936 Allow to provide store name as part of URL path.
  • Loading branch information
dimitriyTsemma authored Nov 28, 2024
1 parent fbbc2f4 commit fac365d
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 6 deletions.
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
"spryker/laminas": "^1.0.0",
"spryker/log": "^3.0.0",
"spryker/router-extension": "^1.0.0",
"spryker/store": "^1.19.0",
"spryker/symfony": "^3.5.0"
},
"require-dev": {
"spryker/application": "*",
"spryker/code-sniffer": "*",
"spryker/config": "*",
"spryker/event-dispatcher": "*",
"spryker/storage": "*",
"spryker/testify": "*",
"spryker/util-text": "*"
},
Expand Down
10 changes: 10 additions & 0 deletions src/Spryker/Shared/Router/RouterConstants.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,14 @@ interface RouterConstants
* @var string
*/
public const PROJECT_NAMESPACES = 'PROJECT_NAMESPACES';

/**
* Specification:
* - Returns true if the store routing is enabled.
*
* @api
*
* @var string
*/
public const IS_STORE_ROUTING_ENABLED = 'ROUTER:IS_STORE_ROUTING_ENABLED';
}
4 changes: 4 additions & 0 deletions src/Spryker/Shared/Router/Transfer/router.transfer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@
<transfer name="RouterActionCollection">
<property name="actions" type="string[]" singular="action"/>
</transfer>

<transfer name="Store">
<property name="name" type="string"/>
</transfer>
</transfers>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/**
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
*/

namespace Spryker\Yves\Router\Dependency\Client;

use Generated\Shared\Transfer\StoreTransfer;

class RouterToStoreClientBridge implements RouterToStoreClientInterface
{
/**
* @var \Spryker\Client\Store\StoreClientInterface
*/
protected $storeClient;

/**
* @param \Spryker\Client\Store\StoreClientInterface $storeClient
*/
public function __construct($storeClient)
{
$this->storeClient = $storeClient;
}

/**
* @return \Generated\Shared\Transfer\StoreTransfer
*/
public function getCurrentStore(): StoreTransfer
{
return $this->storeClient->getCurrentStore();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/**
* Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
* Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
*/

namespace Spryker\Yves\Router\Dependency\Client;

use Generated\Shared\Transfer\StoreTransfer;

interface RouterToStoreClientInterface
{
/**
* @return \Generated\Shared\Transfer\StoreTransfer
*/
public function getCurrentStore(): StoreTransfer;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@

/**
* @method \Spryker\Yves\Router\RouterConfig getConfig()
* @method \Spryker\Yves\Router\RouterFactory getFactory()
*/
class StorePrefixRouterEnhancerPlugin extends AbstractRouterEnhancerPlugin
{
/**
* @var string
*/
protected const PARAMETER_STORE = 'store';

/**
* @var string|null
*/
Expand Down Expand Up @@ -52,7 +58,7 @@ public function beforeMatch(string $pathinfo, RequestContext $requestContext): s
public function afterMatch(array $parameters, RequestContext $requestContext): array
{
if ($this->currentStore !== null) {
$parameters['store'] = $this->currentStore;
$parameters[static::PARAMETER_STORE] = $this->currentStore;
}

return $parameters;
Expand Down Expand Up @@ -83,11 +89,11 @@ public function afterGenerate(string $url, RequestContext $requestContext, int $
*/
protected function findStore(RequestContext $requestContext): ?string
{
if ($requestContext->hasParameter('store')) {
return $requestContext->getParameter('store');
}

return null;
return $requestContext->hasParameter(static::PARAMETER_STORE) && $requestContext->getParameter(static::PARAMETER_STORE) !== null
? $requestContext->getParameter(static::PARAMETER_STORE)
: ($this->getConfig()->isStoreRoutingEnabled()
? $this->getFactory()->getStoreClient()->getCurrentStore()->getNameOrFail()
: null);
}

/**
Expand Down
13 changes: 13 additions & 0 deletions src/Spryker/Yves/Router/RouterConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,17 @@ public function getAllowedStores(): array
'US',
];
}

/**
* Specification:
* - Returns true if the store routing is enabled.
*
* @api
*
* @return bool
*/
public function isStoreRoutingEnabled(): bool
{
return $this->get(RouterConstants::IS_STORE_ROUTING_ENABLED, false);
}
}
21 changes: 21 additions & 0 deletions src/Spryker/Yves/Router/RouterDependencyProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Spryker\Yves\Kernel\AbstractBundleDependencyProvider;
use Spryker\Yves\Kernel\Container;
use Spryker\Yves\Router\Dependency\Client\RouterToStoreClientBridge;

/**
* @method \Spryker\Yves\Router\RouterConfig getConfig()
Expand All @@ -35,6 +36,11 @@ class RouterDependencyProvider extends AbstractBundleDependencyProvider
*/
public const ROUTER_ENHANCER_PLUGINS = 'ROUTER_ENHANCER_PLUGINS';

/**
* @var string
*/
public const CLIENT_STORE = 'CLIENT_STORE';

/**
* @param \Spryker\Yves\Kernel\Container $container
*
Expand All @@ -46,6 +52,7 @@ public function provideDependencies(Container $container)
$container = $this->addRouterEnhancerPlugins($container);
$container = $this->addRouteProvider($container);
$container = $this->addPostAddRouteManipulator($container);
$container = $this->addStoreClient($container);

return $container;
}
Expand Down Expand Up @@ -137,4 +144,18 @@ protected function getPostAddRouteManipulator(): array
{
return [];
}

/**
* @param \Spryker\Yves\Kernel\Container $container
*
* @return \Spryker\Yves\Kernel\Container
*/
protected function addStoreClient(Container $container): Container
{
$container->set(static::CLIENT_STORE, function (Container $container) {
return new RouterToStoreClientBridge($container->getLocator()->store()->client());
});

return $container;
}
}
9 changes: 9 additions & 0 deletions src/Spryker/Yves/Router/RouterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Spryker\Shared\Router\Cache\CacheInterface;
use Spryker\Yves\Kernel\AbstractFactory;
use Spryker\Yves\Router\Cache\Cache;
use Spryker\Yves\Router\Dependency\Client\RouterToStoreClientInterface;
use Spryker\Yves\Router\Loader\ClosureLoader;
use Spryker\Yves\Router\Loader\LoaderInterface;
use Spryker\Yves\Router\Resolver\RequestRequestValueResolver;
Expand Down Expand Up @@ -219,4 +220,12 @@ public function createCache(): CacheInterface
{
return new Cache($this->createRouter(), $this->getConfig());
}

/**
* @return \Spryker\Yves\Router\Dependency\Client\RouterToStoreClientInterface
*/
public function getStoreClient(): RouterToStoreClientInterface
{
return $this->getProvidedDependency(RouterDependencyProvider::CLIENT_STORE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function setUp(): void
{
parent::setUp();

$this->tester->setupStorageRedisConfig();
$this->tester->mockEnvironmentConfig(RouterConstants::YVES_IS_CACHE_ENABLED, false);

$this->tester->mockFactoryMethod('getRouteProviderPlugins', [
Expand Down Expand Up @@ -123,6 +124,7 @@ public function testGenerateReturnsUrlWithLanguageAndStoreWhenLanguageAndStoreAr
*/
public function testGenerateReturnsUrlWithoutLanguageAndStoreWhenLanguageAndStoreAreNotInContext(string $url, string $routeName): void
{
$this->tester->mockEnvironmentConfig(RouterConstants::IS_STORE_ROUTING_ENABLED, false);
$routerPlugin = new YvesRouterPlugin();
$routerPlugin->setFactory($this->tester->getFactory());

Expand All @@ -133,6 +135,28 @@ public function testGenerateReturnsUrlWithoutLanguageAndStoreWhenLanguageAndStor
$this->assertSame($url, $generatedUrl);
}

/**
* @dataProvider generatorWithoutLanguageAndStoreDataProviderWithStoreRoutingEnabled
*
* @param string $url
* @param string $routeName
*
* @return void
*/
public function testGenerateReturnsUrlWithoutLanguageAndStoreWhenLanguageAndStoreAreNotInContextWithStoreRoutingEnabled(
string $url,
string $routeName
): void {
$this->tester->mockEnvironmentConfig(RouterConstants::IS_STORE_ROUTING_ENABLED, true);
$routerPlugin = new YvesRouterPlugin();
$routerPlugin->setFactory($this->tester->getFactory());
$router = $routerPlugin->getRouter();

$generatedUrl = $router->generate($routeName);

$this->assertSame($url, $generatedUrl);
}

/**
* @return array<array<string>>
*/
Expand Down Expand Up @@ -169,4 +193,15 @@ public function generatorWithoutLanguageAndStoreDataProvider(): array
['/foo', 'foo'],
];
}

/**
* @return array<array<string>>
*/
public function generatorWithoutLanguageAndStoreDataProviderWithStoreRoutingEnabled(): array
{
return [
['/DE', 'home'],
['/DE/foo', 'foo'],
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public function testGenerateReturnsUrlWithStoreAndLanguageWhenStoreAndLanguageAr
*/
public function testGenerateReturnsUrlWithoutStoreAndLanguageWhenStoreAndLanguageAreNotInContextParameter(): void
{
$this->tester->mockEnvironmentConfig(RouterConstants::IS_STORE_ROUTING_ENABLED, false);
$routerPlugin = new YvesRouterPlugin();
$routerPlugin->setFactory($this->tester->getFactory());

Expand All @@ -109,4 +110,20 @@ public function testGenerateReturnsUrlWithoutStoreAndLanguageWhenStoreAndLanguag

$this->assertSame('/foo', $url);
}

/**
* @return void
*/
public function testGenerateReturnsUrlWithoutStoreAndLanguageWhenStoreAndLanguageAreNotInContextParameterWithStoreRoutingEnabled(): void
{
$this->tester->mockEnvironmentConfig(RouterConstants::IS_STORE_ROUTING_ENABLED, true);
$routerPlugin = new YvesRouterPlugin();
$routerPlugin->setFactory($this->tester->getFactory());

$router = $routerPlugin->getRouter();

$url = $router->generate('foo');

$this->assertSame('/DE/foo', $url);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,28 @@ public function testGenerateReturnsUrlWithStoreWhenStoreIsInContext(string $url,
*/
public function testGenerateReturnsUrlWithoutStoreWhenStoreIsNotInContext(string $url, string $routeName): void
{
$this->tester->mockEnvironmentConfig(RouterConstants::IS_STORE_ROUTING_ENABLED, false);
$routerPlugin = new YvesRouterPlugin();
$routerPlugin->setFactory($this->tester->getFactory());

$router = $routerPlugin->getRouter();

$generatedUrl = $router->generate($routeName);

$this->assertSame($url, $generatedUrl);
}

/**
* @dataProvider generatorWithoutLanguageAndStoreDataProviderWithStoreRoutingEnabled
*
* @param string $url
* @param string $routeName
*
* @return void
*/
public function testGenerateReturnsUrlWithoutStoreWhenStoreIsNotInContextWithStoreRoutingEnabled(string $url, string $routeName): void
{
$this->tester->mockEnvironmentConfig(RouterConstants::IS_STORE_ROUTING_ENABLED, true);
$routerPlugin = new YvesRouterPlugin();
$routerPlugin->setFactory($this->tester->getFactory());

Expand Down Expand Up @@ -157,4 +179,15 @@ public function generatorWithoutLanguageAndStoreDataProvider(): array
['/foo', 'foo'],
];
}

/**
* @return array<array<string>>
*/
public function generatorWithoutLanguageAndStoreDataProviderWithStoreRoutingEnabled(): array
{
return [
['/DE', 'home'],
['/DE/foo', 'foo'],
];
}
}
Loading

0 comments on commit fac365d

Please sign in to comment.