MessageManager::buildTranslationFiles()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 8
c 2
b 0
f 0
dl 0
loc 14
ccs 6
cts 6
cp 1
rs 10
cc 4
nc 6
nop 1
crap 4
1
<?php
2
3
namespace Printful\GettextCms;
4
5
use Printful\GettextCms\Exceptions\GettextCmsException;
6
use Printful\GettextCms\Interfaces\MessageConfigInterface;
7
use Printful\GettextCms\Structures\ScanItem;
8
9
class MessageManager
10
{
11
    /** @var LocaleLoader */
12
    private $loader;
13
14
    /** @var string Current locale set */
15
    private $locale;
16
17
    /** @var MessageRevisions */
18
    private $revisions;
19
20
    /** @var self */
21
    private static $instance;
22
23
    /** @var MessageConfigInterface */
24
    private $config;
25
26
    /** @var MessageStorage */
27
    private $storage;
28
29 1
    /**
30
     * @param MessageConfigInterface $config
31 1
     */
32 1
    public function __construct(MessageConfigInterface $config)
33 1
    {
34 1
        $this->revisions = new MessageRevisions($config);
35 1
        $this->loader = new LocaleLoader($config, new MessageRevisions($config));
36
        $this->config = $config;
37 1
        $this->storage = new MessageStorage($this->config->getRepository());
38 1
        $this->locale = $config->getDefaultLocale();
39
40 1
        if ($config->useShortFunctions()) {
41
            $this->declareFunctions();
42
        }
43
    }
44
45
    /**
46
     * Initialize singleton instance
47
     * Singleton is necessary for short functions because they need to access the revision functionality globally.
48
     *
49 1
     * @param MessageConfigInterface $config
50
     * @return MessageManager
51 1
     */
52
    public static function init(MessageConfigInterface $config): self
53 1
    {
54
        self::$instance = new static($config);
55
56
        return self::$instance;
57
    }
58
59 1
    /**
60
     * @return MessageManager
61 1
     */
62
    public static function getInstance(): self
63
    {
64
        return self::$instance;
65
    }
66
67
    /**
68
     * @param string $locale
69 1
     * @return MessageManager
70
     * @throws GettextCmsException
71 1
     */
72
    public function setLocale(string $locale): self
73 1
    {
74
        $this->locale = $locale;
75 1
76
        $this->loader->load($locale);
77
78
        return $this;
79
    }
80
81
    /**
82
     * Declare helper functions for easier gettext usage
83
     *
84
     * @return MessageManager
85
     *
86
     * @see _d()
87
     * @see _x()
88
     * @see _dn()
89
     * @see _dx()
90 1
     * @see _dxn()
91
     * @see _n()
92 1
     */
93
    private function declareFunctions(): self
94 1
    {
95
        require __DIR__ . '/helpers/functions.php';
96
97
        return $this;
98
    }
99
100
    /**
101
     * Get revisioned domain for current locale or the original domain name if revision does not exist for this domain
102
     *
103 1
     * @param string $domain
104
     * @return string
105 1
     */
106
    public function getRevisionedDomain(string $domain): string
107
    {
108
        return $this->revisions->getRevisionedDomain($this->locale, $domain);
109
    }
110
111
    /**
112
     * Extract translations from files and save them to repository
113
     * Careful, previous translations will be disabled, so everything has to be scanned at once
114
     *
115
     * @param ScanItem[] $scanItems
116
     * @param bool $disableUnusedTranslations Should old, unused translations be disabled
117 1
     * @param array|null $domains Force domains to scan. If null, will scan default domains.
118
     * @throws GettextCmsException
119
     */
120
    public function extractAndSaveFromFiles(
121
        array $scanItems,
122 1
        bool $disableUnusedTranslations = true,
123
        array $domains = null
124
    ) {
125 1
        if ($this->config->useShortFunctions()) {
126
            // If using short functions, we need to pre-fill them
127 1
            // so they are extracted too
128 1
            $functions = $this->getFunctions();
129 1
130
            foreach ($scanItems as $scanItem) {
131
                $scanItem->functions = $scanItem->functions ?: [];
132
                $scanItem->functions += $functions;
133 1
            }
134 1
        }
135 1
136 1
        $importer = new MessageImporter(
137
            $this->config,
138
            $this->storage,
139 1
            new MessageExtractor($this->config)
140 1
        );
141
142
        $importer->extractAndSave($scanItems, $disableUnusedTranslations, $domains);
143
    }
144
145
    /**
146
     * Export PO string of untranslated messages
147
     *
148
     * @param string $locale
149 1
     * @param string $domain
150
     * @return string
151 1
     */
152
    public function exportUntranslatedPo(string $locale, string $domain): string
153 1
    {
154
        $exporter = new UntranslatedMessageExporter($this->storage);
155
156
        return $exporter->exportPoString($locale, $domain);
157
    }
158
159
    /**
160
     * Create a zip archive with messages that require translations as PO files
161
     *
162
     * @param string $zipPathname Full pathname to the file where the ZIP archive should be written
163
     * @param string $locale
164 1
     * @param string[]|null $domains Domains to export. If not provided, export all domains defined in config
165
     * @return bool
166 1
     */
167 1
    public function exportUntranslatedPoZip(string $zipPathname, string $locale, array $domains = null): bool
168 1
    {
169
        $exporter = new UntranslatedMessageZipExporter(
170
            $this->config,
171 1
            new UntranslatedMessageExporter($this->storage)
172
        );
173
174
        return $exporter->export($zipPathname, $locale, $domains);
175
    }
176
177
    /**
178
     * Import translated messages from PO file
179
     *
180 1
     * @param string $poContent
181
     * @throws GettextCmsException
182 1
     */
183 1
    public function importTranslated($poContent)
184 1
    {
185
        $importer = new TranslatedMessageImporter($this->config, $this->storage);
186
        $importer->importFromPo($poContent);
187
    }
188
189
    /**
190
     * Build MO translation files for each locale and domain
191 1
     *
192
     * @param array|null $locales
193 1
     * @throws Exceptions\InvalidPathException
194
     */
195 1
    public function buildTranslationFiles(array $locales = null)
196 1
    {
197 1
        $builder = new MessageBuilder($this->config, $this->storage, $this->revisions);
198
199 1
        if ($locales === null) {
200 1
            $locales = $this->config->getLocales();
201
        }
202
203 1
        foreach ($locales as $locale) {
204
            $domains = $this->config->getOtherDomains();
205
            $domains[] = $this->config->getDefaultDomain();
206
207
            foreach ($domains as $domain) {
208
                $builder->export($locale, $domain);
209
            }
210 1
        }
211
    }
212 1
213
    /**
214
     * Get the dynamic importer for adding dynamic messages
215
     *
216
     * @return DynamicMessageImporter
217
     */
218
    public function getDynamicMessageImporter(): DynamicMessageImporter
219
    {
220 1
        return new DynamicMessageImporter($this->config, $this->storage);
221
    }
222
223
    /**
224 1
     * Functions to scan for including (default functions + custom functions)
225
     *
226
     * @return array
227
     */
228
    private function getFunctions(): array
229
    {
230
        return [
231
            // Default functions
232
            '_' => 'gettext',
233
            'gettext' => 'gettext',
234
            'ngettext' => 'ngettext',
235
            'pgettext' => 'pgettext',
236
            'dgettext' => 'dgettext',
237
            'dngettext' => 'dngettext',
238
            'dpgettext' => 'dpgettext',
239
            'npgettext' => 'npgettext',
240
            'dnpgettext' => 'dnpgettext',
241
242
            // Our custom functions
243
            '_n' => 'ngettext',
244
            '_nc' => 'npgettext',
245
            '_c' => 'pgettext',
246
            '_dc' => 'dpgettext',
247
            '_d' => 'dgettext',
248
            '_dn' => 'dngettext',
249
            '_dnc' => 'dnpgettext',
250
        ];
251
    }
252
}