Completed
Push — master ( e4a30a...1a3d0b )
by Tobias
07:42
created

FileStorage::export()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of the PHP Translation package.
5
 *
6
 * (c) PHP Translation team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Translation\SymfonyStorage;
13
14
use Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader as SymfonyTranslationLoader;
15
use Symfony\Component\Translation\MessageCatalogue;
16
use Symfony\Component\Translation\MessageCatalogueInterface;
17
use Symfony\Component\Translation\Writer\TranslationWriter;
18
use Translation\Common\Model\Message;
19
use Translation\Common\Storage;
20
use Translation\Common\TransferableStorage;
21
22
/**
23
 * This storage uses Symfony's writer and loader.
24
 *
25
 * @author Tobias Nyholm <[email protected]>
26
 */
27
final class FileStorage implements Storage, TransferableStorage
28
{
29
    /**
30
     * @var TranslationWriter
31
     */
32
    private $writer;
33
34
    /**
35
     * @var TranslationLoader|SymfonyTranslationLoader
36
     */
37
    private $loader;
38
39
    /**
40
     * @var array directory path
41
     */
42
    private $dir;
43
44
    /**
45
     * @var MessageCatalogue[] Fetched catalogies
46
     */
47
    private $catalogues;
48
49
    /**
50
     * @param TranslationWriter                          $writer
51
     * @param SymfonyTranslationLoader|TranslationLoader $loader
52
     * @param array                                      $dir
53
     */
54 3
    public function __construct(TranslationWriter $writer, $loader, array $dir)
55
    {
56 3
        if (!$loader instanceof SymfonyTranslationLoader && !$loader instanceof TranslationLoader) {
57 1
            throw new \LogicException('Second parameter of FileStorage must be a Symfony translation loader or implement Translation\SymfonyStorage\TranslationLoader');
58
        }
59
60 2
        if (empty($dir)) {
61 1
            throw new \LogicException('Third parameter of FileStorage cannot be empty');
62
        }
63
64 1
        $this->writer = $writer;
65 1
        $this->loader = $loader;
66 1
        $this->dir = $dir;
67 1
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function get($locale, $domain, $key)
73
    {
74
        $catalogue = $this->getCatalogue($locale);
75
        $translation = $catalogue->get($key, $domain);
76
77
        return new Message($key, $domain, $locale, $translation);
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function create(Message $m)
84
    {
85
        $catalogue = $this->getCatalogue($m->getLocale());
86
        if (!$catalogue->defines($m->getKey(), $m->getDomain())) {
87
            $catalogue->set($m->getKey(), $m->getTranslation(), $m->getDomain());
88
            $this->writeCatalogue($catalogue, $m->getLocale(), $m->getDomain());
89
        }
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function update(Message $m)
96
    {
97
        $catalogue = $this->getCatalogue($m->getLocale());
98
        $catalogue->set($m->getKey(), $m->getTranslation(), $m->getDomain());
99
        $this->writeCatalogue($catalogue, $m->getLocale(), $m->getDomain());
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    public function delete($locale, $domain, $key)
106
    {
107
        $catalogue = $this->getCatalogue($locale);
108
        $messages = $catalogue->all($domain);
109
        unset($messages[$key]);
110
111
        $catalogue->replace($messages, $domain);
112
        $this->writeCatalogue($catalogue, $locale, $domain);
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    public function export(MessageCatalogueInterface $catalogue)
119
    {
120
        $locale = $catalogue->getLocale();
121
        $catalogue->addCatalogue($this->getCatalogue($locale));
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function import(MessageCatalogueInterface $catalogue)
128
    {
129
        $domains = $catalogue->getDomains();
130
        foreach ($domains as $domain) {
131
            $this->writeCatalogue($catalogue, $catalogue->getLocale(), $domain);
0 ignored issues
show
Compatibility introduced by
$catalogue of type object<Symfony\Component...sageCatalogueInterface> is not a sub-type of object<Symfony\Component...ation\MessageCatalogue>. It seems like you assume a concrete implementation of the interface Symfony\Component\Transl...ssageCatalogueInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
132
        }
133
    }
134
135
    /**
136
     * Save catalogue back to file.
137
     *
138
     * @param MessageCatalogue $catalogue
139
     * @param string           $domain
140
     */
141
    private function writeCatalogue(MessageCatalogue $catalogue, $locale, $domain)
142
    {
143
        $resources = $catalogue->getResources();
144
        foreach ($resources as $resource) {
145
            $path = (string) $resource;
146
            if (preg_match('|/'.$domain.'\.'.$locale.'\.([a-z]+)$|', $path, $matches)) {
147
                $this->writer->writeTranslations($catalogue, $matches[1], ['path' => str_replace($matches[0], '', $path)]);
148
            }
149
        }
150
    }
151
152
    /**
153
     * @param string $locale
154
     *
155
     * @return MessageCatalogue
156
     */
157
    private function getCatalogue($locale)
158
    {
159
        if (empty($this->catalogues[$locale])) {
160
            $this->loadCatalogue($locale, $this->dir);
161
        }
162
163
        return $this->catalogues[$locale];
164
    }
165
166
    /**
167
     * Load catalogue from files.
168
     *
169
     * @param string $locale
170
     * @param array  $dirs
171
     */
172
    private function loadCatalogue($locale, array $dirs)
173
    {
174
        $currentCatalogue = new MessageCatalogue($locale);
175
        foreach ($dirs as $path) {
176
            if (is_dir($path)) {
177
                $this->loader->loadMessages($path, $currentCatalogue);
178
            }
179
        }
180
181
        $this->catalogues[$locale] = $currentCatalogue;
182
    }
183
}
184