Completed
Push — master ( 7b8b46...795e4b )
by ARCANEDEV
14:25
created

FileSize::getRatios()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
ccs 15
cts 15
cp 1
cc 1
eloc 15
nc 1
nop 0
crap 1
1
<?php namespace Arcanedev\Units\Measures;
2
3
use Arcanedev\Units\Bases\UnitMeasure;
4
use Arcanedev\Units\Contracts\Measures\FileSize as FileSizeContract;
5
use Arcanedev\Units\Traits\Calculatable;
6
7
/**
8
 * Class     FileSize
9
 *
10
 * @package  Arcanedev\Units\Measures
11
 * @author   ARCANEDEV <[email protected]>
12
 */
13
class FileSize extends UnitMeasure implements FileSizeContract
14
{
15
    /* -----------------------------------------------------------------
16
     |  Traits
17
     | -----------------------------------------------------------------
18
     */
19
    use Calculatable;
20
21
    /* -----------------------------------------------------------------
22
     |  Getters & Setters
23
     | -----------------------------------------------------------------
24
     */
25
    /**
26
     * Get the default names.
27
     *
28
     * @return array
29
     */
30 189
    public function defaultNames()
31
    {
32 189
        return array_combine(static::units(), [
33 189
            'yotta',
34 63
            'zetta',
35 63
            'exa',
36 63
            'peta',
37 63
            'tera',
38 63
            'gigabyte',
39 63
            'megabyte',
40 63
            'kilobyte',
41 63
            'byte',
42 63
        ]);
43
    }
44
45
    /* -----------------------------------------------------------------
46
     |  Constructor
47
     | -----------------------------------------------------------------
48
     */
49
    /**
50
     * Distance constructor.
51
     *
52
     * @param  float|int  $value
53
     * @param  string     $unit
54
     * @param  array      $options
55
     */
56 198
    public function __construct($value = 0, $unit = self::B, array $options = [])
57
    {
58 198
        $this->init($value, $unit, $options);
59 198
    }
60
61
    /* -----------------------------------------------------------------
62
     |  Main Methods
63
     | -----------------------------------------------------------------
64
     */
65
    /**
66
     * Make a distance instance.
67
     *
68
     * @param  float|int  $value
69
     * @param  string     $unit
70
     * @param  array      $options
71
     *
72
     * @return static
73
     */
74 81
    public static function make($value = 0, $unit = self::B, array $options = [])
75
    {
76 81
        return parent::make($value, $unit, $options);
77
    }
78
79
    /* -----------------------------------------------------------------
80
     |  Calculation Methods
81
     | -----------------------------------------------------------------
82
     */
83
    /**
84
     * Add the file size.
85
     *
86
     * @param  float|int  $value
87
     * @param  string     $unit
88
     *
89
     * @return \Arcanedev\Units\Contracts\Measures\FileSize
90
     */
91 18
    public function addSize($value, $unit = self::B)
92
    {
93 18
        return $this->add(static::make($value, $unit));
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->add(static::make($value, $unit)); (Arcanedev\Units\Contracts\UnitMeasure) is incompatible with the return type declared by the interface Arcanedev\Units\Contract...sures\FileSize::addSize of type Arcanedev\Units\Contracts\Measures\FileSize.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
94
    }
95
96
    /**
97
     * Sub the file size.
98
     *
99
     * @param  float|int  $value
100
     * @param  string     $unit
101
     *
102
     * @return \Arcanedev\Units\Contracts\Measures\FileSize
103
     */
104 18
    public function subSize($value, $unit = self::B)
105
    {
106 18
        return $this->sub(static::make($value, $unit));
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->sub(static::make($value, $unit)); (Arcanedev\Units\Contracts\UnitMeasure) is incompatible with the return type declared by the interface Arcanedev\Units\Contract...sures\FileSize::subSize of type Arcanedev\Units\Contracts\Measures\FileSize.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
107
    }
108
109
    /* -----------------------------------------------------------------
110
     |  Other Methods
111
     | -----------------------------------------------------------------
112
     */
113
    /**
114
     * Get all the distance ratios.
115
     *
116
     * @return array
117
     */
118 27
    protected static function getRatios()
119
    {
120 27
        $rate   = 1024;
121
        $ratios = [
122 27
            FileSize::YB => 0,
123 27
            FileSize::ZB => 1,
124 27
            FileSize::EB => 2,
125 27
            FileSize::PB => 3,
126 27
            FileSize::TB => 4,
127 27
            FileSize::GB => 5,
128 27
            FileSize::MB => 6,
129 27
            FileSize::KB => 7,
130 27
            FileSize::B  => 8,
131 9
        ];
132
133 27
        return array_map(function ($ratio) use ($rate) {
134 27
            return static::calculate($rate, '^', $ratio);
135 27
        }, $ratios);
136
    }
137
}
138