Open Journal Systems  3.3.0
PKPPageRouter.inc.php
1 <?php
2 
16 define('ROUTER_DEFAULT_PAGE', './pages/index/index.php');
17 define('ROUTER_DEFAULT_OP', 'index');
18 
19 import('lib.pkp.classes.core.PKPRouter');
20 
21 class PKPPageRouter extends PKPRouter {
23  var $_installationPages = array('install', 'help', 'header', 'sidebar');
24 
25  //
26  // Internal state cache variables
27  // NB: Please do not access directly but
28  // only via their respective getters/setters
29  //
31  var $_page;
33  var $_op;
35  var $_indexUrl;
38 
43  function getInstallationPages() {
45  }
46 
51  function getCacheablePages() {
52  // Can be overridden by sub-classes.
53  return array();
54  }
55 
63  function isCacheable($request, $testOnly = false) {
64  if (defined('SESSION_DISABLE_INIT') && !$testOnly) return false;
65  if (!Config::getVar('general', 'installed')) return false;
66  if (!empty($_POST) || Validation::isLoggedIn()) return false;
67 
68  if ($request->isPathInfoEnabled()) {
69  if (!empty($_GET)) return false;
70  } else {
71  $application = $this->getApplication();
72  $ok = array_merge($application->getContextList(), array('page', 'op', 'path'));
73  if (!empty($_GET) && count(array_diff(array_keys($_GET), $ok)) != 0) {
74  return false;
75  }
76  }
77 
78  if (in_array($this->getRequestedPage($request), $this->getCacheablePages())) return true;
79 
80  return false;
81  }
82 
88  function getRequestedPage($request) {
89  if (!isset($this->_page)) {
90  $this->_page = $this->_getRequestedUrlParts(array('Core', 'getPage'), $request);
91  }
92  return $this->_page;
93  }
94 
100  function getRequestedOp($request) {
101  if (!isset($this->_op)) {
102  $this->_op = $this->_getRequestedUrlParts(array('Core', 'getOp'), $request);
103  }
104  return $this->_op;
105  }
106 
112  function getRequestedArgs($request) {
113  return $this->_getRequestedUrlParts(array('Core', 'getArgs'), $request);
114  }
115 
122  function getRequestedAnchor($request) {
123  $url = $request->getRequestUrl();
124  $parts = explode('#', $url);
125  if (count($parts) < 2) {
126  return '';
127  }
128  return $parts[1];
129  }
130 
131 
132  //
133  // Implement template methods from PKPRouter
134  //
138  function getCacheFilename($request) {
139  if (!isset($this->_cacheFilename)) {
140  if ($request->isPathInfoEnabled()) {
141  $id = isset($_SERVER['PATH_INFO'])?$_SERVER['PATH_INFO']:'index';
142  $id .= '-' . AppLocale::getLocale();
143  } else {
144  $id = '';
145  $application = $this->getApplication();
146  foreach($application->getContextList() as $contextName) {
147  $id .= $request->getUserVar($contextName) . '-';
148  }
149  $id .= $request->getUserVar('page') . '-' . $request->getUserVar('op') . '-' . $request->getUserVar('path') . '-' . AppLocale::getLocale();
150  }
151  $path = Core::getBaseDir();
152  $this->_cacheFilename = $path . '/cache/wc-' . md5($id) . '.html';
153  }
154  return $this->_cacheFilename;
155  }
156 
160  function route($request) {
161  // Determine the requested page and operation
162  $page = $this->getRequestedPage($request);
163  $op = $this->getRequestedOp($request);
164 
165  // If the application has not yet been installed we only
166  // allow installer pages to be displayed.
167  if (!Config::getVar('general', 'installed')) {
168  if (!in_array($page, $this->getInstallationPages())) {
169  // A non-installation page was called although
170  // the system is not yet installed. Redirect to
171  // the installation page.
172  $redirectMethod = array($request, 'redirect');
173 
174  // The correct redirection for the installer page
175  // depends on the context depth of this application.
176  $application = $this->getApplication();
177  $contextDepth = $application->getContextDepth();
178  // The context will be filled with all nulls
179  $redirectArguments = array_pad(array('install'), - $contextDepth - 1, null);
180 
181  // Call request's redirect method
182  call_user_func_array($redirectMethod, $redirectArguments);
183  }
184  }
185 
186  // Redirect requests from logged-out users to a context which is not
187  // publicly enabled
188  if (!defined('SESSION_DISABLE_INIT')) {
189  $user = $request->getUser();
190  $currentContext = $request->getContext();
191  if ($currentContext && !$currentContext->getEnabled() && !is_a($user, 'User')) {
192  if ($page != 'login') $request->redirect(null, 'login');
193  }
194  }
195 
196  // Determine the page index file. This file contains the
197  // logic to resolve a page to a specific handler class.
198  $sourceFile = sprintf('pages/%s/index.php', $page);
199 
200  // If a hook has been registered to handle this page, give it the
201  // opportunity to load required resources and set HANDLER_CLASS.
202  if (!HookRegistry::call('LoadHandler', array(&$page, &$op, &$sourceFile))) {
203  if (file_exists($sourceFile)) require('./'.$sourceFile);
204  elseif (file_exists(PKP_LIB_PATH . DIRECTORY_SEPARATOR . $sourceFile))
205  require('.' . DIRECTORY_SEPARATOR . PKP_LIB_PATH . DIRECTORY_SEPARATOR . $sourceFile);
206  elseif (empty($page)) require(ROUTER_DEFAULT_PAGE);
207  else {
208  $dispatcher = $this->getDispatcher();
209  $dispatcher->handle404();
210  }
211  }
212 
213  if (!defined('SESSION_DISABLE_INIT')) {
214  // Initialize session
216  }
217 
218  // Call the selected handler's index operation if
219  // no operation was defined in the request.
220  if (empty($op)) $op = ROUTER_DEFAULT_OP;
221 
222  // Redirect to 404 if the operation doesn't exist
223  // for the handler.
224  $methods = array();
225  if (defined('HANDLER_CLASS')) $methods = get_class_methods(HANDLER_CLASS);
226  if (!in_array($op, $methods)) {
227  $dispatcher = $this->getDispatcher();
228  $dispatcher->handle404();
229  }
230 
231  // Instantiate the handler class
232  $handlerClass = HANDLER_CLASS;
233  $handler = new $handlerClass($request);
234  $this->setHandler($handler);
235 
236  // Authorize and initialize the request but don't call the
237  // validate() method on page handlers.
238  // FIXME: We should call the validate() method for page
239  // requests also (last param = true in the below method
240  // call) once we've made sure that all validate() calls can
241  // be removed from handler operations without damage (i.e.
242  // they don't depend on actions being performed before the
243  // call to validate().
244  $args = $this->getRequestedArgs($request);
245  $serviceEndpoint = array($handler, $op);
246  $this->_authorizeInitializeAndCallRequest($serviceEndpoint, $request, $args, false);
247  }
248 
252  function url($request, $newContext = null, $page = null, $op = null, $path = null,
253  $params = null, $anchor = null, $escape = false) {
254  $pathInfoEnabled = $request->isPathInfoEnabled();
255 
256  //
257  // Base URL and Context
258  //
259  $newContext = $this->_urlCanonicalizeNewContext($newContext);
260  $baseUrlAndContext = $this->_urlGetBaseAndContext($request, $newContext);
261  $baseUrl = array_shift($baseUrlAndContext);
262  $context = $baseUrlAndContext;
263 
264  //
265  // Additional path info
266  //
267  if (empty($path)) {
268  $additionalPath = array();
269  } else {
270  if (is_array($path)) {
271  $additionalPath = array_map('rawurlencode', $path);
272  } else {
273  $additionalPath = array(rawurlencode($path));
274  }
275 
276  // If path info is disabled then we have to
277  // encode the path as query parameters.
278  if (!$pathInfoEnabled) {
279  $pathKey = $escape?'path%5B%5D=':'path[]=';
280  foreach($additionalPath as $key => $pathElement) {
281  $additionalPath[$key] = $pathKey.$pathElement;
282  }
283  }
284  }
285 
286  //
287  // Page and Operation
288  //
289 
290  // Are we in a page request?
291  $currentRequestIsAPageRequest = is_a($request->getRouter(), 'PKPPageRouter');
292 
293  // Determine the operation
294  if ($op) {
295  // If an operation has been explicitly set then use it.
296  $op = rawurlencode($op);
297  } else {
298  // No operation has been explicitly set so let's determine a sensible
299  // default operation.
300  if (empty($newContext) && empty($page) && $currentRequestIsAPageRequest) {
301  // If we remain in the existing context and on the existing page then
302  // we will default to the current operation. We can only determine a
303  // current operation if the current request is a page request.
304  $op = $this->getRequestedOp($request);
305  } else {
306  // If a new context (or page) has been set then we'll default to the
307  // index operation within the new context (or on the new page).
308  if (empty($additionalPath)) {
309  // If no additional path is set we can simply leave the operation
310  // undefined which automatically defaults to the index operation
311  // but gives shorter (=nicer) URLs.
312  $op = null;
313  } else {
314  // If an additional path is set then we have to explicitly set the
315  // index operation to disambiguate the path info.
316  $op = 'index';
317  }
318  }
319  }
320 
321  // Determine the page
322  if ($page) {
323  // If a page has been explicitly set then use it.
324  $page = rawurlencode($page);
325  } else {
326  // No page has been explicitly set so let's determine a sensible default page.
327  if (empty($newContext) && $currentRequestIsAPageRequest) {
328  // If we remain in the existing context then we will default to the current
329  // page. We can only determine a current page if the current request is a
330  // page request.
331  $page = $this->getRequestedPage($request);
332  } else {
333  // If a new context has been set then we'll default to the index page
334  // within the new context.
335  if (empty($op)) {
336  // If no explicit operation is set we can simply leave the page
337  // undefined which automatically defaults to the index page but gives
338  // shorter (=nicer) URLs.
339  $page = null;
340  } else {
341  // If an operation is set then we have to explicitly set the index
342  // page to disambiguate the path info.
343  $page = 'index';
344  }
345  }
346  }
347 
348  //
349  // Additional query parameters
350  //
351  $additionalParameters = $this->_urlGetAdditionalParameters($request, $params, $escape);
352 
353  //
354  // Anchor
355  //
356  $anchor = (empty($anchor) ? '' : '#'.rawurlencode($anchor));
357 
358  //
359  // Assemble URL
360  //
361  if ($pathInfoEnabled) {
362  // If path info is enabled then context, page,
363  // operation and additional path go into the
364  // path info.
365  $pathInfoArray = $context;
366  if (!empty($page)) {
367  $pathInfoArray[] = $page;
368  if (!empty($op)) {
369  $pathInfoArray[] = $op;
370  }
371  }
372  $pathInfoArray = array_merge($pathInfoArray, $additionalPath);
373 
374  // Query parameters
375  $queryParametersArray = $additionalParameters;
376  } else {
377  // If path info is disabled then context, page,
378  // operation and additional path are encoded as
379  // query parameters.
380  $pathInfoArray = array();
381 
382  // Query parameters
383  $queryParametersArray = $context;
384  if (!empty($page)) {
385  $queryParametersArray[] = "page=$page";
386  if (!empty($op)) {
387  $queryParametersArray[] = "op=$op";
388  }
389  }
390  $queryParametersArray = array_merge($queryParametersArray, $additionalPath, $additionalParameters);
391  }
392 
393  return $this->_urlFromParts($baseUrl, $pathInfoArray, $queryParametersArray, $anchor, $escape);
394  }
395 
399  function handleAuthorizationFailure($request, $authorizationMessage) {
400  // Redirect to the authorization denied page.
401  if (!$request->getUser()) Validation::redirectLogin();
402  $request->redirect(null, 'user', 'authorizationDenied', null, array('message' => $authorizationMessage));
403  }
404 
409  function redirectHome($request) {
410  $request->redirectUrl($this->getHomeUrl($request));
411  }
412 
417  function getHomeUrl($request) {
418  $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); /* @var $userGroupDao UserGroupDAO */
419  $user = $request->getUser();
420  $userId = $user->getId();
421 
422  if ($context = $this->getContext($request, 1)) {
423  // The user is in the context, see if they have zero or one roles only
424  $userGroups = $userGroupDao->getByUserId($userId, $context->getId());
425  if($userGroups->getCount() <= 1) {
426  $userGroup = $userGroups->next();
427  if (!$userGroup || $userGroup->getRoleId() == ROLE_ID_READER) return $request->url(null, 'index');
428  }
429  return $request->url(null, 'submissions');
430  } else {
431  // The user is at the site context, check to see if they are
432  // only registered in one place w/ one role
433  $userGroups = $userGroupDao->getByUserId($userId, CONTEXT_ID_NONE);
434 
435  if($userGroups->getCount() == 1) {
436  $contextDao = Application::getContextDAO();
437  $userGroup = $userGroups->next();
438  $context = $contextDao->getById($userGroup->getContextId());
439  if (!isset($context)) $request->redirect('index', 'index');
440  if ($userGroup->getRoleId() == ROLE_ID_READER) $request->redirect(null, 'index');
441  }
442  return $request->url('index', 'index');
443  }
444  }
445 
446 
447  //
448  // Private helper methods.
449  //
458  private function _getRequestedUrlParts($callback, &$request) {
459  $url = null;
460  assert(is_a($request->getRouter(), 'PKPPageRouter'));
461  $isPathInfoEnabled = $request->isPathInfoEnabled();
462 
463  if ($isPathInfoEnabled) {
464  if (isset($_SERVER['PATH_INFO'])) {
465  $url = $_SERVER['PATH_INFO'];
466  }
467  } else {
468  $url = $request->getCompleteUrl();
469  }
470 
471  $userVars = $request->getUserVars();
472  return call_user_func_array($callback, array($url, $isPathInfoEnabled, $userVars));
473  }
474 }
475 
476 
PKPRouter\_authorizeInitializeAndCallRequest
_authorizeInitializeAndCallRequest(&$serviceEndpoint, $request, &$args, $validate=true)
Definition: PKPRouter.inc.php:393
Application\getContextDAO
static getContextDAO()
Definition: Application.inc.php:137
$op
$op
Definition: lib/pkp/pages/help/index.php:18
PKPRouter\setHandler
setHandler($handler)
Definition: PKPRouter.inc.php:153
SessionManager\getManager
static getManager()
Definition: SessionManager.inc.php:124
PKPPageRouter\getCacheFilename
getCacheFilename($request)
Definition: PKPPageRouter.inc.php:153
$application
$application
Definition: index.php:65
Validation\redirectLogin
static redirectLogin($message=null)
Definition: Validation.inc.php:168
Validation\isLoggedIn
static isLoggedIn()
Definition: Validation.inc.php:376
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
PKPPageRouter\route
route($request)
Definition: PKPPageRouter.inc.php:175
PKPPageRouter\$_indexUrl
$_indexUrl
Definition: PKPPageRouter.inc.php:47
PKPPageRouter\getRequestedArgs
getRequestedArgs($request)
Definition: PKPPageRouter.inc.php:127
PKPPageRouter
Class mapping an HTTP request to a handler or context.
Definition: PKPPageRouter.inc.php:21
PKPRouter\_urlCanonicalizeNewContext
_urlCanonicalizeNewContext($newContext)
Definition: PKPRouter.inc.php:452
PKPPageRouter\getInstallationPages
getInstallationPages()
Definition: PKPPageRouter.inc.php:58
PKPRouter\_urlGetBaseAndContext
_urlGetBaseAndContext($request, $newContext=array())
Definition: PKPRouter.inc.php:487
PKPPageRouter\url
url($request, $newContext=null, $page=null, $op=null, $path=null, $params=null, $anchor=null, $escape=false)
Definition: PKPPageRouter.inc.php:267
PKPPageRouter\getRequestedAnchor
getRequestedAnchor($request)
Definition: PKPPageRouter.inc.php:137
HANDLER_CLASS
const HANDLER_CLASS
Definition: lib/pkp/pages/help/index.php:19
PKPPageRouter\redirectHome
redirectHome($request)
Definition: PKPPageRouter.inc.php:424
PKPPageRouter\$_page
$_page
Definition: PKPPageRouter.inc.php:37
Config\getVar
static getVar($section, $key, $default=null)
Definition: Config.inc.php:35
PKPPageRouter\getRequestedPage
getRequestedPage($request)
Definition: PKPPageRouter.inc.php:103
PKPRouter\getContext
& getContext($request, $requestedContextLevel=1, $forceReload=false)
Definition: PKPRouter.inc.php:250
PKPPageRouter\getRequestedOp
getRequestedOp($request)
Definition: PKPPageRouter.inc.php:115
PKPPageRouter\$_installationPages
$_installationPages
Definition: PKPPageRouter.inc.php:26
PKPPageRouter\$_op
$_op
Definition: PKPPageRouter.inc.php:42
PKPRouter\getApplication
& getApplication()
Definition: PKPRouter.inc.php:114
PKPRouter
Basic router class that has functionality common to all routers.
Definition: PKPRouter.inc.php:57
PKPRouter\_urlFromParts
_urlFromParts($baseUrl, $pathInfoArray=array(), $queryParametersArray=array(), $anchor='', $escape=false)
Definition: PKPRouter.inc.php:582
PKPPageRouter\$_cacheFilename
$_cacheFilename
Definition: PKPPageRouter.inc.php:52
Core\getBaseDir
static getBaseDir()
Definition: Core.inc.php:37
PKPPageRouter\getHomeUrl
getHomeUrl($request)
Definition: PKPPageRouter.inc.php:432
PKPPageRouter\isCacheable
isCacheable($request, $testOnly=false)
Definition: PKPPageRouter.inc.php:78
PKPPageRouter\handleAuthorizationFailure
handleAuthorizationFailure($request, $authorizationMessage)
Definition: PKPPageRouter.inc.php:414
HookRegistry\call
static call($hookName, $args=null)
Definition: HookRegistry.inc.php:86
AppLocale\getLocale
static getLocale()
Definition: env1/MockAppLocale.inc.php:40
PKPRouter\_urlGetAdditionalParameters
_urlGetAdditionalParameters($request, $params=null, $escape=true)
Definition: PKPRouter.inc.php:555
PKPRouter\getDispatcher
& getDispatcher()
Definition: PKPRouter.inc.php:136
PKPPageRouter\getCacheablePages
getCacheablePages()
Definition: PKPPageRouter.inc.php:66