Url::__construct()   F
last analyzed

Complexity

Conditions 30
Paths 288

Size

Total Lines 92
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 6 Features 0
Metric Value
cc 30
eloc 59
c 9
b 6
f 0
nc 288
nop 3
dl 0
loc 92
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
    public function __construct(Builder $builder, $value, ?array $options = null)
48
    {
49
        $this->builder = $builder;
50
        $this->config = $builder->getConfig();
51
52
        // handles options
53
        $canonical = null; // if true prefix url with baseurl config
54
        $format = null;    // output format
55
        $language = null;  // force language
56
        extract(\is_array($options) ? $options : [], EXTR_IF_EXISTS);
57
58
        // base URL
59
        $base = '';
60
        // enable canonical URL
61
        if ($this->config->isEnabled('canonicalurl') || $canonical === true) {
62
            $base = rtrim((string) $this->config->get('baseurl'), '/');
63
        }
64
        // disable canonical URL by option
65
        if ($canonical === false) {
0 ignored issues
show
introduced by
The condition $canonical === false is always true.
Loading history...
66
            $base = '';
67
        }
68
        // use URL path as base if exists
69
        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
        if (\is_null($value) || empty($value) || $value == '/') {
77
            $this->url = $base;
78
79
            return;
80
        }
81
82
        switch (true) {
83
            case $value instanceof Page: // $value is a Page
84
                /** @var Page $value */
85
                if (!$format) {
86
                    $format = $value->getVariable('output');
87
                    if (\is_array($value->getVariable('output'))) {
88
                        $default = array_search('html', $value->getVariable('output')) ?: 0;
89
                        $format = $value->getVariable('output')[$default];
90
                    }
91
                    if (!$format) {
92
                        $format = 'html';
93
                    }
94
                }
95
                $this->url = $base . '/' . ltrim((new PageRenderer($this->builder, $value))->getPath($format), '/');
96
                if ($canonical && $value->hasVariable('canonical') && $value->getVariable('canonical')['url']) { // canonical URL
97
                    $this->url = $value->getVariable('canonical')['url'];
98
                }
99
                break;
100
            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
            case $value instanceof Asset: // $value is an Asset
109
                /** @var Asset $value */
110
                $value->save(); // be sure Asset file is saved
111
                $this->url = $base . '/' . ltrim($value['path'], '/');
112
                if ($value->isImageInCdn()) {
113
                    $this->url = (string) $value;
114
                }
115
                break;
116
            case \is_string($value): // others cases
117
                /** @var non-falsy-string $value */
118
                // $value is a potential Page ID
119
                $pageId = Page::slugify($value);
120
                // should force language?
121
                $lang = '';
122
                if ($language !== null && $language != $this->config->getLanguageDefault()) {
123
                    $pageId = "$language/$pageId";
124
                    $lang = "$language/";
125
                }
126
                switch (true) {
127
                    case Util\File::isRemote($value): // $value is an external URL
128
                        $this->url = $value;
129
                        break;
130
                    case $this->builder->getPages()->has($pageId): // $pageId exists in pages collection
131
                        $this->url = (string) new self($this->builder, $this->builder->getPages()->get($pageId), $options);
132
                        break;
133
                    default:
134
                        // remove double language prefix
135
                        if ($lang && Util\Str::startsWith($value, $lang)) {
136
                            $value = substr($value, \strlen($lang));
137
                        }
138
                        $this->url = $base . '/' . $lang . ltrim($value, '/');
139
                }
140
        }
141
    }
142
143
    /**
144
     * If called like a string returns built URL.
145
     */
146
    public function __toString(): string
147
    {
148
        return $this->getUrl();
149
    }
150
151
    /**
152
     * Returns built URL.
153
     */
154
    public function getUrl(): string
155
    {
156
        return (string) $this->url ?: '/';
157
    }
158
}
159