Completed
Push — lazy-loading-not-avail-content ( 189e64...1dbb7d )
by André
17:36
created

MaskGenerator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the Language MaskGenerator class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\Core\Persistence\Legacy\Content\Language;
10
11
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
12
use eZ\Publish\SPI\Persistence\Content\Language\Handler as LanguageHandler;
13
use RuntimeException;
14
15
/**
16
 * Language MaskGenerator.
17
 */
18
class MaskGenerator
19
{
20
    /**
21
     * Language lookup.
22
     *
23
     * @var \eZ\Publish\Core\Persistence\Legacy\Content\Language\Handler
24
     */
25
    protected $languageHandler;
26
27
    /**
28
     * Creates a new Language MaskGenerator.
29
     *
30
     * @param \eZ\Publish\SPI\Persistence\Content\Language\Handler $languageHandler
31
     */
32
    public function __construct(LanguageHandler $languageHandler)
33
    {
34
        $this->languageHandler = $languageHandler;
0 ignored issues
show
Documentation Bug introduced by
$languageHandler is of type object<eZ\Publish\SPI\Pe...ntent\Language\Handler>, but the property $languageHandler was declared to be of type object<eZ\Publish\Core\P...ntent\Language\Handler>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
35
    }
36
37
    /**
38
     * @deprecated Move towards using {@see generateLanguageMaskFromLanguageMap()}
39
     */
40
    public function generateLanguageMask(array $languageMap)
41
    {
42
        return $this->generateLanguageMaskFromLanguageMap($languageMap);
43
    }
44
45
    /**
46
     * Generates a language mask from the keys of $languages.
47
     *
48
     * Typically used for ->name values to get language mask directly from such structure.
49
     *
50
     * @param array $languageMap Key values are language code, value is ignored.
51
     *                           Exception is 'always-available' key, if set and true, always available flag is added.
52
     *
53
     * @throws \RuntimeException If non allowed values are provided as keys.
54
     *
55
     * @return int
56
     */
57
    public function generateLanguageMaskFromLanguageMap(array $languageMap): int
58
    {
59
        $mask = 0;
60
        if (isset($languageMap['always-available'])) {
61
            $mask |= $languageMap['always-available'] ? 1 : 0;
62
            unset($languageMap['always-available']);
63
        }
64
65
        foreach ($languageMap as $languageCode => $value) {
66
            try {
67
                $mask |= $this->languageHandler->loadByLanguageCode($languageCode)->id;
68
            } catch (NotFoundException $e) {
69
                if (\is_int($languageCode)) {
70
                    throw new RuntimeException("Keys expected as language codes, got: $languageCode", 0, $e);
71
                }
72
            }
73
        }
74
75
        return $mask;
76
    }
77
78
    /**
79
     * Generates a language mask for $translations argument.
80
     *
81
     * @param string[] $languageCodes Array of Language codes.
82
     * @param bool $useAlwaysAvailable
83
     *
84
     * @return int
85
     */
86
    public function generateLanguageMaskFromLanguageCodes(array $languageCodes, bool $useAlwaysAvailable): int
87
    {
88
        $mask = 0;
89
        $mask |= $useAlwaysAvailable ? 1 : 0;
90
91
        foreach ($languageCodes as $languageCode) {
92
            try {
93
                $mask |= $this->languageHandler->loadByLanguageCode($languageCode)->id;
94
            } catch (NotFoundException $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
95
        }
96
97
        return $mask;
98
    }
99
100
    /**
101
     * Generates a language mask from pre-loaded Language Ids.
102
     *
103
     * @param int[] $languageIds
104
     * @param bool $alwaysAvailable
105
     *
106
     * @return int
107
     */
108
    public function generateLanguageMaskFromLanguageIds(array $languageIds, $alwaysAvailable): int
109
    {
110
        // make sure alwaysAvailable part of bit mask always results in 1 or 0
111
        $languageMask = $alwaysAvailable ? 1 : 0;
112
113
        foreach ($languageIds as $languageId) {
114
            $languageMask |= $languageId;
115
        }
116
117
        return $languageMask;
118
    }
119
120
    /**
121
     * Generates a language indicator from $languageCode and $alwaysAvailable.
122
     *
123
     * @param string $languageCode
124
     * @param bool $alwaysAvailable
125
     *
126
     * @return int
127
     */
128
    public function generateLanguageIndicator($languageCode, $alwaysAvailable)
129
    {
130
        return $this->languageHandler->loadByLanguageCode($languageCode)->id | ($alwaysAvailable ? 1 : 0);
131
    }
132
133
    /**
134
     * Checks if $language is always available in $languages;.
135
     *
136
     * @param string $language
137
     * @param array $languages
138
     *
139
     * @return bool
140
     */
141
    public function isLanguageAlwaysAvailable($language, array $languages)
142
    {
143
        return isset($languages['always-available'])
144
           && ($languages['always-available'] == $language)
145
        ;
146
    }
147
148
    /**
149
     * Checks if $languageMask contains the alwaysAvailable bit field.
150
     *
151
     * @param int $languageMask
152
     *
153
     * @return bool
154
     */
155
    public function isAlwaysAvailable($languageMask)
156
    {
157
        return (bool)($languageMask & 1);
158
    }
159
160
    /**
161
     * Removes the alwaysAvailable flag from $languageId and returns cleaned up $languageId.
162
     *
163
     * @param int $languageId
164
     *
165
     * @return int
166
     */
167
    public function removeAlwaysAvailableFlag($languageId)
168
    {
169
        return $languageId & ~1;
170
    }
171
172
    /**
173
     * Extracts every language Ids contained in $languageMask.
174
     *
175
     * @param int $languageMask
176
     *
177
     * @return array Array of language Id
178
     */
179 View Code Duplication
    public function extractLanguageIdsFromMask($languageMask)
180
    {
181
        $exp = 2;
182
        $result = array();
183
184
        // Decomposition of $languageMask into its binary components.
185
        while ($exp <= $languageMask) {
186
            if ($languageMask & $exp) {
187
                $result[] = $exp;
188
            }
189
190
            $exp *= 2;
191
        }
192
193
        return $result;
194
    }
195
196
    /**
197
     * Extracts Language codes contained in given $languageMask.
198
     *
199
     * @param int $languageMask
200
     *
201
     * @return array
202
     */
203
    public function extractLanguageCodesFromMask($languageMask)
204
    {
205
        $languageCodes = array();
206
207
        foreach ($this->extractLanguageIdsFromMask($languageMask) as $languageId) {
208
            $languageCodes[] = $this->languageHandler->load($languageId)->languageCode;
209
        }
210
211
        return $languageCodes;
212
    }
213
214
    /**
215
     * Checks if given $languageMask consists of multiple languages.
216
     *
217
     * @param int $languageMask
218
     *
219
     * @return bool
220
     */
221
    public function isLanguageMaskComposite($languageMask)
222
    {
223
        // Ignore first bit
224
        $languageMask = $this->removeAlwaysAvailableFlag($languageMask);
225
226
        // Special case
227
        if ($languageMask === 0) {
228
            return false;
229
        }
230
231
        // Return false if power of 2
232
        return (bool)($languageMask & ($languageMask - 1));
233
    }
234
}
235