Completed
Push — master ( f576a1...b86af8 )
by Mārtiņš
01:55
created

LocaleLoader::bindDomains()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

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