Url::__construct()   F
last analyzed

Complexity

Conditions 31
Paths 576

Size

Total Lines 94
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 34.5925

Importance

Changes 9
Bugs 7 Features 0
Metric Value
cc 31
eloc 60
c 9
b 7
f 0
nc 576
nop 3
dl 0
loc 94
ccs 49
cts 58
cp 0.8448
crap 34.5925
rs 0.5888

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