<file_sep><?php

namespace FondOfSpryker\Yves\Router\Plugin\RouteManipulator;

use Spryker\Yves\Kernel\AbstractPlugin;
use Spryker\Yves\RouterExtension\Dependency\Plugin\PostAddRouteManipulatorPluginInterface;
use Symfony\Component\Routing\Route;

/**
 * @method \Spryker\Yves\Router\RouterConfig getConfig()
 * @method \FondOfSpryker\Yves\Router\RouterFactory getFactory()
 */
class LanguageDefaultPostAddRouteManipulatorPlugin extends AbstractPlugin implements PostAddRouteManipulatorPluginInterface
{
    /**
     * @var string
     */
    protected $allowedLocalesPattern;

    /**
     * @param string $routeName
     * @param \Symfony\Component\Routing\Route $route
     *
     * @return \Symfony\Component\Routing\Route
     */
    public function manipulate(string $routeName, Route $route): Route
    {
        $route->setDefault('language', $this->getFactory()->createStoreDataProvider()->getCurrentLanguage());

        return $route;
    }
}
<file_sep><?php

namespace FondOfSpryker\Yves\Router\DataProvider;

use Spryker\Shared\Kernel\Store;

class StoreDataProvider implements DataProviderInterface
{
    /**
     * @var array
     */
    protected $availableLocales;

    /**
     * @var \Spryker\Shared\Kernel\Store
     */
    protected $storeInstance;

    /**
     * @param \Spryker\Shared\Kernel\Store $storeInstance
     */
    public function __construct(Store $storeInstance)
    {
        $this->storeInstance = $storeInstance;
    }

    /**
     * @return array
     */
    public function getAvailableLocales(): array
    {
        if ($this->availableLocales === null) {
            $this->availableLocales = $this->storeInstance->getLocales();
        }

        return $this->availableLocales;
    }

    /**
     * @param string $locale
     *
     * @return string|null
     */
    public function getLanguageFromLocale(string $locale): ?string
    {
        return array_search($locale, $this->getAvailableLocales());
    }

    /**
     * @return string
     */
    public function getCurrentLanguage(): string
    {
        return $this->getLanguageFromLocale($this->storeInstance->getCurrentLocale());
    }
}
<file_sep><?php

namespace FondOfSpryker\Yves\Router\Plugin\RouteManipulator;

use Spryker\Yves\Kernel\AbstractPlugin;
use Spryker\Yves\RouterExtension\Dependency\Plugin\PostAddRouteManipulatorPluginInterface;
use Symfony\Component\Routing\Route;

/**
 * @method \Spryker\Yves\Router\RouterConfig getConfig()
 * @method \FondOfSpryker\Yves\Router\RouterFactory getFactory()
 */
class StoreDefaultPostAddRouteManipulatorPlugin extends AbstractPlugin implements PostAddRouteManipulatorPluginInterface
{
    /**
     * @var string
     */
    protected $allowedLocalesPattern;

    /**
     * @param string $routeName
     * @param \Symfony\Component\Routing\Route $route
     *
     * @return \Symfony\Component\Routing\Route
     */
    public function manipulate(string $routeName, Route $route): Route
    {
        $route->setDefault('store', APPLICATION_STORE);

        return $route;
    }
}
<file_sep><?php

namespace FondOfSpryker\Yves\Router\Plugin\RouterEnhancer;

use FondOfSpryker\Yves\Router\DataProvider\DataProviderInterface;
use Spryker\Yves\Router\Plugin\RouterEnhancer\LanguagePrefixRouterEnhancerPlugin as SprykerLanguagePrefixRouterEnhancerPlugin;
use Symfony\Component\Routing\RequestContext;

/**
 * @method \Spryker\Yves\Router\RouterConfig getConfig()
 * @method \FondOfSpryker\Yves\Router\RouterFactory getFactory()
 */
class LanguagePrefixRouterEnhancerPlugin extends SprykerLanguagePrefixRouterEnhancerPlugin
{
    protected $storeDataProvder;

