Passed
Branch master (e985ab)
by Mihail
120:46 queued 116:24
created

MultiLanguageFeatures::runMultiLanguage()   D

Complexity

Conditions 10
Paths 15

Size

Total Lines 34
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 16
nc 15
nop 0
dl 0
loc 34
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Ffcms\Core\Network\Request;
4
5
use Ffcms\Core\App;
6
use Ffcms\Core\Helper\Type\Any;
7
use Ffcms\Core\Helper\Type\Arr;
8
use Ffcms\Core\Helper\Type\Str;
9
use Symfony\Component\HttpFoundation\ParameterBag;
10
use Symfony\Component\HttpFoundation\RedirectResponse;
11
12
/**
13
 * Trait MultiLanguageFeatures. Multilanguage features for Request controller.
14
 * @package Ffcms\Core\Network\Request
15
 * @property ParameterBag $query
16
 */
17
trait MultiLanguageFeatures
18
{
19
    protected $language;
20
    protected $languageInPath = false;
21
22
    /**
23
     * Build multi language pathway binding.
24
     * @return void
25
     */
26
    private function runMultiLanguage(): void
27
    {
28
        // check if multi-language is enabled
29
        if (!App::$Properties->get('multiLanguage')) {
30
            $this->language = App::$Properties->get('singleLanguage');
31
            return;
32
        }
33
34
        // check if domain-lang binding is enabled
35
        if (Any::isArray(App::$Properties->get('languageDomainAlias'))) {
36
            /** @var array $domainAlias */
37
            $domainAlias = App::$Properties->get('languageDomainAlias');
38
            if (Any::isArray($domainAlias) && !Str::likeEmpty($domainAlias[$this->getHost()])) {
0 ignored issues
show
Bug introduced by
It seems like getHost() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

38
            if (Any::isArray($domainAlias) && !Str::likeEmpty($domainAlias[$this->/** @scrutinizer ignore-call */ getHost()])) {
Loading history...
39
                $this->language = $domainAlias[$this->getHost()];
40
            }
41
            return;
42
        }
43
44
        // try to find language in pathway
45
        foreach (App::$Properties->get('languages') as $lang) {
46
            if (Str::startsWith('/' . $lang, $this->getPathInfo())) {
0 ignored issues
show
Bug introduced by
It seems like getPathInfo() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

46
            if (Str::startsWith('/' . $lang, $this->/** @scrutinizer ignore-call */ getPathInfo())) {
Loading history...
47
                $this->language = $lang;
48
                $this->languageInPath = true;
49
            }
50
        }
51
52
        // try to find in ?lang get
53
        if (!$this->language && Arr::in($this->query->get('lang'), App::$Properties->get('languages'))) {
0 ignored issues
show
Bug introduced by
It seems like Ffcms\Core\App::Properties->get('languages') can also be of type false; however, parameter $haystack of Ffcms\Core\Helper\Type\Arr::in() does only seem to accept null|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

53
        if (!$this->language && Arr::in($this->query->get('lang'), /** @scrutinizer ignore-type */ App::$Properties->get('languages'))) {
Loading history...
54
            $this->language = $this->query->get('lang');
55
        }
56
57
        // language still not defined?!
58
        if (!$this->language) {
59
            $this->setLanguageFromBrowser();
60
        }
61
    }
62
63
    /**
64
     * Set language from browser headers
65
     * @return void
66
     */
67
    private function setLanguageFromBrowser(): void
68
    {
69
        $userLang = App::$Properties->get('singleLanguage');
70
        $browserAccept = $this->getLanguages();
0 ignored issues
show
Bug introduced by
The method getLanguages() does not exist on Ffcms\Core\Network\Request\MultiLanguageFeatures. Did you maybe mean getLanguage()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

70
        /** @scrutinizer ignore-call */ 
71
        $browserAccept = $this->getLanguages();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
71
        if (Any::isArray($browserAccept) && count($browserAccept) > 0) {
72
            foreach ($browserAccept as $bLang) {
73
                if (Arr::in($bLang, App::$Properties->get('languages'))) {
0 ignored issues
show
Bug introduced by
It seems like Ffcms\Core\App::Properties->get('languages') can also be of type false; however, parameter $haystack of Ffcms\Core\Helper\Type\Arr::in() does only seem to accept null|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
                if (Arr::in($bLang, /** @scrutinizer ignore-type */ App::$Properties->get('languages'))) {
Loading history...
74
                    $userLang = $bLang;
75
                    break; // stop calculating, language is founded in priority
76
                }
77
            }
78
        }
79
80
        // parse query string
81
        $queryString = null;
82
        if (count($this->query->all()) > 0) {
83
            $queryString = '?' . http_build_query($this->query->all());
84
        }
85
86
        // build response with redirect to language-based path
87
        $redirectUrl = $this->getSchemeAndHttpHost() . $this->basePath . '/' . $userLang . $this->getPathInfo() . $queryString;
0 ignored issues
show
Bug introduced by
It seems like getSchemeAndHttpHost() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

87
        $redirectUrl = $this->/** @scrutinizer ignore-call */ getSchemeAndHttpHost() . $this->basePath . '/' . $userLang . $this->getPathInfo() . $queryString;
Loading history...
Bug Best Practice introduced by
The property basePath does not exist on Ffcms\Core\Network\Request\MultiLanguageFeatures. Did you maybe forget to declare it?
Loading history...
88
        $response = new RedirectResponse($redirectUrl);
89
        $response->send();
90
        exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
91
    }
92
93
    /**
94
     * Get current language
95
     * @return string|null
96
     */
97
    public function getLanguage(): ?string
98
    {
99
        return $this->language;
100
    }
101
102
    /**
103
     * Set current language
104
     * @param string $lang
105
     * @return bool
106
     */
107
    public function setLanguage($lang): bool
108
    {
109
        if (Arr::in($lang, App::$Properties->get('languages'))) {
0 ignored issues
show
Bug introduced by
It seems like Ffcms\Core\App::Properties->get('languages') can also be of type false; however, parameter $haystack of Ffcms\Core\Helper\Type\Arr::in() does only seem to accept null|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
        if (Arr::in($lang, /** @scrutinizer ignore-type */ App::$Properties->get('languages'))) {
Loading history...
110
            $this->language = $lang;
111
            return true;
112
        }
113
114
        return false;
115
    }
116
117
    /**
118
     * Check if language used in path
119
     * @return bool
120
     */
121
    public function languageInPath(): bool
122
    {
123
        return (bool)$this->languageInPath;
124
    }
125
}
126