Completed
Pull Request — master (#16)
by Sergii
07:37
created

Url   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 0
dl 0
loc 133
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 13 5
A __toString() 0 4 1
A setUrl() 0 11 3
A scheme() 0 16 2
A credentials() 0 12 3
A host() 0 6 1
A components() 0 10 3
1
<?php
2
/**
3
 * @author Sergii Bondarenko, <[email protected]>
4
 */
5
namespace Drupal\TqExtension\Utils;
6
7
/**
8
 * Class Url.
9
 *
10
 * @package Drupal\TqExtension\Utils
11
 */
12
class Url
13
{
14
    /**
15
     * URL to build.
16
     *
17
     * @var string
18
     */
19
    private $url = '';
20
    /**
21
     * URL components.
22
     *
23
     * @var string[]
24
     */
25
    private $components = [];
26
27
    /**
28
     * Url constructor.
29
     *
30
     * @param string $baseUrl
31
     *   Base URL.
32
     * @param string $path
33
     *   Path on a base URL.
34
     */
35
    public function __construct($baseUrl, $path = '')
36
    {
37
        if (empty($baseUrl)) {
38
            throw new \InvalidArgumentException('Set base URL before continue.');
39
        }
40
41
        // Start with base URL when path is empty, or not starts from "//" or "http".
42
        if (empty($path) || strpos($path, '//') !== 0 && strpos($path, 'http') !== 0) {
43
            $path = rtrim($baseUrl, '/') . '/' . trim($path, '/');
44
        }
45
46
        $this->setUrl($path)->scheme()->credentials()->host()->components();
47
    }
48
49
    /**
50
     * @return string
51
     *   Constructed URL.
52
     */
53
    public function __toString()
54
    {
55
        return $this->url;
56
    }
57
58
    /**
59
     * Initialize URL creation.
60
     *
61
     * @param string $url
62
     *
63
     * @return $this
64
     */
65
    private function setUrl($url)
66
    {
67
        $this->url = $url;
68
        $this->components = parse_url(strtolower($this->url));
69
70
        if (false === $this->components || !isset($this->components['host'])) {
71
            throw new \InvalidArgumentException(sprintf('%s - incorrect URL.', $this->url));
72
        }
73
74
        return $this;
75
    }
76
77
    /**
78
     * Append HTTP scheme.
79
     *
80
     * @return $this
81
     */
82
    private function scheme()
83
    {
84
        $this->components += [
85
            // When URL starts from "//" the "scheme" key will not exists.
86
            'scheme' => 'http',
87
        ];
88
89
        // Check scheme.
90
        if (!in_array($this->components['scheme'], ['http', 'https'])) {
91
            throw new \InvalidArgumentException(sprintf('%s - invalid scheme.', $this->components['scheme']));
92
        }
93
94
        $this->url = $this->components['scheme'] . '://';
95
96
        return $this;
97
    }
98
99
    /**
100
     * Append authentication credentials.
101
     *
102
     * @return $this
103
     */
104
    private function credentials()
105
    {
106
        if (isset($this->components['user'], $this->components['pass'])) {
107
            // Encode special characters in username and password. Useful
108
            // when some item contain something like "@" symbol.
109
            foreach (['user' => ':', 'pass' => '@'] as $part => $suffix) {
110
                $this->url .= rawurlencode($this->components[$part]) . $suffix;
111
            }
112
        }
113
114
        return $this;
115
    }
116
117
    /**
118
     * Append host.
119
     *
120
     * @return $this
121
     */
122
    private function host()
123
    {
124
        $this->url .= $this->components['host'];
125
126
        return $this;
127
    }
128
129
    /**
130
     * Append additional URL components.
131
     *
132
     * @return $this
133
     */
134
    private function components()
135
    {
136
        foreach (['port' => ':', 'path' => '', 'query' => '?', 'fragment' => '#'] as $part => $prefix) {
137
            if (isset($this->components[$part])) {
138
                $this->url .= $prefix . $this->components[$part];
139
            }
140
        }
141
142
        return $this;
143
    }
144
}
145