Skip to content

Commit

Permalink
Merge pull request #253 from Bertware/development
Browse files Browse the repository at this point in the history
Set language from browser, accept enter key in planner #242 #243
  • Loading branch information
Bertware authored Sep 22, 2017
2 parents 7e9986a + fc8df86 commit 1575956
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 13 deletions.
2 changes: 1 addition & 1 deletion app/Http/Controllers/Welcome.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function __construct()

public function index()
{
if (! Session::get('lang')) {
if (Session::get('lang') == null || empty(Session::get('lang'))) {
return View('language');
} else {
return Redirect::to('route');
Expand Down
64 changes: 61 additions & 3 deletions app/Http/Middleware/Language.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

namespace App\Http\Middleware;

use Locale;
use Closure;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Session;

class Language
{
Expand All @@ -29,7 +30,18 @@ class Language
*/
public function handle($request, Closure $next)
{
$language = (Input::get('lang')) ?: Session::get('lang');
$browserLanguage = $this->matchAcceptLanguage($request->server('HTTP_ACCEPT_LANGUAGE'), ['nl', 'fr', 'en']);

if (! empty(Input::get('lang'))) {
// if a language is set in the browser, we need to update the language. User may have requested a switch.
$language = Input::get('lang');
} elseif (empty(Session::get('lang')) && ! empty($browserLanguage)) {
// if the user didn't set a language in the cookie, and a browser language is available, use browser language.
$language = $browserLanguage;
} else {
$language = Session::get('lang');
}

$this->setSupportedLanguage($language);

return $next($request);
Expand All @@ -55,4 +67,50 @@ private function setSupportedLanguage($lang)
Session::put('lang', $lang);
}
}

/**
* Search a HTTP accept-header for a supported language. Take order (weight, q=) into account. Skip unsupported
* languages.
*
* This method has a big avantage over locale_lookup, as locale_lookup will only look at the first language in accept-language.
* This method will skip unsupported languages and keep searching for a supported, meaning that if only NL and EN are supported,
* da, nl;q=0.5, en;q=0.2 will result in nl being chosen. (vs null return from locale_lookup)
*
* @param string $header the HTTP accept-language header to search
* @param array $supported the list of supported languages
* @return string|null if a language matches, a value from the supported array is returned. If not, null is
* returned.
*/
private function matchAcceptLanguage($header, $supported)
{

// step 1: transform header into array
// source for step 1: http://stackoverflow.com/questions/6168519/transform-accept-language-output-in-array

$values = explode(',', $header);

$accept_language = [];

foreach ($values as $lang) {
$cnt = preg_match('/([-a-zA-Z]+)\s*;\s*q=([0-9\.]+)/', $lang, $matches);
if ($cnt === 0) {
$accept_language[$lang] = 1;
} else {
$accept_language[$matches[1]] = $matches[2];
}
}

// step 2: match array with supported languages

foreach ($accept_language as $accept_lang => $accept_lang_q) {
foreach ($supported as $supported_lang) {
// use filterMatches to ensure nl-be, nl, nl-nl all match nl, etc..
if (Locale::filterMatches($accept_lang, $supported_lang)) {
return $supported_lang;
}
}
}

// no match found
}
}
6 changes: 0 additions & 6 deletions public/app/js/iRail/Controllers/PlannerCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ var PlannerCtrl = function ($scope, $http, $filter, $timeout, $window) {
* FUNCTIONS THAT CAN BE CALLED
*-------------------------------------------------------*/

$(document).keypress(function (e) {
if(e.which === 13){
$("#confirm").focus();
}
});

/**
* Check if we can dump the data
*/
Expand Down
6 changes: 4 additions & 2 deletions resources/views/_partials/route/planner.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
</a>
</script>

<form>

<div class="row">

<div class="col-sm-6">
<div class="form-group">
<div class="input-group-oneliner has-affix">
<label for="departureStation" class="input-group-label">{{ Lang::get('client.fromStation') }}</label>
<input type="text" id="departureStation" ng-model="departure" placeholder="{{ Lang::get('client.typeFromStation') }}" typeahead="station as station.name for station in getStations($viewValue)" typeahead-template-url="customTemplate.html" class="form-control input-lg" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
<input type="text" id="departureStation" ng-model="departure" placeholder="{{ Lang::get('client.typeFromStation') }}" typeahead="station as station.name for station in getStations($viewValue)" typeahead-template-url="customTemplate.html" class="form-control input-lg" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus>
<a class="input-group-affix" ng-click="reverse()" ng-show="results"><i class="fa fa-exchange"></i> <span class="sr-only">{{Lang::get('client.reverse')}}</span></a>
</div>
</div>
Expand Down Expand Up @@ -66,7 +68,7 @@
</button>
</div>
</div>

</form>
<div class="alert alert-danger" ng-show="data === null">
<p ng-show="stationnotfound === true">
{{ Lang::get('client.errorCheckInput') }}
Expand Down
33 changes: 33 additions & 0 deletions tests/App/Http/Middleware/LanguageMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,39 @@ public function testSetLanguageToFrench()
$this->setAssertLanguageTest('fr', 'fr');
}

public function testSetLanguageToFrenchWhileBrowserDutch()
{
// GET parameters should have priority over browser language.
$response = $this->get('/?lang=fr', ['accept-language' => 'nl-be']);
$this->assertEquals('fr', $this->getApplicationLanguage());
}

public function testSetLanguageFromBrowser()
{
$response = $this->get('/', ['accept-language' => 'nl-be']);
$this->assertEquals('nl', $this->getApplicationLanguage());
}

public function testSetLanguageFromBrowser2()
{
$response = $this->get('/', ['accept-language' => 'nl']);
$this->assertEquals('nl', $this->getApplicationLanguage());
}

public function testSetLanguageFromBrowser3()
{
// unsupported languages mixed with supported. Should pick first supported.
$response = $this->get('/', ['accept-language' => 'da, nl;q=0.9, en;q=0.5']);
$this->assertEquals('nl', $this->getApplicationLanguage());
}

public function testSetLanguageFromBrowser4()
{
// unsupported languages. Should fall back to en.
$response = $this->get('/', ['accept-language' => 'da, se;q=0.9, no;q=0.5']);
$this->assertEquals('en', $this->getApplicationLanguage());
}

public function testFallbackToDefaultLanguageWhenLanguageDoesNotExist()
{
$this->setAssertLanguageTest('en', 'NotALanguage');
Expand Down
3 changes: 2 additions & 1 deletion tests/VariousTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ class VariousTest extends TestCase
{
public function testHome()
{
// expect redirect, since call includes "accept-language" header
$response = $this->call('GET', '/');
$this->assertEquals(200, $response->status());
$this->assertEquals(302, $response->status());
}

public function testContributors()
Expand Down

0 comments on commit 1575956

Please sign in to comment.