Completed
Push — master ( 0842cd...0b5524 )
by ARCANEDEV
07:12
created

src/Helpers/SitemapStyler.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
    const VENDOR_PATH = 'vendor/sitemap';
18
19
    /* ------------------------------------------------------------------------------------------------
20
     |  Properties
21
     | ------------------------------------------------------------------------------------------------
22
     */
23
    /**
24
     * The enabled status.
25
     *
26
     * @var  bool
27
     */
28
    protected $enabled = true;
29
30
    /**
31
     * The location for xsl styles (must end with slash).
32
     *
33
     * @var string|null
34
     */
35
    private $location;
36
37
    /* ------------------------------------------------------------------------------------------------
38
     |  Constructor
39
     | ------------------------------------------------------------------------------------------------
40
     */
41
    /**
42
     * SitemapStyler constructor.
43
     */
44 80
    public function __construct()
45
    {
46
        //
47 80
    }
48
49
    /* ------------------------------------------------------------------------------------------------
50
     |  Getters & Setters
51
     | ------------------------------------------------------------------------------------------------
52
     */
53
    /**
54
     * Check if the styler is enabled (Get the enabled status).
55
     *
56
     * @return bool
57
     */
58 40
    public function isEnabled()
59
    {
60 40
        return $this->enabled;
61
    }
62
63
    /**
64
     * Set the enabled status.
65
     *
66
     * @param  bool  $status
67
     *
68
     * @return bool
69
     */
70 16
    public function setEnabled($status)
71
    {
72 16
        $this->enabled = (bool) $status;
73
74 16
        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...
75
    }
76
77
    /**
78
     * Get the location for xsl styles.
79
     *
80
     * @return string|null
81
     */
82 32
    public function getLocation()
83
    {
84 32
        return $this->location;
85
    }
86
87
    /**
88
     * Set the location for xsl styles.
89
     *
90
     * @param  string  $location
91
     *
92
     * @return self
93
     */
94 24
    public function setLocation($location)
95
    {
96 24
        if (is_string($location) && ! empty($location)) {
97 24
            $location .= substr($location, -1) === '/' ? '' : '/';
98 18
        }
99
100 24
        $this->location = $location;
101
102 24
        return $this;
103
    }
104
105
    /* ------------------------------------------------------------------------------------------------
106
     |  Main Functions
107
     | ------------------------------------------------------------------------------------------------
108
     */
109
    /**
110
     * Get the sitemap style.
111
     *
112
     * @param  string       $format
113
     * @param  string|null  $style
114
     *
115
     * @return string|null
116
     */
117 24
    public function get($format, $style = null)
118
    {
119 24
        return $this->isEnabled() ? $this->getStyle($format, $style) : null;
120
    }
121
122
    /**
123
     * Enable the sitemap styles.
124
     *
125
     * @return bool
126
     */
127 8
    public function enable()
128
    {
129 8
        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...
130
    }
131
132
    /**
133
     * Disable the sitemap styles.
134
     *
135
     * @return bool
136
     */
137 8
    public function disable()
138
    {
139 8
        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...
140
    }
141
142
    /* ------------------------------------------------------------------------------------------------
143
     |  Other Functions
144
     | ------------------------------------------------------------------------------------------------
145
     */
146
    /**
147
     * Get the sitemap style (ugly stuff here).
148
     *
149
     * @param  string       $format
150
     * @param  string|null  $style
151
     *
152
     * @return string|null
153
     */
154 24
    protected function getStyle($format, $style)
155
    {
156 24
        if ( ! is_null($style) && $this->hasPublicFile($style)) {
157 8
            return $style;
158
        }
159
160
        // Use style from a custom location
161 16
        if ($this->hasLocation() && $this->hasPublicFile($this->fromLocation($format))) {
162 8
            return $this->fromLocation($format);
163
        }
164
165
        // Use the published vendor style
166 8
        if ($this->hasPublicFile(self::VENDOR_PATH . "/styles/$format.xsl")) {
167 8
            return asset(self::VENDOR_PATH . "/styles/$format.xsl");
168
        }
169
170 8
        return null;
171
    }
172
173
    /**
174
     * Get the format location.
175
     *
176
     * @param  string  $format
177
     *
178
     * @return string
179
     */
180 8
    protected function fromLocation($format)
181
    {
182 8
        return $this->getLocation()."$format.xsl";
183
    }
184
185
    /**
186
     * Check if the location is set.
187
     *
188
     * @return bool
189
     */
190 16
    protected function hasLocation()
191
    {
192 16
        return ! is_null($this->getLocation());
193
    }
194
195
    /**
196
     * Check if the public file exists.
197
     *
198
     * @param  string  $path
199
     *
200
     * @return bool
201
     */
202 24
    protected function hasPublicFile($path)
203
    {
204 24
        return file_exists(public_path($path));
205
    }
206
}
207