    /**
     * @param string $locale
     *
     * @return string
     */
    protected function getLanguageFromLocale(string $locale): string
    {
        $language = $this->getStoreDataProvider()->getLanguageFromLocale($locale);

        if ($language === null) {
            $language = parent::getLanguageFromLocale($locale);
        }

        return $language;
    }

    /**
     * @param \Symfony\Component\Routing\RequestContext $requestContext
     *
     * @return string|null
     */
    protected function findLanguage(RequestContext $requestContext): ?string
    {
        $language = parent::findLanguage($requestContext);
        $availableLocales = $this->getStoreDataProvider()->getAvailableLocales();
        if (!array_key_exists($language, $availableLocales)) {
            foreach ($availableLocales as $lang => $locale) {
                if (substr($locale, 0, strlen($language)) === $language) {
                    $language = $lang;

                    break;
                }
            }
        }

        return $language;
    }

    /**
     * @return \FondOfSpryker\Yves\Router\DataProvider\DataProviderInterface
     */
    protected function getStoreDataProvider(): DataProviderInterface
    {
        if ($this->storeDataProvder === null) {
            $this->storeDataProvder = $this->getFactory()->createStoreDataProvider();
        }

        return $this->storeDataProvder;
    }
}
<file_sep><?php

namespace FondOfSpryker\Yves\Router;

use FondOfSpryker\Yves\Router\Dependency\Client\RouterToSessionClientBridge;
use FondOfSpryker\Yves\Router\Dependency\Client\RouterToStoreClientBridge;
use Spryker\Shared\Kernel\Store;
use Spryker\Yves\Router\RouterDependencyProvider as SprykerRouterDependencyProvider;
use Spryker\Yves\Kernel\Container;

/**
 * @method \Spryker\Yves\Router\RouterConfig getConfig()
 */
class RouterDependencyProvider extends SprykerRouterDependencyProvider
{
    public const DIRTY_STORE_INSTANCE = 'DIRTY_STORE_INSTANCE';

    /**
     * @param \Spryker\Yves\Kernel\Container $container
     *
     * @return \Spryker\Yves\Kernel\Container
     */
    public function provideDependencies(Container $container)
    {
        $container = parent::provideDependencies($container);
        $container = $this->addStore($container);

        return $container;
    }

    /**
     * @param \Spryker\Yves\Kernel\Container $container
     *
     * @return \Spryker\Yves\Kernel\Container
     */
    protected function addStore(Container $container): Container
    {
        $container[static::DIRTY_STORE_INSTANCE] = function () {
            return Store::getInstance();
        };

        return $container;
    }
}
<file_sep><?php

namespace FondOfSpryker\Yves\Router\DataProvider;

interface DataProviderInterface
{
    /**
     * @return array
     */
    public function getAvailableLocales(): array;

    /**
     * @param  string  $locale
     *
     * @return string|null
     */
    public function getLanguageFromLocale(string $locale): ?string;

    /**
     * @return string
     */
    public function getCurrentLanguage(): string;
}
<file_sep># spryker-router

## Install
```
composer require fond-of-spryker/router
```
<file_sep><?php

namespace FondOfSpryker\Yves\Router;

use FondOfSpryker\Yves\Router\DataProvider\DataProviderInterface;
use FondOfSpryker\Yves\Router\DataProvider\StoreDataProvider;
use Spryker\Shared\Kernel\Store;
use Spryker\Yves\Router\RouterFactory as SprykerRouterFactory;

/**
 * @method \Spryker\Yves\Router\RouterConfig getConfig()
 */
class RouterFactory extends SprykerRouterFactory
{
    /**
     * @return \Spryker\Shared\Kernel\Store
     */
    public function getStoreInstance(): Store
    {
        return $this->getProvidedDependency(RouterDependencyProvider::DIRTY_STORE_INSTANCE);
    }

    /**
     * @return \FondOfSpryker\Yves\Router\DataProvider\DataProviderInterface
     */
    public function createStoreDataProvider(): DataProviderInterface
    {
        return new StoreDataProvider($this->getStoreInstance());
    }
}
