Passed
Pull Request — v3 (#685)
by Timothy
16:12
created

UrlHelper::siteUrl()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 4
eloc 11
c 3
b 0
f 0
nc 3
nop 4
dl 0
loc 19
ccs 0
cts 12
cp 0
crap 20
rs 9.9
1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS 3.x
4
 *
5
 * A turnkey SEO implementation for Craft CMS that is comprehensive, powerful,
6
 * and flexible
7
 *
8
 * @link      https://nystudio107.com
9
 * @copyright Copyright (c) 2017 nystudio107
10
 */
11
12
namespace nystudio107\seomatic\helpers;
13
14
use nystudio107\seomatic\Seomatic;
15
16
use Craft;
17
use craft\errors\SiteNotFoundException;
18
use craft\helpers\UrlHelper as CraftUrlHelper;
19
20
use yii\base\Exception;
21
22
/**
23
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
24
 * @package   Seomatic
25
 * @since     3.0.0
26
 */
27
class UrlHelper extends CraftUrlHelper
28
{
29
    // Public Static Properties
30
    // =========================================================================
31
32
    // Public Static Methods
33
    // =========================================================================
34
35
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $path should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $params should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $scheme should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $siteId should have a doc-comment as per coding-style.
Loading history...
36
     * @inheritDoc
37
     */
38
    public static function siteUrl(string $path = '', $params = null, string $scheme = null, int $siteId = null): string
39
    {
40
        $siteUrl = Seomatic::$settings->siteUrlOverride;
41
        if (!empty($siteUrl)) {
42
            $siteUrl = MetaValue::parseString($siteUrl);
43
            // Extract out just the path part
44
            $parts = self::decomposeUrl($path);
45
            $path = $parts['path'].$parts['suffix'];
46
            $url = rtrim($siteUrl, '/').'/'.ltrim($path, '/');
47
            // Handle trailing slashes properly for generated URLs
48
            $generalConfig = Craft::$app->getConfig()->getGeneral();
49
            if ($generalConfig->addTrailingSlashesToUrls && !preg_match('/\.[^\/]+$/', $url)) {
50
                $url = rtrim($url, '/') . '/';
51
            }
52
53
            return $url;
54
        }
55
56
        return parent::siteUrl($path, $params, $scheme, $siteId);
57
    }
58
59
    /**
60
     * Return the page trigger and the value of the page trigger (null if it doesn't exist)
61
     *
62
     * @return array
63
     */
64
    public static function pageTriggerValue(): array
65
    {
66
        $pageTrigger = Craft::$app->getConfig()->getGeneral()->pageTrigger;
67
        if (!\is_string($pageTrigger) || $pageTrigger === '') {
0 ignored issues
show
introduced by
The condition is_string($pageTrigger) is always true.
Loading history...
68
            $pageTrigger = 'p';
69
        }
70
        // Is this query string-based pagination?
71
        if ($pageTrigger[0] === '?') {
72
            $pageTrigger = trim($pageTrigger, '?=');
73
        }
74
        // Avoid conflict with the path param
75
        $pathParam = Craft::$app->getConfig()->getGeneral()->pathParam;
76
        if ($pageTrigger === $pathParam) {
77
            $pageTrigger = $pathParam === 'p' ? 'pg' : 'p';
78
        }
79
        $pageTriggerValue = Craft::$app->getRequest()->getParam($pageTrigger);
80
81
        return [$pageTrigger, $pageTriggerValue];
82
    }
83
84
    /**
85
     * Return an absolute URL with protocol that curl will be happy with
86
     *
87
     * @param string $url
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
88
     *
89
     * @return string
90
     */
91
    public static function absoluteUrlWithProtocol($url): string
92
    {
93
        // Make this a full URL
94
        if (!self::isAbsoluteUrl($url)) {
95
            $protocol = 'http';
96
            if (isset($_SERVER['HTTPS']) && (strcasecmp($_SERVER['HTTPS'], 'on') === 0 || $_SERVER['HTTPS'] == 1)
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (IssetNode && strcasecmp...PROTO'], 'https') === 0, Probably Intended Meaning: IssetNode && (strcasecmp...ROTO'], 'https') === 0)
Loading history...
97
                || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strcasecmp($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') === 0
98
            ) {
99
                $protocol = 'https';
100
            }
101
            if (self::isProtocolRelativeUrl($url)) {
102
                try {
103
                    $url = self::urlWithScheme($url, $protocol);
104
                } catch (SiteNotFoundException $e) {
105
                    Craft::error($e->getMessage(), __METHOD__);
106
                }
107
            } else {
108
                try {
109
                    $url = self::siteUrl($url, null, $protocol);
110
                    if (self::isProtocolRelativeUrl($url)) {
111
                        $url = self::urlWithScheme($url, $protocol);
112
                    }
113
                } catch (Exception $e) {
114
                    Craft::error($e->getMessage(), __METHOD__);
115
                }
116
            }
117
        }
118
        // Ensure that any spaces in the URL are encoded
119
        $url = str_replace(' ', '%20', $url);
120
121
        // Handle trailing slashes properly for generated URLs
122
        $generalConfig = Craft::$app->getConfig()->getGeneral();
123
        if ($generalConfig->addTrailingSlashesToUrls && !preg_match('/\.[^\/]+$/', $url)) {
124
            $url = rtrim($url, '/') . '/';
125
        }
126
127
        return $url;
128
    }
129
130
    // Protected Methods
131
    // =========================================================================
132
133
    /**
134
     * Decompose a url into a prefix, path, and suffix
135
     *
136
     * @param $pathOrUrl
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
137
     *
138
     * @return array
139
     */
140
    protected static function decomposeUrl($pathOrUrl): array
141
    {
142
        $result = array();
143
144
        if (filter_var($pathOrUrl, FILTER_VALIDATE_URL)) {
145
            $url_parts = parse_url($pathOrUrl);
146
            $result['prefix'] = $url_parts['scheme'] . '://' . $url_parts['host'];
147
            $result['path'] = $url_parts['path'];
148
            $result['suffix'] = '';
149
            $result['suffix'] .= empty($url_parts['query']) ? '' : '?' . $url_parts['query'];
150
            $result['suffix'] .= empty($url_parts['fragment']) ? '' : '#' . $url_parts['fragment'];
151
        } else {
152
            $result['prefix'] = '';
153
            $result['path'] = $pathOrUrl;
154
            $result['suffix'] = '';
155
        }
156
157
        return $result;
158
    }
159
}
160