GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Link::toString()   F
last analyzed

Complexity

Conditions 35
Paths 221

Size

Total Lines 160

Duplication

Lines 14
Ratio 8.75 %

Importance

Changes 0
Metric Value
cc 35
nc 221
nop 1
dl 14
loc 160
rs 2.4566
c 0
b 0
f 0

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
namespace phpMyFAQ;
4
5
/**
6
 * Link management
7
 *
8
 * This class wrap the needs for managing an HTML anchor
9
 * taking into account also the HTML anchor creation
10
 * with specific handling for mod_rewrite PMF native support
11
 *
12
 * This Source Code Form is subject to the terms of the Mozilla Public License,
13
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
14
 * obtain one at http://mozilla.org/MPL/2.0/.
15
 *
16
 * @package phpMyFAQ
17
 * @author Matteo Scaramuccia <[email protected]>
18
 * @author Thorsten Rinne <[email protected]>
19
 * @copyright 2005-2019 phpMyFAQ Team
20
 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
21
 * @link https://www.phpmyfaq.de
22
 * @since 2005-11-02
23
 */
24
25
if (!defined('IS_VALID_PHPMYFAQ')) {
26
    exit();
27
}
28
29
/**
30
 * Link Class.
31
 *
32
 * @package phpMyFAQ
33
 * @author Matteo Scaramuccia <[email protected]>
34
 * @author Thorsten Rinne <[email protected]>
35
 * @copyright 2005-2019 phpMyFAQ Team
36
 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
37
 * @link https://www.phpmyfaq.de
38
 * @since 2005-11-02
39
 */
