Url::__construct()   F
last analyzed

Complexity

Conditions 30
Paths 288

Size

Total Lines 91
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 47
CRAP Score 33.7349

Importance

Changes 8
Bugs 6 Features 0
Metric Value
cc 30
eloc 58
c 8
b 6
f 0
nc 288
nop 3
dl 0
loc 91
ccs 47
cts 56
cp 0.8393
crap 33.7349
rs 2.2333

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cecil;
15
16
use Cecil\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
24
/**
25
 * URL class.
26
 *
27
 * Builds an URL from a Page, a Menu Entry, an Asset or a string.
28
 */
29
class Url
30
{
31
    /** @var Builder */
32
    protected $builder;
33
34
    /** @var Config */
35
    protected $config;
36
37
    /** @var string */
38
    protected $url;
39
40
    /**
41
     * Creates an URL from a Page, a Menu Entry, an Asset or a string.
42
     *
43
     * @param Builder                          $builder
44
     * @param Page|MenuEntry|Asset|string|null $value
45
     * @param array|null                       $options Rendering options, e.g.: ['canonical' => true, 'format' => 'html', 'language' => 'fr']
46
     */
47 1
    public function __construct(Builder $builder, $value, ?array $options = null)
48
    {
49 1
        $this->builder = $builder;
50 1
        $this->config = $builder->getConfig();
51
52
        // handles options
53 1
        $canonical = null; // if true prefix url with baseurl config
54 1
        $format = null;    // output format
55 1
        $language = null;  // force language
56 1
        extract(\is_array($options) ? $options : [], EXTR_IF_EXISTS);
57
58
        // base URL
59 1
        $base = '';
60
        // enable canonical URL
61 1
        if ($this->config->isEnabled('canonicalurl') || $canonical === true) {
62 1
            $base = rtrim((string) $this->config->get('baseurl'), '/');
63
        }
64
        // disable canonical URL by option
65 1
        if ($canonical === false) {
0 ignored issues
show
introduced by
The condition $canonical === false is always true.
Loading history...
66 1
            $base = '';
67
        }
68
        // use URL path as base if exists
69 1
        if ($base == '' && '/' != $basepath = parse_url((string) $this->config->get('baseurl'), PHP_URL_PATH)) {
70
            if (\is_string($basepath)) {
71
                $base = '/' . trim($basepath, '/');
72
            }
73
        }
74
75
        // if value is empty returns base URL
76 1
        if (\is_null($value) || empty($value) || $value == '/') {
77 1
            $this->url = $base;
78
79 1
            return;
80
        }
81
82
        switch (true) {
83 1
            case $value instanceof Page: // $value is a Page
84
                /** @var Page $value */
85 1
                if (!$format) {
86 1
                    $format = $value->getVariable('output');
87 1
                    if (\is_array($value->getVariable('output'))) {
88 1
                        $default = array_search('html', $value->getVariable('output')) ?: 0;
89 1
                        $format = $value->getVariable('output')[$default];
90
                    }
91 1
                    if (!$format) {
92 1
                        $format = 'html';
93
                    }
94
                }
95 1
                $this->url = $base . '/' . ltrim((new PageRenderer($this->builder, $value))->getPath($format), '/');
96 1
                if ($canonical && $value->hasVariable('canonical') && $value->getVariable('canonical')['url']) { // canonical URL
97
                    $this->url = $value->getVariable('canonical')['url'];
98
                }
99 1
                break;
100 1
            case $value instanceof MenuEntry: // $value is a Menu Entry
101
                /** @var MenuEntry $value */
102
                if (Util\File::isRemote($value['url'])) {
103
                    $this->url = $value['url'];
104
                    break;
105
                }
106
                $this->url = $base . '/' . ltrim($value['url'], '/');
107
                break;
108 1
            case $value instanceof Asset: // $value is an Asset
109
                /** @var Asset $value */
110 1
                $this->url = $base . '/' . ltrim($value['path'], '/');
111 1
                if ($value->isImageInCdn()) {
112
                    $this->url = (string) $value;
113
                }
114 1
                break;
115 1
            case \is_string($value): // others cases
116
                /** @var non-falsy-string $value */
117
                // $value is a potential Page ID
118 1
                $pageId = Page::slugify($value);
119
                // should force language?
120 1
                $lang = '';
121 1
                if ($language !== null && $language != $this->config->getLanguageDefault()) {
122 1
                    $pageId = "$language/$pageId";
123 1
                    $lang = "$language/";
124
                }
125
                switch (true) {
126 1
                    case Util\File::isRemote($value): // $value is an external URL
127 1
                        $this->url = $value;
128 1
                        break;
129 1
                    case $this->builder->getPages()->has($pageId): // $pageId exists in pages collection
130 1
                        $this->url = (string) new self($this->builder, $this->builder->getPages()->get($pageId), $options);
131 1
                        break;
132
                    default:
133
                        // remove double language prefix
134 1
                        if ($lang && Util\Str::startsWith($value, $lang)) {
135 1
                            $value = substr($value, \strlen($lang));
136
                        }
137 1
                        $this->url = $base . '/' . $lang . ltrim($value, '/');
138
                }
139
        }
140
    }
141
142
    /**
143
     * If called like a string returns built URL.
144
     */
145 1
    public function __toString(): string
146
    {
147 1
        return $this->getUrl();
148
    }
149
150
    /**
151
     * Returns built URL.
152
     */
153 1
    public function getUrl(): string
154
    {
155 1
        return (string) $this->url ?: '/';
156
    }
157
}
158