PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 19.0
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v19.0
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 19.0, at src/helpers/url-helper.php

222 lines 6.0 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 * @param string $url The URL to get the path from.
104 *
105 * @return string The path of the URL. Returns an empty string if URL parsing fails.
106 */
107 public function get_url_path( $url ) {
108 if ( \is_string( $url ) === false
109 && \is_object( $url ) === false
110 || ( \is_object( $url ) === true && \method_exists( $url, '__toString' ) === false )
111 ) {
112 return '';
113 }
114
115 return (string) \wp_parse_url( $url, \PHP_URL_PATH );
116 }
117
118 /**
119 * Determines the file extension of the given url.
120 *
121 * @param string $url The URL.
122 *
123 * @return string The extension.
124 */
125 public function get_extension_from_url( $url ) {
126 $path = $this->get_url_path( $url );
127
128 if ( $path === '' ) {
129 return '';
130 }
131
132 $parts = \explode( '.', $path );
133 if ( empty( $parts ) || \count( $parts ) === 1 ) {
134 return '';
135 }
136
137 return \end( $parts );
138 }
139
140 /**
141 * Ensures that the given url is an absolute url.
142 *
143 * @param string $url The url that needs to be absolute.
144 *
145 * @return string The absolute url.
146 */
147 public function ensure_absolute_url( $url ) {
148 if ( ! \is_string( $url ) || $url === '' ) {
149 return $url;
150 }
151
152 if ( $this->is_relative( $url ) === true ) {
153 return $this->build_absolute_url( $url );
154 }
155
156 return $url;
157 }
158
159 /**
160 * Parse the home URL setting to find the base URL for relative URLs.
161 *
162 * @param string|null $path Optional path string.
163 *
164 * @return string
165 */
166 public function build_absolute_url( $path = null ) {
167 $path = \wp_parse_url( $path, \PHP_URL_PATH );
168 $url_parts = \wp_parse_url( \home_url() );
169
170 $base_url = \trailingslashit( $url_parts['scheme'] . '://' . $url_parts['host'] );
171
172 if ( ! \is_null( $path ) ) {
173 $base_url .= \ltrim( $path, '/' );
174 }
175
176 return $base_url;
177 }
178
179 /**
180 * Returns the link type.
181 *
182 * @param array $url The URL, as parsed by wp_parse_url.
183 * @param array|null $home_url Optional. The home URL, as parsed by wp_parse_url. Used to avoid reparsing the home_url.
184 * @param bool $is_image Whether or not the link is an image.
185 *
186 * @return string The link type.
187 */
188 public function get_link_type( $url, $home_url = null, $is_image = false ) {
189 // If there is no scheme and no host the link is always internal.
190 // Beware, checking just the scheme isn't enough as a link can be //yoast.com for instance.
191 if ( empty( $url['scheme'] ) && empty( $url['host'] ) ) {
192 return ( $is_image ) ? SEO_Links::TYPE_INTERNAL_IMAGE : SEO_Links::TYPE_INTERNAL;
193 }
194
195 // If there is a scheme but it's not http(s) then the link is always external.
196 if ( \array_key_exists( 'scheme', $url ) && ! \in_array( $url['scheme'], [ 'http', 'https' ], true ) ) {
197 return ( $is_image ) ? SEO_Links::TYPE_EXTERNAL_IMAGE : SEO_Links::TYPE_EXTERNAL;
198 }
199
200 if ( \is_null( $home_url ) ) {
201 $home_url = \wp_parse_url( \home_url() );
202 }
203
204 // When the base host is equal to the host.
205 if ( isset( $url['host'] ) && $url['host'] !== $home_url['host'] ) {
206 return ( $is_image ) ? SEO_Links::TYPE_EXTERNAL_IMAGE : SEO_Links::TYPE_EXTERNAL;
207 }
208
209 // There is no base path and thus all URLs of the same domain are internal.
210 if ( empty( $home_url['path'] ) ) {
211 return ( $is_image ) ? SEO_Links::TYPE_INTERNAL_IMAGE : SEO_Links::TYPE_INTERNAL;
212 }
213
214 // When there is a path and it matches the start of the url.
215 if ( isset( $url['path'] ) && \strpos( $url['path'], $home_url['path'] ) === 0 ) {
216 return ( $is_image ) ? SEO_Links::TYPE_INTERNAL_IMAGE : SEO_Links::TYPE_INTERNAL;
217 }
218
219 return ( $is_image ) ? SEO_Links::TYPE_EXTERNAL_IMAGE : SEO_Links::TYPE_EXTERNAL;
220 }
221 }
222