2 /************************************************************************/
4 /************************************************************************/
5 /* Copyright (c) 2002-2010 */
6 /* Inclusive Design Institute */
8 /* This program is free software. You can redistribute it and/or */
9 /* modify it under the terms of the GNU General Public License */
10 /* as published by the Free Software Foundation. */
11 /************************************************************************/
14 //Include all the classes for external rewrite rules
15 require_once('ForumsUrl.class.php');
16 require_once('ContentUrl.class.php');
17 require_once('FileStorageUrl.class.php');
18 require_once('TestsUrl.class.php');
19 require_once('GlossaryUrl.class.php');
23 * Class for rewriting pretty urls.
30 var $path; //the path of this script
31 var $filename; //script name
32 var $query; //the queries of the REQUEST
33 var $isEmpty; //true if path, filename, and query are empty
36 function UrlRewrite($path, $filename, $query) {
37 if ($path=='' && $filename=='' && $query==''){
38 $this->isEmpty = true;
40 $this->isEmpty = false;
43 $this->filename = $filename;
44 $this->query = $query;
48 * Returns the link that points to this object as a page.
52 //redirect to that url.
53 return '/'.$this->getPage();
57 * Parser for the pathinfo, return an array with mapped key values similar to the querystring.
59 * @return array key=>value, where keys and values have the same meaning as the ones in the query strings.
61 function parsePrettyQuery(){
65 //return empty array if query is empty
66 if (empty($this->query)){
70 //if course_dir_name is disabled from admin.
71 if ($_config['pretty_url']==0){
75 //If the first char is /, cut it
76 if (strpos($this->query, '/') == 0){
77 $query_parts = explode('/', substr($this->query, 1));
79 $query_parts = explode('/', $this->query);
82 //dynamically create the array
83 //assumption: pathinfo ALWAYS in the format of key1/value1/key2/value2/key3/value3/etc...
84 foreach ($query_parts as $array_index=>$key_value){
85 if($array_index%2 == 0 && $query_parts[$array_index]!=''){
86 if (isset($query_parts[$array_index+1])) $result[$key_value] = $query_parts[$array_index+1];
94 * Parser for the querystrings url
96 * @param string querystring
97 * @return array an array of mapped keys and values like the querystrings.
99 * NOTE: Stopped using this function since we've decided to dynamically create the URL.
100 * See: parsePrettyQuery()
102 function parseQuery($query){
103 //return empty array if query is empty
108 parse_str($this->query, $result);
114 * Construct the pretty url based on the given query.
116 * @param string the pathinfo query
117 * @return string pretty url
119 function constructPrettyUrl($query){
127 //Take out bookmark, and store it.
128 if (($pos = strpos($query, '#'))!==FALSE){
129 $bookmark = substr($query, $pos);
130 $query = substr($query, 0, $pos);
133 //If this is already a pretty url,but without mod_apache rule
134 //unwrap it and reconstruct
135 if (is_array($query)){
137 foreach($query as $fk=>$fv){
138 if (preg_match('/\.php/', $fv)==1){
139 continue; //skip the php file
142 //check if this is part of the rule, if so,add it, o/w ignore
143 if (array_search($fv, $this->rule)!==FALSE){
144 $new_query .= $fv . '=' . $query[$fk+1] . SEP;
145 } elseif (preg_match('/([0-9]+)\.html/', $fv, $matches)==1){
146 $new_query .= 'page=' . $matches[1] . SEP;
149 $query = $new_query; //done
152 //do not change query if pretty url is disabled
153 if ($_config['pretty_url'] == 0){
154 $pretty_url = $query;
156 $pretty_url = ''; //init url
157 $query_parts = explode(SEP, $query);
158 foreach ($query_parts as $index=>$attributes){
159 if(empty($attributes)){
160 //skip the ones that are empty.
163 list($key, $value) = preg_split('/\=/', $attributes, 2);
164 $pretty_url .= $key . '/' . $value .'/';
168 //finally, append bookmark if not emptied
170 $pretty_url .= $bookmark;
178 * This function is used to convert the input URL to a pretty URL.
179 * @param int course id
180 * @param string normal URL, WITHOUT the <prototal>://<host>
183 function convertToPrettyUrl($course_id, $url){
184 global $_config, $db;
187 if (strpos($url, '?')!==FALSE){
188 list($front, $end) = preg_split('/\?/', $url);
193 $front_array = explode('/', $front);
194 if ($front_array[1]=='_standard' || $front_array[1]=='_core' ){
195 //shift the first 2 elements.
196 array_shift($front_array);
197 array_shift($front_array);
198 $front = implode('/', $front_array);
200 //find out what kind of link this is, pretty url? relative url? or PHP_SELF url?
201 $dir_deep = substr_count(AT_INCLUDE_PATH, '..');
202 $url_parts = explode('/', $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
203 $host_dir = implode('/', array_slice($url_parts, 0, count($url_parts) - $dir_deep-1));
204 //The link is a bounce link
205 if(preg_match('/bounce.php\?course=([\d]+)$/', $url, $matches)==1){
206 if (!empty($course_id)) {
207 $pretty_url = $course_id; //course_id should be assigned by vitals depending on the system pref.
209 $pretty_url = $matches[1]; //happens when course dir name is disabled
211 } elseif(in_array(AT_PRETTY_URL_HANDLER, $front_array)===TRUE){
212 //The relative link is a pretty URL
213 $front_result = array();
214 //spit out the URL in between AT_PRETTY_URL_HANDLER to *.php
215 //note, pretty url is defined to be AT_PRETTY_URL_HANDLER/course_slug/type/location/...
216 //ie. AT_PRETTY_URL_HANDLER/1/forum/view.php/...
217 while (($needle = array_search(AT_PRETTY_URL_HANDLER, $front_array)) !== FALSE){
218 $front_array = array_slice($front_array, $needle + 1);
220 $front_array = array_slice($front_array, $needle + 1); //+2 because we want the entries after the course_slug
222 //Handle url differently IF mod_rewrite is enabled, and if there are no query strings at the back,
223 //then we will have to reuse the current pathinfo to reconstruct the query.
224 if ($_config['apache_mod_rewrite'] > 0 && $end==''){
225 $end = $front_array; //let the class handles it
228 /* Overwrite pathinfo
229 * ie. /go.php/1/forum/view.php/fid/1/pid/17/?fid=1&pid=17&page=5
230 * In the above case, cut off the original pathinfo, and replace it with the new querystrings
231 * If querystring is empty, then use the old one, ie. /go.php/1/forum/view.php/fid/1/pid/17/.
233 foreach($front_array as $fk=>$fv){
234 array_push($front_result, $fv);
235 if (!empty($end) && preg_match('/\.php/', $fv)==1){
239 $front = implode('/', $front_result);
240 } elseif (strpos($front, $host_dir)!==FALSE){
241 //Not a relative link, it contains the full PHP_SELF path.
242 $front = substr($front, strlen($host_dir)+1); //stripe off the slash after the host_dir as well
243 } elseif ($course_id == ''){
244 //if this is my start page
247 //Turn querystring to pretty URL
248 if ($pretty_url==''){
249 //Get the original course id back
250 $sql = "SELECT course_id FROM ".TABLE_PREFIX."courses WHERE course_dir_name='$course_id'";
251 $result = mysql_query($sql, $db);
252 $row = mysql_fetch_assoc($result);
253 $course_orig = $course_id;
255 if ($row['course_id']!=''){
256 $course_orig = $row['course_id'];
259 //Add course id in if both course_id or course_dir_name are not there
260 if (preg_match('/^\/?('.$course_id.'|'.$course_orig.')\//', $front)==0){
261 $pretty_url = $course_id.'/';
264 //check if there are any rules overwriting the original rules
265 //TODO: have a better way to do this
266 // extend modularity into this.
267 $obj =& $this; //default
268 //Overwrite the UrlRewrite obj if there are any private rules
269 if ($_config['apache_mod_rewrite'] > 0){
270 //take out '.php' if any exists. (Apply only to non-modules, otherwise it might cause problems)
271 if (preg_match('/^mods/', $front)!=1){
272 if ($end=='' && preg_match('/index\.php$/', $front)==1){
273 $pretty_url .= preg_replace('/index.php/', '', $front);
275 $pretty_url .= preg_replace('/\.php/', '', $front);
278 $pretty_url .= $front;
281 if (preg_match('/forum\/(index|view|list)\.php/', $front)==1) {
282 $pretty_url = $course_id.'/forum';
283 $obj = new ForumsUrl();
284 } elseif (preg_match('/(content\.php)(\/cid(\/\d+))?/', $front, $matches)==1){
285 $pretty_url = $course_id.'/content';
286 //if there are other pretty url queries at the back, append it
287 //Note: this is to fix the hopping content problem between diff courses
288 if (isset($matches[3]) && $matches[3] != ''){
289 $pretty_url .= $matches[3];
291 $obj = new ContentUrl();
292 } elseif (preg_match('/file_storage\/((index|revisions|comments)\.php)?/', $front, $matches)==1){
293 $pretty_url = $course_id.'/file_storage';
294 $obj = new FileStorageUrl($matches[1]);
295 } elseif (preg_match('/tools\/test_intro\.php/', $front)==1){
296 $pretty_url = $course_id.'/tests_surveys';
297 $obj = new TestsUrl();
298 } elseif (preg_match('/glossary\/index\.php/', $front)==1){
299 $pretty_url = $course_id.'/glossary';
300 $obj = new GlossaryUrl();
303 $pretty_url .= $front;
307 //if pretty url is turned off, use '?' to separate the querystring.
308 ($_config['pretty_url'] == 0)? $qs_sep = '?': $qs_sep = '/';
309 $pretty_url .= $qs_sep.$obj->constructPrettyUrl($end);
312 //if mod_rewrite is switched on, defined in constants.inc.php
313 if ($_config['apache_mod_rewrite'] > 0){
316 return AT_PRETTY_URL_HANDLER.'/'.$pretty_url;
321 * Return the paths where this script is
324 //for 2.0, most of the paths are moved into mods/_standard
326 //TODO: Add regex into the path, ie. /social/* means all folders under social.
328 '/backups' => 'mods/_core',
329 '/content' => 'mods/_core',
330 '/enrolment' => 'mods/_core',
331 '/file_manager' => 'mods/_core',
332 '/glossary' => 'mods/_core',
333 '/groups' => 'mods/_core',
334 '/imscp' => 'mods/_core',
335 '/properties' => 'mods/_core',
336 '/announcements'=> 'mods/_standard',
337 '/assignments' => 'mods/_standard',
338 '/blogs' => 'mods/_standard',
339 '/chat' => 'mods/_standard',
340 '/chat/manage' => 'mods/_standard',
341 '/course_tools' => 'mods/_standard',
342 '/directory' => 'mods/_standard',
343 '/faq' => 'mods/_standard',
344 '/file_storage' => 'mods/_standard',
345 '/forums' => 'mods/_standard',
346 '/forums/forum' => 'mods/_standard',
347 '/google_search'=> 'mods/_standard',
348 '/gradebook' => 'mods/_standard',
349 '/links' => 'mods/_standard',
350 '/photos' => 'mods/_standard',
351 '/polls' => 'mods/_standard',
352 '/sitemap' => 'mods/_standard',
353 '/social' => 'mods/_standard',
354 '/social/groups'=> 'mods/_standard',
355 '/student_tools'=> 'mods/_standard',
356 '/tile_search' => 'mods/_standard',
357 '/tests' => 'mods/_standard',
358 '/tracker' => 'mods/_standard',
359 '/reading_list' => 'mods/_standard',
360 '/assignment_dropbox' => 'mods/_standard'
363 if ($this->path != ''){
364 $path = substr($this->path, 1).'/';
365 if (isset($hmap[$this->path])){
366 $path = $hmap[$this->path].'/'.$path;
374 * Return the script name
376 function getFileName(){
377 return $this->filename;
381 * Return the link of the page.
384 return $this->getPath().$this->getFileName();
388 * Return true if path, filename, and query are empty.
391 return $this->isEmpty;