[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
05122024
/
htdocs
/
jurnal-kesmas
/
v1
/
lib
/
pkp
/
classes
/
core
/
[
Home
]
File: PKPRequest.php
<?php /** * @file classes/core/PKPRequest.php * * Copyright (c) 2014-2021 Simon Fraser University * Copyright (c) 2000-2021 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class PKPRequest * * @ingroup core * * @brief Class providing operations associated with HTTP requests. */ namespace PKP\core; use APP\core\Application; use APP\facades\Repo; use APP\file\PublicFileManager; use PKP\config\Config; use PKP\context\Context; use PKP\db\DAORegistry; use PKP\handler\APIHandler; use PKP\plugins\Hook; use PKP\security\Validation; use PKP\session\Session; use PKP\session\SessionManager; use PKP\site\Site; use PKP\site\SiteDAO; use PKP\user\User; class PKPRequest { // // Internal state - please do not reference directly // /** @var PKPRouter router instance used to route this request */ public $_router = null; /** @var Dispatcher dispatcher instance used to dispatch this request */ public $_dispatcher = null; /** @var array the request variables cache (GET/POST) */ public $_requestVars = null; /** @var string request base path */ public $_basePath; /** @var string request path */ public $_requestPath; /** @var bool true if restful URLs are enabled in the config */ public $_isRestfulUrlsEnabled; /** @var string server host */ public $_serverHost; /** @var string request protocol */ public $_protocol; /** @var bool bot flag */ public $_isBot; /** @var string user agent */ public $_userAgent; /** * get the router instance * * @return PKPRouter */ public function &getRouter() { return $this->_router; } /** * set the router instance * * @param PKPRouter $router */ public function setRouter($router) { $this->_router = $router; } /** * Set the dispatcher * * @param Dispatcher $dispatcher */ public function setDispatcher($dispatcher) { $this->_dispatcher = $dispatcher; } /** * Get the dispatcher * * @return Dispatcher */ public function &getDispatcher() { if (! $this->_dispatcher) { $application = Application::get(); $this->setDispatcher($application->getDispatcher()); } return $this->_dispatcher; } /** * Perform an HTTP redirect to an absolute or relative (to base system URL) URL. * * @param string $url (exclude protocol for local redirects) */ public function redirectUrl($url) { if (Hook::call('Request::redirect', [&$url])) { return; } header("Location: {$url}"); exit; } /** * Request an HTTP redirect via JSON to be used from components. * * @param string $url * * @return JSONMessage */ public function redirectUrlJson($url) { $json = new JSONMessage(true); $json->setEvent('redirectRequested', $url); return $json; } /** * Redirect to the current URL, forcing the HTTPS protocol to be used. */ public function redirectSSL() { // Note that we are intentionally skipping PKP processing of REQUEST_URI and QUERY_STRING for a protocol redirect // This processing is deferred to the redirected (target) URI $url = 'https://' . $this->getServerHost() . $_SERVER['REQUEST_URI']; $queryString = $_SERVER['QUERY_STRING']; if (!empty($queryString)) { $url .= "?{$queryString}"; } $this->redirectUrl($url); } /** * Redirect to the current URL, forcing the HTTP protocol to be used. */ public function redirectNonSSL() { // Note that we are intentionally skipping PKP processing of REQUEST_URI and QUERY_STRING for a protocol redirect // This processing is deferred to the redirected (target) URI $url = 'http://' . $this->getServerHost() . $_SERVER['REQUEST_URI']; $queryString = $_SERVER['QUERY_STRING']; if (!empty($queryString)) { $url .= "?{$queryString}"; } $this->redirectUrl($url); } /** * Get the IF_MODIFIED_SINCE date (as a numerical timestamp) if available * * @return ?int */ public function getIfModifiedSince() { if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { return null; } return strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); } /** * Get the base URL of the request (excluding script). * * @param bool $allowProtocolRelative True iff protocol-relative URLs are allowed * * @return string */ public function getBaseUrl($allowProtocolRelative = false) { $serverHost = $this->getServerHost(false); if ($serverHost !== false) { // Auto-detection worked. if ($allowProtocolRelative) { $baseUrl = '//' . $this->getServerHost() . $this->getBasePath(); } else { $baseUrl = $this->getProtocol() . '://' . $this->getServerHost() . $this->getBasePath(); } } else { // Auto-detection didn't work (e.g. this is a command-line call); use configuration param $baseUrl = Config::getVar('general', 'base_url'); } Hook::call('Request::getBaseUrl', [&$baseUrl]); return $baseUrl; } /** * Get the base path of the request (excluding trailing slash). * * @return string */ public function getBasePath() { if (!isset($this->_basePath)) { // Strip the PHP filename off of the script's executed path // We expect the SCRIPT_NAME to look like /path/to/file.php // If the SCRIPT_NAME ends in /, assume this is the directory and the script's actual name // is masked as the DirectoryIndex // If the SCRIPT_NAME ends in neither / or .php, assume the the script's actual name is masked // and we need to avoid stripping the terminal directory $path = preg_replace('#/[^/]*$#', '', $_SERVER['SCRIPT_NAME'] . (substr($_SERVER['SCRIPT_NAME'], -1) == '/' || preg_match('#.php$#i', $_SERVER['SCRIPT_NAME']) ? '' : '/')); // Encode characters which need to be encoded in a URL. // Simply using rawurlencode() doesn't work because it // also encodes characters which are valid in a URL (i.e. @, $). $parts = explode('/', $path); foreach ($parts as $i => $part) { $pieces = array_map([$this, 'encodeBasePathFragment'], str_split($part)); $parts[$i] = implode('', $pieces); } $this->_basePath = implode('/', $parts); if ($this->_basePath == '/' || $this->_basePath == '\\') { $this->_basePath = ''; } Hook::call('Request::getBasePath', [&$this->_basePath]); } return $this->_basePath; } /** * Callback function for getBasePath() to correctly encode (or not encode) * a basepath fragment. * * @param string $fragment * * @return string */ public function encodeBasePathFragment($fragment) { if (!preg_match('/[A-Za-z0-9-._~!$&\'()*+,;=:@]/', $fragment)) { return rawurlencode($fragment); } return $fragment; } /** * Deprecated * * @see PKPPageRouter::getIndexUrl() */ public function getIndexUrl() { static $indexUrl; if (!isset($indexUrl)) { $indexUrl = $this->_delegateToRouter('getIndexUrl'); // Call legacy hook Hook::call('Request::getIndexUrl', [&$indexUrl]); } return $indexUrl; } /** * Get the complete URL to this page, including parameters. * * @return string */ public function getCompleteUrl() { static $completeUrl; if (!isset($completeUrl)) { $completeUrl = $this->getRequestUrl(); $queryString = $this->getQueryString(); if (!empty($queryString)) { $completeUrl .= "?{$queryString}"; } Hook::call('Request::getCompleteUrl', [&$completeUrl]); } return $completeUrl; } /** * Get the complete URL of the request. * * @return string */ public function getRequestUrl() { static $requestUrl; if (!isset($requestUrl)) { $requestUrl = $this->getProtocol() . '://' . $this->getServerHost() . $this->getRequestPath(); Hook::call('Request::getRequestUrl', [&$requestUrl]); } return $requestUrl; } /** * Get the complete set of URL parameters to the current request. * * @return string */ public function getQueryString() { static $queryString; if (!isset($queryString)) { $queryString = $_SERVER['QUERY_STRING'] ?? ''; Hook::call('Request::getQueryString', [&$queryString]); } return $queryString; } /** * Get the complete set of URL parameters to the current request as an * associative array. * * @return array */ public function getQueryArray() { $queryString = $this->getQueryString(); $queryArray = []; if (isset($queryString)) { parse_str($queryString, $queryArray); } return $queryArray; } /** * Get the completed path of the request. * * @return string */ public function getRequestPath() { if (!isset($this->_requestPath)) { if ($this->isRestfulUrlsEnabled()) { $this->_requestPath = $this->getBasePath(); } else { $this->_requestPath = $_SERVER['SCRIPT_NAME'] ?? ''; } $this->_requestPath .= $_SERVER['PATH_INFO'] ?? ''; Hook::call('Request::getRequestPath', [&$this->_requestPath]); } return $this->_requestPath; } /** * Get the server hostname in the request. * * @param string $default Default hostname (defaults to localhost) * @param bool $includePort Whether to include non-standard port number; default true * * @return string */ public function getServerHost($default = null, $includePort = true) { if ($default === null) { $default = 'localhost'; } if (!isset($this->_serverHost)) { $this->_serverHost = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? ($_SERVER['HTTP_HOST'] ?? ($_SERVER['SERVER_NAME'] ?? $default)); // in case of multiple host entries in the header (e.g. multiple reverse proxies) take the first entry $this->_serverHost = strtok($this->_serverHost, ','); Hook::call('Request::getServerHost', [&$this->_serverHost, &$default, &$includePort]); } if (!$includePort) { // Strip the port number, if one is included. (#3912) return preg_replace("/:\d*$/", '', $this->_serverHost); } return $this->_serverHost; } /** * Get the protocol used for the request (HTTP or HTTPS). * * @return string */ public function getProtocol() { if (!isset($this->_protocol)) { $this->_protocol = (!isset($_SERVER['HTTPS']) || strtolower_codesafe($_SERVER['HTTPS']) != 'on') ? 'http' : 'https'; Hook::call('Request::getProtocol', [&$this->_protocol]); } return $this->_protocol; } /** * Get the request method * * @return string */ public function getRequestMethod() { return ($_SERVER['REQUEST_METHOD'] ?? ''); } /** * Determine whether the request is a POST request * * @return bool */ public function isPost() { return ($this->getRequestMethod() == 'POST'); } /** * Determine whether the request is a GET request * * @return bool */ public function isGet() { return ($this->getRequestMethod() == 'GET'); } /** * Determine whether a CSRF token is present and correct. * * @return bool */ public function checkCSRF() { $session = $this->getSession(); return $this->getUserVar('csrfToken') == $session->getCSRFToken(); } /** * Get the remote IP address of the current request. * * @return string */ public function getRemoteAddr() { $ipaddr = & Registry::get('remoteIpAddr'); // Reference required. if (is_null($ipaddr)) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && Config::getVar('general', 'trust_x_forwarded_for', true) && preg_match_all('/([0-9.a-fA-F:]+)/', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) { } elseif (isset($_SERVER['REMOTE_ADDR']) && preg_match_all('/([0-9.a-fA-F:]+)/', $_SERVER['REMOTE_ADDR'], $matches)) { } elseif (preg_match_all('/([0-9.a-fA-F:]+)/', getenv('REMOTE_ADDR'), $matches)) { } else { $ipaddr = ''; } if (!isset($ipaddr)) { // If multiple addresses are listed, take the last. (Supports ipv6.) $ipaddr = $matches[0][count($matches[0]) - 1]; } Hook::call('Request::getRemoteAddr', [&$ipaddr]); } return $ipaddr; } /** * Get the remote domain of the current request * * @return string */ public function getRemoteDomain() { static $remoteDomain; if (!isset($remoteDomain)) { $remoteDomain = null; $remoteDomain = @getHostByAddr($this->getRemoteAddr()); Hook::call('Request::getRemoteDomain', [&$remoteDomain]); } return $remoteDomain; } /** * Get the user agent of the current request. * * @return string */ public function getUserAgent() { if (!isset($this->_userAgent)) { if (isset($_SERVER['HTTP_USER_AGENT'])) { $this->_userAgent = $_SERVER['HTTP_USER_AGENT']; } if (!isset($this->_userAgent) || empty($this->_userAgent)) { $this->_userAgent = getenv('HTTP_USER_AGENT'); } if (!isset($this->_userAgent) || $this->_userAgent == false) { $this->_userAgent = ''; } Hook::call('Request::getUserAgent', [&$this->_userAgent]); } return $this->_userAgent; } /** * Determine whether the user agent is a bot or not. * * @return bool */ public function isBot() { if (!isset($this->_isBot)) { $userAgent = $this->getUserAgent(); $this->_isBot = Core::isUserAgentBot($userAgent); } return $this->_isBot; } /** * Check if the HTTP_DNT (Do Not Track) is set */ public function getDoNotTrack(): bool { return (array_key_exists('HTTP_DNT', $_SERVER) && ((int) $_SERVER['HTTP_DNT'] === 1)); } /** * Return true if RESTFUL_URLS is enabled. */ public function isRestfulUrlsEnabled() { if (!isset($this->_isRestfulUrlsEnabled)) { $this->_isRestfulUrlsEnabled = Config::getVar('general', 'restful_urls') ? true : false; } return $this->_isRestfulUrlsEnabled; } /** * Get site data. * */ public function getSite(): ?Site { $site = & Registry::get('site', true, null); /** @var SiteDAO */ $siteDao = DAORegistry::getDAO('SiteDAO'); return $site ??= $siteDao->getSite(); } /** * Get the user session associated with the current request. */ public function getSession(): Session { $session = & Registry::get('session', true, null); return $session ??= SessionManager::getManager()->getUserSession(); } /** * Get the user associated with the current request. */ public function getUser(): ?User { $user = & Registry::get('user', true, null); if ($user) { return $user; } // Attempt to load user from API token if (($handler = $this->getRouter()->getHandler()) && ($token = $handler->getApiToken()) && ($apiUser = Repo::user()->getByApiKey($token)) && $apiUser->getData('apiKeyEnabled') ) { return $user = $apiUser; } // Attempts to retrieve a logged user if (Validation::isLoggedIn()) { $user = SessionManager::getManager()->getUserSession()->getUser(); } return $user; } /** * Get the value of a GET/POST variable. */ public function getUserVar($key) { // special treatment for APIRouter. APIHandler gets to fetch parameter first $router = $this->getRouter(); if ($router instanceof \PKP\core\APIRouter && (!is_null($handler = $router->getHandler()))) { /** @var APIHandler */ $handler = $router->getHandler(); $value = $handler->getParameter($key); if (!is_null($value)) { return $value; } } // Get all vars (already cleaned) $vars = $this->getUserVars(); return $vars[$key] ?? null; } /** * Get all GET/POST variables as an array * * @return array */ public function &getUserVars() { $this->_requestVars ??= array_map(fn ($s) => is_string($s) ? trim($s) : $s, array_merge($_GET, $_POST)); return $this->_requestVars; } /** * Get the value of a GET/POST variable generated using the Smarty * html_select_date and/or html_select_time function. * * @param string $prefix * @param int $defaultDay * @param int $defaultMonth * @param int $defaultYear * @param int $defaultHour * @param int $defaultMinute * @param int $defaultSecond * * @return ?int Linux timestamp */ public function getUserDateVar($prefix, $defaultDay = null, $defaultMonth = null, $defaultYear = null, $defaultHour = 0, $defaultMinute = 0, $defaultSecond = 0) { $monthPart = $this->getUserVar($prefix . 'Month'); $dayPart = $this->getUserVar($prefix . 'Day'); $yearPart = $this->getUserVar($prefix . 'Year'); $hourPart = $this->getUserVar($prefix . 'Hour'); $minutePart = $this->getUserVar($prefix . 'Minute'); $secondPart = $this->getUserVar($prefix . 'Second'); switch ($this->getUserVar($prefix . 'Meridian')) { case 'pm': if (is_numeric($hourPart) && $hourPart != 12) { $hourPart += 12; } break; case 'am': default: // Do nothing. break; } if (empty($dayPart)) { $dayPart = $defaultDay; } if (empty($monthPart)) { $monthPart = $defaultMonth; } if (empty($yearPart)) { $yearPart = $defaultYear; } if (empty($hourPart)) { $hourPart = $defaultHour; } if (empty($minutePart)) { $minutePart = $defaultMinute; } if (empty($secondPart)) { $secondPart = $defaultSecond; } if (empty($monthPart) || empty($dayPart) || empty($yearPart)) { return null; } return mktime($hourPart, $minutePart, $secondPart, $monthPart, $dayPart, $yearPart); } /** * Get the value of a cookie variable. */ public function getCookieVar($key) { if (isset($_COOKIE[$key])) { return $_COOKIE[$key]; } else { return null; } } /** * Set a cookie variable. * * @param string $key * @param int $expire (optional) */ public function setCookieVar($key, $value, $expire = 0) { $basePath = $this->getBasePath(); if (!$basePath) { $basePath = '/'; } setcookie($key, $value, $expire, $basePath); $_COOKIE[$key] = $value; } /** * Redirect to the specified page within a PKP Application. * Shorthand for a common call to $request->redirect($dispatcher->url($request, PKPApplication::ROUTE_PAGE, ...)). * * @param mixed $context The optional contextual paths * @param string $page The name of the op to redirect to. * @param string $op optional The name of the op to redirect to. * @param mixed $path string or array containing path info for redirect. * @param array $params Map of name => value pairs for additional parameters * @param string $anchor Name of desired anchor on the target page */ public function redirect($context = null, $page = null, $op = null, $path = null, $params = null, $anchor = null) { $dispatcher = $this->getDispatcher(); $this->redirectUrl($dispatcher->url($this, PKPApplication::ROUTE_PAGE, $context, $page, $op, $path, $params, $anchor)); } /** * Get the current "context" (press/journal/etc) object. * * @see PKPPageRouter::getContext() */ public function getContext(): ?Context { return $this->_delegateToRouter('getContext'); } /** * Deprecated * * @see PKPPageRouter::getRequestedPage() */ public function getRequestedPage() { return $this->_delegateToRouter('getRequestedPage'); } /** * Deprecated * * @see PKPPageRouter::getRequestedOp() */ public function getRequestedOp() { return $this->_delegateToRouter('getRequestedOp'); } /** * Deprecated * * @see PKPPageRouter::getRequestedArgs() */ public function getRequestedArgs() { return $this->_delegateToRouter('getRequestedArgs'); } /** * Deprecated * * @see PKPPageRouter::url() * * @param null|mixed $context * @param null|mixed $page * @param null|mixed $op * @param null|mixed $path * @param null|mixed $params * @param null|mixed $anchor */ public function url( $context = null, $page = null, $op = null, $path = null, $params = null, $anchor = null, $escape = false ) { return $this->_delegateToRouter( 'url', $context, $page, $op, $path, $params, $anchor, $escape ); } /** * Get the URL to the public file uploads directory */ public function getPublicFilesUrl(?Context $context = null): string { $publicFileManager = new PublicFileManager(); return join('/', [ $this->getBaseUrl(), $context ? $publicFileManager->getContextFilesPath($context->getId()) : $publicFileManager->getSiteFilesPath() ]); } /** * This method exists to maintain backwards compatibility * with calls to methods that have been factored into the * Router implementations. * * It delegates the call to the router and returns the result. * * NB: This method is protected and may not be used by * external classes. It should also only be used in legacy * methods. * * @return mixed depends on the called method */ public function &_delegateToRouter($method) { // This call is deprecated. We don't trigger a // deprecation error, though, as there are so // many instances of this error that it has a // performance impact and renders the error // log virtually useless when deprecation // warnings are switched on. // FIXME: Fix enough instances of this error so that // we can put a deprecation warning in here. $router = $this->getRouter(); if (is_null($router)) { assert(false); $nullValue = null; return $nullValue; } // Construct the method call $callable = [$router, $method]; // Get additional parameters but replace // the first parameter (currently the // method to be called) with the request // as all router methods required the request // as their first parameter. $parameters = func_get_args(); $parameters[0] = & $this; $returner = call_user_func_array($callable, $parameters); return $returner; } } if (!PKP_STRICT_MODE) { class_alias('\PKP\core\PKPRequest', '\PKPRequest'); }