Файл: vendor/intervention/image/src/DataUri.php
Строк: 201
<?php
declare(strict_types=1);
namespace InterventionImage;
use InterventionImageExceptionsInvalidArgumentException;
use InterventionImageInterfacesDataUriInterface;
use Stringable;
class DataUri implements DataUriInterface
{
/**
* Pattern of data uri scheme.
*/
protected const string PATTERN = "/^data:(?P<mediaType>w+/[-+.w]+)?" .
"(?P<parameters>(;[-w]+=[-w]+)*)(?P<base64>;base64)?,(?P<data>.*)/";
/**
* Media type of data uri output.
*/
protected ?string $mediaType = null;
/**
* Parameters of data uri output.
*
* @var array<string, string>
*/
protected array $parameters = [];
/**
* Create new data uri instance.
*
* @param array<string, string> $parameters
*/
public function __construct(
protected string|Stringable $data = '',
null|string|MediaType $mediaType = null,
array $parameters = [],
protected bool $base64 = true,
) {
$this->setMediaType($mediaType);
$this->setParameters($parameters);
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::create()
*/
public static function create(
string $data,
null|string|MediaType $mediaType = null,
array $parameters = [],
bool $base64 = true,
): self {
return new self(
data: $data,
mediaType: $mediaType,
parameters: $parameters,
base64: $base64,
);
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::parse()
*
* @throws InvalidArgumentException
*/
public static function parse(string|Stringable $dataUriScheme): self
{
$result = preg_match(self::PATTERN, (string) $dataUriScheme, $matches);
if ($result === false || $result === 0) {
throw new InvalidArgumentException('Invalid data uri scheme');
}
$isBase64Encoded = $matches['base64'] !== '';
$datauri = new self(
data: $isBase64Encoded ? base64_decode($matches['data'], strict: true) : rawurldecode($matches['data']),
mediaType: $matches['mediaType'],
base64: $isBase64Encoded,
);
if ($matches['parameters'] !== '') {
$parameters = explode(';', $matches['parameters']);
$parameters = array_filter($parameters, fn(string $value): bool => $value !== '');
$parameters = array_map(fn(string $value): array => explode('=', $value), $parameters);
foreach ($parameters as $parameter) {
$datauri->setParameter(...$parameter);
}
}
return $datauri;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::data()
*/
public function data(): string
{
return (string) $this->data;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::setData()
*/
public function setData(string|Stringable $data): self
{
$this->data = (string) $data;
return $this;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::mediaType()
*/
public function mediaType(): ?string
{
return $this->mediaType;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::setMediaType()
*/
public function setMediaType(null|string|MediaType $mediaType): self
{
$this->mediaType = $mediaType instanceof MediaType ? $mediaType->value : $mediaType;
return $this;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::parameters()
*/
public function parameters(): array
{
return $this->parameters;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::setParameters()
*/
public function setParameters(array $parameters): self
{
$this->parameters = $parameters;
return $this;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::appendParameters()
*/
public function appendParameters(array $parameters): self
{
foreach ($parameters as $key => $value) {
$this->setParameter((string) $key, (string) $value);
}
return $this;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::parameter()
*/
public function parameter(string $key): ?string
{
return $this->parameters[$key] ?? null;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::setParameter()
*/
public function setParameter(string $key, string $value): self
{
$this->parameters[$key] = $value;
return $this;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::charset()
*/
public function charset(): ?string
{
return $this->parameter('charset');
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::setCharset()
*/
public function setCharset(string $charset): self
{
$this->setParameter('charset', $charset);
return $this;
}
/**
* Prepare data for output.
*/
private function encodedData(): string
{
return $this->base64 === true ? (string) base64_encode($this->data) : rawurlencode((string) $this->data);
}
/**
* Prepare all set parameters for output.
*/
private function encodedParameters(): string
{
if (count($this->parameters) === 0 && $this->base64 === false) {
return '';
}
$parameters = array_map(function (mixed $key, mixed $value) {
return $key . '=' . $value;
}, array_keys($this->parameters), $this->parameters);
$parameterString = count($parameters) > 0 ? ';' . implode(';', $parameters) : '';
if ($this->base64 === true) {
$parameterString .= ';base64';
}
return $parameterString;
}
/**
* {@inheritdoc}
*
* @see DataUriInterface::toString()
*/
public function toString(): string
{
return 'data:' . $this->mediaType() . $this->encodedParameters() . ',' . $this->encodedData();
}
/**
* {@inheritdoc}
*
* @see Stringable::__toString()
*/
public function __toString(): string
{
return $this->toString();
}
/**
* Show debug info for the current data uri scheme.
*
* @return array<string, mixed>
*/
public function __debugInfo(): array
{
return [
'mediaType' => $this->mediaType,
'size' => strlen($this->data),
];
}
}