uiharu/lib/mediatype.php
2022-07-03 22:41:44 +00:00

107 lines
3.5 KiB
PHP

<?php
class MediaType implements JsonSerializable {
private $type = '';
private $subtype = '';
private $suffix = '';
private $params = [];
public function __construct(string $mediaType) {
if(preg_match('#^([A-Za-z0-9\!\#\$%&\'\*\+\.\-_\{\}\|]+)/([A-Za-z0-9\!\#\$%&\'\*\+\.\-_\{\}\|]+)(?: ?; ?([A-Za-z0-9\!\#\$%&\'\*\+\.\-_\{\}\|\=; ]+))?$#', $mediaType, $matches) !== 1)
throw new InvalidArgumentException('Invalid media type supplied.');
$this->type = $matches[1];
$subTypeSplit = explode('+', $matches[2], 2);
$this->subtype = $subTypeSplit[0];
if(isset($subTypeSplit[1]))
$this->suffix = $subTypeSplit[1];
if(isset($matches[3])) {
$params = explode(';', $matches[3]);
foreach($params as $param) {
$parts = explode('=', trim($param), 2);
if(!isset($parts[1]))
continue;
$this->params[$parts[0]] = $parts[1];
}
}
}
public function getType(): string {
return $this->type;
}
public function getSubtype(): string {
return $this->subtype;
}
public function getSuffix(): string {
return $this->subtype;
}
public function getParams(): array {
return $this->params;
}
public function getParam(string $name, int $filter = FILTER_DEFAULT, $options = null) {
if(!isset($this->params[$name]))
return null;
return filter_var($this->params[$name], $filter, $options);
}
public function getCharset(): string {
return $this->getParam('charset', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH) ?? 'utf-8';
}
public function getQuality(): float {
return max(min(round($this->getParam('q', FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) ?? 1, 2), 1), 0);
}
public function match($other): bool {
if(is_string($other))
return $this->matchPattern($other);
if($other instanceof self)
return $this->matchType($other);
return false;
}
public function matchPattern(string $pattern): bool {
try {
$mediaType = new static($pattern);
} catch(InvalidArgumentException $ex) {
return false;
}
return $this->matchType($mediaType);
}
public function matchType(MediaType $other): bool {
return ($other->getType() === '*' && $other->getSubtype() === '*')
|| (
($other->getType() === $this->getType())
&& ($other->getSubtype() === '*' || $other->getSubtype() === $this->getSubtype())
);
}
public function __toString() {
$string = $this->type . '/';
$string .= $this->subtype;
if(!empty($this->suffix))
$string .= '+' . $this->suffix;
if(!empty($this->params))
foreach($this->params as $key => $value) {
$string .= ';';
if(!empty($key))
$string .= $key . '=';
$string .= $value;
}
return $string;
}
public function jsonSerialize(): stdClass {
$obj = new stdClass;
$obj->string = (string)$this;
$obj->type = $this->type;
$obj->subtype = $this->subtype;
if(!empty($this->suffix))
$obj->suffix = $this->suffix;
if(!empty($this->params))
$obj->params = $this->params;
return $obj;
}
}