Issues (1783)

src/helpers/UrlHelper.php (37 issues)

1
<?php
2
/**
3
 * Retour plugin for Craft CMS
4
 *
5
 * Retour allows you to intelligently redirect legacy URLs, so that you don't
6
 * lose SEO value when rebuilding & restructuring a website
7
 *
8
 * @link      https://nystudio107.com/
0 ignored issues
show
The tag in position 1 should be the @copyright tag
Loading history...
9
 * @copyright Copyright (c) 2020 nystudio107
0 ignored issues
show
@copyright tag must contain a year and the name of the copyright holder
Loading history...
10
 */
0 ignored issues
show
PHP version not specified
Loading history...
Missing @category tag in file comment
Loading history...
Missing @package tag in file comment
Loading history...
Missing @author tag in file comment
Loading history...
Missing @license tag in file comment
Loading history...
11
12
namespace nystudio107\retour\helpers;
13
14
use Craft;
15
use craft\errors\SiteNotFoundException;
16
use craft\helpers\UrlHelper as CraftUrlHelper;
17
18
/**
0 ignored issues
show
Missing short description in doc comment
Loading history...
19
 * @author    nystudio107
0 ignored issues
show
The tag in position 1 should be the @package tag
Loading history...
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
20
 * @package   Retour
0 ignored issues
show
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
21
 * @since     3.1.34
0 ignored issues
show
The tag in position 3 should be the @author tag
Loading history...
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
22
 */
0 ignored issues
show
Missing @category tag in class comment
Loading history...
Missing @license tag in class comment
Loading history...
Missing @link tag in class comment
Loading history...
23
class UrlHelper extends CraftUrlHelper
24
{
25
    // Public Static Methods
26
    // =========================================================================
27
28
    /**
29
     * Returns a query string that is a combination of al of the query strings from
30
     * the passed in $urls
31
     *
32
     * @param ...$urls
0 ignored issues
show
Missing parameter comment
Loading history...
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
33
     * @return string
0 ignored issues
show
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
34
     */
35
    public static function combineQueryStringsFromUrls(...$urls): string
36
    {
37
        $queryParams = [];
38
        foreach ($urls as $url) {
39
            $parsedUrl = parse_url($url);
40
            $params = [];
41
            parse_str($parsedUrl['query'] ?? '', $params);
42
            $queryParams[] = $params;
43
        }
44
        $queryParams = array_unique(array_merge([], ...$queryParams), SORT_REGULAR);
45
46
        return http_build_query($queryParams);
47
    }
48
49
    /**
50
     * Strip out any site-defined sub-path from the incoming $path
51
     * e.g. if the Site's baseUrl is set to https://example.com/es and $path is /es/blog
52
     * this function will return /blog
53
     *
54
     * @param string $path
0 ignored issues
show
Missing parameter comment
Loading history...
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
55
     * @return string
0 ignored issues
show
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
56
     */
57
    public static function stripSitePathPrefix(string $path): string
58
    {
59
        try {
60
            $baseSiteUrl = self::baseSiteUrl();
61
        } catch (SiteNotFoundException $e) {
62
            $baseSiteUrl = '';
63
        }
64
        $sitePath = parse_url($baseSiteUrl, PHP_URL_PATH);
65
        $addSlash = str_ends_with($path, '/');
66
        if (!empty($sitePath)) {
67
            // Normalizes a URI path by trimming leading/ trailing slashes and removing double slashes
68
            $sitePath = '/' . preg_replace('/\/\/+/', '/', trim($sitePath, '/'));
69
        }
70
        // Strip the $sitePath from the incoming $path
71
        if (str_starts_with($path, $sitePath)) {
72
            $path = substr($path, strlen($sitePath));
73
            $path = '/' . preg_replace('/\/\/+/', '/', trim($path, '/'));
74
        }
75
        $path = $addSlash ? $path . '/' : $path;
76
77
        return $path;
78
    }
79
80
    /**
81
     * See if the path includes a site prefix for any site
82
     *
83
     * @param string $path
0 ignored issues
show
Missing parameter comment
Loading history...
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
84
     * @return bool
0 ignored issues
show
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
85
     */
86
    public static function pathHasSitePrefix(string $path): bool
87
    {
88
        $sites = Craft::$app->getSites()->getAllSites();
89
        foreach ($sites as $site) {
90
            $sitePath = parse_url($site->baseUrl, PHP_URL_PATH);
91
            if (!empty($sitePath)) {
92
                // Normalizes a URI path by trimming leading/ trailing slashes and removing double slashes
93
                $sitePath = '/' . preg_replace('/\/\/+/', '/', trim($sitePath, '/'));
94
            }
95
            // See if the path begins with a site path prefix
96
            if ($sitePath !== '/' && str_starts_with($path, $sitePath)) {
97
                return true;
98
            }
99
        }
100
101
        return false;
102
    }
103
104
    /**
105
     * Merge the $url and $path together, combining any overlapping path segments
106
     *
107
     * @param ?string $url
0 ignored issues
show
Missing parameter comment
Loading history...
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
108
     * @param ?string $path
0 ignored issues
show
Missing parameter comment
Loading history...
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
109
     * @return string
0 ignored issues
show
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
110
     */
111
    public static function mergeUrlWithPath(?string $url, ?string $path): string
112
    {
113
        $overlap = 0;
114
        $url = $url ?? '';
115
        $path = $path ?? '';
116
        $url = rtrim($url, '/') . '/';
117
        $path = '/' . ltrim($path, '/');
118
        $urlOffset = strlen($url);
119
        $pathLength = strlen($path);
120
        $pathOffset = 0;
121
        while ($urlOffset > 0 && $pathOffset < $pathLength) {
122
            $urlOffset--;
123
            $pathOffset++;
124
            if (str_starts_with($path, substr($url, $urlOffset, $pathOffset))) {
125
                $overlap = $pathOffset;
126
            }
127
        }
128
129
        return rtrim($url, '/') . '/' . ltrim(substr($path, $overlap), '/');
130
    }
131
132
    /**
133
     * Return a sanitized URL
134
     *
135
     * @param string $url
0 ignored issues
show
Missing parameter comment
Loading history...
136
     *
137
     * @return string
138
     */
139
    public static function sanitizeUrl(string $url): string
140
    {
141
        // HTML decode the entities, then strip out any tags
142
        $url = html_entity_decode($url, ENT_NOQUOTES, 'UTF-8');
143
        $url = urldecode($url);
144
        $url = strip_tags($url);
145
        // Remove any Twig tags that somehow are present in the incoming URL
146
        /** @noinspection CallableParameterUseCaseInTypeContextInspection */
0 ignored issues
show
The open comment tag must be the only content on the line
Loading history...
Missing short description in doc comment
Loading history...
The close comment tag must be the only content on the line
Loading history...
147
        $url = preg_replace('/{.*}/', '', $url);
148
        // Remove any linebreaks that may be errantly in the URL
149
        $url = (string)str_replace([
0 ignored issues
show
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
150
                PHP_EOL,
151
                "\r",
152
                "\n",
153
            ]
154
            , '', $url
0 ignored issues
show
Space found before comma in argument list
Loading history...
155
        );
156
157
        return $url;
158
    }
159
}
160