Completed
Push — master ( ffee16...931d62 )
by Chin
01:04
created

PhpWeekday::refreshLocales()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 1
nop 0
1
<?php
2
3
namespace ChinLeung\PhpWeekday;
4
5
use InvalidArgumentException;
6
7
class PhpWeekday
8
{
9
    /**
10
     * The locale of the application.
11
     *
12
     * @var string
13
     */
14
    protected $locale;
15
16
    /**
17
     * The name of the weekday.
18
     *
19
     * @var string
20
     */
21
    protected $name;
22
23
    /**
24
     * The value of the weekday.
25
     *
26
     * @var int
27
     */
28
    protected $value;
29
30
    /**
31
     * Constructor of the class.
32
     *
33
     * @param  string|int  $value
34
     * @param  string  $locale
35
     * @return self
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
36
     */
37
    public function __construct($value, string $locale, bool $force = false)
0 ignored issues
show
Unused Code introduced by
The parameter $force is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
38
    {
39
        $this->setLocale($locale)
40
             ->set($value);
41
42
        return $this;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
43
    }
44
45
    /**
46
     * Retrieve the current locale.
47
     *
48
     * @return string
49
     */
50
    public function getLocale() : string
51
    {
52
        return $this->locale;
53
    }
54
55
    /**
56
     * Retrieve the supported locales.
57
     *
58
     * @return array
59
     */
60
    public static function getLocales() : array
61
    {
62
        return array_map(
63
            'basename',
64
            glob(__DIR__.'/../resources/lang/*') ?: []
65
        );
66
    }
67
68
    /**
69
     * Retrieve the name of the weekday.
70
     *
71
     * @param  string  $locale
72
     * @return string
73
     */
74
    public function getName(string $locale = null) : string
75
    {
76
        if ($locale && $locale != $this->locale) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $locale of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
77
            return $this->parseName($this->getValue(), $locale);
78
        }
79
80
        if (is_null($this->name)) {
81
            $this->name = $this->parseName($this->getValue());
82
        }
83
84
        return $this->name;
85
    }
86
87
    /**
88
     * Retrieve the name from a value.
89
     *
90
     * @param  int  $value
91
     * @param  string  $locale
92
     * @return string
93
     */
94
    public static function getNameFromValue(int $value, string $locale) : string
95
    {
96
        return static::parse($value, $locale)->getName();
97
    }
98
99
    /**
100
     * Retrieve the names of every weekday for a locale.
101
     *
102
     * @param  string  $locale
103
     * @return array
104
     */
105
    public static function getNames(string $locale) : array
106
    {
107
        $path = __DIR__."/../resources/lang/$locale/names.php";
108
109
        if (! file_exists($path)) {
110
            static::throwNotSupportedLocaleException($locale);
111
        }
112
113
        return require $path;
114
    }
115
116
    /**
117
     * Retrieve the value of the weekday.
118
     *
119
     * @return int
120
     */
121
    public function getValue() : int
122
    {
123
        if (is_null($this->value)) {
124
            $this->value = $this->parseValue($this->getName());
125
        }
126
127
        return $this->value;
128
    }
129
130
    /**
131
     * Retrieve the value from a name.
132
     *
133
     * @param  string  $name
134
     * @param  string  $locale
135
     * @return string
136
     */
137
    public static function getValueFromName(string $name, string $locale) : string
138
    {
139
        return static::parse($name, $locale)->getValue();
140
    }
141
142
    /**
143
     * Check if the locale is supported.
144
     *
145
     * @param  string  $locales
0 ignored issues
show
Documentation introduced by
There is no parameter named $locales. Did you maybe mean $locale?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
146
     * @return bool
147
     */
148
    public function isSupported(string $locale) : bool
149
    {
150
        return file_exists(__DIR__."/../resources/lang/$locale");
151
    }
152
153
    /**
154
     * Check if the locale is not supported.
155
     *
156
     * @param  string  $locales
0 ignored issues
show
Documentation introduced by
There is no parameter named $locales. Did you maybe mean $locale?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
157
     * @return bool
158
     */
159
    public function isNotSupported(string $locale) : bool
160
    {
161
        return ! $this->isSupported($locale);
162
    }
163
164
    /**
165
     * Create a new instance from a value.
166
     *
167
     * @param  string|int  $value
168
     * @param  string  $locale
169
     * @return self
170
     */
171
    public static function parse($value, string $locale)
172
    {
173
        return new static($value, $locale);
174
    }
175
176
    /**
177
     * Parse the name of the weekday based on the value.
178
     *
179
     * @param  int  $value
180
     * @param  string  $locale
181
     * @return string
182
     */
183
    public function parseName(int $value, string $locale = null) : string
184
    {
185
        if ($value < 0 || $value > 6) {
186
            throw new InvalidArgumentException(
187
                "The provided value ($value) is not a valid weekday."
188
            );
189
        }
190
191
        return array_values(static::getNames($locale ?: $this->locale))[$value];
192
    }
193
194
    /**
195
     * Parse the value from the weekday name.
196
     *
197
     * @param  string  $name
198
     * @param  string  $locale
199
     * @return int
200
     */
201
    public function parseValue(string $name, string $locale = null) : int
202
    {
203
        $names = array_map(
204
            'strtolower',
205
            static::getNames($locale ?: $this->locale)
206
        );
207
208
        $value = array_search(
209
            strtolower($name),
210
            array_values($names)
211
        );
212
213
        if ($value === false) {
214
            throw new InvalidArgumentException(
215
                sprintf(
216
                    'The value could not be parsed for %s in %s.',
217
                    $name,
218
                    $locale ?: $this->locale
219
                )
220
            );
221
        }
222
223
        return $value;
224
    }
225
226
    /**
227
     * Set the weekday based on the integer or string value.
228
     *
229
     * @param  string|int  $value
230
     * @return self
231
     */
232
    public function set($value) : self
233
    {
234
        if (is_numeric($value)) {
235
            $this->value = $value;
0 ignored issues
show
Documentation Bug introduced by
It seems like $value can also be of type double or string. However, the property $value is declared as type integer. Maybe add an additional type 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 mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
236
            $this->name = null;
237
        } else {
238
            $this->name = $value;
239
            $this->value = null;
240
        }
241
242
        return $this;
243
    }
244
245
    /**
246
     * Set the locale of the instance.
247
     *
248
     * @param  string  $locale
249
     * @return self
250
     */
251
    public function setLocale(string $locale) : self
252
    {
253
        if ($locale != $this->locale) {
254
            if ($this->isNotSupported($locale)) {
255
                static::throwNotSupportedLocaleException($locale);
256
            }
257
258
            $this->name = null;
259
            $this->locale = $locale;
260
        }
261
262
        return $this;
263
    }
264
265
    /**
266
     * Throw an exception to let the user know that the locale is not yet
267
     * supported.
268
     *
269
     * @param  string  $locale
270
     * @return void
271
     */
272
    protected static function throwNotSupportedLocaleException(string $locale) : void
273
    {
274
        throw new InvalidArgumentException(
275
            "The locale ($locale) is not yet supported."
276
        );
277
    }
278
}
279