Issues (14)

src/Saver/TranslationValueSaver.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Locastic\SymfonyTranslationBundle\Saver;
6
7
use Locastic\SymfonyTranslationBundle\Exception\GenerateTranslationFileNameException;
8
use Locastic\SymfonyTranslationBundle\Exception\TranslationNotFoundException;
9
use Locastic\SymfonyTranslationBundle\Model\TranslationValueInterface;
10
use Locastic\SymfonyTranslationBundle\Provider\TranslationFileNameProviderInterface;
11
use Locastic\SymfonyTranslationBundle\Provider\TranslationFilePathProviderInterface;
12
use Locastic\SymfonyTranslationBundle\Provider\TranslationsProviderInterface;
13
use Locastic\SymfonyTranslationBundle\Utils\ArrayUtils;
14
use Symfony\Component\Filesystem\Filesystem;
15
use Symfony\Component\Yaml\Yaml;
16
17
use function array_key_exists;
18
use function array_replace_recursive;
19
use function is_string;
20
21
final class TranslationValueSaver implements TranslationValueSaverInterface
22
{
23
    private string $directory;
24
25
    private TranslationFileNameProviderInterface $translationFileNameProvider;
26
27
    private TranslationFilePathProviderInterface $translationFilePathProvider;
28
29
    private TranslationsProviderInterface $translationsProvider;
30
31
    public function __construct(
32
        string $directory,
33
        TranslationFileNameProviderInterface $translationFileNameProvider,
34
        TranslationFilePathProviderInterface $translationFilePathProvider,
35
        TranslationsProviderInterface $translationsProvider
36
    ) {
37
        $this->directory = $directory;
38
        $this->translationFileNameProvider = $translationFileNameProvider;
39
        $this->translationFilePathProvider = $translationFilePathProvider;
40
        $this->translationsProvider = $translationsProvider;
41
    }
42
43
    /**
44
     * @throws TranslationNotFoundException
45
     * @throws GenerateTranslationFileNameException
46
     */
47
    public function saveTranslationValue(TranslationValueInterface $translationValue, bool $overrideExisting = true): void
48
    {
49
        $translation = $translationValue->getTranslation();
50
        $existingTranslations = $this->translationsProvider->getTranslations($translationValue->getLocaleCode(), [$translationValue->getLocaleCode()]);
0 ignored issues
show
It seems like $translationValue->getLocaleCode() can also be of type null; however, parameter $defaultLocaleCode of Locastic\SymfonyTranslat...face::getTranslations() 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

50
        $existingTranslations = $this->translationsProvider->getTranslations(/** @scrutinizer ignore-type */ $translationValue->getLocaleCode(), [$translationValue->getLocaleCode()]);
Loading history...
51
        $existingTranslations = $existingTranslations[$translationValue->getTheme()][$translation->getDomainName()] ?? [];
52
53
        if ($overrideExisting) {
54
            $newTranslations = array_replace_recursive($existingTranslations, [
55
                $translation->getKey() => [
56
                    $translationValue->getLocaleCode() => $translationValue->getValue(),
57
                ],
58
            ]);
59
        } else {
60
            // just add new value if it does not exist in the original translations
61
            $newTranslations = $existingTranslations;
62
63
            if (!array_key_exists($translation->getKey(), $existingTranslations)
64
                || !array_key_exists($translationValue->getLocaleCode(), $existingTranslations[$translation->getKey()])
65
            ) {
66
                $newTranslations[$translation->getKey()][$translationValue->getLocaleCode()] = $translationValue->getValue();
67
            }
68
        }
69
70
        // Remove empty keys to fall back to default ones
71
        $newTranslations = $this->translationsProvider->removeEmptyKeys($newTranslations);
72
73
        $result = [];
74
        foreach ($newTranslations as $newTranslationKey => $newTranslation) {
75
            if (!array_key_exists($translationValue->getLocaleCode(), $newTranslation)) {
76
                continue;
77
            }
78
            if (!is_string($newTranslation[$translationValue->getLocaleCode()])) {
79
                continue;
80
            }
81
            $result = array_replace_recursive($result, ArrayUtils::keyToArray($newTranslationKey, $newTranslation[$translationValue->getLocaleCode()]));
82
        }
83
        ArrayUtils::recursiveKsort($result);
84
85
        $fileName = $this->translationFileNameProvider->getFileName($translationValue);
86
        $filePath = $this->translationFilePathProvider->getFilePath($translationValue);
87
88
        $filesystem = new Filesystem();
89
        $filesystem->dumpFile($filePath . $fileName, Yaml::dump($result, 8));
90
    }
91
92
    /**
93
     * @throws TranslationNotFoundException
94
     * @throws GenerateTranslationFileNameException
95
     */
96
    public function saveTranslations(array $translations): void
97
    {
98
        $files = [];
99
        foreach ($translations as $translation) {
100
            foreach ($translation->getValues() as $translationValue) {
101
                $fileName = $this->translationFileNameProvider->getFileName($translationValue);
102
                if (!array_key_exists($fileName, $files)) {
103
                    $files[$fileName] = [];
104
                }
105
106
                $files[$fileName] = array_replace_recursive($files[$fileName], ArrayUtils::keyToArray($translation->getKey(), $translationValue->getValue()));
107
            }
108
        }
109
110
        $filesystem = new Filesystem();
111
        foreach ($files as $fileName => $fileTranslations) {
112
            $filesystem->dumpFile($this->directory . '/' . $fileName, Yaml::dump($fileTranslations, 10));
113
        }
114
    }
115
}
116