This repository has been archived on 2023-10-21. You can view files and clone it, but cannot push or open issues or pull requests.
patchouli/src/Platform.php
2020-12-29 22:44:39 +00:00

142 lines
5 KiB
PHP

<?php
namespace Patchouli;
use InvalidArgumentException;
use FWIF\FWIFSerializable;
class Platform implements FWIFSerializable {
public const ANY = '*';
public const WINDOWS = 'win';
public const OSX = 'mac';
public const LINUX = 'lin';
public const IA32 = 'ia32';
public const AMD64 = 'amd64';
public const ARMSF = 'armsf';
public const ARMHF = 'armhf';
public const ARM64 = 'arm64';
public const ANY_ANY = self::ANY . '/' . self::ANY;
public const ANY_IA32 = self::ANY . '/' . self::IA32;
public const ANY_AMD64 = self::ANY . '/' . self::AMD64;
public const ANY_ARMSF = self::ANY . '/' . self::ARMSF;
public const ANY_ARMHF = self::ANY . '/' . self::ARMHF;
public const ANY_ARM64 = self::ANY . '/' . self::ARM64;
public const WIN_ANY = self::WINDOWS . '/' . self::ANY;
public const WIN_IA32 = self::WINDOWS . '/' . self::IA32;
public const WIN_AMD64 = self::WINDOWS . '/' . self::AMD64;
public const WIN_ARM64 = self::WINDOWS . '/' . self::ARM64;
public const OSX_ANY = self::OSX . '/' . self::ANY;
public const OSX_AMD64 = self::OSX . '/' . self::AMD64;
public const OSX_ARM64 = self::OSX . '/' . self::ARM64;
public const LIN_ANY = self::LINUX . '/' . self::ANY;
public const LIN_IA32 = self::LINUX . '/' . self::IA32;
public const LIN_AMD64 = self::LINUX . '/' . self::AMD64;
public const LIN_ARMSF = self::LINUX . '/' . self::ARMSF;
public const LIN_ARMHF = self::LINUX . '/' . self::ARMHF;
public const LIN_ARM64 = self::LINUX . '/' . self::ARM64;
private static $platforms = [];
public static function get(string $platform): self {
if(empty(self::$platforms[$platform]))
self::$platforms[$platform] = new static($platform);
return self::$platforms[$platform];
}
public static function getUser(?string $os = null, ?string $arch = null): self {
$os ??= filter_input(INPUT_GET, 'os', FILTER_SANITIZE_STRING);
$arch ??= filter_input(INPUT_GET, 'arch', FILTER_SANITIZE_STRING);
if(empty($os) || !ctype_alnum($os))
$os = self::ANY;
if(empty($arch) || !ctype_alnum($arch))
$arch = self::ANY;
return self::get(sprintf('%s/%s', strtolower($os), strtolower($arch)));
}
public static function isMatch(string $platform, Platform $other): bool {
return self::get($platform)->match($other);
}
public static function isWindows(Platform $other): bool { return self::isMatch(self::WIN_ANY, $other); }
public static function isMacOS(Platform $other) : bool { return self::isMatch(self::OSX_ANY, $other); }
public static function isLinux(Platform $other) : bool { return self::isMatch(self::LIN_ANY, $other); }
private string $os;
private string $arch;
private ?Version $version;
public function __construct(string $os, ?string $arch = null, ?Version $version = null) {
if($arch == null) {
if(strpos($os, '/') === true)
throw new InvalidArgumentException('$arch cannot be null if $os doesn\'t contain a slash.');
$parts = explode('/', $os, 2);
$os = $parts[0];
$arch = $parts[1];
}
$this->os = $os;
$this->arch = $arch;
$this->version = $version;
}
public function getOperatingSystem(): string {
return $this->os;
}
public function getArchitecture(): string {
return $this->arch;
}
public function hasVersion(): bool {
return $this->version !== null;
}
public function getVersion(): Version {
return $this->version;
}
public function withVersion(Version $version): self {
return new static($this->getOperatingSystem(), $this->getArchitecture(), $version);
}
public function matchOperatingSystem(Platform $other): bool {
if($this->getOperatingSystem() === '*' || $other->getOperatingSystem() === '*')
return true;
return $this->getOperatingSystem() === $other->getOperatingSystem();
}
public function matchArchitecture(Platform $other): bool {
if($this->getArchitecture() === '*' || $other->getArchitecture() === '*')
return true;
return $this->getArchitecture() === $other->getArchitecture();
}
public function matchVersion(Platform $other): bool {
if(!$this->hasVersion())
return !$other->hasVersion();
if(!$other->hasVersion())
return false;
return $this->getVersion()->match($other->getVersion());
}
public function match(Platform $other, bool $matchVersion = false): bool {
if(!$this->matchOperatingSystem($other) || !$this->matchArchitecture($other))
return false;
if($matchVersion && !$this->matchVersion($other))
return false;
return true;
}
public function __toString(): string {
return sprintf('%s/%s', $this->getOperatingSystem(), $this->getArchitecture());
}
public function fwifSerialize() {
return (string)$this;
}
}