Completed
Push — master ( 05264e...b99b30 )
by Łukasz
41:08 queued 15:05
created

generateLanguageMaskFromLanguageCodes()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 2
dl 0
loc 10
rs 9.9332
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\SPI\Persistence\Content\Language\Handler as LanguageHandler;
12
use RuntimeException;
13
14
/**
15
 * Language MaskGenerator.
16
 */
17
class MaskGenerator
18
{
19
    /**
20
     * Language lookup.
21
     *
22
     * @var \eZ\Publish\Core\Persistence\Legacy\Content\Language\Handler
23
     */
24
    protected $languageHandler;
25
26
    /**
27
     * Creates a new Language MaskGenerator.
28
     *
29
     * @param \eZ\Publish\SPI\Persistence\Content\Language\Handler $languageHandler
30
     */
31
    public function __construct(LanguageHandler $languageHandler)
32
    {
33
        $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...
34
    }
35
36
    /**
37
     * Generates a language mask from the keys of $languages.
38
     *
39
     * @param array $languages
40
     *
41
     * @return int
42
     */
43
    public function generateLanguageMask(array $languages)
44
    {
45
        $mask = 0;
46
        if (isset($languages['always-available'])) {
47
            $mask |= $languages['always-available'] ? 1 : 0;
48
            unset($languages['always-available']);
49
        }
50
51
        foreach ($languages as $language => $value) {
52
            if (is_int($language)) {
53
                throw new RuntimeException(
54
                    "Expected flipped array with language codes as keys, got int key: $language"
55
                );
56
            }
57
            $mask |= $this->languageHandler->loadByLanguageCode($language)->id;
58
        }
59
60
        return $mask;
61
    }
62
63
    /**
64
     * Generates a language mask from pre-loaded Language Ids.
65
     *
66
     * @param array $languageIds
67
     * @param bool $alwaysAvailable
68
     *
69
     * @return int
70
     */
71
    public function generateLanguageMaskFromLanguageIds(array $languageIds, $alwaysAvailable)
72
    {
73
        // make sure alwaysAvailable part of bit mask always results in 1 or 0
74
        $languageMask = $alwaysAvailable ? 1 : 0;
75
76
        foreach ($languageIds as $languageId) {
77
            $languageMask |= $languageId;
78
        }
79
80
        return $languageMask;
81
    }
82
83
    /**
84
     * Generates a language indicator from $languageCode and $alwaysAvailable.
85
     *
86
     * @param string $languageCode
87
     * @param bool $alwaysAvailable
88
     *
89
     * @return int
90
     */
91
    public function generateLanguageIndicator($languageCode, $alwaysAvailable)
92
    {
93
        return $this->languageHandler->loadByLanguageCode($languageCode)->id | ($alwaysAvailable ? 1 : 0);
94
    }
95
96
    /**
97
     * Checks if $language is always available in $languages;.
98
     *
99
     * @param string $language
100
     * @param array $languages
101
     *
102
     * @return bool
103
     */
104
    public function isLanguageAlwaysAvailable($language, array $languages)
105
    {
106
        return isset($languages['always-available'])
107
           && ($languages['always-available'] == $language)
108
        ;
109
    }
110
111
    /**
112
     * Checks if $languageMask contains the alwaysAvailable bit field.
113
     *
114
     * @param int $languageMask
115
     *
116
     * @return bool
117
     */
118
    public function isAlwaysAvailable($languageMask)
119
    {
120
        return (bool)($languageMask & 1);
121
    }
122
123
    /**
124
     * Removes the alwaysAvailable flag from $languageId and returns cleaned up $languageId.
125
     *
126
     * @param int $languageId
127
     *
128
     * @return int
129
     */
130
    public function removeAlwaysAvailableFlag($languageId)
131
    {
132
        return $languageId & ~1;
133
    }
134
135
    /**
136
     * Extracts every language Ids contained in $languageMask.
137
     *
138
     * @param int $languageMask
139
     *
140
     * @return array Array of language Id
141
     */
142 View Code Duplication
    public function extractLanguageIdsFromMask($languageMask)
143
    {
144
        $exp = 2;
145
        $result = array();
146
147
        // Decomposition of $languageMask into its binary components.
148
        while ($exp <= $languageMask) {
149
            if ($languageMask & $exp) {
150
                $result[] = $exp;
151
            }
152
153
            $exp *= 2;
154
        }
155
156
        return $result;
157
    }
158
159
    /**
160
     * Extracts Language codes contained in given $languageMask.
161
     *
162
     * @param int $languageMask
163
     *
164
     * @return array
165
     */
166
    public function extractLanguageCodesFromMask($languageMask)
167
    {
168
        $languageCodes = array();
169
170
        foreach ($this->extractLanguageIdsFromMask($languageMask) as $languageId) {
171
            $languageCodes[] = $this->languageHandler->load($languageId)->languageCode;
172
        }
173
174
        return $languageCodes;
175
    }
176
177
    /**
178
     * Checks if given $languageMask consists of multiple languages.
179
     *
180
     * @param int $languageMask
181
     *
182
     * @return bool
183
     */
184
    public function isLanguageMaskComposite($languageMask)
185
    {
186
        // Ignore first bit
187
        $languageMask = $this->removeAlwaysAvailableFlag($languageMask);
188
189
        // Special case
190
        if ($languageMask === 0) {
191
            return false;
192
        }
193
194
        // Return false if power of 2
195
        return (bool)($languageMask & ($languageMask - 1));
196
    }
197
198
    /**
199
     * @param array $languageCodes
200
     * @param bool $isAlwaysAvailable
201
     *
202
     * @return int
203
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
204
     */
205
    public function generateLanguageMaskFromLanguageCodes(array $languageCodes, bool $isAlwaysAvailable = false): int
206
    {
207
        $mask = $isAlwaysAvailable ? 1 : 0;
208
209
        foreach ($languageCodes as $languageCode) {
210
            $mask |= $this->languageHandler->loadByLanguageCode($languageCode)->id;
211
        }
212
213
        return $mask;
214
    }
215
}
216