Completed
Push — master ( a855fe...41d494 )
by Mārtiņš
02:07
created

LocaleLoader::setLocale()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 7
cts 8
cp 0.875
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 3
nop 1
crap 3.0175
1
<?php
2
3
namespace Printful\GettextCms;
4
5
use Printful\GettextCms\Exceptions\UnsupportedLocaleException;
6
use Printful\GettextCms\Interfaces\MessageConfigInterface;
7
8
/**
9
 * Class sets locales and binds domains for current request
10
 */
11
class LocaleLoader
12
{
13
    /** @var MessageConfigInterface */
14
    private $config;
15
16
    /** @var MessageRevisions */
17
    private $revisions;
18
19 1
    public function __construct(MessageConfigInterface $config)
20
    {
21 1
        $this->revisions = new MessageRevisions($config);
22 1
        $this->config = $config;
23 1
    }
24
25
    /**
26
     * Globally set current locale and bind gettext domains
27
     *
28
     * @param string $locale
29
     * @return bool If false is returned, some domains may not have been bound and will fail
30
     * @throws UnsupportedLocaleException
31
     */
32 1
    public function load(string $locale): bool
33
    {
34 1
        putenv("LANG=" . $locale);
35
36 1
        if (!$this->setLocale($locale)) {
37
            throw new UnsupportedLocaleException('Locale is not supported by your system: ' . $locale);
38
        }
39
40 1
        return $this->bindDomains($locale);
41
    }
42
43 1
    private function setLocale($locale): bool
44
    {
45
        // Some locales contain utf postfix, so we should try them all
46
        $locales = [
47 1
            $locale,
48 1
            $locale . '.utf8',
49 1
            $locale . '.UTF-8',
50
        ];
51
52 1
        foreach ($locales as $v) {
53 1
            if (setlocale(LC_ALL, $v)) {
54 1
                return true;
55
            }
56
        }
57
58
        return false;
59
    }
60
61
    /**
62
     * Bind all domains for locale
63
     *
64
     * @param string $locale
65
     * @return bool Returns false if binding fails, translations may not work correctly
66
     */
67 1
    private function bindDomains(string $locale): bool
68
    {
69 1
        $domainBound = true;
70
71 1
        $domainDir = rtrim($this->config->getMoDirectory(), '/');
72
73 1
        $defaultDomain = $this->config->getDefaultDomain();
74
75 1
        $allDomains = $this->config->getOtherDomains();
76 1
        $allDomains[] = $defaultDomain;
77
78 1
        foreach ($allDomains as $domain) {
79 1
            $actualDomain = $this->getActualDomain($locale, $domain);
80
81
            // File structure for a translation is: mo-directory/{locale}/LC_MESSAGES/{domain}.mo
82 1
            if (!bindtextdomain($actualDomain, $domainDir)) {
83
                // If text domain binding fails, something is wrong with the paths
84
                $domainBound = false;
85
            }
86
87 1
            bind_textdomain_codeset($actualDomain, 'utf8');
88
        }
89
90
        // Bind the default domain for _() calls (and other non-domain specific calls)
91 1
        textdomain($this->getActualDomain($locale, $defaultDomain));
92
93 1
        return $domainBound;
94
    }
95
96
    /**
97
     * Get actual domain name. If revisions are enabled, this will return something like "domain_xxxxxx"
98
     *
99
     * @param string $locale
100
     * @param string $domain
101
     * @return string
102
     */
103 1
    private function getActualDomain(string $locale, string $domain): string
104
    {
105 1
        if ($this->config->useRevisions()) {
106
            return $this->revisions->getRevisionedDomain($locale, $domain);
107
        }
108
109 1
        return $domain;
110
    }
111
}