PluginProbe
Redirection / 5.0.1
Redirection v5.0.1
5.10.0 5.9.0 5.8.1 5.8.0 3.7.2 3.7.3 4.0 4.0.1 4.1 4.1.1 4.2 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6.2 4.7.1 All 130 releases
redirection / models / url / url-path.php

url-path.php in Redirection 5.0.1, at models/url/url-path.php

136 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The path part of a URL
5 */
6 class Red_Url_Path {
7 /**
8 * URL path
9 *
10 * @var String
11 */
12 private $path;
13
14 /**
15 * Constructor
16 *
17 * @param String $path URL.
18 */
19 public function __construct( $path ) {
20 $this->path = $this->get_path_component( $path );
21 }
22
23 /**
24 * Is the supplied `url` a match for this object?
25 *
26 * @param String $url URL to match against.
27 * @param Red_Source_Flags $flags Source flags to use in match.
28 * @return boolean
29 */
30 public function is_match( $url, Red_Source_Flags $flags ) {
31 $target = new Red_Url_Path( $url );
32
33 $target_path = $target->get();
34 $source_path = $this->get();
35
36 if ( $flags->is_ignore_trailing() ) {
37 // Ignore trailing slashes
38 $source_path = $this->get_without_trailing_slash();
39 $target_path = $target->get_without_trailing_slash();
40 }
41
42 if ( $flags->is_ignore_case() ) {
43 // Case insensitive match
44 $source_path = self::to_lower( $source_path );
45 $target_path = self::to_lower( $target_path );
46 }
47
48 return $target_path === $source_path;
49 }
50
51 /**
52 * Convert a URL to lowercase
53 *
54 * @param String $url URL.
55 * @return String
56 */
57 public static function to_lower( $url ) {
58 if ( function_exists( 'mb_strtolower' ) ) {
59 return mb_strtolower( $url, 'UTF-8' );
60 }
61
62 return strtolower( $url );
63 }
64
65 /**
66 * Get the path value
67 *
68 * @return String
69 */
70 public function get() {
71 return $this->path;
72 }
73
74 /**
75 * Get the path value without trailing slash, or `/` if home
76 *
77 * @return String
78 */
79 public function get_without_trailing_slash() {
80 // Return / or // as-is
81 if ( $this->path === '/' ) {
82 return $this->path;
83 }
84
85 // Anything else remove the last /
86 return preg_replace( '@/$@', '', $this->get() );
87 }
88
89 /**
90 * `parse_url` doesn't handle 'incorrect' URLs, such as those with double slashes
91 * These are often used in redirects, so we fall back to our own parsing
92 *
93 * @param String $url URL.
94 * @return String
95 */
96 private function get_path_component( $url ) {
97 $path = $url;
98
99 if ( preg_match( '@^https?://@', $url, $matches ) > 0 ) {
100 $parts = explode( '://', $url );
101
102 if ( count( $parts ) > 1 ) {
103 $rest = explode( '/', $parts[1] );
104 $path = '/' . implode( '/', array_slice( $rest, 1 ) );
105 }
106 }
107
108 return urldecode( $this->get_query_before( $path ) );
109 }
110
111 /**
112 * Get the path component up to the query string
113 *
114 * @param String $url URL.
115 * @return String
116 */
117 private function get_query_before( $url ) {
118 $qpos = strpos( $url, '?' );
119 $qrpos = strpos( $url, '\\?' );
120
121 // Have we found an escaped query and it occurs before a normal query?
122 if ( $qrpos !== false && $qrpos < $qpos ) {
123 // Yes, the path is everything up to the escaped query
124 return substr( $url, 0, $qrpos );
125 }
126
127 // No query - return everything as path
128 if ( $qpos === false ) {
129 return $url;
130 }
131
132 // Query found - return everything up to it
133 return substr( $url, 0, $qpos );
134 }
135 }
136