PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.1
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.1
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / helpers / url-helper.php

url-helper.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.1, at src/helpers/url-helper.php

217 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Helpers;
4
5 use Yoast\WP\SEO\Models\SEO_Links;
6
7 /**
8 * A helper object for URLs.
9 */
10 class Url_Helper {
11
12 /**
13 * Retrieve home URL with proper trailing slash.
14 *
15 * @param string $path Path relative to home URL.
16 * @param string|null $scheme Scheme to apply.
17 *
18 * @return string Home URL with optional path, appropriately slashed if not.
19 */
20 public function home( $path = '', $scheme = null ) {
21 $home_url = \home_url( $path, $scheme );
22
23 if ( ! empty( $path ) ) {
24 return $home_url;
25 }
26
27 $home_path = \wp_parse_url( $home_url, \PHP_URL_PATH );
28
29 if ( $home_path === '/' ) { // Home at site root, already slashed.
30 return $home_url;
31 }
32
33 if ( \is_null( $home_path ) ) { // Home at site root, always slash.
34 return \trailingslashit( $home_url );
35 }
36
37 if ( \is_string( $home_path ) ) { // Home in subdirectory, slash if permalink structure has slash.
38 return \user_trailingslashit( $home_url );
39 }
40
41 return $home_url;
42 }
43
44 /**
45 * Determines whether the plugin is active for the entire network.
46 *
47 * @return bool Whether or not the plugin is network-active.
48 */
49 public function is_plugin_network_active() {
50 static $network_active = null;
51
52 if ( ! \is_multisite() ) {
53 return false;
54 }
55
56 // If a cached result is available, bail early.
57 if ( $network_active !== null ) {
58 return $network_active;
59 }
60
61 $network_active_plugins = \wp_get_active_network_plugins();
62
63 // Consider MU plugins and network-activated plugins as network-active.
64 $network_active = \strpos( \wp_normalize_path( \WPSEO_FILE ), \wp_normalize_path( \WPMU_PLUGIN_DIR ) ) === 0
65 || \in_array( \WP_PLUGIN_DIR . '/' . \WPSEO_BASENAME, $network_active_plugins, true );
66
67 return $network_active;
68 }
69
70 /**
71 * Retrieve network home URL if plugin is network-activated, or home url otherwise.
72 *
73 * @return string Home URL with optional path, appropriately slashed if not.
74 */
75 public function network_safe_home_url() {
76 /**
77 * Action: 'wpseo_home_url' - Allows overriding of the home URL.
78 */
79 \do_action( 'wpseo_home_url' );
80
81 // If the plugin is network-activated, use the network home URL.
82 if ( self::is_plugin_network_active() ) {
83 return \network_home_url();
84 }
85
86 return \home_url();
87 }
88
89 /**
90 * Check whether a url is relative.
91 *
92 * @param string $url URL string to check.
93 *
94 * @return bool True when url is relative.
95 */
96 public function is_relative( $url ) {
97 return ( \strpos( $url, 'http' ) !== 0 && \strpos( $url, '//' ) !== 0 );
98 }
99
100 /**
101 * Gets the path from the passed URL.
102 *
103 * @codeCoverageIgnore It only wraps a WordPress function.
104 *
105 * @param string $url The URL to get the path from.
106 *
107 * @return string The path of the URL. Returns an empty string if URL parsing fails.
108 */
109 public function get_url_path( $url ) {
110 return (string) \wp_parse_url( $url, \PHP_URL_PATH );
111 }
112
113 /**
114 * Determines the file extension of the given url.
115 *
116 * @param string $url The URL.
117 *
118 * @return string The extension.
119 */
120 public function get_extension_from_url( $url ) {
121 $path = $this->get_url_path( $url );
122
123 if ( $path === '' ) {
124 return '';
125 }
126
127 $parts = \explode( '.', $path );
128 if ( empty( $parts ) || \count( $parts ) === 1 ) {
129 return '';
130 }
131
132 return \end( $parts );
133 }
134
135 /**
136 * Ensures that the given url is an absolute url.
137 *
138 * @param string $url The url that needs to be absolute.
139 *
140 * @return string The absolute url.
141 */
142 public function ensure_absolute_url( $url ) {
143 if ( ! \is_string( $url ) || $url === '' ) {
144 return $url;
145 }
146
147 if ( $this->is_relative( $url ) === true ) {
148 return $this->build_absolute_url( $url );
149 }
150
151 return $url;
152 }
153
154 /**
155 * Parse the home URL setting to find the base URL for relative URLs.
156 *
157 * @param string|null $path Optional path string.
158 *
159 * @return string
160 */
161 public function build_absolute_url( $path = null ) {
162 $path = \wp_parse_url( $path, \PHP_URL_PATH );
163 $url_parts = \wp_parse_url( \home_url() );
164
165 $base_url = \trailingslashit( $url_parts['scheme'] . '://' . $url_parts['host'] );
166
167 if ( ! \is_null( $path ) ) {
168 $base_url .= \ltrim( $path, '/' );
169 }
170
171 return $base_url;
172 }
173
174 /**
175 * Returns the link type.
176 *
177 * @param array $url The URL, as parsed by wp_parse_url.
178 * @param array|null $home_url Optional. The home URL, as parsed by wp_parse_url. Used to avoid reparsing the home_url.
179 * @param bool $is_image Whether or not the link is an image.
180 *
181 * @return string The link type.
182 */
183 public function get_link_type( $url, $home_url = null, $is_image = false ) {
184 // If there is no scheme and no host the link is always internal.
185 // Beware, checking just the scheme isn't enough as a link can be //yoast.com for instance.
186 if ( empty( $url['scheme'] ) && empty( $url['host'] ) ) {
187 return ( $is_image ) ? SEO_Links::TYPE_INTERNAL_IMAGE : SEO_Links::TYPE_INTERNAL;
188 }
189
190 // If there is a scheme but it's not http(s) then the link is always external.
191 if ( \array_key_exists( 'scheme', $url ) && ! \in_array( $url['scheme'], [ 'http', 'https' ], true ) ) {
192 return ( $is_image ) ? SEO_Links::TYPE_EXTERNAL_IMAGE : SEO_Links::TYPE_EXTERNAL;
193 }
194
195 if ( \is_null( $home_url ) ) {
196 $home_url = \wp_parse_url( \home_url() );
197 }
198
199 // When the base host is equal to the host.
200 if ( isset( $url['host'] ) && $url['host'] !== $home_url['host'] ) {
201 return ( $is_image ) ? SEO_Links::TYPE_EXTERNAL_IMAGE : SEO_Links::TYPE_EXTERNAL;
202 }
203
204 // There is no base path and thus all URLs of the same domain are internal.
205 if ( empty( $home_url['path'] ) ) {
206 return ( $is_image ) ? SEO_Links::TYPE_INTERNAL_IMAGE : SEO_Links::TYPE_INTERNAL;
207 }
208
209 // When there is a path and it matches the start of the url.
210 if ( isset( $url['path'] ) && \strpos( $url['path'], $home_url['path'] ) === 0 ) {
211 return ( $is_image ) ? SEO_Links::TYPE_INTERNAL_IMAGE : SEO_Links::TYPE_INTERNAL;
212 }
213
214 return ( $is_image ) ? SEO_Links::TYPE_EXTERNAL_IMAGE : SEO_Links::TYPE_EXTERNAL;
215 }
216 }
217