Completed
Push — master ( 10274c...a4edad )
by Neomerx
03:11
created

BundleEncoder::assertNamespace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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