<?php
declare(strict_types=1);
/**
* @package Grav\Framework\Psr7
*
* @copyright Copyright (c) 2015 - 2025 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Framework\Psr7;
use Grav\Framework\Psr7\Traits\ServerRequestDecoratorTrait;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use function is_array;
use function is_object;
/**
* Class ServerRequest
* @package Slim\Http
*/
class ServerRequest implements ServerRequestInterface
{
use ServerRequestDecoratorTrait;
/**
* @param string $method HTTP method
* @param string|UriInterface $uri URI
* @param array $headers Request headers
* @param string|null|resource|StreamInterface $body Request body
* @param string $version Protocol version
* @param array $serverParams Typically the $_SERVER superglobal
*/
public function __construct(string $method, $uri, array $headers = [], $body = null, string $version = '1.1', array $serverParams = [])
{
$this->message = new \Nyholm\Psr7\ServerRequest($method, $uri, $headers, $body, $version, $serverParams);
}
/**
* Get serverRequest content character set, if known.
*
* Note: This method is not part of the PSR-7 standard.
*
* @return string|null
*/
public function getContentCharset(): ?string
{
$mediaTypeParams = $this->getMediaTypeParams();
if (isset($mediaTypeParams['charset'])) {
return $mediaTypeParams['charset'];
}
return null;
}
/**
* Get serverRequest content type.
*
* Note: This method is not part of the PSR-7 standard.
*
* @return string|null The serverRequest content type, if known
*/
public function getContentType(): ?string
{
$result = $this->getRequest()->getHeader('Content-Type');
return $result ? $result[0] : null;
}
/**
* Get serverRequest content length, if known.
*
* Note: This method is not part of the PSR-7 standard.
*
* @return int|null
*/
public function getContentLength(): ?int
{
$result = $this->getRequest()->getHeader('Content-Length');
return $result ? (int) $result[0] : null;
}
/**
* Fetch cookie value from cookies sent by the client to the server.
*
* Note: This method is not part of the PSR-7 standard.
*
* @param string $key The attribute name.
* @param mixed $default Default value to return if the attribute does not exist.
*
* @return mixed
*/
public function getCookieParam($key, $default = null)
{
$cookies = $this->getRequest()->getCookieParams();
return $cookies[$key] ?? $default;
}
/**
* Get serverRequest media type, if known.
*
* Note: This method is not part of the PSR-7 standard.
*
* @return string|null The serverRequest media type, minus content-type params
*/
public function getMediaType(): ?string
{
$contentType = $this->getContentType();
if ($contentType) {
$contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
if ($contentTypeParts === false) {
return null;
}
return strtolower($contentTypeParts[0]);
}
return null;
}
/**
* Get serverRequest media type params, if known.
*
* Note: This method is not part of the PSR-7 standard.
*
* @return mixed[]
*/
public function getMediaTypeParams(): array
{
$contentType = $this->getContentType();
$contentTypeParams = [];
if ($contentType) {
$contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
if ($contentTypeParts !== false) {
$contentTypePartsLength = count($contentTypeParts);
for ($i = 1; $i < $contentTypePartsLength; $i++) {
$paramParts = explode('=', $contentTypeParts[$i]);
$contentTypeParams[strtolower($paramParts[0])] = $paramParts[1];
}
}
}
return $contentTypeParams;
}
/**
* Fetch serverRequest parameter value from body or query string (in that order).
*
* Note: This method is not part of the PSR-7 standard.
*
* @param string $key The parameter key.
* @param string|null $default The default value.
*
* @return mixed The parameter value.
*/
public function getParam($key, $default = null)
{
$postParams = $this->getParsedBody();
$getParams = $this->getQueryParams();
$result = $default;
if (is_array($postParams) && isset($postParams[$key])) {
$result = $postParams[$key];
} elseif (is_object($postParams) && property_exists($postParams, $key)) {
$result = $postParams->$key;
} elseif (isset($getParams[$key])) {
$result = $getParams[$key];
}
return $result;
}
/**
* Fetch associative array of body and query string parameters.
*
* Note: This method is not part of the PSR-7 standard.
*
* @return mixed[]
*/
public function getParams(): array
{
$params = $this->getQueryParams();
$postParams = $this->getParsedBody();
if ($postParams) {
$params = array_merge($params, (array)$postParams);
}
return $params;
}
/**
* Fetch parameter value from serverRequest body.
*
* Note: This method is not part of the PSR-7 standard.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function getParsedBodyParam($key, $default = null)
{
$postParams = $this->getParsedBody();
$result = $default;
if (is_array($postParams) && isset($postParams[$key])) {
$result = $postParams[$key];
} elseif (is_object($postParams) && property_exists($postParams, $key)) {
$result = $postParams->{$key};
}
return $result;
}
/**
* Fetch parameter value from query string.
*
* Note: This method is not part of the PSR-7 standard.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function getQueryParam($key, $default = null)
{
$getParams = $this->getQueryParams();
return $getParams[$key] ?? $default;
}
/**
* Retrieve a server parameter.
*
* Note: This method is not part of the PSR-7 standard.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function getServerParam($key, $default = null)
{
$serverParams = $this->getRequest()->getServerParams();
return $serverParams[$key] ?? $default;
}
/**
* Does this serverRequest use a given method?
*
* Note: This method is not part of the PSR-7 standard.
*
* @param string $method HTTP method
* @return bool
*/
public function isMethod($method): bool
{
return $this->getRequest()->getMethod() === $method;
}
/**
* Is this a DELETE serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isDelete(): bool
{
return $this->isMethod('DELETE');
}
/**
* Is this a GET serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isGet(): bool
{
return $this->isMethod('GET');
}
/**
* Is this a HEAD serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isHead(): bool
{
return $this->isMethod('HEAD');
}
/**
* Is this a OPTIONS serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isOptions(): bool
{
return $this->isMethod('OPTIONS');
}
/**
* Is this a PATCH serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isPatch(): bool
{
return $this->isMethod('PATCH');
}
/**
* Is this a POST serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isPost(): bool
{
return $this->isMethod('POST');
}
/**
* Is this a PUT serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isPut(): bool
{
return $this->isMethod('PUT');
}
/**
* Is this an XHR serverRequest?
*
* Note: This method is not part of the PSR-7 standard.
*
* @return bool
*/
public function isXhr(): bool
{
return $this->getRequest()->getHeaderLine('X-Requested-With') === 'XMLHttpRequest';
}
}