Completed
Push — master ( f02869...8251a6 )
by Nicolas
03:31
created

AsgardAssetManager   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 121
rs 10
c 0
b 0
f 0
wmc 14
lcom 1
cbo 2

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A addAssets() 0 6 2
A addAsset() 0 9 3
A allCss() 0 4 1
A allJs() 0 4 1
A isJs() 0 4 1
A isCss() 0 4 1
A getJs() 0 8 1
A getCss() 0 8 1
A guardForAssetNotFound() 0 6 2
1
<?php namespace Modules\Core\Foundation\Asset\Manager;
2
3
use Illuminate\Support\Collection;
4
use Modules\Core\Foundation\Asset\AssetNotFoundException;
5
6
final class AsgardAssetManager implements AssetManager
7
{
8
    /**
9
     * @var array
10
     */
11
    protected $css = [];
12
    /**
13
     * @var array
14
     */
15
    protected $js = [];
16
17
    public function __construct()
18
    {
19
        $this->css = new Collection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Illuminate\Support\Collection() of type object<Illuminate\Support\Collection> is incompatible with the declared type array of property $css.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
20
        $this->js = new Collection();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Illuminate\Support\Collection() of type object<Illuminate\Support\Collection> is incompatible with the declared type array of property $js.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
21
    }
22
23
    /**
24
     * Add an array of possible assets
25
     * @param array $assets
26
     * @return void
27
     */
28
    public function addAssets(array $assets)
29
    {
30
        foreach ($assets as $dependency => $path) {
31
            $this->addAsset($dependency, $path);
32
        }
33
    }
34
35
    /**
36
     * Add a possible asset
37
     * @param string $dependency
38
     * @param string $path
39
     * @return void
40
     */
41
    public function addAsset($dependency, $path)
42
    {
43
        if ($this->isJs($path)) {
44
            return $this->js->put($dependency, $path);
0 ignored issues
show
Bug introduced by
The method put cannot be called on $this->js (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
45
        }
46
        if ($this->isCss($path)) {
47
            return $this->css->put($dependency, $path);
0 ignored issues
show
Bug introduced by
The method put cannot be called on $this->css (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
48
        }
49
    }
50
51
    /**
52
     * Return all css files to include
53
     * @return \Illuminate\Support\Collection
54
     */
55
    public function allCss()
56
    {
57
        return $this->css;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->css; (array) is incompatible with the return type declared by the interface Modules\Core\Foundation\...er\AssetManager::allCss of type Illuminate\Support\Collection.

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...
58
    }
59
60
    /**
61
     * Return all js files to include
62
     * @return \Illuminate\Support\Collection
63
     */
64
    public function allJs()
65
    {
66
        return $this->js;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->js; (array) is incompatible with the return type declared by the interface Modules\Core\Foundation\...ger\AssetManager::allJs of type Illuminate\Support\Collection.

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...
67
    }
68
69
    /**
70
     * Check if the given path is a javascript file
71
     * @param string $path
72
     * @return bool
73
     */
74
    private function isJs($path)
75
    {
76
        return pathinfo($path, PATHINFO_EXTENSION) == 'js';
77
    }
78
79
    /**
80
     * Check if the given path is a css file
81
     * @param string $path
82
     * @return bool
83
     */
84
    private function isCss($path)
85
    {
86
        return pathinfo($path, PATHINFO_EXTENSION) == 'css';
87
    }
88
89
    /**
90
     * @param string $dependency
91
     * @return string
92
     */
93
    public function getJs($dependency)
94
    {
95
        $assetPath = $this->js->get($dependency);
0 ignored issues
show
Bug introduced by
The method get cannot be called on $this->js (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
96
97
        $this->guardForAssetNotFound($assetPath);
98
99
        return $assetPath;
100
    }
101
102
    /**
103
     * @param string $dependency
104
     * @return string
105
     */
106
    public function getCss($dependency)
107
    {
108
        $assetPath = $this->css->get($dependency);
0 ignored issues
show
Bug introduced by
The method get cannot be called on $this->css (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
109
110
        $this->guardForAssetNotFound($assetPath);
111
112
        return $assetPath;
113
    }
114
115
    /**
116
     * If asset was not found, throw an exception
117
     * @param string $assetPath
118
     * @throws AssetNotFoundException
119
     */
120
    private function guardForAssetNotFound($assetPath)
121
    {
122
        if (is_null($assetPath)) {
123
            throw new AssetNotFoundException($assetPath);
124
        }
125
    }
126
}
127