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

Title   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 436
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 436
c 0
b 0
f 0
ccs 103
cts 103
cp 1
rs 8.2857
wmc 39
lcom 1
cbo 3

27 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A init() 0 8 1
A getTitleOnly() 0 4 1
A set() 0 7 1
A getSiteName() 0 4 1
A setSiteName() 0 7 2
A hideSiteName() 0 4 1
A showSiteName() 0 4 1
A setSiteNameVisibility() 0 6 1
A getSeparator() 0 4 1
A setSeparator() 0 7 2
A setFirst() 0 4 1
A setLast() 0 4 1
A switchPosition() 0 6 1
A isTitleFirst() 0 4 1
A getMax() 0 4 1
A setMax() 0 8 1
A make() 0 9 1
A render() 0 9 2
A renderSeparator() 0 4 2
A __toString() 0 4 1
A hasSiteName() 0 4 2
A checkTitle() 0 14 3
A checkMax() 0 10 3
A renderTitleFirst() 0 12 2
A renderTitleLast() 0 13 2
A prepareTitleOutput() 0 6 1
1
<?php namespace Arcanedev\SeoHelper\Entities;
2
3
use Arcanedev\SeoHelper\Contracts\Entities\Title as TitleContract;
4
use Arcanedev\SeoHelper\Exceptions\InvalidArgumentException;
5
use Arcanedev\Support\Traits\Configurable;
6
use Illuminate\Support\Str;
7
8
/**
9
 * Class     Title
10
 *
11
 * @package  Arcanedev\SeoHelper\Entities
12
 * @author   ARCANEDEV <[email protected]>
13
 */
