2 /************************************************************************/
4 /************************************************************************/
5 /* Copyright (c) 2002-2008 by Greg Gay, Joel Kronenberg & Heidi Hazelton*/
6 /* Adaptive Technology Resource Centre / University of Toronto */
9 /* This program is free software. You can redistribute it and/or */
10 /* modify it under the terms of the GNU General Public License */
11 /* as published by the Free Software Foundation. */
12 /************************************************************************/
15 //Include all the classes for external rewrite rules
16 require_once('ForumsUrl.class.php');
17 require_once('ContentUrl.class.php');
18 require_once('FileStorageUrl.class.php');
19 require_once('TestsUrl.class.php');
20 require_once('GlossaryUrl.class.php');
24 * Class for rewriting pretty urls.
31 var $path; //the path of this script
32 var $filename; //script name
33 var $query; //the queries of the REQUEST
34 var $isEmpty; //true if path, filename, and query are empty
37 function UrlRewrite($path, $filename, $query) {
38 if ($path=='' && $filename=='' && $query==''){
39 $this->isEmpty = true;
41 $this->isEmpty = false;
44 $this->filename = $filename;
45 $this->query = $query;
49 * Returns the link that points to this object as a page.
53 //redirect to that url.
54 return '/'.$this->getPage();
58 * Parser for the pathinfo, return an array with mapped key values similar to the querystring.
60 * @return array key=>value, where keys and values have the same meaning as the ones in the query strings.
62 function parsePrettyQuery(){
66 //return empty array if query is empty
67 if (empty($this->query)){
71 //if course_dir_name is disabled from admin.
72 if ($_config['pretty_url']==0){
76 //If the first char is /, cut it
77 if (strpos($this->query, '/') == 0){
78 $query_parts = explode('/', substr($this->query, 1));
80 $query_parts = explode('/', $this->query);
83 //dynamically create the array
84 //assumption: pathinfo ALWAYS in the format of key1/value1/key2/value2/key3/value3/etc...
85 foreach ($query_parts as $array_index=>$key_value){
86 if($array_index%2 == 0 && $query_parts[$array_index]!=''){
87 $result[$key_value] = $query_parts[$array_index+1];
95 * Parser for the querystrings url
97 * @param string querystring
98 * @return array an array of mapped keys and values like the querystrings.
100 * NOTE: Stopped using this function since we've decided to dynamically create the URL.
101 * See: parsePrettyQuery()
103 function parseQuery($query){
104 //return empty array if query is empty
109 parse_str($this->query, $result);
115 * Construct the pretty url based on the given query.
117 * @param string the pathinfo query
118 * @return string pretty url
120 function constructPrettyUrl($query){
128 //Take out bookmark, and store it.
129 if (($pos = strpos($query, '#'))!==FALSE){
130 $bookmark = substr($query, $pos);
131 $query = substr($query, 0, $pos);
134 //If this is already a pretty url,but without mod_apache rule
135 //unwrap it and reconstruct
136 if (is_array($query)){
138 foreach($query as $fk=>$fv){
139 if (preg_match('/\.php/', $fv)==1){
140 continue; //skip the php file
143 //check if this is part of the rule, if so,add it, o/w ignore
144 if (array_search($fv, $this->rule)!==FALSE){
145 $new_query .= $fv . '=' . $query[$fk+1] . SEP;
146 } elseif (preg_match('/([0-9]+)\.html/', $fv, $matches)==1){
147 $new_query .= 'page=' . $matches[1] . SEP;
150 $query = $new_query; //done
153 //do not change query if pretty url is disabled
154 if ($_config['pretty_url'] == 0){
155 $pretty_url = $query;
157 $pretty_url = ''; //init url
158 $query_parts = explode(SEP, $query);
159 foreach ($query_parts as $index=>$attributes){
160 if(empty($attributes)){
161 //skip the ones that are empty.
164 list($key, $value) = preg_split('/\=/', $attributes, 2);
165 $pretty_url .= $key . '/' . $value .'/';
169 //finally, append bookmark if not emptied
171 $pretty_url .= $bookmark;
179 * This function is used to convert the input URL to a pretty URL.
180 * @param int course id
181 * @param string normal URL, WITHOUT the <prototal>://<host>
184 function convertToPrettyUrl($course_id, $url){
185 global $_config, $db;
188 if (strpos($url, '?')!==FALSE){
189 list($front, $end) = preg_split('/\?/', $url);
195 $front_array = explode('/', $front);
197 //find out what kind of link this is, pretty url? relative url? or PHP_SELF url?
198 $dir_deep = substr_count(AT_INCLUDE_PATH, '..');
199 $url_parts = explode('/', $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
200 $host_dir = implode('/', array_slice($url_parts, 0, count($url_parts) - $dir_deep-1));
201 //The link is a bounce link
202 if(preg_match('/bounce.php\?course=([\d]+)$/', $url, $matches)==1){
203 if (!empty($course_id)) {
204 $pretty_url = $course_id; //course_id should be assigned by vitals depending on the system pref.
206 $pretty_url = $matches[1]; //happens when course dir name is disabled
208 } elseif(in_array(AT_PRETTY_URL_HANDLER, $front_array)===TRUE){
209 //The relative link is a pretty URL
210 $front_result = array();
211 //spit out the URL in between AT_PRETTY_URL_HANDLER to *.php
212 //note, pretty url is defined to be AT_PRETTY_URL_HANDLER/course_slug/type/location/...
213 //ie. AT_PRETTY_URL_HANDLER/1/forum/view.php/...
214 while (($needle = array_search(AT_PRETTY_URL_HANDLER, $front_array)) !== FALSE){
215 $front_array = array_slice($front_array, $needle + 1);
217 $front_array = array_slice($front_array, $needle + 1); //+2 because we want the entries after the course_slug
219 //Handle url differently IF mod_rewrite is enabled, and if there are no query strings at the back,
220 //then we will have to reuse the current pathinfo to reconstruct the query.
221 if ($_config['apache_mod_rewrite'] > 0 && $end==''){
222 $end = $front_array; //let the class handles it
225 /* Overwrite pathinfo
226 * ie. /go.php/1/forum/view.php/fid/1/pid/17/?fid=1&pid=17&page=5
227 * In the above case, cut off the original pathinfo, and replace it with the new querystrings
228 * If querystring is empty, then use the old one, ie. /go.php/1/forum/view.php/fid/1/pid/17/.
230 foreach($front_array as $fk=>$fv){
231 array_push($front_result, $fv);
232 if (!empty($end) && preg_match('/\.php/', $fv)==1){
236 $front = implode('/', $front_result);
237 } elseif (strpos($front, $host_dir)!==FALSE){
238 //Not a relative link, it contains the full PHP_SELF path.
239 $front = substr($front, strlen($host_dir)+1); //stripe off the slash after the host_dir as well
240 } elseif ($course_id == ''){
241 //if this is my start page
244 //Turn querystring to pretty URL
245 if ($pretty_url==''){
246 //Get the original course id back
247 $sql = "SELECT course_id FROM ".TABLE_PREFIX."courses WHERE course_dir_name='$course_id'";
248 $result = mysql_query($sql, $db);
249 $row = mysql_fetch_assoc($result);
250 $course_orig = $course_id;
252 if ($row['course_id']!=''){
253 $course_orig = $row['course_id'];
256 //Add course id in if both course_id or course_dir_name are not there
257 if (preg_match('/^\/?('.$course_id.'|'.$course_orig.')\//', $front)==0){
258 $pretty_url = $course_id.'/';
261 //check if there are any rules overwriting the original rules
262 //TODO: have a better way to do this
263 // extend modularity into this.
264 $obj =& $this; //default
265 //Overwrite the UrlRewrite obj if there are any private rules
266 if ($_config['apache_mod_rewrite'] > 0){
267 //take out '.php' if any exists. (Apply only to non-modules, otherwise it might cause problems)
268 if (preg_match('/^mods/', $front)!=1){
269 if ($end=='' && preg_match('/index\.php$/', $front)==1){
270 $pretty_url .= preg_replace('/index.php/', '', $front);
272 $pretty_url .= preg_replace('/\.php/', '', $front);
275 $pretty_url .= $front;
278 if (preg_match('/forum\/(index|view|list)\.php/', $front)==1) {
279 $pretty_url = $course_id.'/forum';
280 $obj = new ForumsUrl();
281 } elseif (preg_match('/(content\.php)(\/cid(\/\d+))?/', $front, $matches)==1){
282 $pretty_url = $course_id.'/content';
283 //if there are other pretty url queries at the back, append it
284 //Note: this is to fix the hopping content problem between diff courses
285 if (isset($matches[3]) && $matches[3] != ''){
286 $pretty_url .= $matches[3];
288 $obj = new ContentUrl();
289 } elseif (preg_match('/file_storage\/((index|revisions|comments)\.php)?/', $front, $matches)==1){
290 $pretty_url = $course_id.'/file_storage';
291 $obj = new FileStorageUrl($matches[1]);
292 } elseif (preg_match('/tools\/test_intro\.php/', $front)==1){
293 $pretty_url = $course_id.'/tests_surveys';
294 $obj = new TestsUrl();
295 } elseif (preg_match('/glossary\/index\.php/', $front)==1){
296 $pretty_url = $course_id.'/glossary';
297 $obj = new GlossaryUrl();
300 $pretty_url .= $front;
304 //if pretty url is turned off, use '?' to separate the querystring.
305 ($_config['pretty_url'] == 0)? $qs_sep = '?': $qs_sep = '/';
306 $pretty_url .= $qs_sep.$obj->constructPrettyUrl($end);
310 //if mod_rewrite is switched on, defined in constants.inc.php
311 if ($_config['apache_mod_rewrite'] > 0){
314 return AT_PRETTY_URL_HANDLER.'/'.$pretty_url;
319 * Return the paths where this script is
322 if ($this->path != ''){
323 return substr($this->path, 1).'/';
329 * Return the script name
331 function getFileName(){
332 return $this->filename;
339 return $this->getPath().$this->getFileName();
343 * Return true if path, filename, and query are empty.
346 return $this->isEmpty;