Completed
Push — 6.0 ( eb641c...92cb73 )
by Ruud
148:12 queued 131:31
created

Importer::addLoader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
namespace Kunstmaan\TranslatorBundle\Service\Command\Importer;
4
5
use Box\Spout\Common\Type;
6
use Box\Spout\Reader\ODS\Sheet;
7
use Box\Spout\Reader\ReaderFactory;
8
use Kunstmaan\TranslatorBundle\Model\Translation\TranslationGroup;
9
use Kunstmaan\TranslatorBundle\Service\TranslationGroupManager;
10
use Symfony\Component\Console\Exception\LogicException;
11
use Symfony\Component\HttpFoundation\File\File;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\Translation\Loader\LoaderInterface;
14
15
class Importer
16
{
17
    /**
18
     * @var array
19
     */
20
    private $loaders = [];
21
22
    /**
23
     * @var TranslationGroupManager
24
     */
25
    private $translationGroupManager;
26
27
    public function import(\Symfony\Component\Finder\SplFileInfo $file, $force = false)
28
    {
29
        $this->validateLoaders($this->loaders);
30
31
        $filename = $file->getFilename();
32
        list($domain, $locale, $extension) = explode('.', $filename);
33
34
        if (!isset($this->loaders[$extension]) || !$this->loaders[$extension] instanceof \Symfony\Component\Translation\Loader\LoaderInterface) {
35
            throw new \Exception(sprintf('Requested loader for extension .%s isnt set', $extension));
36
        }
37
38
        $loader = $this->loaders[$extension];
39
        $messageCatalogue = $loader->load($file->getPathname(), $locale, $domain);
40
        $importedTranslations = 0;
41
42
        foreach ($messageCatalogue->all($domain) as $keyword => $text) {
43
            if ($this->importSingleTranslation($keyword, $text, $locale, $filename, $domain, $force)) {
44
                $importedTranslations++;
45
            }
46
        }
47
48
        return $importedTranslations;
49
    }
50
51
    /**
52
     * @param string $file
53
     * @param array  $locales
54
     * @param bool   $force
55
     * @return int
56
     * @throws \Box\Spout\Common\Exception\IOException
57
     * @throws \Box\Spout\Common\Exception\UnsupportedTypeException
58
     * @throws \Box\Spout\Reader\Exception\ReaderNotOpenedException
59
     */
60
    public function importFromSpreadsheet(string $file, array $locales, $force = false)
61
    {
62
        $filePath = realpath(dirname($file)) . DIRECTORY_SEPARATOR;
63
        $fileName = basename($file);
64
        $file = $filePath . $fileName;
65
66
        if (!file_exists($file)) {
67
            throw new LogicException(sprintf('Can not find file in %s', $file));
68
        }
69
70
        $format = (new File($file))->guessExtension();
71
        if (!\in_array($format, [Type::CSV, Type::ODS, Type::XLSX], true)) {
72
            $format = Type::CSV;
73
        }
74
75
        $headers = ['domain', 'keyword'];
76
        $requiredHeaders = array_merge($headers, $locales);
77
        $requiredHeaders = array_map('strtolower', $requiredHeaders);
78
79
        try {
80
            $reader = ReaderFactory::create($format);
81
            $reader->open($file);
82
        } catch (\Exception $e) {
83
            throw new LogicException('Format has to be either xlsx, ods or cvs');
84
        }
85
        $sheets = $reader->getSheetIterator();
86
87
        /** @var Sheet $sheet */
88
        $importedTranslations = 0;
89
        foreach ($sheets as $sheet) {
90
            $rows = $sheet->getRowIterator();
91
            $headers = [];
92
93
            /** @var array $row */
94
            foreach ($rows as $row) {
95
                if (empty($headers)) {
96
                    $headers = $row;
97
                    $headers = array_map('strtolower', $headers);
98
                    foreach ($requiredHeaders as $header) {
99
                        if (!\in_array($header, $headers)) {
100
                            throw new LogicException(sprintf('Header: %s, should be present in the file!', $header));
101
                        }
102
                    }
103
                    continue;
104
                }
105
                $domain = $row[array_search('domain', $headers)];
106
                $keyword = $row[array_search('keyword', $headers)];
107
                foreach ($locales as $locale) {
108
                    $this->importSingleTranslation($keyword, $row[array_search($locale, $headers)], $locale, $file, $domain, $force);
109
                    $importedTranslations++;
110
                }
111
            }
112
            break;
113
        }
114
        $reader->close();
115
116
        return $importedTranslations;
117
    }
118
119
    /**
120
     * @param      $keyword
121
     * @param      $text
122
     * @param      $locale
123
     * @param      $filename
124
     * @param      $domain
125
     * @param bool $force
126
     * @return bool
127
     */
128
    private function importSingleTranslation($keyword, $text, $locale, $filename, $domain, $force = false)
129
    {
130
        if (strlen($keyword) > 255) {
131
            return false;
132
        }
133
134
        $translationGroup = $this->translationGroupManager->getTranslationGroupByKeywordAndDomain($keyword, $domain);
135
136
        if (!($translationGroup instanceof TranslationGroup)) {
137
            $translationGroup = $this->translationGroupManager->create($keyword, $domain);
138
        }
139
140
        $translation = $this->translationGroupManager->addTranslation($translationGroup, $locale, $text, $filename);
141
142
        if (null === $translation && false === $force) {
143
            return false;
144
        }
145
146
        if (true === $force && null === $translation) {
147
            $this->translationGroupManager->updateTranslation($translationGroup, $locale, $text, $filename);
148
149
            return true;
150
        }
151
152
        return true;
153
    }
154
155
    /**
156
     * Validate the loaders
157
     * @param  array $loaders
158
     * @return void
159
     * @throws \Exception If no loaders are defined
160
     */
161
    public function validateLoaders($loaders = [])
162
    {
163
        if (!is_array($loaders) || count($loaders) <= 0) {
164
            throw new \Exception('No translation file loaders tagged.');
165
        }
166
    }
167
168
    public function setLoaders(array $loaders)
169
    {
170
        $this->loaders = $loaders;
171
    }
172
173
    /**
174
     * Adds a loader to the translation importer.
175
     *
176
     * @param string          $format The format of the loader
177
     * @param LoaderInterface $loader
178
     */
179
    public function addLoader($format, LoaderInterface $loader)
180
    {
181
        $this->loaders[$format] = $loader;
182
    }
183
184
    public function setTranslationGroupManager(TranslationGroupManager $translationGroupManager)
185
    {
186
        $this->translationGroupManager = $translationGroupManager;
187
    }
188
}
189