40
class Link
41
{
42
    /**
43
     * class constants.
44
     */
45
    const LINK_AMPERSAND = '&amp;';
46
    const LINK_CATEGORY = 'category/';
47
    const LINK_CONTENT = 'content/';
48
    const LINK_EQUAL = '=';
49
    const LINK_FRAGMENT_SEPARATOR = '#';
50
    const LINK_HTML_MINUS = '-';
51
    const LINK_HTML_UNDERSCORE = '_';
52
    const LINK_HTML_SLASH = '/';
53
    const LINK_HTML_TARGET_BLANK = '_blank';
54
    const LINK_HTML_TARGET_PARENT = '_parent';
55
    const LINK_HTML_TARGET_SELF = '_self';
56
    const LINK_HTML_TARGET_TOP = '_top';
57
    const LINK_NEWS = 'news/';
58
    const LINK_SITEMAP = 'sitemap/';
59
    const LINK_SLASH = '/';
60
    const LINK_SEARCHPART_SEPARATOR = '?';
61
    const LINK_TAGS = 'tags/';
62
63
    const LINK_INDEX_ADMIN = '/admin/index.php';
64
    const LINK_INDEX_HOME = '/index.php';
65
66
    const LINK_GET_ACTION = 'action';
67
    const LINK_GET_ARTLANG = 'artlang';
68
    const LINK_GET_CATEGORY = 'cat';
69
    const LINK_GET_HIGHLIGHT = 'highlight';
70
    const LINK_GET_ID = 'id';
71
    const LINK_GET_LANG = 'lang';
72
    const LINK_GET_LETTER = 'letter';
73
    const LINK_GET_NEWS_ID = 'newsid';
74
    const LINK_GET_NEWS_LANG = 'newslang';
75
    const LINK_GET_PAGE = 'seite';
76
    const LINK_GET_SIDS = 'sid';
77
    const LINK_GET_TAGGING_ID = 'tagging_id';
78
    const LINK_GET_LANGS = 'langs';
79
80
    const LINK_GET_ACTION_ADD = 'add';
81
    const LINK_GET_ACTION_FAQ = 'faq';
82
    const LINK_GET_ACTION_ASK = 'ask';
83
    const LINK_GET_ACTION_CONTACT = 'contact';
84
    const LINK_GET_ACTION_GLOSSARY = 'glossary';
85
    const LINK_GET_ACTION_HELP = 'help';
86
    const LINK_GET_ACTION_LOGIN = 'login';
87
    const LINK_GET_ACTION_NEWS = 'news';
88
    const LINK_GET_ACTION_OPEN = 'open';
89
    const LINK_GET_ACTION_PASSWORD = 'password';
90
    const LINK_GET_ACTION_REGISTER = 'register';
91
    const LINK_GET_ACTION_SEARCH = 'search';
92
    const LINK_GET_ACTION_SITEMAP = 'sitemap';
93
    const LINK_GET_ACTION_SHOW = 'show';
94
95
    const LINK_HTML_CATEGORY = 'category';
96
    const LINK_HTML_EXTENSION = '.html';
97
    const LINK_HTML_SITEMAP = 'sitemap';
98
99
    const LINK_HTML_ADDCONTENT = 'addcontent.html';
100
    const LINK_HTML_ASK = 'ask.html';
101
    const LINK_HTML_CONTACT = 'contact.html';
102
    const LINK_HTML_GLOSSARY = 'glossary.html';
103
    const LINK_HTML_HELP = 'help.html';
104
    const LINK_HTML_LOGIN = 'login.html';
105
    const LINK_HTML_OPEN = 'open.html';
106
    const LINK_HTML_PASSWORD = 'password.html';
107
    const LINK_HTML_REGISTER = 'register.html';
108
    const LINK_HTML_SEARCH = 'search.html';
109
    const LINK_HTML_SHOWCAT = 'showcat.html';
110
111
    /**
112
     * URL.
113
     *
114
     * @var string
115
     */
116
    public $url = '';
117
118
    /**
119
     * CSS class.
120
     *
121
     * @var string
122
     */
123
    public $class = '';
124
125
    /**
126
     * Linktext.
127
     *
128
     * @var string
129
     */
130
    public $text = '';
131
132
    /**
133
     * Tooltip.
134
     *
135
     * @var string
136
     */
137
    public $tooltip = '';
138
139
    /**
140
     * Target.
141
     *
142
     * @var string
143
     */
144
    public $target = '';
145
146
    /**
147
     * Name selector.
148
     *
149
     * @var string
150
     */
151
    public $name = '';
152
153
    /**
154
     * property specific to the SEO/SEF URLs.
155
     *
156
     * @var string
157
     */
158
    public $itemTitle = '';
159
160
    /**
161
     * Item property for HTML5 microdata.
162
     *
163
     * @var string
164
     */
165
    protected $itemprop = '';
166
167
    /**
168
     * rel property.
169
     *
170
     * @var string
171
     */
172
    protected $rel = '';
173
174
    /**
175
     * id selector.
176
     *
177
     * @var string
178
     */
179
    public $id = '';
180
181
    /**
182
     * @var Configuration
183
     */
184
    private $config = null;
185
186
    /**
187
     * Constructor.
188
     *
189
     * @param string            $url    URL
190
     * @param Configuration $config
191
     */
192
    public function __construct($url, Configuration $config)
193
    {
194
        $this->url = $url;
195
        $this->config = $config;
196
    }
197
198
    /**
199
     * Checks if webserver is an IIS Server.
200
     *
201
     * @return bool
202
     */
203
    public static function isIISServer()
204
    {
205
        return (isset($_SERVER['ALL_HTTP']) || isset($_SERVER['COMPUTERNAME']) || isset($_SERVER['APP_POOL_ID']));
206
    }
207
208
    /**
209
     * Checks if the the current URL is the main index.php file.
210
     *
211
     * @return bool
212
     */
213
    protected function isHomeIndex()
214
    {
215
        if (!$this->isSystemLink()) {
216
            return false;
217
        }
218
219
        return !(false === strpos($this->url, self::LINK_INDEX_HOME));
220
    }
221
222
    /**
223
     * Checks if URL is an internal reference.
224
     *
225
     * @return bool
226
     */
227
    protected function isInternalReference()
228
    {
229
        if ($this->isRelativeSystemLink()) {
230
            return true;
231
        }
232
        if (false === strpos($this->url, '#')) {
233
            return false;
234
        }
235
236
        return (strpos($this->url, '#') == 0);
237
    }
238
239
    /**
240
     * Checks if URL is a relative system link.
241
     *
242
     * @return bool
243
     */
244
    protected function isRelativeSystemLink()
245
    {
246
        $slashIdx = strpos($this->url, self::LINK_SLASH);
247
        if (false === $slashIdx) {
248
            return false;
249
        }
250
251
        return ($slashIdx == 0);
252
    }
253
254
    /**
255
     * Checks if URL is a system link.
256
     *
257
     * @return bool
258
     */
259
    protected function isSystemLink()
260
    {
261
        // a. Is the url relative, starting with '/'?
262
        // b. Is the url related to the current running PMF system?
263
        if ($this->isRelativeSystemLink()) {
264
            return true;
265
        }
266
        // $_SERVER['HTTP_HOST'] is the name of the website or virtual host name
267
        return !(false === strpos($this->url, $_SERVER['HTTP_HOST']));
268
    }
269
270
    /**
271
     * @param string $itemprop Item property
272
     */
273
    public function setItemProperty($itemprop)
274
    {
275
        $this->itemprop = $itemprop;
276
    }
277
278
    /**
279
     * @param string $rel rel property
280
     */
281
    public function setRelation($rel)
282
    {
283
        $this->rel = $rel;
284
    }
285
286
    /**
287
     * Checks if URL contains a scheme.
288
     *
289
     * @return bool
290
     */
291
    protected function hasScheme()
292
    {
293
        $parsed = parse_url($this->url);
294
295
        return (!empty($parsed['scheme']));
296
    }
297
298
    /**
299
     * Returns a search engine optimized title.
300
     *
301
     * @param string $title
302
     *
303
     * @return string
304
     */
305
    public function getSEOItemTitle($title = '')
306
    {
307
        if ('' === $title) {
308
            $title = $this->itemTitle;
309
        }
310
311
        $itemTitle = trim($title);
312
        // Lower the case (aesthetic)
313
        $itemTitle = Strings::strtolower($itemTitle);
314
        // Use '_' for some other characters for:
315
        // 1. avoiding regexp match break;
316
        // 2. improving the reading.
317
        $itemTitle = str_replace(array('-', "'", '/', '&#39'), '_', $itemTitle);
318
        // 1. Remove any CR LF sequence
319
        // 2. Use a '-' for the words separation
320
        $itemTitle = Strings::preg_replace('/\s/m', '-', $itemTitle);
321
        // Hack: remove some chars for having a better readable title
322
        $itemTitle = str_replace(
323
            array('+', ',', ';', ':', '.', '?', '!', '"', '(', ')', '[', ']', '{', '}', '<', '>', '%'),
324
            '',
325
            $itemTitle
326
        );
327
        // Hack: move some chars to "similar" but plain ASCII chars
328
        $itemTitle = str_replace(
329
            array(
330
                'à', 'è', 'é', 'ì', 'ò', 'ù', 'ä', 'ö', 'ü', 'ß', 'Ä', 'Ö', 'Ü',
331
                'č', 'ę', 'ė', 'į', 'š', 'ų', 'ū', 'ž',
332
                ),
333
            array(
334
                'a', 'e', 'e', 'i', 'o', 'u', 'ae', 'oe', 'ue', 'ss', 'Ae', 'Oe', 'Ue',
335
                'c', 'e', 'e', 'i', 's', 'u', 'u', 'z',
336
            ),
337
            $itemTitle
338
        );
339
        // Clean up
340
        $itemTitle = Strings::preg_replace('/-[\-]+/m', '-', $itemTitle);
341
342
        return $itemTitle;
343
    }
344
345
    /**
346
     * Returns the HTTP GET parameters.
347
     * @return string
348
     */
349
    protected function getHttpGetParameters(): array
350
    {
351
        $query = $this->getQuery();
352
        $parameters = [];
353
354
        if (!empty($query)) {
355
            // Check fragment
356
            if (isset($query['fragment'])) {
357
                $parameters[self::LINK_FRAGMENT_SEPARATOR] = urldecode($query['fragment']);
358
            }
359
360
            // Check if query string contains &amp;
361
            $query['main'] = str_replace('&amp;', '&', $query['main']);
362
363
            $params = explode('&', $query['main']);
364
            foreach ($params as $param) {
365
                if (!empty($param)) {
366
                    $couple = explode(self::LINK_EQUAL, $param);
367
                    list($key, $val) = $couple;
368
                    $parameters[$key] = urldecode($val);
369
                }
370
            }
371
        }
372
373
        return $parameters;
374
    }
375
376
    /**
377
     * Returns the query of an URL.
378
     * @return array
379
     */
380
    protected function getQuery(): array
381
    {
382
        $query = [];
383
384
        if (!empty($this->url)) {
385
            $parsed = parse_url($this->url);
386
387 View Code Duplication
            if (isset($parsed['query'])) {
388
                $query['main'] = filter_var($parsed['query'], FILTER_SANITIZE_STRIPPED);
389
            }
390 View Code Duplication
            if (isset($parsed['fragment'])) {
391
                $query['fragment'] = filter_var($parsed['fragment'], FILTER_SANITIZE_STRIPPED);
392
            }
393
        }
394
395
        return $query;
396
    }
397
398
    /**
399
     * Returns the default scheme.
400
     * @return string
401
     */
402
    protected function getDefaultScheme(): string
403
    {
404
        $scheme = 'http://';
405
        if ($this->isSystemLink()) {
406
            $scheme = $this->getSystemScheme();
407
        }
408
409
        return $scheme;
410
    }
411
412
    /**
413
     * Returns the system scheme, http or https.
414
     * @return string
415
     */
416
    public function getSystemScheme(): string
417
    {
418
        if ($this->config->get('security.useSslOnly')) {
419
            return 'https://';
420
        }
421
422
        if (!self::isIISServer()) {
423
            // Apache, nginx, lighttpd
424
            if (isset($_SERVER['HTTPS']) && 'on' === strtolower($_SERVER['HTTPS'])) {
425
                return 'https://';
426
            } else {
427
                return 'http://';
428
            }
429
        } else {
430
            // IIS Server
431
            if ('on' === strtolower($_SERVER['HTTPS'])) {
432
                return 'https://';
433
            } else {
434
                return 'http://';
435
            }
436
        }
437
    }
438
439
    /**
440
     * Returns the relative URI.
441
     * @param string $path
442
     * @return string
443
     */
444
    public static function getSystemRelativeUri(string $path = null): string
445
    {
446
        if (isset($path)) {
447
            return str_replace($path, '', $_SERVER['SCRIPT_NAME']);
448
        }
449
450
        return str_replace('/src/Link.php', '', $_SERVER['SCRIPT_NAME']);
451
    }
452
453
    /**
454
     * Returns the system URI.
455
     *
456
     * $_SERVER['HTTP_HOST'] is the name of the website or virtual host name (HTTP/1.1)
457
     * Precisely, it contains what the user has written in the Host request-header, see below.
458
     * RFC 2616: The Host request-header field specifies the Internet host and port number of the resource
459
     *           being requested, as obtained from the original URI given by the user or referring resource
460
     *
461
     * @param string $path
462
     * @return string
463
     */
464
    public function getSystemUri($path = null): string
465
    {
466
        // Remove any ref to standard ports 80 and 443.
467
        $pattern[0] = '/:80$/'; // HTTP: port 80
468
        $pattern[1] = '/:443$/'; // HTTPS: port 443
469
        $sysUri = $this->getSystemScheme().preg_replace($pattern, '', $_SERVER['HTTP_HOST']);
470
471
        return $sysUri.self::getSystemRelativeUri($path);
472
    }
473
474
    /**
475
     * Builds a HTML anchor.
476
     * @return string
477
     */
478
    public function toHtmlAnchor():string
479
    {
480
        // Sanitize the provided url
481
        $url = $this->toString();
482
        // Prepare HTML anchor element
483
        $htmlAnchor = '<a';
484
        if (!empty($this->class)) {
485
            $htmlAnchor .= sprintf(' class="%s"', $this->class);
486
        }
487
        if (!empty($this->id)) {
488
            $htmlAnchor .= ' id="'.$this->id.'"';
489
        }
490
        if (!empty($this->tooltip)) {
491
            $htmlAnchor .= sprintf(' title="%s"', addslashes($this->tooltip));
492
        }
493
        if (!empty($this->name)) {
494
            $htmlAnchor .= sprintf(' name="%s"', $this->name);
495
        } else {
496
            if (!empty($this->url)) {
497
                $htmlAnchor .= sprintf(' href="%s"', $url);
498
            }
499
            if (!empty($this->target)) {
500
                $htmlAnchor .= sprintf(' target="%s"', $this->target);
501
            }
502
        }
503
        if (!empty($this->itemprop)) {
504
            $htmlAnchor .= sprintf(' itemprop="%s"', $this->itemprop);
505
        }
506
        if (!empty($this->rel)) {
507
            $htmlAnchor .= sprintf(' rel="%s"', $this->rel);
508
        }
509
        $htmlAnchor .= '>';
510
        if (('0' == $this->text) || (!empty($this->text))) {
511
            $htmlAnchor .= $this->text;
512
        } else {
513
            if (!empty($this->name)) {
514
                $htmlAnchor .= $this->name;
515
            } else {
516
                $htmlAnchor .= $url;
517
            }
518
        }
519
        $htmlAnchor .= '</a>';
520
521
        return $htmlAnchor;
522
    }
523
524
    /**
525
     * Appends the session id.
526
     * @param string $url  URL
527
     * @param int    $sids Session Id
528
     * @return string
529
     */
530
    protected function appendSids(string $url, int $sids): string
531
    {
532
        $separator = (false === strpos($url, self::LINK_SEARCHPART_SEPARATOR))
533
                     ?
534
                     self::LINK_SEARCHPART_SEPARATOR
535
                     :
536
                     self::LINK_AMPERSAND;
537
538
        return $url.$separator.self::LINK_GET_SIDS.self::LINK_EQUAL.$sids;
539
    }
540
541
    /**
542
     * Rewrites a URL string. Checks mod_rewrite support and 'rewrite'
543
     * the passed (system) uri according to the rewrite rules written
544
     * in .htaccess
545
     * @param bool $removeSessionFromUrl Remove session from URL
546
     * @return string
547
     */
548
    public function toString(bool $removeSessionFromUrl = false): string
549
    {
550
        $url = $this->toUri();
551
        if ($this->config->get('main.enableRewriteRules')) {
552
            if ($this->isHomeIndex()) {
553
                $getParams = $this->getHttpGetParameters();
554
                if (isset($getParams[self::LINK_GET_ACTION])) {
555
556
                    // Get the part of the url 'till the '/' just before the pattern
557
                    $url = substr($url, 0, strpos($url, self::LINK_INDEX_HOME) + 1);
558
559
                    // Build the Url according to .htaccess rules
560
                    switch ($getParams[self::LINK_GET_ACTION]) {
561
562
                        case self::LINK_GET_ACTION_ADD:
563
                            $url .= self::LINK_HTML_ADDCONTENT;
564
                            break;
565
566
                        case self::LINK_GET_ACTION_FAQ:
567
                            $url .= self::LINK_CONTENT.
568
                                    $getParams[self::LINK_GET_CATEGORY].
569
                                    self::LINK_HTML_SLASH.
570
                                    $getParams[self::LINK_GET_ID].
571
                                    self::LINK_HTML_SLASH.
572
                                    $getParams[self::LINK_GET_ARTLANG].
573
                                    self::LINK_SLASH.
574
                                    $this->getSEOItemTitle().
575
                                    self::LINK_HTML_EXTENSION;
576 View Code Duplication
                            if (isset($getParams[self::LINK_GET_HIGHLIGHT])) {
577
                                $url .= self::LINK_SEARCHPART_SEPARATOR.
578
                                        self::LINK_GET_HIGHLIGHT.'='.
579
                                        $getParams[self::LINK_GET_HIGHLIGHT];
580
                            }
581
                            if (isset($getParams[self::LINK_FRAGMENT_SEPARATOR])) {
582
                                $url .= self::LINK_FRAGMENT_SEPARATOR.
583
                                        $getParams[self::LINK_FRAGMENT_SEPARATOR];
584
                            }
585
                            break;
586
587
                        case self::LINK_GET_ACTION_ASK:
588
                            $url .= self::LINK_HTML_ASK;
589
                            break;
590
591
                        case self::LINK_GET_ACTION_CONTACT:
592
                            $url .= self::LINK_HTML_CONTACT;
593
                            break;
594
595
                        case self::LINK_GET_ACTION_GLOSSARY:
596
                            $url .= self::LINK_HTML_GLOSSARY;
597
                            break;
598
599
                        case self::LINK_GET_ACTION_HELP:
600
                            $url .= self::LINK_HTML_HELP;
601
                            break;
602
603
                        case self::LINK_GET_ACTION_OPEN:
604
                            $url .= self::LINK_HTML_OPEN;
605
                            break;
606
607
                        case self::LINK_GET_ACTION_SEARCH:
608
                            if (!isset($getParams[self::LINK_GET_ACTION_SEARCH]) &&
609
                                isset($getParams[self::LINK_GET_TAGGING_ID])) {
610
                                $url .= self::LINK_TAGS.$getParams[self::LINK_GET_TAGGING_ID];
611
                                if (isset($getParams[self::LINK_GET_PAGE])) {
612
                                    $url .= self::LINK_HTML_SLASH.$getParams[self::LINK_GET_PAGE];
613
                                }
614
                                $url .= self::LINK_SLASH.
615
                                        $this->getSEOItemTitle().
616
                                        self::LINK_HTML_EXTENSION;
617
                            } elseif (isset($getParams[self::LINK_GET_ACTION_SEARCH])) {
618
                                $url .= self::LINK_HTML_SEARCH;
619
                                $url .= self::LINK_SEARCHPART_SEPARATOR.
620
                                        self::LINK_GET_ACTION_SEARCH.'='.
621
                                        $getParams[self::LINK_GET_ACTION_SEARCH];
622 View Code Duplication
                                if (isset($getParams[self::LINK_GET_PAGE])) {
623
                                    $url .= self::LINK_AMPERSAND.self::LINK_GET_PAGE.'='.
624
                                            $getParams[self::LINK_GET_PAGE];
625
                                }
626
                            }
627 View Code Duplication
                            if (isset($getParams[self::LINK_GET_LANGS])) {
628
                                $url .= self::LINK_AMPERSAND.
629
                                        self::LINK_GET_LANGS.'='.
630
                                        $getParams[self::LINK_GET_LANGS];
631
                            }
632
                            break;
633
634
                        case self::LINK_GET_ACTION_SITEMAP:
635
                            if (isset($getParams[self::LINK_GET_LETTER])) {
636
                                $url .= self::LINK_SITEMAP.
637
                                        $getParams[self::LINK_GET_LETTER].
638
                                        self::LINK_HTML_SLASH.
639
                                        $getParams[self::LINK_GET_LANG].
640
                                        self::LINK_HTML_EXTENSION;
641
                            } else {
642
                                $url .= self::LINK_SITEMAP.'A'.
643
                                        self::LINK_HTML_SLASH.
644
                                        $getParams[self::LINK_GET_LANG].
645
                                        self::LINK_HTML_EXTENSION;
646
                            }
647
                            break;
648
649
                        case self::LINK_GET_ACTION_SHOW:
650
                            if (!isset($getParams[self::LINK_GET_CATEGORY]) ||
651
                                (isset($getParams[self::LINK_GET_CATEGORY]) &&
652
                                (0 == $getParams[self::LINK_GET_CATEGORY]))) {
653
                                $url .= self::LINK_HTML_SHOWCAT;
654
                            } else {
655
                                $url .= self::LINK_CATEGORY.
656
                                        $getParams[self::LINK_GET_CATEGORY];
657
                                if (isset($getParams[self::LINK_GET_PAGE])) {
658
                                    $url .= self::LINK_HTML_SLASH.
659
                                            $getParams[self::LINK_GET_PAGE];
660
                                }
661
                                $url .= self::LINK_HTML_SLASH.
662
                                        $this->getSEOItemTitle().
663
                                        self::LINK_HTML_EXTENSION;
664
                            }
665
                            break;
666
667
                        case self::LINK_GET_ACTION_NEWS:
668
                            $url .= self::LINK_NEWS.
669
                                    $getParams[self::LINK_GET_NEWS_ID].
670
                                    self::LINK_HTML_SLASH.
671
                                    $getParams[self::LINK_GET_NEWS_LANG].
672
                                    self::LINK_SLASH.
673
                                    $this->getSEOItemTitle().
674
                                    self::LINK_HTML_EXTENSION;
675
                            break;
676
                    }
677
678
                    if (isset($getParams[self::LINK_GET_SIDS])) {
679
                        $url = $this->appendSids($url, $getParams[self::LINK_GET_SIDS]);
680
                    }
681
682
                    if (isset($getParams['fragment'])) {
683
                        $url .= self::LINK_FRAGMENT_SEPARATOR.$getParams['fragment'];
684
                    }
685
686
                    if ($removeSessionFromUrl) {
687
                        $url = strtok($url, '?');
688
                    }
689
                }
690
            }
691
        } else {
692
            if ($removeSessionFromUrl) {
693
                $getParams = $this->getHttpGetParameters();
694
                if (isset($getParams[self::LINK_GET_ACTION])) {
695
                    $url = substr($url, 0, strpos($url, self::LINK_INDEX_HOME) + 1).'index.php?';
696
                    foreach ($getParams as $key => $value) {
697
                        if ($key !== self::LINK_GET_SIDS) {
698
                            $url .= sprintf('%s=%s&', $key, $value);
699
                        }
700
                    }
701
                    $url = substr($url, 0, -1); // Remove last &
702
                }
703
            }
704
        }
705
706
        return $url;
707
    }
708
709
    /**
710
     * Transforms a URI.
711
     * @return string
712
     */
713
    public function toUri(): string 
714
    {
715
        $url = $this->url;
716
        if (!empty($this->url)) {
717
            if ((!$this->hasScheme()) && (!$this->isInternalReference())) {
718
                $url = $this->getDefaultScheme().$this->url;
719
            }
720
        }
721
722
        return $url;
723
    }
724
725
    /**
726
     * Returns the current URL.
727
     * @return string
728
     */
729
    public function getCurrentUrl(): string
730
    {
731
        return $this->config->getDefaultUrl().Strings::htmlspecialchars(substr($_SERVER['REQUEST_URI'], 1));
732
    }
733
734
    /**
735
     * Static method to generate simple HTML anchors.
736
     * @static
737
     * @param string $url    URL
738
     * @param string $text   Text
739
     * @param bool   $active Add CSS class named "active"?
740
     * @return string
741
     */
742
    public static function renderNavigationLink(string $url, string $text, bool $active = false): string
743
    {
744
        return printf(
745
            '<a %s href="%s">%s</a>',
746
            (true === $active ? 'class="active"' : ''),
747
            $url,
748
            $text
749
        );
750
    }
751
}
752