Completed
Pull Request — master (#6)
by ARCANEDEV
07:21
created

SitemapStyler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 1
nc 1
nop 0
crap 1
1
<?php namespace Arcanedev\LaravelSitemap\Helpers;
2
3
use Arcanedev\LaravelSitemap\Contracts\SitemapStyler as SitemapStylerContract;
4
5
/**
6
 * Class     SitemapStyler
7
 *
8
 * @package  Arcanedev\LaravelSitemap\Helpers
9
 * @author   ARCANEDEV <[email protected]>
10
 */
11
class SitemapStyler implements SitemapStylerContract
12
{
13
    /* -----------------------------------------------------------------
14
     |  Constants
15
     | -----------------------------------------------------------------
16
     */
17
18
    const VENDOR_PATH = 'vendor/sitemap';
19
20
    /* -----------------------------------------------------------------
21
     |  Properties
22
     | -----------------------------------------------------------------
23
     */
24
25
    /**
26
     * The enabled status.
27
     *
28
     * @var  bool
29
     */
30
    protected $enabled = true;
31
32
    /**
33
     * The location for xsl styles (must end with slash).
34
     *
35
     * @var string|null
36
     */
37
    private $location;
38
39
    /* -----------------------------------------------------------------
40
     |  Getters & Setters
41
     | -----------------------------------------------------------------
42
     */
43
44
    /**
45
     * Check if the styler is enabled (Get the enabled status).
46
     *
47
     * @return bool
48
     */
49 63
    public function isEnabled()
50
    {
51 63
        return $this->enabled;
52
    }
53
54
    /**
55
     * Set the enabled status.
56
     *
57
     * @param  bool  $status
58
     *
59
     * @return self
60
     */
61 27
    public function setEnabled($status)
62
    {
63 27
        $this->enabled = (bool) $status;
64
65 27
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Arcanedev\LaravelSitemap\Helpers\SitemapStyler) is incompatible with the return type declared by the interface Arcanedev\LaravelSitemap...temapStyler::setEnabled of type boolean.

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...
66
    }
67
68
    /**
69
     * Get the location for xsl styles.
70
     *
71
     * @return string|null
72
     */
73 54
    public function getLocation()
74
    {
75 54
        return $this->location;
76
    }
77
78
    /**
79
     * Set the location for xsl styles.
80
     *
81
     * @param  string  $location
82
     *
83
     * @return self
84
     */
85 36
    public function setLocation($location)
86
    {
87 36
        if (is_string($location) && ! empty($location)) {
88 36
            $location .= substr($location, -1) === '/' ? '' : '/';
89 12
        }
90
91 36
        $this->location = $location;
92
93 36
        return $this;
94
    }
95
96
    /* -----------------------------------------------------------------
97
     |  Main Methods
98
     | -----------------------------------------------------------------
99
     */
100
101
    /**
102
     * Get the sitemap style.
103
     *
104
     * @param  string       $format
105
     * @param  string|null  $style
106
     *
107
     * @return string|null
108
     */
109 36
    public function get($format, $style = null)
110
    {
111 36
        return $this->isEnabled() ? $this->getStyle($format, $style) : null;
112
    }
113
114
    /**
115
     * Enable the sitemap styles.
116
     *
117
     * @return self
118
     */
119 9
    public function enable()
120
    {
121 9
        return $this->setEnabled(true);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->setEnabled(true); (Arcanedev\LaravelSitemap\Helpers\SitemapStyler) is incompatible with the return type declared by the interface Arcanedev\LaravelSitemap...s\SitemapStyler::enable of type boolean.

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...
122
    }
123
124
    /**
125
     * Disable the sitemap styles.
126
     *
127
     * @return self
128
     */
129 9
    public function disable()
130
    {
131 9
        return $this->setEnabled(false);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->setEnabled(false); (Arcanedev\LaravelSitemap\Helpers\SitemapStyler) is incompatible with the return type declared by the interface Arcanedev\LaravelSitemap...\SitemapStyler::disable of type boolean.

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...
132
    }
133
134
    /* -----------------------------------------------------------------
135
     |  Other Methods
136
     | -----------------------------------------------------------------
137
     */
138
139
    /**
140
     * Get the sitemap style (ugly stuff here).
141
     *
142
     * @param  string       $format
143
     * @param  string|null  $style
144
     *
145
     * @return string|null
146
     */
147 36
    protected function getStyle($format, $style)
148
    {
149 36
        if ( ! is_null($style) && $this->hasPublicFile($style)) {
150 9
            return $style;
151
        }
152
153
        // Use style from a custom location
154 27
        if ($this->hasLocation() && $this->hasPublicFile($this->fromLocation($format))) {
155 9
            return $this->fromLocation($format);
156
        }
157
158
        // Use the published vendor style
159 18
        if ($this->hasPublicFile(self::VENDOR_PATH . "/styles/$format.xsl")) {
160 9
            return asset(self::VENDOR_PATH . "/styles/$format.xsl");
161
        }
162
163 18
        return null;
164
    }
165
166
    /**
167
     * Get the format location.
168
     *
169
     * @param  string  $format
170
     *
171
     * @return string
172
     */
173 9
    protected function fromLocation($format)
174
    {
175 9
        return $this->getLocation()."$format.xsl";
176
    }
177
178
    /**
179
     * Check if the location is set.
180
     *
181
     * @return bool
182
     */
183 27
    protected function hasLocation()
184
    {
185 27
        return ! is_null($this->getLocation());
186
    }
187
188
    /**
189
     * Check if the public file exists.
190
     *
191
     * @param  string  $path
192
     *
193
     * @return bool
194
     */
195 36
    protected function hasPublicFile($path)
196
    {
197 36
        return file_exists(public_path($path));
198
    }
199
}
200