BundleEncoder   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 1
dl 0
loc 167
ccs 57
cts 57
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A addBundle() 0 6 1
A getStorageData() 0 21 5
A getBundles() 0 4 1
A encodeBundle() 0 9 2
A getBundle() 0 10 3
A encodeMergedBundles() 0 30 5
A getLocales() 0 4 1
A hasLocale() 0 8 1
A getNamespaces() 0 6 2
A getBundleValue() 0 7 1
1
<?php declare (strict_types = 1);
2
3
namespace Limoncello\l10n\Messages;
4
5
/**
6
 * Copyright 2015-2019 [email protected]
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
use Limoncello\l10n\Contracts\Messages\BundleEncoderInterface;
22
use Limoncello\l10n\Contracts\Messages\BundleStorageInterface;
23
use Limoncello\l10n\Contracts\Messages\ResourceBundleInterface;
24
use function array_diff;
25
use function array_intersect;
26
use function array_keys;
27
use function assert;
28
use function in_array;
29
30
/**
31
 * @package Limoncello\l10n
32
 */
33
class BundleEncoder implements BundleEncoderInterface
34
{
35
    /**
36
     * @var array
37
     */
38
    private $bundles = [];
39
40
    /**
41
     * @inheritdoc
42
     */
43 7
    public function addBundle(ResourceBundleInterface $bundle): BundleEncoderInterface
44
    {
45 7
        $this->bundles[$bundle->getLocale()][$bundle->getNamespace()] = $bundle;
46
47 7
        return $this;
48
    }
49
50
    /**
51
     * @inheritdoc
52
     */
53 7
    public function getStorageData(string  $defaultLocale): array
54
    {
55 7
        $defaultNamespaces = $this->getNamespaces($defaultLocale);
56
57 7
        $data = [];
58 7
        foreach ($this->getLocales() as $locale) {
59 7
            $localizedNamespaces = $this->getNamespaces($locale);
60 7
            $combinedNamespaces  = $defaultNamespaces + $localizedNamespaces;
61 7
            foreach ($combinedNamespaces as $namespace) {
62 7
                $bundle = $this->getBundle($locale, $namespace);
63 7
                $bundle = $bundle !== null ? $bundle : $this->getBundle($defaultLocale, $namespace);
64 7
                $data[$locale][$namespace] = $defaultLocale === $locale ? $this->encodeBundle($bundle) :
65 7
                    $this->encodeMergedBundles($bundle, $this->getBundle($defaultLocale, $namespace));
66
            }
67
        }
68
69
        return [
70 7
            BundleStorage::INDEX_DEFAULT_LOCALE => $defaultLocale,
71 7
            BundleStorage::INDEX_DATA           => $data
72
        ];
73
    }
74
75
    /**
76
     * @return array
77
     */
78 7
    protected function getBundles(): array
79
    {
80 7
        return $this->bundles;
81
    }
82
83
    /**
84
     * @param ResourceBundleInterface $bundle
85
     *
86
     * @return array
87
     */
88 7
    private function encodeBundle(ResourceBundleInterface $bundle): array
89
    {
90 7
        $encodedBundle = [];
91 7
        foreach ($bundle->getKeys() as $key) {
92 7
            $encodedBundle[$key] = $this->getBundleValue($bundle, (string)$key);
93
        }
94
95 7
        return $encodedBundle;
96
    }
97
98
    /**
99
     * @param string $locale
100
     * @param string $namespace
101
     *
102
     * @return null|ResourceBundleInterface
103
     */
104 7
    private function getBundle(string $locale, string $namespace)
105
    {
106 7
        assert(empty($locale) === false && empty($namespace) === false);
107
108 7
        $bundles   = $this->getBundles();
109 7
        $hasBundle = isset($bundles[$locale][$namespace]) === true;
110 7
        $result    = $hasBundle === true ? $bundles[$locale][$namespace] : null;
111
112 7
        return $result;
113
    }
114
115
    /**
116
     * @param ResourceBundleInterface      $localizedBundle
117
     * @param ResourceBundleInterface|null $defaultBundle
118
     *
119
     * @return array
120
     */
121 7
    private function encodeMergedBundles(
122
        ResourceBundleInterface $localizedBundle,
123
        ResourceBundleInterface $defaultBundle = null
124
    ): array {
125 7
        if ($defaultBundle === null) {
126
            // there is no default bundle for this localized one
127 6
            return $this->encodeBundle($localizedBundle);
128
        }
129
130 2
        $localizedKeys = $localizedBundle->getKeys();
131 2
        $defaultKeys   = $defaultBundle->getKeys();
132
133 2
        $commonKeys        = array_intersect($localizedKeys, $defaultKeys);
134 2
        $localizedOnlyKeys = array_diff($localizedKeys, $commonKeys);
135 2
        $defaultOnlyKeys   = array_diff($defaultKeys, $commonKeys);
136
137 2
        $encodedBundle = [];
138
139 2
        foreach ($commonKeys as $key) {
140 2
            $encodedBundle[$key] = $this->getBundleValue($localizedBundle, (string)$key);
141
        }
142 2
        foreach ($localizedOnlyKeys as $key) {
143 1
            $encodedBundle[$key] = $this->getBundleValue($localizedBundle, (string)$key);
144
        }
145 2
        foreach ($defaultOnlyKeys as $key) {
146 1
            $encodedBundle[$key] = $this->getBundleValue($defaultBundle, (string)$key);
147
        }
148
149 2
        return $encodedBundle;
150
    }
151
152
    /**
153
     * @return array
154
     */
155 7
    private function getLocales(): array
156
    {
157 7
        return array_keys($this->getBundles());
158
    }
159
160
    /**
161
     * @param string $locale
162
     *
163
     * @return bool
164
     */
165 7
    private function hasLocale(string $locale): bool
166
    {
167 7
        assert(empty($locale) === false);
168
169 7
        $result = in_array($locale, $this->getLocales());
170
171 7
        return $result;
172
    }
173
174
    /**
175
     * @param string $locale
176
     *
177
     * @return string[]
178
     */
179 7
    private function getNamespaces(string $locale): array
180
    {
181 7
        $result = $this->hasLocale($locale) === true ? array_keys($this->getBundles()[$locale]) : [];
182
183 7
        return $result;
184
    }
185
186
    /**
187
     * @param ResourceBundleInterface $bundle
188
     * @param string                  $key
189
     *
190
     * @return string[]
191
     */
192 7
    private function getBundleValue(ResourceBundleInterface $bundle, string $key): array
193
    {
194
        return [
195 7
            BundleStorageInterface::INDEX_PAIR_VALUE  => $bundle->getValue($key),
196 7
            BundleStorageInterface::INDEX_PAIR_LOCALE => $bundle->getLocale(),
197
        ];
198
    }
199
}
200