Passed
Push — master ( 6bcf36...3d467e )
by Arnaud
05:58
created

Url::__construct()   F

Complexity

Conditions 30
Paths 288

Size

Total Lines 92
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 48
CRAP Score 33.5431

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
ccs 48
cts 57
cp 0.8421
crap 33.5431
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
                $value->save(); // be sure Asset file is saved
111 1
                $this->url = $base . '/' . ltrim($value['path'], '/');
112 1
                if ($value->isImageInCdn()) {
113
                    $this->url = (string) $value;
114
                }
115 1
                break;
116 1
            case \is_string($value): // others cases
117
                /** @var non-falsy-string $value */
118
                // $value is a potential Page ID
119 1
                $pageId = Page::slugify($value);
120
                // should force language?
121 1
                $lang = '';
122 1
                if ($language !== null && $language != $this->config->getLanguageDefault()) {
123 1
                    $pageId = "$language/$pageId";
124 1
                    $lang = "$language/";
125
                }
126
                switch (true) {
127 1
                    case Util\File::isRemote($value): // $value is an external URL
128 1
                        $this->url = $value;
129 1
                        break;
130 1
                    case $this->builder->getPages()->has($pageId): // $pageId exists in pages collection
131 1
                        $this->url = (string) new self($this->builder, $this->builder->getPages()->get($pageId), $options);
132 1
                        break;
133
                    default:
134
                        // remove double language prefix
135 1
                        if ($lang && Util\Str::startsWith($value, $lang)) {
136 1
                            $value = substr($value, \strlen($lang));
137
                        }
138 1
                        $this->url = $base . '/' . $lang . ltrim($value, '/');
139
                }
140
        }
141
    }
142
143
    /**
144
     * If called like a string returns built URL.
145
     */
146 1
    public function __toString(): string
147
    {
148 1
        return $this->getUrl();
149
    }
150
151
    /**
152
     * Returns built URL.
153
     */
154 1
    public function getUrl(): string
155
    {
156 1
        return (string) $this->url ?: '/';
157
    }
158
}
159