CUrl   A
last analyzed

Complexity

Total Complexity 41

Size/Duplication

Total Lines 293
Duplicated Lines 8.53 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 83.02%

Importance

Changes 0
Metric Value
dl 25
loc 293
ccs 44
cts 53
cp 0.8302
rs 9.1199
c 0
b 0
f 0
wmc 41
lcom 1
cbo 1

11 Methods

Rating   Name   Duplication   Size   Complexity  
A setDefaultsFromConfiguration() 0 21 3
C create() 0 51 16
A createRelative() 13 19 6
B asset() 12 23 8
A setSiteUrl() 0 5 1
A setBaseUrl() 0 5 1
A setStaticSiteUrl() 0 5 1
A setStaticBaseUrl() 0 5 1
A setScriptName() 0 5 1
A setUrlType() 0 9 2
A slugify() 0 8 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like CUrl often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CUrl, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Anax\Url;
4
5
/**
6
 * A helper to create urls.
7
 *
8
 */
9
class CUrl
10
{
11
    use \Anax\TConfigure;
12
13
14
15
    /**
16
     * Properties
17
     *
18
     */
19
    const URL_CLEAN  = 'clean';  // controller/action/param1/param2
20
    const URL_APPEND = 'append'; // index.php/controller/action/param1/param2
21
22
    private $urlType = self::URL_APPEND; // What type of urls to generate
23
24
    private $siteUrl = null; // Siteurl to prepend to all absolute urls created
25
    private $baseUrl = null; // Baseurl to prepend to all relative urls created
26
    private $scriptName = null; // Name of the frontcontroller script
27
28
29
    private $staticSiteUrl = null; // Siteurl to prepend to all absolute urls for assets
30
    private $staticBaseUrl = null; // Baseurl to prepend to all relative urls for assets
31
32
33
34
    /**
35
     * Set default values from configuration.
36
     *
37
     * @return this.
0 ignored issues
show
Documentation introduced by
The doc-type this. could not be parsed: Unknown type name "this." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
38
     */
39 17
    public function setDefaultsFromConfiguration()
40
    {
41 17
        $set = [
42
            "urlType",
43 2
            "siteUrl",
44 2
            "baseUrl",
45 2
            "staticSiteUrl",
46 2
            "staticBaseUrl",
47
            "scriptName",
48 15
        ];
49
        
50 3
        foreach ($set as $item) {
51
            if (!isset($this->config[$item])) {
52 12
                continue;
53
            }
54 4
            
55
            $this->$item = $this->config[$item];
56
        }
57
58 8
        return $this;
59 8
    }
60 4
61
62 4
63
    /**
64
     * Create an url and prepending the baseUrl.
65
     *
66
     * @param string $uri     part of uri to use when creating an url.
67
     *                        "" or null means baseurl to current
68
     *                        frontcontroller.
69
     * @param string $baseuri optional base to prepend uri.
70
     *
71
     * @return string as resulting url.
72
     */
73
    public function create($uri = null, $baseuri = null)
74
    {
75
        if (empty($uri) && empty($baseuri)) {
76
            // Empty uri means baseurl
77
            return $this->baseUrl
78
                . (($this->urlType == self::URL_APPEND)
79
                    ? "/$this->scriptName"
80
                    : null);
81
        } elseif (empty($uri)) {
82
            // Empty uri means baseurl with appended $baseuri
83
            ;
84
        } elseif (substr($uri, 0, 7) == "http://"
85
            || substr($uri, 0, 8) == "https://"
86
            || substr($uri, 0, 2) == "//"
87
        ) {
88
            // Fully qualified, just leave as is.
89
            return $uri;
90
        } elseif ($uri[0] == "/") {
91
            // Absolute url, prepend with siteUrl
92
            //return rtrim($this->siteUrl . rtrim($uri, '/'), '/');
93
            return $this->siteUrl . $uri;
94
        } elseif ($uri[0] == "#"
95
            || $uri[0] == "?"
96
        ) {
97
            // Hashtag url to local page, or query part leave as is.
98
            return $uri;
99
        } elseif (substr($uri, 0, 7) == "mailto:"
100
            || substr(html_entity_decode($uri), 0, 7) == "mailto:") {
101
            // Leave mailto links as is
102
            // The odd fix is for markdown converting mailto: to UTF-8
103
            // Might be a better way to solve this...
104
            return $uri;
105 8
        }
106
107 8
        // Prepend uri with baseuri
108
        $uri = rtrim($uri, "/");
109
        if (!empty($baseuri)) {
110 8
            $uri = rtrim($baseuri, "/") . "/$uri";
111
        }
112 4
113
        // Remove the trailing index part of the url
114 4
        if (basename($uri) == "index") {
115
            $uri = dirname($uri);
116 2
        }
117
118
        if ($this->urlType == self::URL_CLEAN) {
119
            return rtrim($this->baseUrl . "/" . $uri, "/");
120 2
        } else {
121
            return rtrim($this->baseUrl . "/" . $this->scriptName . "/" . $uri, "/");
122 2
        }
123 2
    }
124 2
125
126
127
    /**
128
     * Create an url and prepend the baseUrl to the directory of
129
     * the frontcontroller.
130
     *
131
     * @param string $uri part of uri to use when creating an url.
132
     *                    "" or null means baseurl to directory of
133
     *                    the current frontcontroller.
134
     *
135
     * @return string as resulting url.
136 17
     */
137
    public function createRelative($uri = null)
138 17
    {
139 17 View Code Duplication
        if (empty($uri)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
140
            // Empty uri means baseurl
141
            return $this->baseUrl;
142
        } elseif (substr($uri, 0, 7) == "http://"
143
            || substr($uri, 0, 8) == "https://"
144
            || substr($uri, 0, 2) == "//"
145
        ) {
146
            // Fully qualified, just leave as is.
147
            return rtrim($uri, '/');
148
        } elseif ($uri[0] == '/') {
149
            // Absolute url, prepend with siteUrl
150
            return rtrim($this->siteUrl . rtrim($uri, '/'), '/');
151 18
        }
152
153 18
        $uri = rtrim($uri, '/');
154 18
        return $this->baseUrl . '/' . $uri;
155
    }
156
157
158
159
    /**
160
     * Create an url for a static asset.
161
     *
162
     * @param string $uri part of uri to use when creating an url.
163
     *
164
     * @return string as resulting url.
165
     */
166 4
    public function asset($uri = null)
167
    {
168 4 View Code Duplication
        if (empty($uri)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
169 4
            // Allow empty
170
        } elseif (substr($uri, 0, 7) == "http://"
171
            || substr($uri, 0, 8) == "https://"
172
            || substr($uri, 0, 2) == "//"
173
        ) {
174
            // Fully qualified, just leave as is.
175
            return rtrim($uri, '/');
176
        } elseif ($uri[0] == '/') {
177
            // Absolute url, prepend with staticSiteUrl
178
            return rtrim($this->staticSiteUrl . rtrim($uri, '/'), '/');
179
        }
180
181 4
        $baseUrl = isset($this->staticBaseUrl)
182
            ? $this->staticBaseUrl
183 4
            : $this->baseUrl;
184 4
185
        return empty($uri)
186
            ? $baseUrl
187
            : $baseUrl . '/' . $uri;
188
    }
189
190
191
192
    /**
193
     * Set the siteUrl to prepend all absolute urls created.
194
     *
195
     * @param string $url part of url to use when creating an url.
196 7
     *
197
     * @return $this
198 7
     */
199 7
    public function setSiteUrl($url)
200
    {
201
        $this->siteUrl = rtrim($url, '/');
202
        return $this;
203
    }
204
205
206
207
    /**
208
     * Set the baseUrl to prepend all relative urls created.
209
     *
210
     * @param string $url part of url to use when creating an url.
211 15
     *
212
     * @return $this
213 15
     */
214 1
    public function setBaseUrl($url)
215
    {
216
        $this->baseUrl = rtrim($url, '/');
217 14
        return $this;
218 14
    }
219
220
221
222
    /**
223
     * Set the siteUrl to prepend absolute urls for assets.
224
     *
225
     * @param string $url part of url to use when creating an url.
226
     *
227
     * @return $this
228
     */
229
    public function setStaticSiteUrl($url)
230
    {
231
        $this->staticSiteUrl = rtrim($url, '/');
232
        return $this;
233
    }
234
235
236
237
    /**
238
     * Set the baseUrl to prepend relative urls for assets.
239
     *
240
     * @param string $url part of url to use when creating an url.
241
     *
242
     * @return $this
243
     */
244
    public function setStaticBaseUrl($url)
245
    {
246
        $this->staticBaseUrl = rtrim($url, '/');
247
        return $this;
248
    }
249
250
251
252
    /**
253
     * Set the scriptname to use when creating URL_APPEND urls.
254
     *
255
     * @param string $name as the scriptname, for example index.php.
256
     *
257
     * @return $this
258
     */
259
    public function setScriptName($name)
260
    {
261
        $this->scriptName = $name;
262
        return $this;
263
    }
264
265
266
267
    /**
268
     * Set the type of urls to be generated, URL_CLEAN, URL_APPEND.
269
     *
270
     * @param string $type what type of urls to create.
271
     *
272
     * @return $this
273
     */
274
    public function setUrlType($type)
275
    {
276
        if (!in_array($type, [self::URL_APPEND, self::URL_CLEAN])) {
277
            throw new \Exception("Unsupported Url type.");
278
        }
279
280
        $this->urlType = $type;
281
        return $this;
282
    }
283
284
285
286
    /**
287
     * Create a slug of a string, to be used as url.
288
     *
289
     * @param string $str the string to format as slug.
290
     *
291
     * @return str the formatted slug.
292
     */
293
    public function slugify($str)
294
    {
295
        $str = mb_strtolower(trim($str));
296
        $str = str_replace(array('å','ä','ö'), array('a','a','o'), $str);
297
        $str = preg_replace('/[^a-z0-9-]/', '-', $str);
298
        $str = trim(preg_replace('/-+/', '-', $str), '-');
299
        return $str;
300
    }
301
}
302