Passed
Pull Request — master (#360)
by Arman
02:53
created

LangFactory::getLangFromUrlSegment()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 5
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 11
rs 9.6111
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.9
13
 */
14
15
namespace Quantum\Libraries\Lang\Factories;
16
17
use Quantum\Libraries\Lang\Exceptions\LangException;
18
use Quantum\Config\Exceptions\ConfigException;
19
use Quantum\Di\Exceptions\DiException;
20
use Quantum\Libraries\Lang\Translator;
21
use Quantum\Libraries\Lang\Lang;
22
use Quantum\Http\Request;
23
use Quantum\Loader\Setup;
24
use ReflectionException;
25
26
/**
27
 * Class LangFactory
28
 * @package Quantum\Libraries\Lang
29
 */
30
class LangFactory
31
{
32
33
    /**
34
     * @var Lang|null Cached Lang instance
35
     */
36
    private static $instance = null;
37
38
    /**
39
     * @return Lang
40
     * @throws ConfigException
41
     * @throws LangException
42
     * @throws DiException
43
     * @throws ReflectionException
44
     */
45
    public static function get(): Lang
46
    {
47
        if (self::$instance !== null) {
48
            return self::$instance;
49
        }
50
51
        list($isEnabled, $supported, $default) = self::loadLangConfig();
52
53
        $lang = self::detectLanguage($supported, $default);
54
55
        $translator = new Translator($lang);
56
57
        return self::$instance = new Lang($lang, $isEnabled, $translator);
58
59
    }
60
61
    /**
62
     * @return array
63
     * @throws ConfigException
64
     * @throws DiException
65
     * @throws ReflectionException
66
     */
67
    private static function loadLangConfig(): array
68
    {
69
        if (!config()->has('lang')) {
70
            config()->import(new Setup('config', 'lang'));
71
        }
72
73
        return [
74
            filter_var(config()->get('lang.enabled'), FILTER_VALIDATE_BOOLEAN),
75
            (array)config()->get('lang.supported'),
76
            config()->get('lang.default'),
77
        ];
78
    }
79
80
    /**
81
     * @param array $supported
82
     * @param string|null $default
83
     * @return string
84
     * @throws LangException
85
     */
86
    private static function detectLanguage(array $supported, ?string $default): string
87
    {
88
        $lang = self::getLangFromQuery($supported);
89
90
        if (empty($lang)) {
91
            $lang = self::getLangFromUrlSegment($supported);
92
        }
93
94
        if (empty($lang)) {
95
            $lang = self::getLangFromHeader($supported);
96
        }
97
98
        if (empty($lang)) {
99
            $lang = $default;
100
        }
101
102
        if (!$lang) {
103
            throw LangException::misconfiguredDefaultConfig();
104
        }
105
106
        return $lang;
107
    }
108
109
    /**
110
     * @param array $supported
111
     * @return string|null
112
     */
113
    private static function getLangFromQuery(array $supported): ?string
114
    {
115
        $queryLang = Request::getQueryParam('lang');
116
117
        return $queryLang && in_array($queryLang, $supported) ? $queryLang : null;
118
    }
119
120
    /**
121
     * @param array $supported
122
     * @return string|null
123
     */
124
    private static function getLangFromUrlSegment(array $supported): ?string
125
    {
126
        $segmentIndex = (int)config()->get('lang.url_segment');
127
128
        if (!empty(route_prefix()) && $segmentIndex == 1) {
129
            $segmentIndex++;
130
        }
131
132
        $segmentLang = Request::getSegment($segmentIndex);
133
134
        return $segmentLang && in_array($segmentLang, $supported) ? $segmentLang : null;
135
    }
136
137
    /**
138
     * @param array $supported
139
     * @return string|null
140
     */
141
    private static function getLangFromHeader(array $supported): ?string
142
    {
143
        $acceptedLang = server()->acceptedLang();
144
145
        return $acceptedLang && in_array($acceptedLang, $supported) ? $acceptedLang : null;
146
    }
147
}