<?php
declare(strict_types=1);
namespace SHServ\Integrations\GAuth\Http;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
final class Psr7Request implements RequestInterface
{
private string $method;
private string $uri;
private array $headers = [];
private StreamInterface $body;
private string $protocolVersion = '1.1';
private string $requestTarget = '';
public function __construct(string $method, string $uri, array $headers = [], ?StreamInterface $body = null)
{
$this->method = $method;
$this->uri = $uri;
$this->headers = $this->normalizeHeaders($headers);
$this->body = $body ?? new Psr7Stream('');
}
private function normalizeHeaders(array $headers): array
{
$normalized = [];
foreach ($headers as $name => $values) {
$name = $this->normalizeHeaderName($name);
if (!is_array($values)) {
$values = [$values];
}
$normalized[$name] = array_map('strval', $values);
}
return $normalized;
}
private function normalizeHeaderName(string $name): string
{
return strtolower($name);
}
public function getProtocolVersion(): string
{
return $this->protocolVersion;
}
public function withProtocolVersion(string $version): RequestInterface
{
$new = clone $this;
$new->protocolVersion = $version;
return $new;
}
public function getHeaders(): array
{
$result = [];
foreach ($this->headers as $name => $values) {
$result[$this->studlyCase($name)] = $values;
}
return $result;
}
public function hasHeader(string $name): bool
{
return isset($this->headers[$this->normalizeHeaderName($name)]);
}
public function getHeader(string $name): array
{
return $this->headers[$this->normalizeHeaderName($name)] ?? [];
}
public function getHeaderLine(string $name): string
{
return implode(', ', $this->getHeader($name));
}
public function withHeader(string $name, $value): RequestInterface
{
$new = clone $this;
$new->headers[$this->normalizeHeaderName($name)] = is_array($value) ? array_map('strval', $value) : [(string) $value];
return $new;
}
public function withAddedHeader(string $name, $value): RequestInterface
{
$new = clone $this;
$name = $this->normalizeHeaderName($name);
if (!isset($new->headers[$name])) {
$new->headers[$name] = [];
}
$new->headers[$name] = array_merge($new->headers[$name], is_array($value) ? array_map('strval', $value) : [(string) $value]);
return $new;
}
public function withoutHeader(string $name): RequestInterface
{
$new = clone $this;
unset($new->headers[$this->normalizeHeaderName($name)]);
return $new;
}
public function getBody(): StreamInterface
{
return $this->body;
}
public function withBody(StreamInterface $body): RequestInterface
{
$new = clone $this;
$new->body = $body;
return $new;
}
public function getRequestTarget(): string
{
if ($this->requestTarget !== '') {
return $this->requestTarget;
}
return $this->uri;
}
public function withRequestTarget(string $requestTarget): RequestInterface
{
$new = clone $this;
$new->requestTarget = $requestTarget;
return $new;
}
public function getMethod(): string
{
return $this->method;
}
public function withMethod(string $method): RequestInterface
{
$new = clone $this;
$new->method = $method;
return $new;
}
public function getUri(): UriInterface
{
return new Psr7Uri($this->uri);
}
public function withUri(UriInterface $uri, bool $preserveHost = false): RequestInterface
{
$new = clone $this;
$new->uri = (string) $uri;
return $new;
}
private function studlyCase(string $name): string
{
return str_replace(' ', '-', ucwords(str_replace('-', ' ', $name)));
}
}
final class Psr7Uri implements UriInterface
{
private string $uri;
public function __construct(string $uri = '')
{
$this->uri = $uri;
}
public function __toString(): string
{
return $this->uri;
}
public function getScheme(): string { return ''; }
public function getAuthority(): string { return ''; }
public function getUserInfo(): string { return ''; }
public function getHost(): string { return ''; }
public function getPort(): ?int { return null; }
public function getPath(): string { return $this->uri; }
public function getQuery(): string { return ''; }
public function getFragment(): string { return ''; }
public function withScheme(string $scheme): UriInterface { return $this; }
public function withUserInfo(string $user, ?string $password = null): UriInterface { return $this; }
public function withHost(string $host): UriInterface { return $this; }
public function withPort(?int $port): UriInterface { return $this; }
public function withPath(string $path): UriInterface { $new = clone $this; $new->uri = $path; return $new; }
public function withQuery(string $query): UriInterface { return $this; }
public function withFragment(string $fragment): UriInterface { return $this; }
}