Merge branch 'package'
[speedfreak] / Server / system / helpers / url.php
1 <?php defined('SYSPATH') OR die('No direct access allowed.');
2 /**
3  * URL helper class.
4  *
5  * $Id: url.php 4029 2009-03-03 12:39:32Z Shadowhand $
6  *
7  * @package    Core
8  * @author     Kohana Team
9  * @copyright  (c) 2007-2008 Kohana Team
10  * @license    http://kohanaphp.com/license.html
11  */
12 class url_Core {
13
14         /**
15          * Fetches the current URI.
16          *
17          * @param   boolean  include the query string
18          * @return  string
19          */
20         public static function current($qs = FALSE)
21         {
22                 return ($qs === TRUE) ? Router::$complete_uri : Router::$current_uri;
23         }
24
25         /**
26          * Base URL, with or without the index page.
27          *
28          * If protocol (and core.site_protocol) and core.site_domain are both empty,
29          * then
30          *
31          * @param   boolean  include the index page
32          * @param   boolean  non-default protocol
33          * @return  string
34          */
35         public static function base($index = FALSE, $protocol = FALSE)
36         {
37                 if ($protocol == FALSE)
38                 {
39                         // Use the default configured protocol
40                         $protocol = Kohana::config('core.site_protocol');
41                 }
42
43                 // Load the site domain
44                 $site_domain = (string) Kohana::config('core.site_domain', TRUE);
45
46                 if ($protocol == FALSE)
47                 {
48                         if ($site_domain === '' OR $site_domain[0] === '/')
49                         {
50                                 // Use the configured site domain
51                                 $base_url = $site_domain;
52                         }
53                         else
54                         {
55                                 // Guess the protocol to provide full http://domain/path URL
56                                 $base_url = ((empty($_SERVER['HTTPS']) OR $_SERVER['HTTPS'] === 'off') ? 'http' : 'https').'://'.$site_domain;
57                         }
58                 }
59                 else
60                 {
61                         if ($site_domain === '' OR $site_domain[0] === '/')
62                         {
63                                 // Guess the server name if the domain starts with slash
64                                 $base_url = $protocol.'://'.$_SERVER['HTTP_HOST'].$site_domain;
65                         }
66                         else
67                         {
68                                 // Use the configured site domain
69                                 $base_url = $protocol.'://'.$site_domain;
70                         }
71                 }
72
73                 if ($index === TRUE AND $index = Kohana::config('core.index_page'))
74                 {
75                         // Append the index page
76                         $base_url = $base_url.$index;
77                 }
78
79                 // Force a slash on the end of the URL
80                 return rtrim($base_url, '/').'/';
81         }
82
83         /**
84          * Fetches an absolute site URL based on a URI segment.
85          *
86          * @param   string  site URI to convert
87          * @param   string  non-default protocol
88          * @return  string
89          */
90         public static function site($uri = '', $protocol = FALSE)
91         {
92                 if ($path = trim(parse_url($uri, PHP_URL_PATH), '/'))
93                 {
94                         // Add path suffix
95                         $path .= Kohana::config('core.url_suffix');
96                 }
97
98                 if ($query = parse_url($uri, PHP_URL_QUERY))
99                 {
100                         // ?query=string
101                         $query = '?'.$query;
102                 }
103
104                 if ($fragment = parse_url($uri, PHP_URL_FRAGMENT))
105                 {
106                         // #fragment
107                         $fragment =  '#'.$fragment;
108                 }
109
110                 // Concat the URL
111                 return url::base(TRUE, $protocol).$path.$query.$fragment;
112         }
113
114         /**
115          * Return the URL to a file. Absolute filenames and relative filenames
116          * are allowed.
117          *
118          * @param   string   filename
119          * @param   boolean  include the index page
120          * @return  string
121          */
122         public static function file($file, $index = FALSE)
123         {
124                 if (strpos($file, '://') === FALSE)
125                 {
126                         // Add the base URL to the filename
127                         $file = url::base($index).$file;
128                 }
129
130                 return $file;
131         }
132
133         /**
134          * Merges an array of arguments with the current URI and query string to
135          * overload, instead of replace, the current query string.
136          *
137          * @param   array   associative array of arguments
138          * @return  string
139          */
140         public static function merge(array $arguments)
141         {
142                 if ($_GET === $arguments)
143                 {
144                         $query = Router::$query_string;
145                 }
146                 elseif ($query = http_build_query(array_merge($_GET, $arguments)))
147                 {
148                         $query = '?'.$query;
149                 }
150
151                 // Return the current URI with the arguments merged into the query string
152                 return Router::$current_uri.$query;
153         }
154
155         /**
156          * Convert a phrase to a URL-safe title.
157          *
158          * @param   string  phrase to convert
159          * @param   string  word separator (- or _)
160          * @return  string
161          */
162         public static function title($title, $separator = '-')
163         {
164                 $separator = ($separator === '-') ? '-' : '_';
165
166                 // Replace accented characters by their unaccented equivalents
167                 $title = utf8::transliterate_to_ascii($title);
168
169                 // Remove all characters that are not the separator, a-z, 0-9, or whitespace
170                 $title = preg_replace('/[^'.$separator.'a-z0-9\s]+/', '', strtolower($title));
171
172                 // Replace all separator characters and whitespace by a single separator
173                 $title = preg_replace('/['.$separator.'\s]+/', $separator, $title);
174
175                 // Trim separators from the beginning and end
176                 return trim($title, $separator);
177         }
178
179         /**
180          * Sends a page redirect header and runs the system.redirect Event.
181          *
182          * @param  mixed   string site URI or URL to redirect to, or array of strings if method is 300
183          * @param  string  HTTP method of redirect
184          * @return void
185          */
186         public static function redirect($uri = '', $method = '302')
187         {
188                 if (Event::has_run('system.send_headers'))
189                 {
190                         return FALSE;
191                 }
192
193                 $codes = array
194                 (
195                         'refresh' => 'Refresh',
196                         '300' => 'Multiple Choices',
197                         '301' => 'Moved Permanently',
198                         '302' => 'Found',
199                         '303' => 'See Other',
200                         '304' => 'Not Modified',
201                         '305' => 'Use Proxy',
202                         '307' => 'Temporary Redirect'
203                 );
204
205                 // Validate the method and default to 302
206                 $method = isset($codes[$method]) ? (string) $method : '302';
207
208                 if ($method === '300')
209                 {
210                         $uri = (array) $uri;
211
212                         $output = '<ul>';
213                         foreach ($uri as $link)
214                         {
215                                 $output .= '<li>'.html::anchor($link).'</li>';
216                         }
217                         $output .= '</ul>';
218
219                         // The first URI will be used for the Location header
220                         $uri = $uri[0];
221                 }
222                 else
223                 {
224                         $output = '<p>'.html::anchor($uri).'</p>';
225                 }
226
227                 // Run the redirect event
228                 Event::run('system.redirect', $uri);
229
230                 if (strpos($uri, '://') === FALSE)
231                 {
232                         // HTTP headers expect absolute URLs
233                         $uri = url::site($uri, request::protocol());
234                 }
235
236                 if ($method === 'refresh')
237                 {
238                         header('Refresh: 0; url='.$uri);
239                 }
240                 else
241                 {
242                         header('HTTP/1.1 '.$method.' '.$codes[$method]);
243                         header('Location: '.$uri);
244                 }
245
246                 // We are about to exit, so run the send_headers event
247                 Event::run('system.send_headers');
248
249                 exit('<h1>'.$method.' - '.$codes[$method].'</h1>'.$output);
250         }
251
252 } // End url