From 29f9ea25bbb97888aa4e0c0e36787b0f80b9920f Mon Sep 17 00:00:00 2001 From: Andrey Shatrov Date: Tue, 25 Apr 2017 19:27:29 +0400 Subject: [PATCH] [#293] Cant switch to default language if hiding default locale in URL (#439) * [#293] Cant switch to default language if hiding default locale in URL. https://github.com/mcamara/laravel-localization/issues/293 * [#293] Cant switch to default language if hiding default locale in URL. https://github.com/mcamara/laravel-localization/issues/293 --- .../LaravelLocalization.php | 20 +-- tests/LocalizerTests.php | 123 ++++++++++++------ 2 files changed, 96 insertions(+), 47 deletions(-) diff --git a/src/Mcamara/LaravelLocalization/LaravelLocalization.php b/src/Mcamara/LaravelLocalization/LaravelLocalization.php index 00cea7f..89d11d3 100644 --- a/src/Mcamara/LaravelLocalization/LaravelLocalization.php +++ b/src/Mcamara/LaravelLocalization/LaravelLocalization.php @@ -211,13 +211,14 @@ public function localizeURL($url = null, $locale = null) * @param string|bool $locale Locale to adapt, false to remove locale * @param string|false $url URL to adapt in the current language. If not passed, the current url would be taken. * @param array $attributes Attributes to add to the route, if empty, the system would try to extract them from the url. + * @param bool $forceDefaultLocation Force to show default location even hideDefaultLocaleInURL set as TRUE * * @throws SupportedLocalesNotDefined * @throws UnsupportedLocaleException * * @return string|false URL translated, False if url does not exist */ - public function getLocalizedURL($locale = null, $url = null, $attributes = []) + public function getLocalizedURL($locale = null, $url = null, $attributes = [], $forceDefaultLocation = false) { if ($locale === null) { $locale = $this->getCurrentLocale(); @@ -233,7 +234,7 @@ public function getLocalizedURL($locale = null, $url = null, $attributes = []) if (empty($url)) { if (!empty($this->routeName)) { - return $this->getURLFromRouteNameTranslated($locale, $this->routeName, $attributes); + return $this->getURLFromRouteNameTranslated($locale, $this->routeName, $attributes, $forceDefaultLocation); } $url = $this->request->fullUrl(); @@ -242,7 +243,7 @@ public function getLocalizedURL($locale = null, $url = null, $attributes = []) } if ($locale && $translatedRoute = $this->findTranslatedRouteByUrl($url, $attributes, $this->currentLocale)) { - return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes); + return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes, $forceDefaultLocation); } $base_path = $this->request->getBaseUrl(); @@ -272,11 +273,13 @@ public function getLocalizedURL($locale = null, $url = null, $attributes = []) $parsed_url['path'] = ltrim($parsed_url['path'], '/'); if ($translatedRoute = $this->findTranslatedRouteByPath($parsed_url['path'], $url_locale)) { - return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes); + return $this->getURLFromRouteNameTranslated($locale, $translatedRoute, $attributes, $forceDefaultLocation); } - if (!empty($locale) && ($locale != $this->defaultLocale || !$this->hideDefaultLocaleInURL())) { - $parsed_url['path'] = $locale.'/'.ltrim($parsed_url['path'], '/'); + if (!empty($locale)) { + if ($locale != $this->getDefaultLocale() || !$this->hideDefaultLocaleInURL() || $forceDefaultLocation) { + $parsed_url['path'] = $locale.'/'.ltrim($parsed_url['path'], '/'); + } } $parsed_url['path'] = ltrim(ltrim($base_path, '/').'/'.$parsed_url['path'], '/'); @@ -302,13 +305,14 @@ public function getLocalizedURL($locale = null, $url = null, $attributes = []) * @param string|bool $locale Locale to adapt * @param string $transKeyName Translation key name of the url to adapt * @param array $attributes Attributes for the route (only needed if transKeyName needs them) + * @param bool $forceDefaultLocation Force to show default location even hideDefaultLocaleInURL set as TRUE * * @throws SupportedLocalesNotDefined * @throws UnsupportedLocaleException * * @return string|false URL translated */ - public function getURLFromRouteNameTranslated($locale, $transKeyName, $attributes = []) + public function getURLFromRouteNameTranslated($locale, $transKeyName, $attributes = [], $forceDefaultLocation = false) { if (!$this->checkLocaleInSupportedLocales($locale)) { throw new UnsupportedLocaleException('Locale \''.$locale.'\' is not in the list of supported locales.'); @@ -320,7 +324,7 @@ public function getURLFromRouteNameTranslated($locale, $transKeyName, $attribute $route = ''; - if (!($locale === $this->defaultLocale && $this->hideDefaultLocaleInURL())) { + if ($forceDefaultLocation || !($locale === $this->defaultLocale && $this->hideDefaultLocaleInURL())) { $route = '/'.$locale; } if (is_string($locale) && $this->translator->has($transKeyName, $locale)) { diff --git a/tests/LocalizerTests.php b/tests/LocalizerTests.php index a67aba6..0214882 100644 --- a/tests/LocalizerTests.php +++ b/tests/LocalizerTests.php @@ -188,31 +188,6 @@ public function testLocalizeURL() public function testGetLocalizedURL() { - $this->assertEquals( - $this->test_url.'es/acerca', - app('laravellocalization')->getLocalizedURL('es', $this->test_url.'en/about') - ); - - $this->assertEquals( - $this->test_url.'es/ver/1', - app('laravellocalization')->getLocalizedURL('es', $this->test_url.'view/1') - ); - - $this->assertEquals( - $this->test_url.'es/ver/1/proyecto', - app('laravellocalization')->getLocalizedURL('es', $this->test_url.'view/1/project') - ); - - $this->assertEquals( - $this->test_url.'es/ver/1/proyecto/1', - app('laravellocalization')->getLocalizedURL('es', $this->test_url.'view/1/project/1') - ); - - $this->assertEquals( - $this->test_url.'en/about', - app('laravellocalization')->getLocalizedURL('en', $this->test_url.'about') - ); - $this->assertEquals( $this->test_url.app('laravellocalization')->getCurrentLocale(), app('laravellocalization')->getLocalizedURL() @@ -221,20 +196,6 @@ public function testGetLocalizedURL() app('config')->set('laravellocalization.hideDefaultLocaleInURL', true); // testing default language hidden - $this->assertEquals( - $this->test_url.'es/acerca', - app('laravellocalization')->getLocalizedURL('es', $this->test_url.'about') - ); - $this->assertEquals( - $this->test_url.'about', - app('laravellocalization')->getLocalizedURL('en', $this->test_url.'about') - ); - - $this->assertEquals( - $this->test_url, - app('laravellocalization')->getLocalizedURL() - ); - $this->assertNotEquals( $this->test_url.app('laravellocalization')->getDefaultLocale(), app('laravellocalization')->getLocalizedURL() @@ -311,6 +272,90 @@ public function testGetLocalizedURL() ); } + /** + * @param bool $hideDefaultLocaleInURL + * @param bool $forceDefault + * @param string $locale + * @param string $path + * @param string $expectedURL + * + * @dataProvider getLocalizedURLDataProvider + */ + public function testGetLocalizedURLFormat($hideDefaultLocaleInURL, $forceDefault, $locale, $path, $expectedURL) + { + app('config')->set('laravellocalization.hideDefaultLocaleInURL', $hideDefaultLocaleInURL); + $this->assertEquals( + $expectedURL, + app('laravellocalization')->getLocalizedURL($locale, $path, [], $forceDefault) + ); + + } + + public function getLocalizedURLDataProvider() + { + return [ + // Do not hide default + [false, false, 'es', $this->test_url, $this->test_url.'es'], + [false, false, 'es', $this->test_url.'es', $this->test_url.'es'], + [false, false, 'es', $this->test_url.'en/about', $this->test_url.'es/acerca'], + [false, false, 'es', $this->test_url.'ver/1', $this->test_url.'es/ver/1'], + [false, false, 'es', $this->test_url.'view/1/project', $this->test_url.'es/ver/1/proyecto'], + [false, false, 'es', $this->test_url.'view/1/project/1', $this->test_url.'es/ver/1/proyecto/1'], + + // Do not hide default + [false, false, 'en', $this->test_url.'en', $this->test_url.'en'], + [false, false, 'en', $this->test_url.'about', $this->test_url.'en/about'], + [false, false, 'en', $this->test_url.'ver/1', $this->test_url.'en/ver/1'], + [false, false, 'en', $this->test_url.'view/1/project', $this->test_url.'en/view/1/project'], + [false, false, 'en', $this->test_url.'view/1/project/1', $this->test_url.'en/view/1/project/1'], + + // Hide default + [true, false, 'es', $this->test_url, $this->test_url.'es'], + [true, false, 'es', $this->test_url.'es', $this->test_url.'es'], + [true, false, 'es', $this->test_url.'en/about', $this->test_url.'es/acerca'], + [true, false, 'es', $this->test_url.'ver/1', $this->test_url.'es/ver/1'], + [true, false, 'es', $this->test_url.'view/1/project', $this->test_url.'es/ver/1/proyecto'], + [true, false, 'es', $this->test_url.'view/1/project/1', $this->test_url.'es/ver/1/proyecto/1'], + + // Hide default + [true, false, 'en', $this->test_url.'en', $this->test_url.''], + [true, false, 'en', $this->test_url.'about', $this->test_url.'about'], + [true, false, 'en', $this->test_url.'ver/1', $this->test_url.'ver/1'], + [true, false, 'en', $this->test_url.'view/1/project', $this->test_url.'view/1/project'], + [true, false, 'en', $this->test_url.'view/1/project/1', $this->test_url.'view/1/project/1'], + + // Do not hide default FORCE SHOWING + [false, true, 'es', $this->test_url, $this->test_url.'es'], + [false, true, 'es', $this->test_url.'es', $this->test_url.'es'], + [false, true, 'es', $this->test_url.'en/about', $this->test_url.'es/acerca'], + [false, true, 'es', $this->test_url.'ver/1', $this->test_url.'es/ver/1'], + [false, true, 'es', $this->test_url.'view/1/project', $this->test_url.'es/ver/1/proyecto'], + [false, true, 'es', $this->test_url.'view/1/project/1', $this->test_url.'es/ver/1/proyecto/1'], + + // Do not hide default FORCE SHOWING + [false, true, 'en', $this->test_url.'en', $this->test_url.'en'], + [false, true, 'en', $this->test_url.'about', $this->test_url.'en/about'], + [false, true, 'en', $this->test_url.'ver/1', $this->test_url.'en/ver/1'], + [false, true, 'en', $this->test_url.'view/1/project', $this->test_url.'en/view/1/project'], + [false, true, 'en', $this->test_url.'view/1/project/1', $this->test_url.'en/view/1/project/1'], + + // Hide default FORCE SHOWING + [true, true, 'es', $this->test_url, $this->test_url.'es'], + [true, true, 'es', $this->test_url.'es', $this->test_url.'es'], + [true, true, 'es', $this->test_url.'en/about', $this->test_url.'es/acerca'], + [true, true, 'es', $this->test_url.'ver/1', $this->test_url.'es/ver/1'], + [true, true, 'es', $this->test_url.'view/1/project', $this->test_url.'es/ver/1/proyecto'], + [true, true, 'es', $this->test_url.'view/1/project/1', $this->test_url.'es/ver/1/proyecto/1'], + + // Hide default FORCE SHOWING + [true, true, 'en', $this->test_url.'en', $this->test_url.'en'], + [true, true, 'en', $this->test_url.'about', $this->test_url.'en/about'], + [true, true, 'en', $this->test_url.'ver/1', $this->test_url.'en/ver/1'], + [true, true, 'en', $this->test_url.'view/1/project', $this->test_url.'en/view/1/project'], + [true, true, 'en', $this->test_url.'view/1/project/1', $this->test_url.'en/view/1/project/1'], + ]; + } + public function testGetURLFromRouteNameTranslated() { $this->assertEquals(