Completed
Push — master ( 9d729c...78ea8b )
by Valentyn
03:06
created

TranslatableTrait::addTranslation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace App\Translation;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
7
/**
8
 * Trait TranslatableTrait.
9
 *
10
 * @property ArrayCollection $translations
11
 * @property int|null        $id
12
 */
13
trait TranslatableTrait
14
{
15
    private $isTranslationsMappedByLocale = false;
16
17
    /**
18
     * @param array         $translations
19
     * @param callable      $add
20
     * @param callable|null $update
21
     *
22
     * @throws \ErrorException
23
     */
24 5
    public function updateTranslations(array $translations, callable $add, callable $update = null)
25
    {
26 5
        foreach ($translations as $translation) {
27 5
            $locale = is_object($translation) ? $translation->getLocale() : $translation['locale'];
28 5
            if (null === $oldTranslation = $this->getTranslation($locale, false)) {
29 4
                $add($translation);
30 4
                continue;
31
            }
32
33 1
            if ($update === null) {
34
                // This will called only when there's update action and $update function not defined
35
                // But you still can keep it as null if you creating entity
36
                throw new \InvalidArgumentException('Unexpected behavior: founded old translation but $update function not defined');
37
            }
38
39 1
            $update($translation, $oldTranslation);
40
        }
41 5
    }
42
43 5
    public function addTranslation(EntityTranslationInterface $translation): self
44
    {
45 5
        $this->translations->set($translation->getLocale(), $translation);
46
47 5
        return $this;
48
    }
49
50
    /**
51
     * @return array
52
     */
53 12
    public function getTranslations(): array
54
    {
55 12
        if ($this->isTranslationsMappedByLocale === true) {
56 4
            return $this->translations->toArray();
57
        }
58
59 11
        $this->mapTranslationsByLocale();
60
61 11
        return $this->translations->toArray();
62
    }
63
64
    /**
65
     * @param string $locale
66
     * @param bool   $useFallbackLocale
67
     *
68
     * @throws \ErrorException
69
     *
70
     * @return EntityTranslationInterface|null
71
     */
72 6
    public function getTranslation(string $locale, bool $useFallbackLocale = true): ?EntityTranslationInterface
73
    {
74 6
        if ($this->isTranslationsMappedByLocale === false) {
75 6
            $this->mapTranslationsByLocale();
76
        }
77
78 6
        $translation = $this->translations->get($locale);
79
80 6
        if ($translation === null && $useFallbackLocale === true) {
81 1
            return $this->getFallbackTranslation();
82
        }
83
84 6
        return $translation;
85
    }
86
87
    /**
88
     * @throws \ErrorException
89
     *
90
     * @return mixed
91
     */
92 1
    private function getFallbackTranslation(): EntityTranslationInterface
93
    {
94 1
        if (null === $translation = $this->translations->first()) {
95
            throw new \ErrorException(sprintf('You are trying to get translation for %s with ID %s but there\'s no translations found.', self::class, $this->id));
96
        }
97
98 1
        return $translation;
99
    }
100
101 14
    private function mapTranslationsByLocale(): void
102
    {
103 14
        $mappedTranslations = new ArrayCollection();
104
105 14
        foreach ($this->translations as $translation) {
106 12
            $mappedTranslations->set($translation->getLocale(), $translation);
107
        }
108
109 14
        $this->isTranslationsMappedByLocale = true;
110 14
        $this->translations = $mappedTranslations;
111 14
    }
112
}
113