PluginProbe
FeedWordPress / 2009.1112
FeedWordPress v2009.1112
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
feedwordpress / relative_uri.class.php

relative_uri.class.php in FeedWordPress 2009.1112, at relative_uri.class.php

175 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 # Relative URI static class: PHP class for resolving relative URLs
3 #
4 # This class is derived (under the terms of the GPL) from URL Class 0.3 by
5 # Keyvan Minoukadeh <keyvan@k1m.com>, which is great but more than we need
6 # for FeedWordPress's purposes. The class has been stripped down to a single
7 # public method: Relative_URI::resolve($url, $base), which resolves the URI in
8 # $url relative to the URI in $base
9
10 class Relative_URI
11 {
12 // Resolve relative URI in $url against the base URI in $base. If $base
13 // is not supplied, then we use the REQUEST_URI of this script.
14 //
15 // I'm hoping this method reflects RFC 2396 Section 5.2
16 function resolve ($url, $base = NULL)
17 {
18 if (is_null($base)):
19 $base = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
20 endif;
21
22 $base = Relative_URI::_encode(trim($base));
23 $uri_parts = Relative_URI::_parse_url($base);
24
25 $url = Relative_URI::_encode(trim($url));
26 $parts = Relative_URI::_parse_url($url);
27
28 $uri_parts['fragment'] = (isset($parts['fragment']) ? $parts['fragment'] : null);
29 $uri_parts['query'] = (isset($parts['query']) ? $parts['query'] : null);
30
31 // if path is empty, and scheme, host, and query are undefined,
32 // the URL is referring the base URL
33
34 if (($parts['path'] == '') && !isset($parts['scheme']) && !isset($parts['host']) && !isset($parts['query'])) {
35 // If the URI is empty or only a fragment, return the base URI
36 return $base . (isset($parts['fragment']) ? '#'.$parts['fragment'] : '');
37 } elseif (isset($parts['scheme'])) {
38 // If the scheme is set, then the URI is absolute.
39 return $url;
40 } elseif (isset($parts['host'])) {
41 $uri_parts['host'] = $parts['host'];
42 $uri_parts['path'] = $parts['path'];
43 } else {
44 // We have a relative path but not a host.
45
46 // start ugly fix:
47 // prepend slash to path if base host is set, base path is not set, and url path is not absolute
48 if ($uri_parts['host'] && ($uri_parts['path'] == '')
49 && (strlen($parts['path']) > 0)
50 && (substr($parts['path'], 0, 1) != '/')) {
51 $parts['path'] = '/'.$parts['path'];
52 } // end ugly fix
53
54 if (substr($parts['path'], 0, 1) == '/') {
55 $uri_parts['path'] = $parts['path'];
56 } else {
57 // copy base path excluding any characters after the last (right-most) slash character
58 $buffer = substr($uri_parts['path'], 0, (int)strrpos($uri_parts['path'], '/')+1);
59 // append relative path
60 $buffer .= $parts['path'];
61 // remove "./" where "." is a complete path segment.
62 $buffer = str_replace('/./', '/', $buffer);
63 if (substr($buffer, 0, 2) == './') {
64 $buffer = substr($buffer, 2);
65 }
66 // if buffer ends with "." as a complete path segment, remove it
67 if (substr($buffer, -2) == '/.') {
68 $buffer = substr($buffer, 0, -1);
69 }
70 // remove "<segment>/../" where <segment> is a complete path segment not equal to ".."
71 $search_finished = false;
72 $segment = explode('/', $buffer);
73 while (!$search_finished) {
74 for ($x=0; $x+1 < count($segment);) {
75 if (($segment[$x] != '') && ($segment[$x] != '..') && ($segment[$x+1] == '..')) {
76 if ($x+2 == count($segment)) $segment[] = '';
77 unset($segment[$x], $segment[$x+1]);
78 $segment = array_values($segment);
79 continue 2;
80 } else {
81 $x++;
82 }
83 }
84 $search_finished = true;
85 }
86 $buffer = (count($segment) == 1) ? '/' : implode('/', $segment);
87 $uri_parts['path'] = $buffer;
88
89 }
90 }
91
92 // If we've gotten to this point, we can try to put the pieces
93 // back together.
94 $ret = '';
95 if (isset($uri_parts['scheme'])) $ret .= $uri_parts['scheme'].':';
96 if (isset($uri_parts['user'])) {
97 $ret .= $uri_parts['user'];
98 if (isset($uri_parts['pass'])) $ret .= ':'.$uri_parts['parts'];
99 $ret .= '@';
100 }
101 if (isset($uri_parts['host'])) {
102 $ret .= '//'.$uri_parts['host'];
103 if (isset($uri_parts['port'])) $ret .= ':'.$uri_parts['port'];
104 }
105 $ret .= $uri_parts['path'];
106 if (isset($uri_parts['query'])) $ret .= '?'.$uri_parts['query'];
107 if (isset($uri_parts['fragment'])) $ret .= '#'.$uri_parts['fragment'];
108
109 return $ret;
110 }
111
112 /**
113 * Parse URL
114 *
115 * Regular expression grabbed from RFC 2396 Appendix B.
116 * This is a replacement for PHPs builtin parse_url().
117 * @param string $url
118 * @access private
119 * @return array
120 */
121 function _parse_url($url)
122 {
123 // I'm using this pattern instead of parse_url() as there's a few strings where parse_url()
124 // generates a warning.
125 if (preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!', $url, $match)) {
126 $parts = array();
127 if ($match[1] != '') $parts['scheme'] = $match[2];
128 if ($match[3] != '') $parts['auth'] = $match[4];
129 // parse auth
130 if (isset($parts['auth'])) {
131 // store user info
132 if (($at_pos = strpos($parts['auth'], '@')) !== false) {
133 $userinfo = explode(':', substr($parts['auth'], 0, $at_pos), 2);
134 $parts['user'] = $userinfo[0];
135 if (isset($userinfo[1])) $parts['pass'] = $userinfo[1];
136 $parts['auth'] = substr($parts['auth'], $at_pos+1);
137 }
138 // get port number
139 if ($port_pos = strrpos($parts['auth'], ':')) {
140 $parts['host'] = substr($parts['auth'], 0, $port_pos);
141 $parts['port'] = (int)substr($parts['auth'], $port_pos+1);
142 if ($parts['port'] < 1) $parts['port'] = null;
143 } else {
144 $parts['host'] = $parts['auth'];
145 }
146 }
147 unset($parts['auth']);
148 $parts['path'] = $match[5];
149 if (isset($match[6]) && ($match[6] != '')) $parts['query'] = $match[7];
150 if (isset($match[8]) && ($match[8] != '')) $parts['fragment'] = $match[9];
151 return $parts;
152 }
153 // shouldn't reach here
154 return array('path'=>'');
155 }
156
157 function _encode($string)
158 {
159 static $replace = array();
160 if (!count($replace)) {
161 $find = array(32, 34, 60, 62, 123, 124, 125, 91, 92, 93, 94, 96, 127);
162 $find = array_merge(range(0, 31), $find);
163 $find = array_map('chr', $find);
164 foreach ($find as $char) {
165 $replace[$char] = '%'.bin2hex($char);
166 }
167 }
168 // escape control characters and a few other characters
169 $encoded = strtr($string, $replace);
170 // remove any character outside the hex range: 21 - 7E (see www.asciitable.com)
171 return preg_replace('/[^\x21-\x7e]/', '', $encoded);
172 }
173 } // class Relative_URI
174
175