Completed
Pull Request — master (#7)
by ARCANEDEV
15:23
created

UnitMeasure::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 9
nc 1
nop 3
crap 1
1
<?php namespace Arcanedev\Units\Bases;
2
3
use Arcanedev\Units\Contracts\UnitMeasure as UnitMeasureContract;
4
use Arcanedev\Units\Exceptions\InvalidUnitException;
5
use Illuminate\Support\Arr;
6
use ReflectionClass;
7
8
/**
9
 * Class     UnitMeasure
10
 *
11
 * @package  Arcanedev\Units\Base
12
 * @author   ARCANEDEV <[email protected]>
13
 */
14
abstract class UnitMeasure implements UnitMeasureContract
15
{
16
    /* ------------------------------------------------------------------------------------------------
17
     |  Properties
18
     | ------------------------------------------------------------------------------------------------
19
     */
20
    /**
21
     * The unit.
22
     *
23
     * @var string
24
     */
25
    protected $unit;
26
27
    /**
28
     * The value.
29
     *
30
     * @var float|int
31
     */
32
    protected $value;
33
34
    /**
35
     * The unit symbols.
36
     *
37
     * @var array
38
     */
39
    protected $symbols  = [];
40
41
    /**
42
     * The unit names.
43
     *
44
     * @var array
45
     */
46
    protected $names  = [];
47
48
    /**
49
     * The number of decimals to format.
50
     *
51
     * @var int
52
     */
53
    protected $decimals = 0;
54
55
    /**
56
     * The decimal separator.
57
     *
58
     * @var string
59
     */
60
    protected $decimalSeparator = '.';
61
62
    /**
63
     * The thousands separator.
64
     *
65
     * @var string
66
     */
67
    protected $thousandsSeparator = ',';
68
69
    /* ------------------------------------------------------------------------------------------------
70 408
     |  Init Functions
71
     | ------------------------------------------------------------------------------------------------
72 408
     */
73
    /**
74
     * Make a distance instance.
75
     *
76
     * @param  float|int  $value
77
     * @param  string     $unit
78
     * @param  array      $options
79
     *
80
     * @return static
81
     */
82 528
    public static function make($value = 0, $unit = null, array $options = [])
83
    {
84 528
        return new static($value, $unit, $options);
0 ignored issues
show
Unused Code introduced by
The call to UnitMeasure::__construct() has too many arguments starting with $value.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
85
    }
86 528
87
    /**
88
     * Initialize the unit.
89
     *
90
     * @param  float|int  $value
91
     * @param  string     $unit
92
     * @param  array      $options
93
     */
94 528
    protected function init($value, $unit, array $options)
95
    {
96 528
        $this->setValue($value);
97 528
        $this->setUnit($unit);
98
        $this->setSymbols(Arr::get($options, 'symbols', []));
99 528
        $this->setNames(Arr::get($options, 'names', []));
100
        $this->setFormat(
101
            Arr::get($options, 'format.decimals', 0),
102
            Arr::get($options, 'format.decimal-separator', ','),
103
            Arr::get($options, 'format.thousands-separator', '.')
104
        );
105
    }
106
107 256
    /* ------------------------------------------------------------------------------------------------
108
     |  Getters & Setters
109 256
     | ------------------------------------------------------------------------------------------------
110
     */
111
    /**
112
     * Get the unit value.
113
     *
114
     * @return float|int
115
     */
116
    public function value()
117
    {
118
        return $this->value;
119 528
    }
120
121 528
    /**
122
     * Set the unit value.
123 528
     *
124
     * @param  float|int  $value
125 528
     *
126
     * @return static
127
     */
128
    public function setValue($value)
129
    {
130
        $this->value = $value;
131
132
        return $this;
133 96
    }
134
135 96
    /**
136
     * Get the default units.
137
     *
138
     * @return array
139
     */
140
    public static function units()
141
    {
142
        $constants = (new ReflectionClass(get_called_class()))
143 72
            ->getConstants();
144
145 72
        return array_values($constants);
146
    }
147
148
    /**
149
     * Get the unit key.
150
     *
151
     * @return string
152
     */
153
    public function unit()
154
    {
155
        return $this->unit;
156 528
    }
157
158 528
    /**
159
     * Set the unit key.
160 528
     *
161
     * @param  string  $unit
162 528
     *
163
     * @return static
164
     */
165
    public function setUnit($unit)
166
    {
167
        static::checkUnit($unit);
168
169
        $this->unit = $unit;
170 504
171
        return $this;
172 504
    }
173
174
    /**
175
     * Get the unit symbols.
176
     *
177
     * @return array
178
     */
179
    public function symbols()
180
    {
181
        return $this->symbols;
182 528
    }
183
184 528
    /**
185
     * Get the default symbols.
186 528
     *
187 528
     * @return array
188 396
     */
189
    protected static function defaultSymbols()
190 528
    {
191
        return array_combine(static::units(), static::units());
192
    }
193
194
    /**
195
     * Set the unit symbols.
196
     *
197
     * @param  array  $symbols
198
     *
199
     * @return static
200
     */
201
    public function setSymbols(array $symbols)
202 528
    {
203
        if (empty($symbols)) $symbols = static::defaultSymbols();
204 528
205 528
        foreach ($symbols as $unit => $symbol) {
206 528
            $this->setSymbol($unit, $symbol);
207
        }
208 528
209
        return $this;
210
    }
211
212
    /**
213
     * Get the unit symbol.
214
     *
215
     * @return string
216
     */
217
    public function symbol()
218
    {
219
        return Arr::get($this->symbols(), $this->unit());
220
    }
221
222
    /**
223
     * Set the unit symbol.
224 72
     *
225
     * @param  string  $unit
226
     * @param  string  $symbol
227
     *
228
     * @return static
229 72
     */
230 72
    public function setSymbol($unit, $symbol)
231 72
    {
232 72
        static::checkUnit($unit);
233 54
234
        $this->symbols[$unit] = $symbol;
235
236
        return $this;
237
    }
238
239
    /**
240
     * Get the unit names.
241
     *
242
     * @return array
243
     */
244
    public function names()
245 48
    {
246
        return $this->names;
247
    }
248
249
    /**
250 48
     * Get the default names.
251
     *
252
     * @return array
253
     */
254
    abstract protected function defaultNames();
255
256
    /**
257
     * Set the unit names.
258 24
     *
259
     * @param  array  $names
260 24
     *
261
     * @return static
262
     */
263
    public function setNames(array $names)
264
    {
265
        if (empty($names)) $names = $this->defaultNames();
266
267
        foreach ($names as $unit => $name) {
268
            $this->setName($unit, $name);
269
        }
270
271
        return $this;
272 528
    }
273
274 528
    /**
275 24
     * Get the unit name.
276
     *
277 24
     * @return string
278 24
     */
279 18
    public function name()
280
    {
281 528
        return $this->getName($this->unit());
282
    }
283
284
    /**
285
     * Get the name by a given unit.
286
     *
287
     * @param  string  $unit
288
     *
289
     * @return string
290
     */
291
    public function getName($unit)
292
    {
293
        static::checkUnit($unit);
294
295
        return Arr::get($this->names(), $unit);
296
    }
297
298
    /**
299
     * Set the unit name.
300
     *
301
     * @param  string  $unit
302
     * @param  string  $name
303
     *
304
     * @return static
305
     */
306
    public function setName($unit, $name)
307
    {
308
        static::checkUnit($unit);
309
310
        $this->names[$unit] = $name;
311
312
        return $this;
313
    }
314
315
    /**
316
     * Set the format.
317
     *
318
     * @param  int     $decimals
319
     * @param  string  $decimalSeparator
320
     * @param  string  $thousandsSeparator
321
     *
322
     * @return static
323
     */
324
    public function setFormat($decimals = 0, $decimalSeparator = ',', $thousandsSeparator = '.')
325
    {
326
        $this->decimals           = $decimals;
327
        $this->decimalSeparator   = $decimalSeparator;
328
        $this->thousandsSeparator = $thousandsSeparator;
329
330
        return $this;
331
    }
332
333
    /* ------------------------------------------------------------------------------------------------
334
     |  Main Functions
335
     | ------------------------------------------------------------------------------------------------
336
     */
337
    /**
338
     * Convert the unit to the given unit key.
339
     *
340
     * @param  string  $to
341
     *
342
     * @return \Arcanedev\Units\Contracts\UnitMeasure
343
     */
344
    public function to($to)
345
    {
346
        if ($to === $this->unit()) return $this;
347
348
        $value = static::convert($this->unit(), $to, $this->value());
349
350
        return static::make($value, $to, [
351
            'symbols' => $this->symbols(),
352
            'names'   => $this->names(),
353
            'format'  => [
354
                'decimals'            => $this->decimals,
355
                'decimal-separator'   => $this->decimalSeparator,
356
                'thousands-separator' => $this->thousandsSeparator,
357
            ],
358
        ]);
359
    }
360
361
    /**
362
     * Convert the unit.
363
     *
364
     * @param  string     $from
365
     * @param  string     $to
366
     * @param  float|int  $value
367
     *
368
     * @return float|int
369
     */
370
    public static function convert($from, $to, $value)
371
    {
372
        return $value * static::getRatio($to, $from);
373
    }
374
375
    /**
376
     * Format the unit.
377
     *
378
     * @param  int|null     $decimals
379
     * @param  string|null  $decimalSeparator
380
     * @param  string|null  $thousandsSeparator
381
     *
382
     * @return string
383
     */
384
    public function format(
385
        $decimals = null,
386
        $decimalSeparator = null,
387
        $thousandsSeparator = null
388
    ) {
389
        return number_format($this->value(),
390
            is_null($decimals)           ? $this->decimals           : $decimals,
391
            is_null($decimalSeparator)   ? $this->decimalSeparator   : $decimalSeparator,
392
            is_null($thousandsSeparator) ? $this->thousandsSeparator : $thousandsSeparator
393
        );
394
    }
395
396
    /**
397
     * Format the unit with symbol.
398
     *
399
     * @param  int|null     $decimals
400
     * @param  string|null  $decimalSeparator
401
     * @param  string|null  $thousandsSeparator
402
     *
403
     * @return string
404
     */
405
    public function formatWithSymbol(
406
        $decimals = null,
407
        $decimalSeparator = null,
408
        $thousandsSeparator = null
409
    ) {
410
        return $this->format($decimals, $decimalSeparator, $thousandsSeparator).' '.$this->symbol();
411
    }
412
413
    /**
414
     * Convert object to string.
415
     *
416
     * @return string
417
     */
418
    public function __toString()
419
    {
420
        return $this->formatWithSymbol();
421
    }
422
423
    /* ------------------------------------------------------------------------------------------------
424
     |  Check Functions
425
     | ------------------------------------------------------------------------------------------------
426
     */
427
    /**
428
     * Get the unit ratio.
429
     *
430
     * @param  string  $to
431
     * @param  string  $from
432
     *
433
     * @return float|int
434
     */
435
    protected static function getRatio($to, $from)
436
    {
437
        static::checkUnit($from);
438
        static::checkUnit($to);
439
440
        if ($to === $from) return 1;
441
442
        $ratios = static::getRatios();
443
444
        return $ratios[$to] / $ratios[$from];
445
    }
446
447
    /**
448
     * Get all the unit ratios.
449
     *
450
     * @codeCoverageIgnore
451
     *
452
     * @return array
453
     */
454
    protected static function getRatios()
455
    {
456
        return [];
457
    }
458
459
    /**
460
     * Check the weight unit.
461
     *
462
     * @param  string  $unit
463
     */
464
    protected static function checkUnit($unit)
465
    {
466
        if ( ! in_array($unit, static::units())) {
467
            $class = static::class;
468
469
            throw new InvalidUnitException(
470
                "Invalid unit of measurement [{$unit}] in $class."
471
            );
472
        }
473
    }
474
}
475