Completed
Push — master ( b1b048...d29c62 )
by ARCANEDEV
12:09
created

UnitMeasure::setSymbol()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
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
     |  Init Functions
71
     | ------------------------------------------------------------------------------------------------
72
     */
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 288
    public static function make($value = 0, $unit = null, array $options = [])
83
    {
84 288
        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
87
    /**
88
     * Initialize the unit.
89
     *
90
     * @param  float|int  $value
91
     * @param  string     $unit
92
     * @param  array      $options
93
     */
94 720
    protected function init($value, $unit, array $options)
95
    {
96 720
        $this->setValue($value);
97 720
        $this->setUnit($unit);
98 720
        $this->setSymbols(Arr::get($options, 'symbols', []));
99 720
        $this->setNames(Arr::get($options, 'names', []));
100 720
        $this->setFormat(
101 720
            Arr::get($options, 'format.decimals', 0),
102 720
            Arr::get($options, 'format.decimal-separator', ','),
103 720
            Arr::get($options, 'format.thousands-separator', '.')
104 360
        );
105 720
    }
106
107
    /* ------------------------------------------------------------------------------------------------
108
     |  Getters & Setters
109
     | ------------------------------------------------------------------------------------------------
110
     */
111
    /**
112
     * Get the unit value.
113
     *
114
     * @return float|int
115
     */
116 588
    public function value()
117
    {
118 588
        return $this->value;
119
    }
120
121
    /**
122
     * Set the unit value.
123
     *
124
     * @param  float|int  $value
125
     *
126
     * @return static
127
     */
128 720
    public function setValue($value)
129
    {
130 720
        $this->value = $value;
131
132 720
        return $this;
133
    }
134
135
    /**
136
     * Get the default units.
137
     *
138
     * @return array
139
     */
140 720
    public static function units()
141
    {
142 720
        $constants = (new ReflectionClass(get_called_class()))
143 720
            ->getConstants();
144
145 720
        return array_values($constants);
146
    }
147
148
    /**
149
     * Get the unit key.
150
     *
151
     * @return string
152
     */
153 408
    public function unit()
154
    {
155 408
        return $this->unit;
156
    }
157
158
    /**
159
     * Set the unit key.
160
     *
161
     * @param  string  $unit
162
     *
163
     * @return static
164
     */
165 720
    public function setUnit($unit)
166
    {
167 720
        static::checkUnit($unit);
168
169 720
        $this->unit = $unit;
170
171 720
        return $this;
172
    }
173
174
    /**
175
     * Get the unit symbols.
176
     *
177
     * @return array
178
     */
179 198
    public function symbols()
180
    {
181 198
        return $this->symbols;
182
    }
183
184
    /**
185
     * Get the default symbols.
186
     *
187
     * @return array
188
     */
189 498
    protected static function defaultSymbols()
190
    {
191 498
        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 720
    public function setSymbols(array $symbols)
202
    {
203 720
        if (empty($symbols)) $symbols = static::defaultSymbols();
204
205 720
        foreach ($symbols as $unit => $symbol) {
206 720
            $this->setSymbol($unit, $symbol);
207 360
        }
208
209 720
        return $this;
210
    }
211
212
    /**
213
     * Get the unit symbol.
214
     *
215
     * @return string
216
     */
217 108
    public function symbol()
218
    {
219 108
        return Arr::get($this->symbols(), $this->unit());
220
    }
221
222
    /**
223
     * Set the unit symbol.
224
     *
225
     * @param  string  $unit
226
     * @param  string  $symbol
227
     *
228
     * @return static
229
     */
230 720
    public function setSymbol($unit, $symbol)
231
    {
232 720
        static::checkUnit($unit);
233
234 720
        $this->symbols[$unit] = $symbol;
235
236 720
        return $this;
237
    }
238
239
    /**
240
     * Get the unit names.
241
     *
242
     * @return array
243
     */
244 162
    public function names()
245
    {
246 162
        return $this->names;
247
    }
248
249
    /**
250
     * Get the default names.
251
     *
252
     * @return array
253
     */
254
    abstract protected function defaultNames();
255
256
    /**
257
     * Set the unit names.
258
     *
259
     * @param  array  $names
260
     *
261
     * @return static
262
     */
263 720
    public function setNames(array $names)
264
    {
265 720
        if (empty($names)) $names = $this->defaultNames();
266
267 720
        foreach ($names as $unit => $name) {
268 720
            $this->setName($unit, $name);
269 360
        }
270
271 720
        return $this;
272
    }
273
274
    /**
275
     * Get the unit name.
276
     *
277
     * @return string
278
     */
279 36
    public function name()
280
    {
281 36
        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 72
    public function getName($unit)
292
    {
293 72
        static::checkUnit($unit);
294
295 72
        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 720
    public function setName($unit, $name)
307
    {
308 720
        static::checkUnit($unit);
309
310 720
        $this->names[$unit] = $name;
311
312 720
        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 720
    public function setFormat($decimals = 0, $decimalSeparator = ',', $thousandsSeparator = '.')
325
    {
326 720
        $this->decimals           = $decimals;
327 720
        $this->decimalSeparator   = $decimalSeparator;
328 720
        $this->thousandsSeparator = $thousandsSeparator;
329
330 720
        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 306
    public function to($to)
345
    {
346 306
        if ($to === $this->unit()) return $this;
347
348 90
        $value = static::convert($this->unit(), $to, $this->value());
349
350 90
        return static::make($value, $to, [
351 90
            'symbols' => $this->symbols(),
352 90
            'names'   => $this->names(),
353
            'format'  => [
354 90
                'decimals'            => $this->decimals,
355 90
                'decimal-separator'   => $this->decimalSeparator,
356 90
                'thousands-separator' => $this->thousandsSeparator,
357 45
            ],
358 45
        ]);
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 90
    public static function convert($from, $to, $value)
371
    {
372 90
        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 108
    public function format(
385
        $decimals = null,
386
        $decimalSeparator = null,
387
        $thousandsSeparator = null
388
    ) {
389 108
        return number_format($this->value(),
390 108
            is_null($decimals)           ? $this->decimals           : $decimals,
391 108
            is_null($decimalSeparator)   ? $this->decimalSeparator   : $decimalSeparator,
392 108
            is_null($thousandsSeparator) ? $this->thousandsSeparator : $thousandsSeparator
393 54
        );
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 72
    public function formatWithSymbol(
406
        $decimals = null,
407
        $decimalSeparator = null,
408
        $thousandsSeparator = null
409
    ) {
410 72
        return $this->format($decimals, $decimalSeparator, $thousandsSeparator).' '.$this->symbol();
411
    }
412
413
    /**
414
     * Convert object to string.
415
     *
416
     * @return string
417
     */
418 36
    public function __toString()
419
    {
420 36
        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 36
    protected static function getRatio($to, $from)
436
    {
437 36
        static::checkUnit($from);
438 36
        static::checkUnit($to);
439
440 36
        if ($to === $from) return 1;
441
442 36
        $ratios = static::getRatios();
443
444 36
        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 720
    protected static function checkUnit($unit)
465
    {
466 720
        if ( ! in_array($unit, static::units())) {
467 36
            $class = static::class;
468
469 36
            throw new InvalidUnitException(
470 36
                "Invalid unit of measurement [{$unit}] in $class."
471 18
            );
472
        }
473 720
    }
474
}
475