Passed
Push — master ( 289df5...0ba5f2 )
by
unknown
06:22
created

Url::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Cecil;
15
16
use Cecil\Assets\Asset;
17
use Cecil\Builder;
18
use Cecil\Collection\Menu\Entry as MenuEntry;
19
use Cecil\Collection\Page\Page;
20
use Cecil\Config;
21
use Cecil\Renderer\Page as PageRenderer;
22
use Cecil\Util;
23
use Cocur\Slugify\Slugify;
24
25
class Url
26
{
27
    /** @var Builder */
28
    protected $builder;
29
30
    /** @var Config */
31
    protected $config;
32
33
    /** @var string */
34
    protected $url;
35
36
    /** @var Page Slugifier */
37
    private static $slugifier;
38
39
    /**
40
     * Creates an URL from a Page, a Menu Entry, an Asset or a string.
41
     *
42
     * @param Builder                          $builder
43
     * @param Page|MenuEntry|Asset|string|null $value
44
     * @param array|null                       $options Rendering options, e.g.: ['canonical' => true, 'format' => 'html', 'language' => 'fr']
45
     */
46 1
    public function __construct(Builder $builder, $value, ?array $options = null)
47
    {
48 1
        $this->builder = $builder;
49 1
        $this->config = $builder->getConfig();
50 1
        if (!self::$slugifier instanceof Slugify) {
0 ignored issues
show
introduced by
self::slugifier is never a sub-type of Cocur\Slugify\Slugify.
Loading history...
51 1
            self::$slugifier = Slugify::create(['regexp' => Page::SLUGIFY_PATTERN]);
0 ignored issues
show
Documentation Bug introduced by
It seems like Cocur\Slugify\Slugify::c...Page::SLUGIFY_PATTERN)) of type Cocur\Slugify\Slugify is incompatible with the declared type Cecil\Collection\Page\Page of property $slugifier.

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...
52
        }
53
54
        // handles options
55 1
        $canonical = null; // if true prefix url with baseurl config
56 1
        $format = null;    // output format
57 1
        $language = null;  // force language
58 1
        extract(\is_array($options) ? $options : [], EXTR_IF_EXISTS);
59
60
        // canonical URL?
61 1
        $base = '';
62 1
        if ($this->config->isEnabled('canonicalurl') || $canonical === true) {
63 1
            $base = rtrim((string) $this->config->get('baseurl'), '/');
64
        }
65 1
        if ($canonical === false) {
66 1
            $base = '';
67
        }
68
69
        // if value is empty (i.e.: `url()`) returns home URL
70 1
        if (\is_null($value) || empty($value) || $value == '/') {
71 1
            $this->url = $base . '/';
72
73 1
            return;
74
        }
75
76
        switch (true) {
77 1
            case $value instanceof Page: // $value is a Page
78
                /** @var Page $value */
79 1
                if (!$format) {
80 1
                    $format = $value->getVariable('output');
81 1
                    if (\is_array($value->getVariable('output'))) {
82 1
                        $default = array_search('html', $value->getVariable('output')) ?: 0;
83 1
                        $format = $value->getVariable('output')[$default];
84
                    }
85 1
                    if (!$format) {
86 1
                        $format = 'html';
87
                    }
88
                }
89 1
                $this->url = $base . '/' . ltrim((new PageRenderer($this->config))->getUrl($value, $format), '/');
90 1
                if ($canonical && $value->hasVariable('canonical') && $value->getVariable('canonical')['url']) { // canonical URL
91
                    $this->url = $value->getVariable('canonical')['url'];
92
                }
93 1
                break;
94 1
            case $value instanceof MenuEntry: // $value is a Menu Entry
95
                /** @var MenuEntry $value */
96
                if (Util\File::isRemote($value['url'])) {
97
                    $this->url = $value['url'];
98
                    break;
99
                }
100
                $this->url = $base . '/' . ltrim($value['url'], '/');
101
                break;
102 1
            case $value instanceof Asset: // $value is an Asset
103
                /** @var Asset $value */
104 1
                $this->url = $base . '/' . ltrim($value['path'], '/');
105 1
                if ($value->isImageInCdn()) {
106
                    $this->url = (string) $value;
107
                }
108 1
                break;
109 1
            case \is_string($value): // others cases
110
                /** @var string $value */
111
                // $value is a potential Page ID
112 1
                $pageId = self::$slugifier->slugify($value);
113
                // should force language?
114 1
                $lang = '';
115 1
                if ($language !== null && $language != $this->config->getLanguageDefault()) {
116 1
                    $pageId = "$language/$pageId";
117 1
                    $lang = "$language/";
118
                }
119
                switch (true) {
120 1
                    case Util\File::isRemote($value): // $value is an external URL
121 1
                        $this->url = $value;
122 1
                        break;
123 1
                    case $this->builder->getPages()->has($pageId): // $pageId exists in pages collection
124 1
                        $this->url = (string) new self($this->builder, $this->builder->getPages()->get($pageId), $options);
125 1
                        break;
126
                    default:
127
                        // remove double language prefix
128 1
                        if ($lang && Util\Str::startsWith($value, $lang)) {
129 1
                            $value = substr($value, \strlen($lang));
130
                        }
131 1
                        $this->url = $base . '/' . $lang . ltrim($value, '/');
132
                }
133
        }
134
    }
135
136
    /**
137
     * If called like a string returns built URL.
138
     */
139 1
    public function __toString(): string
140
    {
141 1
        return $this->getUrl();
142
    }
143
144
    /**
145
     * Returns built URL.
146
     */
147 1
    public function getUrl(): string
148
    {
149 1
        return (string) $this->url;
150
    }
151
}
152