Issues (6)

src/Loco.php (3 issues)

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\PlatformAdapter\Loco;
13
14
use FAPI\Localise\Exception\Domain\AssetConflictException;
15
use FAPI\Localise\Exception\Domain\NotFoundException;
16
use FAPI\Localise\LocoClient;
17
use Symfony\Component\Translation\MessageCatalogueInterface;
18
use Symfony\Component\Yaml\Yaml;
19
use Translation\Common\Exception\StorageException;
20
use Translation\Common\Model\Message;
21
use Translation\Common\Model\MessageInterface;
22
use Translation\Common\Storage;
23
use Translation\Common\TransferableStorage;
24
use Translation\PlatformAdapter\Loco\Model\LocoProject;
25
use Translation\SymfonyStorage\XliffConverter;
26
27
/**
28
 * Localize.biz.
29
 *
30
 * @author Tobias Nyholm <[email protected]>
31
 */
32
class Loco implements Storage, TransferableStorage
33
{
34
    /**
35
     * @var LocoClient
36
     */
37
    private $client;
38
39
    /**
40
     * @var LocoProject[]
41
     */
42
    private $projects = [];
43
44
    /**
45
     * @param LocoProject[] $projects
46
     */
47 1
    public function __construct(LocoClient $client, array $projects)
48
    {
49 1
        $this->client = $client;
50 1
        $this->projects = $projects;
51 1
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function get(string $locale, string $domain, string $key): ?MessageInterface
57
    {
58
        $project = $this->getProject($domain);
59
60
        try {
61
            $translation = $this->client->translations()->get($project->getApiKey(), $key, $locale)->getTranslation();
0 ignored issues
show
The method getTranslation() does not exist on Psr\Http\Message\ResponseInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
            $translation = $this->client->translations()->get($project->getApiKey(), $key, $locale)->/** @scrutinizer ignore-call */ getTranslation();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
62
        } catch (\FAPI\Localise\Exception $e) {
63
            return null;
64
        }
65
        $meta = [];
66
67
        return new Message($key, $domain, $locale, $translation, $meta);
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function create(MessageInterface $message): void
74
    {
75
        $project = $this->getProject($message->getDomain());
76
        $isNewAsset = true;
77
78
        try {
79
            // Create asset first
80
            $this->client->asset()->create($project->getApiKey(), $message->getKey());
81
        } catch (AssetConflictException $e) {
82
            // This is okey
83
            $isNewAsset = false;
84
        }
85
86
        $translation = $message->getTranslation();
87
88
        // translation is the same as the key, so we will set it to empty string
89
        // as it was not translated and stats on loco will be unaffected
90
        if ($message->getKey() === $message->getTranslation()) {
91
            $translation = '';
92
        }
93
94
        if ($isNewAsset) {
95
            $this->client->translations()->create(
96
                $project->getApiKey(),
97
                $message->getKey(),
98
                $message->getLocale(),
99
                $translation
100
            );
101
        } else {
102
            try {
103
                $this->client->translations()->get(
104
                    $project->getApiKey(),
105
                    $message->getKey(),
106
                    $message->getLocale()
107
                );
108
            } catch (NotFoundException $e) {
109
                // Create only if not found.
110
                $this->client->translations()->create(
111
                    $project->getApiKey(),
112
                    $message->getKey(),
113
                    $message->getLocale(),
114
                    $translation
115
                );
116
            }
117
        }
118
119
        $this->client->asset()->tag($project->getApiKey(), $message->getKey(), $message->getDomain());
120
121
        if (!empty($message->getMeta('parameters'))) {
122
            // Pretty print the Meta field via YAML export
123
            $dump = Yaml::dump(['parameters' => $message->getMeta('parameters')], 4, 5);
124
            $dump = str_replace("     -\n", '', $dump);
125
            $dump = str_replace('     ', "\xC2\xA0", $dump); // no break space
126
127
            $this->client->asset()->patch(
128
                $project->getApiKey(),
129
                $message->getKey(),
130
                null,
131
                null,
132
                null,
133
                $dump
134
            );
135
        }
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    public function update(MessageInterface $message): void
142
    {
143
        $project = $this->getProject($message->getDomain());
144
145
        try {
146
            $this->client->translations()->create($project->getApiKey(), $message->getKey(), $message->getLocale(), $message->getTranslation());
147
        } catch (NotFoundException $e) {
148
            $this->create($message);
149
        }
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function delete(string $locale, string $domain, string $key): void
156
    {
157
        $project = $this->getProject($domain);
158
159
        $this->client->translations()->delete($project->getApiKey(), $key, $locale);
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    public function export(MessageCatalogueInterface $catalogue, array $options = []): void
166
    {
167
        $locale = $catalogue->getLocale();
168
        foreach ($this->projects as $project) {
169
            foreach ($project->getDomains() as $domain) {
170
                try {
171
                    $params = [
172
                        'format' => 'symfony',
173
                        'index' => $project->getIndexParameter(),
174
                    ];
175
176
                    if ($project->getStatus()) {
177
                        $params['status'] = $project->getStatus();
178
                    }
179
180
                    if ($project->isMultiDomain()) {
181
                        $params['filter'] = $domain;
182
                    }
183
184
                    $data = $this->client->export()->locale($project->getApiKey(), $locale, 'xliff', $params);
185
                    $catalogue->addCatalogue(XliffConverter::contentToCatalogue($data, $locale, $domain));
0 ignored issues
show
It seems like $data can also be of type Psr\Http\Message\ResponseInterface; however, parameter $content of Translation\SymfonyStora...r::contentToCatalogue() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

185
                    $catalogue->addCatalogue(XliffConverter::contentToCatalogue(/** @scrutinizer ignore-type */ $data, $locale, $domain));
Loading history...
186
                } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
187
                }
188
            }
189
        }
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195
    public function import(MessageCatalogueInterface $catalogue, array $options = []): void
196
    {
197
        $locale = $catalogue->getLocale();
198
        foreach ($this->projects as $project) {
199
            foreach ($project->getDomains() as $domain) {
200
                if ('id' === $project->getIndexParameter()) {
201
                    $options['default_locale'] = 'x-id';
202
                }
203
204
                $data = XliffConverter::catalogueToContent($catalogue, $domain, $options);
205
                $params = [
206
                    'locale' => $locale,
207
                    'async' => 1,
208
                    'index' => $project->getIndexParameter(),
209
                ];
210
211
                if ($project->isMultiDomain()) {
212
                    $params['tag-all'] = $domain;
213
                }
214
215
                $this->client->import()->import($project->getApiKey(), 'xliff', $data, $params);
216
            }
217
        }
218
    }
219
220
    private function getProject(string $domain): LocoProject
221
    {
222
        foreach ($this->projects as $project) {
223
            if ($project->hasDomain($domain)) {
224
                return $project;
225
            }
226
        }
227
228
        throw new StorageException(sprintf('Project for "%s" domain was not found.', $domain));
229
    }
230
}
231