14
class Title implements TitleContract
15
{
16
    /* -----------------------------------------------------------------
17
     |  Traits
18
     | -----------------------------------------------------------------
19
     */
20
    use Configurable;
21
22
    /* -----------------------------------------------------------------
23
     |  Properties
24
     | -----------------------------------------------------------------
25
     */
26
    /**
27
     * The title content.
28
     *
29
     * @var string
30
     */
31
    protected $title      = '';
32
33
    /**
34
     * The site name.
35
     *
36
     * @var string
37
     */
38
    protected $siteName   = '';
39
40
    /**
41
     * The site name visibility.
42
     *
43
     * @var bool
44
     */
45
    protected $siteNameVisibility = true;
46
47
    /**
48
     * The title separator.
49
     *
50
     * @var string
51
     */
52
    protected $separator  = '-';
53
54
    /**
55
     * Display the title first.
56
     *
57
     * @var bool
58
     */
59
    protected $titleFirst = true;
60
61
    /**
62
     * The maximum title length.
63
     *
64
     * @var int
65
     */
66
    protected $max        = 55;
67
68
    /* -----------------------------------------------------------------
69
     |  Constructor
70
     | -----------------------------------------------------------------
71
     */
72
    /**
73
     * Make the Title instance.
74
     *
75
     * @param  array  $configs
76
     */
77 153
    public function __construct(array $configs = [])
78
    {
79 153
        $this->setConfigs($configs);
80
81 153
        if ( ! empty($configs)) $this->init();
82 153
    }
83
84
    /**
85
     * Start the engine.
86
     */
87 153
    private function init()
88
    {
89 153
        $this->set($this->getConfig('default', ''));
90 153
        $this->setSiteName($this->getConfig('site-name', ''));
91 153
        $this->setSeparator($this->getConfig('separator', '-'));
92 153
        $this->switchPosition($this->getConfig('first', true));
93 153
        $this->setMax($this->getConfig('max', 55));
94 153
    }
95
96
    /* -----------------------------------------------------------------
97
     |  Getters & Setters
98
     | -----------------------------------------------------------------
99
     */
100
    /**
101
     * Get title only (without site name or separator).
102
     *
103
     * @return string
104
     */
105 93
    public function getTitleOnly()
106
    {
107 93
        return $this->title;
108
    }
109
110
    /**
111
     * Set title.
112
     *
113
     * @param  string  $title
114
     *
115
     * @return \Arcanedev\SeoHelper\Entities\Title
116
     */
117 153
    public function set($title)
118
    {
119 153
        $this->checkTitle($title);
120 153
        $this->title = $title;
121
122 153
        return $this;
123
    }
124
125
    /**
126
     * Get site name.
127
     *
128
     * @return string
129
     */
130 93
    public function getSiteName()
131
    {
132 93
        return $this->siteName;
133
    }
134
135
    /**
136
     * Set site name.
137
     *
138
     * @param  string  $siteName
139
     *
140
     * @return \Arcanedev\SeoHelper\Entities\Title
141
     */
142 153
    public function setSiteName($siteName)
143
    {
144 153
        if ( ! is_null($siteName))
145 153
            $this->siteName = $siteName;
146
147 153
        return $this;
148
    }
149
150
    /**
151
     * Hide the site name.
152
     *
153
     * @return \Arcanedev\SeoHelper\Entities\Title
154
     */
155 6
    public function hideSiteName()
156
    {
157 6
        return $this->setSiteNameVisibility(false);
158
    }
159
160
    /**
161
     * Show the site name.
162
     *
163
     * @return \Arcanedev\SeoHelper\Entities\Title
164
     */
165 6
    public function showSiteName()
166
    {
167 6
        return $this->setSiteNameVisibility(true);
168
    }
169
170
    /**
171
     * Set the site name visibility.
172
     *
173
     * @param  bool  $visible
174
     *
175
     * @return \Arcanedev\SeoHelper\Entities\Title
176
     */
177 6
    public function setSiteNameVisibility($visible)
178
    {
179 6
        $this->siteNameVisibility = (bool) $visible;
180
181 6
        return $this;
182
    }
183
184
    /**
185
     * Get title separator.
186
     *
187
     * @return string
188
     */
189 93
    public function getSeparator()
190
    {
191 93
        return $this->separator;
192
    }
193
194
    /**
195
     * Set title separator.
196
     *
197
     * @param  string  $separator
198
     *
199
     * @return \Arcanedev\SeoHelper\Entities\Title
200
     */
201 153
    public function setSeparator($separator)
202
    {
203 153
        if ( ! is_null($separator))
204 153
            $this->separator = trim($separator);
205
206 153
        return $this;
207
    }
208
209
    /**
210
     * Set title first.
211
     *
212
     * @return \Arcanedev\SeoHelper\Entities\Title
213
     */
214 6
    public function setFirst()
215
    {
216 6
        return $this->switchPosition(true);
217
    }
218
219
    /**
220
     * Set title last.
221
     *
222
     * @return \Arcanedev\SeoHelper\Entities\Title
223
     */
224 6
    public function setLast()
225
    {
226 6
        return $this->switchPosition(false);
227
    }
228
229
    /**
230
     * Switch title position.
231
     *
232
     * @param  bool  $first
233
     *
234
     * @return \Arcanedev\SeoHelper\Entities\Title
235
     */
236 153
    private function switchPosition($first)
237
    {
238 153
        $this->titleFirst = boolval($first);
239
240 153
        return $this;
241
    }
242
243
    /**
244
     * Check if title is first.
245
     *
246
     * @return bool
247
     */
248 93
    public function isTitleFirst()
249
    {
250 93
        return $this->titleFirst;
251
    }
252
253
    /**
254
     * Get title max length.
255
     *
256
     * @return int
257
     */
258 90
    public function getMax()
259
    {
260 90
        return $this->max;
261
    }
262
263
    /**
264
     * Set title max length.
265
     *
266
     * @param  int  $max
267
     *
268
     * @return \Arcanedev\SeoHelper\Entities\Title
269
     */
270 153
    public function setMax($max)
271
    {
272 153
        $this->checkMax($max);
273
274 153
        $this->max = $max;
275
276 153
        return $this;
277
    }
278
279
    /* -----------------------------------------------------------------
280
     |  Main Methods
281
     | -----------------------------------------------------------------
282
     */
283
    /**
284
     * Make a Title instance.
285
     *
286
     * @param  string  $title
287
     * @param  string  $siteName
288
     * @param  string  $separator
289
     *
290
     * @return \Arcanedev\SeoHelper\Entities\Title
291
     */
292 6
    public static function make($title, $siteName = '', $separator = '-')
293
    {
294 6
        return new self([
295 6
            'default'   => $title,
296 6
            'site-name' => $siteName,
297 6
            'separator' => $separator,
298
            'first'     => true
299 2
        ]);
300
    }
301
302
    /**
303
     * Render the tag.
304
     *
305
     * @return string
306
     */
307 87
    public function render()
308
    {
309 87
        $separator = $this->renderSeparator();
310 87
        $output    = $this->isTitleFirst()
311 87
            ? $this->renderTitleFirst($separator)
312 87
            : $this->renderTitleLast($separator);
313
314 87
        return '<title>' . $this->prepareTitleOutput($output) . '</title>';
315
    }
316
317
    /**
318
     * Render the separator.
319
     *
320
     * @return string
321
     */
322 87
    protected function renderSeparator()
323
    {
324 87
        return empty($separator = $this->getSeparator()) ? ' ' : " $separator ";
325
    }
326
327
    /**
328
     * Render the tag.
329
     *
330
     * @return string
331
     */
332 15
    public function __toString()
333
    {
334 15
        return $this->render();
335
    }
336
337
    /* -----------------------------------------------------------------
338
     |  Check Methods
339
     | -----------------------------------------------------------------
340
     */
341
    /**
342
     * Check if site name exists.
343
     *
344
     * @return bool
345
     */
346 87
    private function hasSiteName()
347
    {
348 87
        return ! empty($this->getSiteName()) && $this->siteNameVisibility;
349
    }
350
351
    /**
352
     * Check title.
353
     *
354
     * @param  string  $title
355
     *
356
     * @throws \Arcanedev\SeoHelper\Exceptions\InvalidArgumentException
357
     */
358 153
    private function checkTitle(&$title)
359
    {
360 153
        if ( ! is_string($title)) {
361 3
            $type = gettype($title);
362
363 3
            throw new InvalidArgumentException("The title must be a string value, [$type] is given.");
364
        }
365
366 153
        $title = trim($title);
367
368 153
        if (empty($title)) {
369 3
            throw new InvalidArgumentException('The title is required and must not be empty.');
370
        }
371 153
    }
372
373
    /**
374
     * Check title max length.
375
     *
376
     * @param  int  $max
377
     *
378
     * @throws \Arcanedev\SeoHelper\Exceptions\InvalidArgumentException
379
     */
380 153
    private function checkMax($max)
381
    {
382 153
        if ( ! is_int($max)) {
383 3
            throw new InvalidArgumentException('The title maximum lenght must be integer.');
384
        }
385
386 153
        if ($max <= 0) {
387 3
            throw new InvalidArgumentException('The title maximum lenght must be greater 0.');
388
        }
389 153
    }
390
391
    /* -----------------------------------------------------------------
392
     |  Other Methods
393
     | -----------------------------------------------------------------
394
     */
395
    /**
396
     * Render title first.
397
     *
398
     * @param  string  $separator
399
     *
400
     * @return string
401
     */
402 87
    private function renderTitleFirst($separator)
403
    {
404 87
        $output   = [];
405 87
        $output[] = $this->getTitleOnly();
406
407 87
        if ($this->hasSiteName()) {
408 87
            $output[] = $separator;
409 87
            $output[] = $this->getSiteName();
410 29
        }
411
412 87
        return implode('', $output);
413
    }
414
415
    /**
416
     * Render title last.
417
     *
418
     * @param  string  $separator
419
     *
420
     * @return string
421
     */
422 3
    private function renderTitleLast($separator)
423
    {
424 3
        $output = [];
425
426 3
        if ($this->hasSiteName()) {
427 3
            $output[] = $this->getSiteName();
428 3
            $output[] = $separator;
429 1
        }
430
431 3
        $output[] = $this->getTitleOnly();
432
433 3
        return implode('', $output);
434
    }
435
436
    /**
437
     * Prepare the title output.
438
     *
439
     * @param  string  $output
440
     *
441
     * @return string
442
     */
443 87
    private function prepareTitleOutput($output)
444
    {
445 87
        return htmlspecialchars(
446 87
            Str::limit(strip_tags($output), $this->getMax()), ENT_QUOTES, 'UTF-8', false
447 29
        );
448
    }
449
}
450