Completed
Pull Request — master (#9)
by ARCANEDEV
03:16
created

SitemapManager   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 219
c 0
b 0
f 0
ccs 46
cts 46
cp 1
rs 10
wmc 20
lcom 3
cbo 2

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A create() 0 4 1
A add() 0 6 1
A all() 0 4 1
A get() 0 4 1
A has() 0 4 1
A forget() 0 6 1
A count() 0 4 1
B render() 0 15 5
A renderIndex() 0 4 1
A save() 0 8 2
A toArray() 0 4 1
A toJson() 0 4 1
A jsonSerialize() 0 4 1
A renderView() 0 8 1
1
<?php namespace Arcanedev\LaravelSitemap;
2
3
use Arcanedev\LaravelSitemap\Contracts\Entities\Sitemap as SitemapContract;
4
use Arcanedev\LaravelSitemap\Contracts\SitemapManager as SitemapManagerContract;
5
use Arcanedev\LaravelSitemap\Entities\Sitemap;
6
use DOMDocument;
7
use Illuminate\Support\Collection;
8
9
/**
10
 * Class     SitemapManager
11
 *
12
 * @package  Arcanedev\LaravelSitemap
13
 * @author   ARCANEDEV <[email protected]>
14
 */
15
class SitemapManager implements SitemapManagerContract
16
{
17
    /* -----------------------------------------------------------------
18
     |  Properties
19
     | -----------------------------------------------------------------
20
     */
21
22
    /** @var  \Illuminate\Support\Collection */
23
    protected $sitemaps;
24
25
    /* -----------------------------------------------------------------
26
     |  Constructor
27
     | -----------------------------------------------------------------
28
     */
29
30
    /**
31
     * SitemapManager constructor.
32
     */
33 26
    public function __construct()
34
    {
35 26
        $this->sitemaps = new Collection;
36 26
    }
37
38
    /* -----------------------------------------------------------------
39
     |  Main Methods
40
     | -----------------------------------------------------------------
41
     */
42
43
    /**
44
     * Create and add a sitemap to the collection.
45
     *
46
     * @param  string    $name
47
     * @param  callable  $callback
48
     *
49
     * @return self
50
     */
51 2
    public function create($name, callable $callback)
52
    {
53 2
        return $this->add($name, tap((new Sitemap)->setPath($name), $callback));
54
    }
55
56
    /**
57
     * Add a sitemap to the collection.
58
     *
59
     * @param  string                                                $name
60
     * @param  \Arcanedev\LaravelSitemap\Contracts\Entities\Sitemap  $sitemap
61
     *
62
     * @return self
63
     */
64 20
    public function add($name, SitemapContract $sitemap)
65
    {
66 20
        $this->sitemaps->put($name, $sitemap);
67
68 20
        return $this;
69
    }
70
71
    /**
72
     * Get the sitemaps collection.
73
     *
74
     * @return \Illuminate\Support\Collection
75
     */
76 10
    public function all()
77
    {
78 10
        return $this->sitemaps;
79
    }
80
81
    /**
82
     * Get a sitemap instance.
83
     *
84
     * @param  string      $name
85
     * @param  mixed|null  $default
86
     *
87
     * @return mixed
88
     */
89 10
    public function get($name, $default = null)
90
    {
91 10
        return $this->sitemaps->get($name, $default);
92
    }
93
94
    /**
95
     * Check if a sitemap exists.
96
     *
97
     * @param  string  $name
98
     *
99
     * @return bool
100
     */
101 8
    public function has($name)
102
    {
103 8
        return $this->sitemaps->has($name);
104
    }
105
106
    /**
107
     * Remove a sitemap from the collection by key.
108
     *
109
     * @param  string|array  $names
110
     *
111
     * @return self
112
     */
113 2
    public function forget($names)
114
    {
115 2
        $this->sitemaps->forget($names);
116
117 2
        return $this;
118
    }
119
120
    /**
121
     * Get the sitemaps count.
122
     *
123
     * @return int
124
     */
125 14
    public function count()
126
    {
127 14
        return $this->sitemaps->count();
128
    }
129
130
    /**
131
     * Render the sitemaps.
132
     *
133
     * @param  string  $name
134
     *
135
     * @return string|null
136
     */
137 10
    public function render($name = null)
138
    {
139 10
        if ($this->sitemaps->isEmpty())
140 2
            return null;
141
142 8
        if (is_null($name)) {
143 6
            return $this->count() === 1
144 2
                ? $this->renderView('sitemap::sitemap.xml', ['sitemap' => $this->sitemaps->first()])
145 6
                : $this->renderIndex();
146
        }
147 6
        elseif ($this->has($name))
148 6
            return $this->renderView('sitemap::sitemap.xml', ['sitemap' => $this->get($name)]);
149
150 2
        return null;
151
    }
152
153
    /**
154
     * Render the sitemap index.
155
     *
156
     * @return string
157
     */
158 4
    public function renderIndex()
159
    {
160 4
        return $this->renderView('sitemap::sitemap-index.xml', ['sitemaps' => $this->sitemaps]);
161
    }
162
163
    /**
164
     * Save the sitemaps.
165
     *
166
     * @param  string       $path
167
     * @param  string|null  $name
168
     *
169
     * @return self
170
     */
171 6
    public function save($path, $name = null)
172
    {
173 6
        if ($this->sitemaps->isNotEmpty()) {
174 6
            file_put_contents($path, $this->render($name));
175
        }
176
177 6
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Arcanedev\LaravelSitemap\SitemapManager) is incompatible with the return type declared by the interface Arcanedev\LaravelSitemap...ts\SitemapManager::save 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...
178
    }
179
180
    /**
181
     * Get the collection of items as a plain array.
182
     *
183
     * @return array
184
     */
185 4
    public function toArray()
186
    {
187 4
        return $this->all()->toArray();
188
    }
189
190
    /**
191
     * Get the collection of sitemaps as JSON.
192
     *
193
     * @param  int  $options
194
     *
195
     * @return string
196
     */
197 2
    public function toJson($options = 0)
198
    {
199 2
        return json_encode($this->jsonSerialize(), $options);
200
    }
201
202
    /**
203
     * Convert the object into something JSON serializable.
204
     *
205
     * @return array
206
     */
207 2
    public function jsonSerialize()
208
    {
209 2
        return $this->toArray();
210
    }
211
212
    /* -----------------------------------------------------------------
213
     |  Other Methods
214
     | -----------------------------------------------------------------
215
     */
216
217
    /**
218
     * Render the view.
219
     *
220
     * @param  string  $view
221
     * @param  array   $data
222
     *
223
     * @return string
224
     */
225
    public function renderView($view, array $data)
226
    {
227 8
        return tap(new DOMDocument('1.0'), function (DOMDocument $document) use ($view, $data) {
228 8
            $document->preserveWhiteSpace = false;
229 8
            $document->formatOutput = true;
230 8
            $document->loadXML(view($view, $data)->render());
231 8
        })->saveXML();
232
    }
233
}
234