Passed
Push — master ( 8f0854...fda695 )
by Mārtiņš
02:37
created

LocaleLoader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 1
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 4
    public function __construct(MessageConfigInterface $config, MessageRevisions $revisions)
20
    {
21 4
        $this->config = $config;
22 4
        $this->revisions = $revisions;
23 4
    }
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 4
    public function load(string $locale): bool
33
    {
34 4
        putenv("LANG=" . $locale);
35
36
        // Some systems use LANGUAGE variant above LANG, so we just set both of them, just in case.
37 4
        putenv("LANGUAGE=" . $locale);
38
39 4
        if (!$this->setLocale($locale)) {
40
            throw new UnsupportedLocaleException('Locale is not supported by your system: ' . $locale);
41
        }
42
43 4
        return $this->bindDomains($locale);
44
    }
45
46 4
    private function setLocale($locale): bool
47
    {
48
        // Some locales contain utf postfix, so we should try them all
49
        $locales = [
50 4
            $locale,
51 4
            $locale . '.utf8',
52 4
            $locale . '.UTF-8',
53
        ];
54
55 4
        foreach ($locales as $v) {
56 4
            if (setlocale(LC_ALL, $v)) {
57 4
                return true;
58
            }
59
        }
60
61
        return false;
62
    }
63
64
    /**
65
     * Bind all domains for locale
66
     *
67
     * @param string $locale
68
     * @return bool Returns false if binding fails, translations may not work correctly
69
     */
70 4
    private function bindDomains(string $locale): bool
71
    {
72 4
        $domainBound = true;
73
74 4
        $domainDir = rtrim($this->config->getMoDirectory(), '/');
75
76 4
        $defaultDomain = $this->config->getDefaultDomain();
77
78 4
        $allDomains = $this->config->getOtherDomains();
79 4
        $allDomains[] = $defaultDomain;
80
81 4
        foreach ($allDomains as $domain) {
82 4
            $actualDomain = $this->getActualDomain($locale, $domain);
83
84
            // File structure for a translation is: mo-directory/{locale}/LC_MESSAGES/{domain}.mo
85 4
            if (!bindtextdomain($actualDomain, $domainDir)) {
86
                // If text domain binding fails, something is wrong with the paths
87
                $domainBound = false;
88
            }
89
90 4
            bind_textdomain_codeset($actualDomain, 'utf8');
91
        }
92
93
        // Bind the default domain for _() calls (and other non-domain specific calls)
94 4
        textdomain($this->getActualDomain($locale, $defaultDomain));
95
96 4
        return $domainBound;
97
    }
98
99
    /**
100
     * Get actual domain name. If revisions are enabled, this will return something like "domain_XXXXXX"
101
     *
102
     * @param string $locale
103
     * @param string $domain
104
     * @return string
105
     */
106 4
    private function getActualDomain(string $locale, string $domain): string
107
    {
108 4
        if ($this->config->useRevisions()) {
109 1
            return $this->revisions->getRevisionedDomain($locale, $domain);
110
        }
111
112 3
        return $domain;
113
    }
114
}