Passed
Push — master ( 316db8...97e0d0 )
by Greg
05:28
created

UseLanguage::languages()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 13
nc 2
nop 1
dl 0
loc 27
rs 9.8333
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2019 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Http\Middleware;
21
22
use Fisharebest\Localization\Locale;
23
use Fisharebest\Localization\Locale\LocaleEnUs;
24
use Fisharebest\Localization\Locale\LocaleInterface;
25
use Fisharebest\Webtrees\I18N;
26
use Fisharebest\Webtrees\Module\LanguageEnglishUnitedStates;
27
use Fisharebest\Webtrees\Module\ModuleLanguageInterface;
28
use Fisharebest\Webtrees\Services\ModuleService;
29
use Fisharebest\Webtrees\Session;
30
use Fisharebest\Webtrees\Site;
31
use Fisharebest\Webtrees\Tree;
32
use Generator;
33
use Psr\Http\Message\ResponseInterface;
34
use Psr\Http\Message\ServerRequestInterface;
35
use Psr\Http\Server\MiddlewareInterface;
36
use Psr\Http\Server\RequestHandlerInterface;
37
38
use function app;
39
40
/**
41
 * Middleware to select a language.
42
 */
43
class UseLanguage implements MiddlewareInterface
44
{
45
    /** @var ModuleService */
46
    private $module_service;
47
48
    /**
49
     * UseTheme constructor.
50
     *
51
     * @param ModuleService $module_service
52
     */
53
    public function __construct(ModuleService $module_service)
54
    {
55
        $this->module_service = $module_service;
56
    }
57
58
    /**
59
     * @param ServerRequestInterface  $request
60
     * @param RequestHandlerInterface $handler
61
     *
62
     * @return ResponseInterface
63
     */
64
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
65
    {
66
        foreach ($this->languages($request) as $language) {
67
            if ($language instanceof ModuleLanguageInterface) {
68
                I18N::init($language->locale()->languageTag());
69
                $request = $request->withAttribute('language', $language);
70
                $request = $request->withAttribute('locale', $language->locale());
71
                Session::put('language', $language->locale()->languageTag());
72
                break;
73
            }
74
        }
75
76
        return $handler->handle($request);
77
    }
78
79
    /**
80
     * The language can be chosen in various ways.
81
     * Language module names have the form "language-<code>>".
82
     *
83
     * @param ServerRequestInterface $request
84
     *
85
     * @return Generator
86
     */
87
    private function languages(ServerRequestInterface $request): Generator
88
    {
89
        $tree = $request->getAttribute('tree');
90
91
        $languages = $this->module_service->findByInterface(ModuleLanguageInterface::class);
92
93
        // Last language used
94
        yield $languages->get('language-' . Session::get('language', ''));
95
96
        // Browser negotiation
97
        $locales = $this->module_service->findByInterface(ModuleLanguageInterface::class, true)
98
            ->map(static function (ModuleLanguageInterface $module): LocaleInterface {
99
                return $module->locale();
100
            });
101
102
        if ($tree instanceof Tree) {
103
            $default = Locale::create($tree->getPreference('LANGUAGE', 'en-US'));
104
        } else {
105
            $default = new LocaleEnUs();
106
        }
107
108
        $locale = Locale::httpAcceptLanguage($request->getServerParams(), $locales->all(), $default);
109
110
        yield $languages->get('language-' . $locale->languageTag());
111
112
        // No languages enabled?  Use en-US
113
        yield app(LanguageEnglishUnitedStates::class);
114
    }
115
}
116