PageRenderTime 225ms CodeModel.GetById 110ms app.highlight 45ms RepoModel.GetById 63ms app.codeStats 1ms

/lib/pkp/classes/core/PKPRequest.inc.php

https://github.com/lib-uoguelph-ca/ocs
PHP | 763 lines | 428 code | 101 blank | 234 comment | 82 complexity | cd90b0c8024deff76a93150b80fa2d58 MD5 | raw file
  1<?php
  2
  3/**
  4 * @file classes/core/PKPRequest.inc.php
  5 *
  6 * Copyright (c) 2000-2012 John Willinsky
  7 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  8 *
  9 * @class PKPRequest
 10 * @ingroup core
 11 *
 12 * @brief Class providing operations associated with HTTP requests.
 13 */
 14
 15// $Id$
 16
 17
 18class PKPRequest {
 19	//
 20	// Internal state - please do not reference directly
 21	//
 22	/** @var PKPRouter router instance used to route this request */
 23	var $_router = null;
 24	/** @var array the request variables cache (GET/POST) */
 25	var $_requestVars = null;
 26	/** @var string request base path */
 27	var $_basePath;
 28	/** @var string request path */
 29	var $_requestPath;
 30	/** @var boolean true if restful URLs are enabled in the config */
 31	var $_isRestfulUrlsEnabled;
 32	/** @var boolean true if path info is enabled for this server */
 33	var $_isPathInfoEnabled;
 34	/** @var string server host */
 35	var $_serverHost;
 36	/** @var string base url */
 37	var $_baseUrl;
 38	/** @var string request protocol */
 39	var $_protocol;
 40	/** @var boolean true, if deprecation warning is switched on */
 41	var $_deprecationWarning = null;
 42
 43
 44
 45	/**
 46	 * get the router instance
 47	 * @return PKPRouter
 48	 */
 49	function &getRouter() {
 50		return $this->_router;
 51	}
 52
 53	/**
 54	 * set the router instance
 55	 * @param $router instance PKPRouter
 56	 */
 57	function setRouter(&$router) {
 58		$this->_router =& $router;
 59	}
 60
 61	/**
 62	 * Perform an HTTP redirect to an absolute or relative (to base system URL) URL.
 63	 * @param $url string (exclude protocol for local redirects)
 64	 */
 65	function redirectUrl($url) {
 66		PKPRequest::_checkThis();
 67
 68		if (HookRegistry::call('Request::redirect', array(&$url))) {
 69			return;
 70		}
 71
 72		header("Refresh: 0; url=$url");
 73		exit();
 74	}
 75
 76	/**
 77	 * Redirect to the current URL, forcing the HTTPS protocol to be used.
 78	 */
 79	function redirectSSL() {
 80		$_this =& PKPRequest::_checkThis();
 81
 82		$url = 'https://' . $_this->getServerHost() . $_this->getRequestPath();
 83		$queryString = $_this->getQueryString();
 84		if (!empty($queryString)) $url .= "?$queryString";
 85		$_this->redirectUrl($url);
 86	}
 87
 88	/**
 89	 * Redirect to the current URL, forcing the HTTP protocol to be used.
 90	 */
 91	function redirectNonSSL() {
 92		$_this =& PKPRequest::_checkThis();
 93
 94		$url = 'http://' . $_this->getServerHost() . $_this->getRequestPath();
 95		$queryString = $_this->getQueryString();
 96		if (!empty($queryString)) $url .= "?$queryString";
 97		$_this->redirectUrl($url);
 98	}
 99
100	/**
101	 * Get the IF_MODIFIED_SINCE date (as a numerical timestamp) if available
102	 * @return int
103	 */
104	function getIfModifiedSince() {
105		if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) return null;
106		return strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
107	}
108
109	/**
110	 * Get the base URL of the request (excluding script).
111	 * @return string
112	 */
113	function getBaseUrl() {
114		$_this =& PKPRequest::_checkThis();
115
116		if (!isset($_this->_baseUrl)) {
117			$serverHost = $_this->getServerHost(null);
118			if ($serverHost !== null) {
119				// Auto-detection worked.
120				$_this->_baseUrl = $_this->getProtocol() . '://' . $_this->getServerHost() . $_this->getBasePath();
121			} else {
122				// Auto-detection didn't work (e.g. this is a command-line call); use configuration param
123				$_this->_baseUrl = Config::getVar('general', 'base_url');
124			}
125			HookRegistry::call('Request::getBaseUrl', array(&$_this->_baseUrl));
126		}
127
128		return $_this->_baseUrl;
129	}
130
131	/**
132	 * Get the base path of the request (excluding trailing slash).
133	 * @return string
134	 */
135	function getBasePath() {
136		$_this =& PKPRequest::_checkThis();
137
138		if (!isset($_this->_basePath)) {
139			$_this->_basePath = dirname($_SERVER['SCRIPT_NAME']);
140			if ($_this->_basePath == '/' || $_this->_basePath == '\\') {
141				$_this->_basePath = '';
142			}
143			HookRegistry::call('Request::getBasePath', array(&$_this->_basePath));
144		}
145
146		return $_this->_basePath;
147	}
148
149	/**
150	 * Deprecated
151	 * @see PKPPageRouter::getIndexUrl()
152	 */
153	function getIndexUrl() {
154		static $indexUrl;
155
156		$_this =& PKPRequest::_checkThis();
157		if (!isset($indexUrl)) {
158			$indexUrl = $_this->_delegateToRouter('getIndexUrl');
159
160			// Call legacy hook
161			HookRegistry::call('Request::getIndexUrl', array(&$indexUrl));
162		}
163
164		return $indexUrl;
165	}
166
167	/**
168	 * Get the complete URL to this page, including parameters.
169	 * @return string
170	 */
171	function getCompleteUrl() {
172		$_this =& PKPRequest::_checkThis();
173
174		static $completeUrl;
175
176		if (!isset($completeUrl)) {
177			$completeUrl = $_this->getRequestUrl();
178			$queryString = $_this->getQueryString();
179			if (!empty($queryString)) $completeUrl .= "?$queryString";
180			HookRegistry::call('Request::getCompleteUrl', array(&$completeUrl));
181		}
182
183		return $completeUrl;
184	}
185
186	/**
187	 * Get the complete URL of the request.
188	 * @return string
189	 */
190	function getRequestUrl() {
191		$_this =& PKPRequest::_checkThis();
192
193		static $requestUrl;
194
195		if (!isset($requestUrl)) {
196			$requestUrl = $_this->getProtocol() . '://' . $_this->getServerHost() . $_this->getRequestPath();
197			HookRegistry::call('Request::getRequestUrl', array(&$requestUrl));
198		}
199
200		return $requestUrl;
201	}
202
203	/**
204	 * Get the complete set of URL parameters to the current request.
205	 * @return string
206	 */
207	function getQueryString() {
208		PKPRequest::_checkThis();
209
210		static $queryString;
211
212		if (!isset($queryString)) {
213			$queryString = isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:'';
214			HookRegistry::call('Request::getQueryString', array(&$queryString));
215		}
216
217		return $queryString;
218	}
219
220	/**
221	 * Get the complete set of URL parameters to the current request as an associative array.
222	 * @return array
223	 */
224	function getQueryArray() {
225		$_this =& PKPRequest::_checkThis();
226
227		$queryString = $_this->getQueryString();
228		$queryArray = array();
229
230		if (isset($queryString)) {
231			parse_str($queryString, $queryArray);
232		}
233
234		return $queryArray;
235	}
236
237	/**
238	 * Get the completed path of the request.
239	 * @return string
240	 */
241	function getRequestPath() {
242		$_this =& PKPRequest::_checkThis();
243
244		if (!isset($_this->_requestPath)) {
245			if ($_this->isRestfulUrlsEnabled()) {
246				$_this->_requestPath = $_this->getBasePath();
247			} else {
248				$_this->_requestPath = $_SERVER['SCRIPT_NAME'];
249			}
250
251			if ($_this->isPathInfoEnabled()) {
252				$_this->_requestPath .= isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
253			}
254			HookRegistry::call('Request::getRequestPath', array(&$_this->_requestPath));
255		}
256		return $_this->_requestPath;
257	}
258
259	/**
260	 * Get the server hostname in the request. May optionally include the
261	 * port number if non-standard.
262	 * @return string
263	 */
264	function getServerHost($default = 'localhost') {
265		$_this =& PKPRequest::_checkThis();
266
267		if (!isset($_this->_serverHost)) {
268			$_this->_serverHost = isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST']
269				: (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST']
270				: (isset($_SERVER['HOSTNAME']) ? $_SERVER['HOSTNAME']
271				: $default));
272			HookRegistry::call('Request::getServerHost', array(&$_this->_serverHost));
273		}
274		return $_this->_serverHost;
275	}
276
277	/**
278	 * Get the protocol used for the request (HTTP or HTTPS).
279	 * @return string
280	 */
281	function getProtocol() {
282		$_this =& PKPRequest::_checkThis();
283
284		if (!isset($_this->_protocol)) {
285			$_this->_protocol = (!isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) != 'on') ? 'http' : 'https';
286			HookRegistry::call('Request::getProtocol', array(&$_this->_protocol));
287		}
288		return $_this->_protocol;
289	}
290
291	/**
292	 * Get the request method
293	 * @return string
294	 */
295	function getRequestMethod() {
296		PKPRequest::_checkThis();
297
298		$requestMethod = (isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '');
299		return $requestMethod;
300	}
301
302	/**
303	 * Determine whether the request is a POST request
304	 * @return boolean
305	 */
306	function isPost() {
307		$_this =& PKPRequest::_checkThis();
308
309		return ($_this->getRequestMethod() == 'POST');
310	}
311
312	/**
313	 * Determine whether the request is a GET request
314	 * @return boolean
315	 */
316	function isGet() {
317		$_this =& PKPRequest::_checkThis();
318
319		return ($_this->getRequestMethod() == 'GET');
320	}
321
322	/**
323	 * Get the remote IP address of the current request.
324	 * @return string
325	 */
326	function getRemoteAddr() {
327		PKPRequest::_checkThis();
328
329		static $ipaddr;
330		if (!isset($ipaddr)) {
331			if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) &&
332				preg_match_all('/([0-9.a-fA-F:]+)/', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
333			} else if (isset($_SERVER['REMOTE_ADDR']) && 
334				preg_match_all('/([0-9.a-fA-F:]+)/', $_SERVER['REMOTE_ADDR'], $matches)) {
335			} else if (preg_match_all('/([0-9.a-fA-F:]+)/', getenv('REMOTE_ADDR'), $matches)) {
336			} else {
337				$ipaddr = '';
338			}
339
340			if (!isset($ipaddr)) {
341				// If multiple addresses are listed, take the last. (Supports ipv6.)
342				$ipaddr = $matches[0][count($matches[0])-1];
343			}
344			HookRegistry::call('Request::getRemoteAddr', array(&$ipaddr));
345		}
346		return $ipaddr;
347	}
348
349	/**
350	 * Get the remote domain of the current request
351	 * @return string
352	 */
353	function getRemoteDomain() {
354		$_this =& PKPRequest::_checkThis();
355
356		static $remoteDomain;
357		if (!isset($remoteDomain)) {
358			$remoteDomain = null;
359			$remoteDomain = @getHostByAddr($_this->getRemoteAddr());
360			HookRegistry::call('Request::getRemoteDomain', array(&$remoteDomain));
361		}
362		return $remoteDomain;
363	}
364
365	/**
366	 * Get the user agent of the current request.
367	 * @return string
368	 */
369	function getUserAgent() {
370		PKPRequest::_checkThis();
371
372		static $userAgent;
373		if (!isset($userAgent)) {
374			if (isset($_SERVER['HTTP_USER_AGENT'])) {
375				$userAgent = $_SERVER['HTTP_USER_AGENT'];
376			}
377			if (!isset($userAgent) || empty($userAgent)) {
378				$userAgent = getenv('HTTP_USER_AGENT');
379			}
380			if (!isset($userAgent) || $userAgent == false) {
381				$userAgent = '';
382			}
383			HookRegistry::call('Request::getUserAgent', array(&$userAgent));
384		}
385		return $userAgent;
386	}
387
388	/**
389	 * Determine whether a user agent is a bot or not using an external
390	 * list of regular expressions.
391	 */
392	function isBot() {
393		$_this =& PKPRequest::_checkThis();
394
395		static $isBot;
396		if (!isset($isBot)) {
397			$userAgent = $_this->getUserAgent();
398			$isBot = false;
399			$userAgentsFile = Config::getVar('general', 'registry_dir') . DIRECTORY_SEPARATOR . 'botAgents.txt';
400			$regexps = array_filter(file($userAgentsFile), create_function('&$a', 'return ($a = trim($a)) && !empty($a) && $a[0] != \'#\';'));
401			foreach ($regexps as $regexp) {
402				if (String::regexp_match($regexp, $userAgent)) {
403					$isBot = true;
404					return $isBot;
405				}
406			}
407		}
408		return $isBot;
409	}
410
411	/**
412	 * Return true if PATH_INFO is enabled.
413	 */
414	function isPathInfoEnabled() {
415		$_this =& PKPRequest::_checkThis();
416
417		if (!isset($_this->_isPathInfoEnabled)) {
418			$_this->_isPathInfoEnabled = Config::getVar('general', 'disable_path_info')?false:true;
419		}
420		return $_this->_isPathInfoEnabled;
421	}
422
423	/**
424	 * Return true if RESTFUL_URLS is enabled.
425	 */
426	function isRestfulUrlsEnabled() {
427		$_this =& PKPRequest::_checkThis();
428
429		if (!isset($_this->_isRestfulUrlsEnabled)) {
430			$_this->_isRestfulUrlsEnabled = Config::getVar('general', 'restful_urls')?true:false;
431		}
432		return $_this->_isRestfulUrlsEnabled;
433	}
434
435	/**
436	 * Get site data.
437	 * @return Site
438	 */
439	function &getSite() {
440		PKPRequest::_checkThis();
441
442		$site =& Registry::get('site', true, null);
443		if ($site === null) {
444			$siteDao =& DAORegistry::getDAO('SiteDAO');
445			$site =& $siteDao->getSite();
446			// PHP bug? This is needed for some reason or extra queries results.
447			Registry::set('site', $site);
448		}
449
450		return $site;
451	}
452
453	/**
454	 * Get the user session associated with the current request.
455	 * @return Session
456	 */
457	function &getSession() {
458		PKPRequest::_checkThis();
459
460		$session =& Registry::get('session', true, null);
461
462		if ($session === null) {
463			$sessionManager =& SessionManager::getManager();
464			$session = $sessionManager->getUserSession();
465		}
466
467		return $session;
468	}
469
470	/**
471	 * Get the user associated with the current request.
472	 * @return User
473	 */
474	function &getUser() {
475		PKPRequest::_checkThis();
476
477		$user =& Registry::get('user', true, null);
478		if ($user === null) {
479			$sessionManager =& SessionManager::getManager();
480			$session =& $sessionManager->getUserSession();
481			$user =& $session->getUser();
482		}
483
484		return $user;
485	}
486
487	/**
488	 * Get the value of a GET/POST variable.
489	 * @return mixed
490	 */
491	function getUserVar($key) {
492		$_this =& PKPRequest::_checkThis();
493
494		// Get all vars (already cleaned)
495		$vars =& $_this->getUserVars();
496
497		if (isset($vars[$key])) {
498			return $vars[$key];
499		} else {
500			return null;
501		}
502	}
503
504	/**
505	 * Get all GET/POST variables as an array
506	 * @return array
507	 */
508	function &getUserVars() {
509		$_this =& PKPRequest::_checkThis();
510
511		if (!isset($_this->_requestVars)) {
512			$_this->_requestVars = array_merge($_GET, $_POST);
513			$_this->cleanUserVar($_this->_requestVars);
514		}
515
516		return $_this->_requestVars;
517	}
518
519	/**
520	 * Get the value of a GET/POST variable generated using the Smarty
521	 * html_select_date and/or html_select_time function.
522	 * @param $prefix string
523	 * @param $defaultDay int
524	 * @param $defaultMonth int
525	 * @param $defaultYear int
526	 * @param $defaultHour int
527	 * @param $defaultMinute int
528	 * @param $defaultSecond int
529	 * @return Date
530	 */
531	function getUserDateVar($prefix, $defaultDay = null, $defaultMonth = null, $defaultYear = null, $defaultHour = 0, $defaultMinute = 0, $defaultSecond = 0) {
532		$_this =& PKPRequest::_checkThis();
533
534		$monthPart = $_this->getUserVar($prefix . 'Month');
535		$dayPart = $_this->getUserVar($prefix . 'Day');
536		$yearPart = $_this->getUserVar($prefix . 'Year');
537		$hourPart = $_this->getUserVar($prefix . 'Hour');
538		$minutePart = $_this->getUserVar($prefix . 'Minute');
539		$secondPart = $_this->getUserVar($prefix . 'Second');
540
541		switch ($_this->getUserVar($prefix . 'Meridian')) {
542			case 'pm':
543				if (is_numeric($hourPart) && $hourPart != 12) $hourPart += 12;
544				break;
545			case 'am':
546			default:
547				// Do nothing.
548				break;
549		}
550
551		if (empty($dayPart)) $dayPart = $defaultDay;
552		if (empty($monthPart)) $monthPart = $defaultMonth;
553		if (empty($yearPart)) $yearPart = $defaultYear;
554		if (empty($hourPart)) $hourPart = $defaultHour;
555		if (empty($minutePart)) $minutePart = $defaultMinute;
556		if (empty($secondPart)) $secondPart = $defaultSecond;
557
558		if (empty($monthPart) || empty($dayPart) || empty($yearPart)) return null;
559		return mktime($hourPart, $minutePart, $secondPart, $monthPart, $dayPart, $yearPart);
560	}
561
562	/**
563	 * Sanitize a user-submitted variable (i.e., GET/POST/Cookie variable).
564	 * Strips slashes if necessary, then sanitizes variable as per Core::cleanVar().
565	 * @param $var mixed
566	 */
567	function cleanUserVar(&$var, $stripHtml = false) {
568		$_this =& PKPRequest::_checkThis();
569
570		if (isset($var) && is_array($var)) {
571			foreach ($var as $key => $value) {
572				$_this->cleanUserVar($var[$key], $stripHtml);
573			}
574		} else if (isset($var)) {
575			$var = Core::cleanVar(get_magic_quotes_gpc() ? stripslashes($var) : $var);
576
577		} else {
578			return null;
579		}
580	}
581
582	/**
583	 * Get the value of a cookie variable.
584	 * @return mixed
585	 */
586	function getCookieVar($key) {
587		$_this =& PKPRequest::_checkThis();
588
589		if (isset($_COOKIE[$key])) {
590			$value = $_COOKIE[$key];
591			$_this->cleanUserVar($value);
592			return $value;
593		} else {
594			return null;
595		}
596	}
597
598	/**
599	 * Set a cookie variable.
600	 * @param $key string
601	 * @param $value mixed
602	 */
603	function setCookieVar($key, $value) {
604		$_this =& PKPRequest::_checkThis();
605
606		setcookie($key, $value, 0, $_this->getBasePath());
607		$_COOKIE[$key] = $value;
608	}
609
610	/**
611	 * Redirect to the specified page within a PKP Application.
612	 * Shorthand for a common call to $request->redirect($router->url(...)).
613	 * @param $context Array The optional contextual paths
614	 * @param $page string The name of the op to redirect to.
615	 * @param $op string optional The name of the op to redirect to.
616	 * @param $path mixed string or array containing path info for redirect.
617	 * @param $params array Map of name => value pairs for additional parameters
618	 * @param $anchor string Name of desired anchor on the target page
619	 */
620	function redirect($context = null, $page = null, $op = null, $path = null, $params = null, $anchor = null) {
621		$_this =& PKPRequest::_checkThis();
622
623		$router =& $_this->getRouter();
624		$_this->redirectUrl($router->url($_this, $context, $page, $op, $path, $params, $anchor));
625	}
626
627	/**
628	 * Deprecated
629	 * @see PKPPageRouter::getContext()
630	 */
631	function &getContext() {
632		$_this =& PKPRequest::_checkThis();
633		return $_this->_delegateToRouter('getContext');
634	}
635
636	/**
637	 * Deprecated
638	 * @see PKPPageRouter::getRequestedContextPath()
639	 */
640	function getRequestedContextPath($contextLevel = null) {
641		$_this =& PKPRequest::_checkThis();
642
643		// Emulate the old behavior of getRequestedContextPath for
644		// backwards compatibility.
645		if (is_null($contextLevel)) {
646			return $_this->_delegateToRouter('getRequestedContextPaths');
647		} else {
648			return array($_this->_delegateToRouter('getRequestedContextPath', $contextLevel));
649		}
650	}
651
652	/**
653	 * Deprecated
654	 * @see PKPPageRouter::getRequestedPage()
655	 */
656	function getRequestedPage() {
657		$_this =& PKPRequest::_checkThis();
658		return $_this->_delegateToRouter('getRequestedPage');
659	}
660
661	/**
662	 * Deprecated
663	 * @see PKPPageRouter::getRequestedOp()
664	 */
665	function getRequestedOp() {
666		$_this =& PKPRequest::_checkThis();
667		return $_this->_delegateToRouter('getRequestedOp');
668	}
669
670	/**
671	 * Deprecated
672	 * @see PKPPageRouter::getRequestedArgs()
673	 */
674	function getRequestedArgs() {
675		$_this =& PKPRequest::_checkThis();
676		return $_this->_delegateToRouter('getRequestedArgs');
677	}
678
679	/**
680	 * Deprecated
681	 * @see PKPPageRouter::url()
682	 */
683	function url($context = null, $page = null, $op = null, $path = null,
684				$params = null, $anchor = null, $escape = false) {
685		$_this =& PKPRequest::_checkThis();
686		return $_this->_delegateToRouter('url', $context, $page, $op, $path,
687				$params, $anchor, $escape);
688	}
689
690	/**
691	 * This method exists to maintain backwards compatibility
692	 * with static calls to PKPRequest.
693	 *
694	 * If it is called non-statically then it will simply
695	 * return $this. Otherwise it will issue a deprecation
696	 * warning and expect a global singleton instance in the
697	 * registry that will be returned instead.
698	 *
699	 * NB: This method is protected and may not be used by
700	 * external classes. It should also only be used in legacy
701	 * methods.
702	 *
703	 * @return PKPRequest
704	 */
705	function &_checkThis() {
706		if (isset($this) && is_a($this, 'PKPRequest')) {
707			return $this;
708		} else {
709			// We have to use a static variable here as
710			// this deprecated call is static itself.
711			static $deprecationWarning = null;
712			if (is_null($deprecationWarning)) {
713				$deprecationWarning = Config::getVar('debug', 'deprecation_warnings');
714				if (is_null($deprecationWarning)) $deprecationWarning = false;
715			}
716			if ($deprecationWarning) trigger_error('Deprecated static function call');
717
718			$instance =& Registry::get('request');
719			assert(!is_null($instance));
720			return $instance;
721		}
722	}
723
724	/**
725	 * This method exists to maintain backwards compatibility
726	 * with calls to methods that have been factored into the
727	 * Router implementations.
728	 *
729	 * It delegates the call to the router and returns the result.
730	 *
731	 * NB: This method is protected and may not be used by
732	 * external classes. It should also only be used in legacy
733	 * methods.
734	 *
735	 * @return mixed depends on the called method
736	 */
737	function &_delegateToRouter($method) {
738		$_this =& PKPRequest::_checkThis();
739		if (is_null($_this->_deprecationWarning)) {
740			$_this->_deprecationWarning = Config::getVar('debug', 'deprecation_warnings');
741			if (is_null($_this->_deprecationWarning)) $_this->_deprecationWarning = false;
742		}
743		if ($_this->_deprecationWarning) trigger_error('Deprecated function');
744
745		$router =& $_this->getRouter();
746
747		// Construct the method call
748		$callable = array($router, $method);
749
750		// Get additional parameters but replace
751		// the first parameter (currently the
752		// method to be called) with the request
753		// as all router methods required the request
754		// as their first parameter.
755		$parameters = func_get_args();
756		$parameters[0] =& $_this;
757
758		$returner = call_user_func_array($callable, $parameters);
759		return $returner;
760	}
761}
762
763?>