Open Journal Systems  3.0.0
 All Data Structures Namespaces Functions Variables Groups Pages
Core.inc.php
1 <?php
2 
22 define('PKP_LIB_PATH', 'lib' . DIRECTORY_SEPARATOR . 'pkp');
23 define('USER_AGENTS_FILE', Core::getBaseDir() . DIRECTORY_SEPARATOR . PKP_LIB_PATH . DIRECTORY_SEPARATOR . 'registry' . DIRECTORY_SEPARATOR . 'botAgents.txt');
24 
25 class Core {
26 
28  static $botRegexps = array();
29 
34  static function getBaseDir() {
35  static $baseDir;
36 
37  if (!isset($baseDir)) {
38  // Need to change if the index file moves
39  $baseDir = dirname(INDEX_FILE_LOCATION);
40  }
41 
42  return $baseDir;
43  }
44 
51  static function cleanVar($var) {
52  // only normalize strings that are not UTF-8 already, and when the system is using UTF-8
53  if ( Config::getVar('i18n', 'charset_normalization') == 'On' && strtolower_codesafe(Config::getVar('i18n', 'client_charset')) == 'utf-8' && !PKPString::utf8_is_valid($var) ) {
54 
55  $var = PKPString::utf8_normalize($var);
56 
57  // convert HTML entities into valid UTF-8 characters (do not transcode)
58  $var = html_entity_decode($var, ENT_COMPAT, 'UTF-8');
59 
60  // strip any invalid UTF-8 sequences
61  $var = PKPString::utf8_bad_strip($var);
62 
63  // re-encode special HTML characters
64  if (checkPhpVersion('5.2.3')) {
65  $var = htmlspecialchars($var, ENT_NOQUOTES, 'UTF-8', false);
66  } else {
67  $var = htmlspecialchars($var, ENT_NOQUOTES, 'UTF-8');
68  }
69  }
70 
71  // strip any invalid ASCII control characters
73 
74  return trim($var);
75  }
76 
83  static function cleanFileVar($var) {
84  return PKPString::regexp_replace('/[^\w\-]/', '', $var);
85  }
86 
92  static function getCurrentDate($ts = null) {
93  return date('Y-m-d H:i:s', isset($ts) ? $ts : time());
94  }
95 
100  static function microtime() {
101  list($usec, $sec) = explode(' ', microtime());
102  return (float)$sec + (float)$usec;
103  }
104 
109  static function serverPHPOS() {
110  return PHP_OS;
111  }
117  static function serverPHPVersion() {
118  return phpversion();
119  }
125  static function isWindows() {
126  return strtolower_codesafe(substr(Core::serverPHPOS(), 0, 3)) == 'win';
127  }
134  static function checkGeneralPHPModule($moduleName) {
135  if (extension_loaded($moduleName)) {
136  return true;
137  }
138  return false;
139  }
140 
148  static function isUserAgentBot($userAgent, $botRegexpsFile = USER_AGENTS_FILE) {
149  static $botRegexps;
150  Registry::set('currentUserAgentsFile', $botRegexpsFile);
152  if (!isset($botRegexps[$botRegexpsFile])) {
153  $botFileCacheId = md5($botRegexpsFile);
154  $cacheManager = CacheManager::getManager();
155  $cache = $cacheManager->getCache('core', $botFileCacheId, array('Core', '_botFileListCacheMiss'), CACHE_TYPE_FILE);
156  $botRegexps[$botRegexpsFile] = $cache->getContents();
157  }
158 
159  foreach ($botRegexps[$botRegexpsFile] as $regexp) {
160  if (PKPString::regexp_match($regexp, $userAgent)) {
161  return true;
162  }
163  }
164 
165  return false;
166  }
167 
180  static function getContextPaths($urlInfo, $isPathInfo, $contextList = null, $contextDepth = null, $userVars = array()) {
181  $contextPaths = array();
182  $application = Application::getApplication();
184  if (!$contextList) {
185  $contextList = $application->getContextList();
186  }
187  if (!$contextDepth) {
188  $contextDepth = $application->getContextDepth();
189  }
190 
191  // Handle context depth 0
192  if (!$contextDepth) return $contextPaths;
193 
194  if ($isPathInfo) {
195  // Split the path info into its constituents. Save all non-context
196  // path info in $contextPaths[$contextDepth]
197  // by limiting the explode statement.
198  $contextPaths = explode('/', trim($urlInfo, '/'), $contextDepth + 1);
199  // Remove the part of the path info that is not relevant for context (if present)
200  unset($contextPaths[$contextDepth]);
201  } else {
202  // Retrieve context from url query string
203  foreach($contextList as $key => $contextName) {
204  $contextPaths[$key] = Core::_getUserVar($urlInfo, $contextName, $userVars);
205  }
206  }
207 
208  // Canonicalize and clean context paths
209  for($key = 0; $key < $contextDepth; $key++) {
210  $contextPaths[$key] = (
211  isset($contextPaths[$key]) && !empty($contextPaths[$key]) ?
212  $contextPaths[$key] : 'index'
213  );
214  $contextPaths[$key] = Core::cleanFileVar($contextPaths[$key]);
215  }
216 
217  return $contextPaths;
218  }
219 
231  static function getPage($urlInfo, $isPathInfo, $userVars = array()) {
232  $page = Core::_getUrlComponents($urlInfo, $isPathInfo, 0, 'page', $userVars);
233  return Core::cleanFileVar(is_null($page) ? '' : $page);
234  }
235 
247  static function getOp($urlInfo, $isPathInfo, $userVars = array()) {
248  $operation = Core::_getUrlComponents($urlInfo, $isPathInfo, 1, 'op', $userVars);
249  return Core::cleanFileVar(empty($operation) ? 'index' : $operation);
250  }
251 
264  static function getArgs($urlInfo, $isPathInfo, $userVars = array()) {
265  return Core::_getUrlComponents($urlInfo, $isPathInfo, 2, 'path', $userVars);
266  }
276  function removeBaseUrl($url) {
277  list($baseUrl, $contextPath) = Core::_getBaseUrlAndPath($url);
278 
279  if (!$baseUrl) return false;
280 
281  // Remove base url from url, if any.
282  $url = str_replace($baseUrl, '', $url);
283 
284  // If url doesn't have the entire protocol and host part,
285  // remove any possible base url path from url.
286  $baseUrlPath = parse_url($baseUrl, PHP_URL_PATH);
287  if ($baseUrlPath == $url) {
288  // Access to the base url, no context, the entire
289  // url is part of the base url and we can return empty.
290  $url = '';
291  } else {
292  // Handle case where index.php was removed by rewrite rules,
293  // and we have base url followed by the args.
294  if (strpos($url, $baseUrlPath . '?') === 0) {
295  $replacement = '?'; // Url path replacement.
296  $baseSystemEscapedPath = preg_quote($baseUrlPath . '?', '/');
297  } else {
298  $replacement = '/'; // Url path replacement.
299  $baseSystemEscapedPath = preg_quote($baseUrlPath . '/', '/');
300  }
301  $url = preg_replace('/^' . $baseSystemEscapedPath . '/', $replacement, $url);
302 
303  // Remove possible index.php page from url.
304  $url = str_replace('/index.php', '', $url);
305  }
306 
307  if ($contextPath) {
308  // We found the contextPath using the base_url
309  // config file settings. Check if the url starts
310  // with the context path, if not, prepend it.
311  if (strpos($url, '/' . $contextPath) !== 0) {
312  $url = '/' . $contextPath . $url;
313  }
314  }
315 
316  // Remove any possible trailing slashes.
317  $url = rtrim($url, '/');
318 
319  return $url;
320  }
321 
329  function _getBaseUrlAndPath($url) {
330  $baseUrl = false;
331  $contextPath = false;
333  // Check for override base url settings.
334  $contextBaseUrls = Config::getContextBaseUrls();
335 
336  if (empty($contextBaseUrls)) {
337  $baseUrl = Config::getVar('general', 'base_url');
338  } else {
339  // We are just interested in context base urls, remove the index one.
340  if (isset($contextBaseUrls['index'])) {
341  unset($contextBaseUrls['index']);
342  }
343 
344  // Arrange them in length order, so we make sure
345  // we get the correct one, in case there's an overlaping
346  // of contexts, eg.:
347  // base_url[context1] = http://somesite.com/
348  // base_url[context2] = http://somesite.com/context2
349  $sortedBaseUrls = array_combine($contextBaseUrls, array_map('strlen', $contextBaseUrls));
350  arsort($sortedBaseUrls);
351 
352  foreach (array_keys($sortedBaseUrls) as $workingBaseUrl) {
353  $urlHost = parse_url($url, PHP_URL_HOST);
354  if (is_null($urlHost)) {
355  // Check the base url without the host part.
356  $baseUrlHost = parse_url($workingBaseUrl, PHP_URL_HOST);
357  if (is_null($baseUrlHost)) break;
358  $baseUrlToSearch = substr($workingBaseUrl, strpos($workingBaseUrl, $baseUrlHost) + strlen($baseUrlHost));
359  // Base url with only host part, add trailing slash
360  // so it can be checked below.
361  if (!$baseUrlToSearch) $baseUrlToSearch = '/';
362  } else {
363  $baseUrlToSearch = $workingBaseUrl;
364  }
365 
366  $baseUrlCheck = Core::_checkBaseUrl($baseUrlToSearch, $url);
367  if (is_null($baseUrlCheck)) {
368  // Can't decide. Stop searching.
369  break;
370  } else if ($baseUrlCheck === true) {
371  $contextPath = array_search($workingBaseUrl, $contextBaseUrls);
372  $baseUrl = $workingBaseUrl;
373  break;
374  }
375  }
376  }
377 
378  return array($baseUrl, $contextPath);
379  }
380 
393  function _checkBaseUrl($baseUrl, $url) {
394  // Check if both base url and url have host
395  // component or not.
396  $baseUrlHasHost = (boolean) parse_url($baseUrl, PHP_URL_HOST);
397  $urlHasHost = (boolean) parse_url($url, PHP_URL_HOST);
398  if ($baseUrlHasHost !== $urlHasHost) return false;
399 
400  $contextBaseUrls =& Config::getContextBaseUrls();
401 
402  // If the base url is found inside the passed url,
403  // then we might found the right context path.
404  if (strpos($url, $baseUrl) === 0) {
405  if (strpos($url, '/index.php') == strlen($baseUrl) - 1) {
406  // index.php appears right after the base url,
407  // no more possible paths.
408  return true;
409  } else {
410  // Still have to check if there is no other context
411  // base url that combined with it's context path is
412  // equal to this base url. If it exists, we can't
413  // tell which base url is contained in url.
414  foreach ($contextBaseUrls as $contextPath => $workingBaseUrl) {
415  $urlToCheck = $workingBaseUrl . '/' . $contextPath;
416  if (!$baseUrlHasHost) $urlToCheck = parse_url($urlToCheck, PHP_URL_PATH);
417  if ($baseUrl == $urlToCheck) {
418  return null;
419  }
420  }
421 
422  return true;
423  }
424  }
425 
426  return false;
427  }
428 
434  static function _botFileListCacheMiss($cache) {
435  $id = $cache->getCacheId();
436  $botRegexps = array_filter(file(Registry::get('currentUserAgentsFile')),
437  array('Core', '_filterBotRegexps'));
438  $cache->setEntireCache($botRegexps);
439  return $botRegexps;
440  }
441 
447  static function _filterBotRegexps(&$regexp) {
448  $delimiter = '/';
449  $regexp = trim($regexp);
450  if (!empty($regexp) && $regexp[0] != '#') {
451  if(strpos($regexp, $delimiter) !== 0) {
452  // Make sure delimiters are in place.
453  $regexp = $delimiter . $regexp . $delimiter;
454  }
455  } else {
456  return false;
457  }
458  return true;
459  }
460 
468  private static function _getUserVar($url, $varName, $userVars = array()) {
469  $returner = null;
470  parse_str(parse_url($url, PHP_URL_QUERY), $userVarsFromUrl);
471  if (isset($userVarsFromUrl[$varName])) $returner = $userVarsFromUrl[$varName];
472 
473  if (is_null($returner)) {
474  // Try to retrieve from passed user vars, if any.
475  if (!empty($userVars) && isset($userVars[$varName])) {
476  $returner = $userVars[$varName];
477  }
478  }
479 
480  return $returner;
481  }
482 
494  private static function _getUrlComponents($urlInfo, $isPathInfo, $offset, $varName = '', $userVars = array()) {
495  $component = null;
496 
497  $isArrayComponent = false;
498  if ($varName == 'path') {
499  $isArrayComponent = true;
500  }
501  if ($isPathInfo) {
502  $application = Application::getApplication();
503  $contextDepth = $application->getContextDepth();
504 
505  $vars = explode('/', trim($urlInfo, '/'));
506  if (count($vars) > $contextDepth + $offset) {
507  if ($isArrayComponent) {
508  $component = array_slice($vars, $contextDepth + $offset);
509  for ($i=0, $count=count($component); $i<$count; $i++) {
510  $component[$i] = Core::cleanVar(get_magic_quotes_gpc() ? stripslashes($component[$i]) : $component[$i]);
511  }
512  } else {
513  $component = $vars[$contextDepth + $offset];
514  }
515  }
516  } else {
517  $component = Core::_getUserVar($urlInfo, $varName, $userVars);
518  }
519 
520  if ($isArrayComponent) {
521  if (empty($component)) $component = array();
522  elseif (!is_array($component)) $component = array($component);
523  }
524 
525  return $component;
526  }
527 }
528 
529 ?>
static serverPHPOS()
Definition: Core.inc.php:112
static cleanFileVar($var)
Definition: Core.inc.php:86
static isUserAgentBot($userAgent, $botRegexpsFile=USER_AGENTS_FILE)
Definition: Core.inc.php:151
static getArgs($urlInfo, $isPathInfo, $userVars=array())
Definition: Core.inc.php:267
static set($key, &$value)
static getContextPaths($urlInfo, $isPathInfo, $contextList=null, $contextDepth=null, $userVars=array())
Definition: Core.inc.php:183
Class containing system-wide functions.
Definition: Core.inc.php:25
static microtime()
Definition: Core.inc.php:103
& getContextBaseUrls()
Definition: Config.inc.php:94
static utf8_normalize($str)
static isWindows()
Definition: Core.inc.php:128
static getOp($urlInfo, $isPathInfo, $userVars=array())
Definition: Core.inc.php:250
static getVar($section, $key, $default=null)
Definition: Config.inc.php:35
static _filterBotRegexps(&$regexp)
Definition: Core.inc.php:450
static serverPHPVersion()
Definition: Core.inc.php:120
static regexp_match($pattern, $subject)
static $botRegexps
Definition: Core.inc.php:31
_checkBaseUrl($baseUrl, $url)
Definition: Core.inc.php:396
static utf8_strip_ascii_ctrl($str)
static utf8_bad_strip($str)
static utf8_is_valid($str)
static & get($key, $createIfEmpty=false, $createWithDefault=null)
static _botFileListCacheMiss($cache)
Definition: Core.inc.php:437
static getManager()
static cleanVar($var)
Definition: Core.inc.php:54
static regexp_replace($pattern, $replacement, $subject, $limit=-1)
removeBaseUrl($url)
Definition: Core.inc.php:279
static checkGeneralPHPModule($moduleName)
Definition: Core.inc.php:137
_getBaseUrlAndPath($url)
Definition: Core.inc.php:332
static getPage($urlInfo, $isPathInfo, $userVars=array())
Definition: Core.inc.php:234
static getBaseDir()
Definition: Core.inc.php:37
static getCurrentDate($ts=null)
Definition: Core.inc.php:95