Completed
Push — master ( bd6f71...a09b4a )
by Tobias
04:38
created

FileStorage::__construct()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7.0572

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 17
cts 19
cp 0.8947
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 15
nc 16
nop 4
crap 7.0572
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\Reader\TranslationReader;
18
use Symfony\Component\Translation\Writer\TranslationWriter;
19
use Symfony\Component\Translation\Writer\TranslationWriterInterface;
20
use Translation\Common\Model\Message;
21
use Translation\Common\Storage;
22
use Translation\Common\TransferableStorage;
23
24
/**
25
 * This storage uses Symfony's writer and loader.
26
 *
27
 * @author Tobias Nyholm <[email protected]>
28
 */
29
final class FileStorage implements Storage, TransferableStorage
30
{
31
    /**
32
     * @var TranslationWriterInterface|LegacyTranslationWriter
33
     */
34
    private $writer;
35
36
    /**
37
     * @var TranslationLoader|SymfonyTranslationLoader
38
     */
39
    private $loader;
40
41
    /**
42
     * @var array directory path
43
     */
44
    private $dir;
45
46
    /**
47
     * @var array with option to the dumper
48
     */
49
    private $options;
50
51
    /**
52
     * @var MessageCatalogue[] Fetched catalogies
53
     */
54
    private $catalogues;
55
56
    /**
57
     * @param TranslationWriter                                            $writer
58
     * @param SymfonyTranslationLoader|TranslationLoader|TranslationReader $loader
59
     * @param array                                                        $dir
60
     * @param array                                                        $options
61
     */
62 10
    public function __construct(TranslationWriter $writer, $loader, array $dir, array $options = [])
63
    {
64
        // Create a legacy writer which is a wrapper for TranslationWriter
65 10
        if (!$writer instanceof TranslationWriterInterface) {
66 10
            $writer = new LegacyTranslationWriter($writer);
67 10
        }
68
        // Create a legacy loader which is a wrapper for TranslationReader
69 10
        if ($loader instanceof TranslationReader) {
70
            $loader = new LegacyTranslationLoader($loader);
71
        }
72 10
        if (!$loader instanceof SymfonyTranslationLoader && !$loader instanceof TranslationLoader) {
0 ignored issues
show
Bug introduced by
The class Symfony\Bundle\Framework...ation\TranslationLoader does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
73 1
            throw new \LogicException('Second parameter of FileStorage must be a Symfony translation loader or implement Translation\SymfonyStorage\TranslationLoader');
74
        }
75
76 9
        if (empty($dir)) {
77 1
            throw new \LogicException('Third parameter of FileStorage cannot be empty');
78
        }
79
80 8
        if (!array_key_exists('xliff_version', $options)) {
81
            // Set default value for xliff version.
82 8
            $options['xliff_version'] = '2.0';
83 8
        }
84
85 8
        $this->writer = $writer;
86 8
        $this->loader = $loader;
87 8
        $this->dir = $dir;
88 8
        $this->options = $options;
89 8
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94 1
    public function get($locale, $domain, $key)
95
    {
96 1
        $catalogue = $this->getCatalogue($locale);
97 1
        $translation = $catalogue->get($key, $domain);
98
99 1
        return new Message($key, $domain, $locale, $translation);
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105 2
    public function create(Message $m)
106
    {
107 2
        $catalogue = $this->getCatalogue($m->getLocale());
108 2
        if (!$catalogue->defines($m->getKey(), $m->getDomain())) {
109 2
            $catalogue->set($m->getKey(), $m->getTranslation(), $m->getDomain());
110 2
            $this->writeCatalogue($catalogue, $m->getLocale(), $m->getDomain());
111 2
        }
112 2
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 1
    public function update(Message $m)
118
    {
119 1
        $catalogue = $this->getCatalogue($m->getLocale());
120 1
        $catalogue->set($m->getKey(), $m->getTranslation(), $m->getDomain());
121 1
        $this->writeCatalogue($catalogue, $m->getLocale(), $m->getDomain());
122 1
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 1
    public function delete($locale, $domain, $key)
128
    {
129 1
        $catalogue = $this->getCatalogue($locale);
130 1
        $messages = $catalogue->all($domain);
131 1
        unset($messages[$key]);
132
133 1
        $catalogue->replace($messages, $domain);
134 1
        $this->writeCatalogue($catalogue, $locale, $domain);
135 1
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140 1
    public function export(MessageCatalogueInterface $catalogue)
141
    {
142 1
        $locale = $catalogue->getLocale();
143 1
        $catalogue->addCatalogue($this->getCatalogue($locale));
144 1
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149 1
    public function import(MessageCatalogueInterface $catalogue)
150
    {
151 1
        $domains = $catalogue->getDomains();
152 1
        foreach ($domains as $domain) {
153 1
            $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...
154 1
        }
155 1
    }
156
157
    /**
158
     * Save catalogue back to file.
159
     *
160
     * @param MessageCatalogue $catalogue
161
     * @param string           $domain
162
     */
163 5
    private function writeCatalogue(MessageCatalogue $catalogue, $locale, $domain)
164
    {
165 5
        $resources = $catalogue->getResources();
166 5
        $options = $this->options;
167 5
        $written = false;
168 5
        foreach ($resources as $resource) {
169 3
            $path = (string) $resource;
170 3
            if (preg_match('|/'.$domain.'\.'.$locale.'\.([a-z]+)$|', $path, $matches)) {
171 3
                $options['path'] = str_replace($matches[0], '', $path);
172 3
                $this->writer->write($catalogue, $matches[1], $options);
173 3
                $written = true;
174 3
            }
175 5
        }
176
177 5
        if ($written) {
178
            // We have written the translation to a file.
179 3
            return;
180
        }
181
182 2
        $options['path'] = reset($this->dir);
183 2
        $format = isset($options['default_output_format']) ? $options['default_output_format'] : 'xlf';
184 2
        $this->writer->write($catalogue, $format, $options);
185 2
    }
186
187
    /**
188
     * @param string $locale
189
     *
190
     * @return MessageCatalogue
191
     */
192 6
    private function getCatalogue($locale)
193
    {
194 6
        if (empty($this->catalogues[$locale])) {
195 6
            $this->loadCatalogue($locale, $this->dir);
196 6
        }
197
198 6
        return $this->catalogues[$locale];
199
    }
200
201
    /**
202
     * Load catalogue from files.
203
     *
204
     * @param string $locale
205
     * @param array  $dirs
206
     */
207 6
    private function loadCatalogue($locale, array $dirs)
208
    {
209 6
        $currentCatalogue = new MessageCatalogue($locale);
210 6
        foreach ($dirs as $path) {
211 6
            if (is_dir($path)) {
212 5
                $this->loader->loadMessages($path, $currentCatalogue);
213 5
            }
214 6
        }
215
216 6
        $this->catalogues[$locale] = $currentCatalogue;
217 6
    }
218
}
219