Compare commits

...

2 Commits

Author SHA1 Message Date
cb03c811ef Allow deeper nesting of hostnames 2026-06-02 13:19:25 +00:00
6f3c7338c7 Changed indentation and added type hints 2026-06-02 13:14:16 +00:00
2 changed files with 246 additions and 228 deletions

View File

@@ -20,7 +20,7 @@ class COIDParser {
const COID_VERSIONED = 3; const COID_VERSIONED = 3;
const COID_VERSION_WILDCARD = 4; const COID_VERSION_WILDCARD = 4;
const REGEX_HOSTNAME = "/^([a-z0-9-]+\.)?[a-z0-9-]+\.[a-z]+$/"; const REGEX_HOSTNAME = "/^([a-z0-9-]+\.)*[a-z0-9-]+\.[a-z]+$/";
const REGEX_SEGMENT = "/^[A-Za-z-_0-9\.]+$/"; const REGEX_SEGMENT = "/^[A-Za-z-_0-9\.]+$/";
const REGEX_VERSION_WILDCARD = "/^((\^|~)(\d+\.)?\d|(\d+\.){1,2}\*)$/"; const REGEX_VERSION_WILDCARD = "/^((\^|~)(\d+\.)?\d|(\d+\.){1,2}\*)$/";
@@ -31,7 +31,7 @@ class COIDParser {
* @param string $coidString A COID string. * @param string $coidString A COID string.
* @return IRI * @return IRI
*/ */
public static function fromString($coidString) { public static function fromString($coidString) : IRI {
$coidPre = new IRI( $coidPre = new IRI(
(strtolower(substr($coidString, 0, 7)) == 'coid://') ? $coidString : 'coid://'.$coidString (strtolower(substr($coidString, 0, 7)) == 'coid://') ? $coidString : 'coid://'.$coidString
); );
@@ -45,7 +45,7 @@ class COIDParser {
* @param IRI $coid * @param IRI $coid
* @return int|null * @return int|null
*/ */
public static function getType(IRI $coid) { public static function getType(IRI $coid) : ?int {
if ($coid->getScheme()!='coid' || $coid->getHost()=='' if ($coid->getScheme()!='coid' || $coid->getHost()==''
|| preg_match(self::REGEX_HOSTNAME, $coid->getHost()) != 1) || preg_match(self::REGEX_HOSTNAME, $coid->getHost()) != 1)
return self::COID_INVALID; return self::COID_INVALID;
@@ -79,9 +79,9 @@ class COIDParser {
* Checks whether the given IRI object is a valid COID. * Checks whether the given IRI object is a valid COID.
* *
* @param IRI $coid * @param IRI $coid
* @return boolean * @return bool
*/ */
public static function isValidCOID(IRI $coid) { public static function isValidCOID(IRI $coid) : bool {
return (self::getType($coid)!=self::COID_INVALID); return (self::getType($coid)!=self::COID_INVALID);
} }
@@ -91,7 +91,7 @@ class COIDParser {
* @param IRI $coid * @param IRI $coid
* @return string|null * @return string|null
*/ */
public static function getName(IRI $coid) { public static function getName(IRI $coid) : ?string {
if (self::getType($coid)!=self::COID_INVALID if (self::getType($coid)!=self::COID_INVALID
&& self::getType($coid)!=self::COID_ROOT) { && self::getType($coid)!=self::COID_ROOT) {
$segments = explode('/', $coid->getPath()); $segments = explode('/', $coid->getPath());
@@ -106,7 +106,7 @@ class COIDParser {
* @param IRI $coid * @param IRI $coid
* @return string|null * @return string|null
*/ */
public static function getVersion(IRI $coid) { public static function getVersion(IRI $coid) : ?string {
if (self::getType($coid)==self::COID_VERSIONED) { if (self::getType($coid)==self::COID_VERSIONED) {
$segments = explode('/', $coid->getPath()); $segments = explode('/', $coid->getPath());
return $segments[2]; return $segments[2];
@@ -121,7 +121,7 @@ class COIDParser {
* @param IRI $coid * @param IRI $coid
* @return string|null * @return string|null
*/ */
public static function getVersionWildcard(IRI $coid) { public static function getVersionWildcard(IRI $coid) : ?string {
if (self::getType($coid)==self::COID_VERSION_WILDCARD) { if (self::getType($coid)==self::COID_VERSION_WILDCARD) {
$segments = explode('/', $coid->getPath()); $segments = explode('/', $coid->getPath());
return $segments[2]; return $segments[2];
@@ -136,7 +136,7 @@ class COIDParser {
* @param IRI $coid * @param IRI $coid
* @return IRI|null * @return IRI|null
*/ */
public static function getNamespaceCOID(IRI $coid) { public static function getNamespaceCOID(IRI $coid) : ?IRI {
switch (self::getType($coid)) { switch (self::getType($coid)) {
case self::COID_ROOT: case self::COID_ROOT:
return $coid; return $coid;

View File

@@ -13,13 +13,21 @@ class COIDParserTest extends \PHPUnit\Framework\TestCase {
public function testRootCOID() { public function testRootCOID() {
$coid = new IRI('coid://example.com'); $coid = new IRI('coid://example.com');
$this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid));
$coid = new IRI('coid://subdomain.example.com');
$this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid));
$coid = new IRI('coid://anotherlevel.subdomain.example.com');
$this->assertEquals(COIDParser::COID_ROOT, COIDParser::getType($coid));
} }
public function testInvalidRootCOID() { public function testInvalidRootCOID() {
$coid = new IRI('coid://example'); $coid = new IRI('coid://example');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://exämple.com'); $coid = new IRI('coid://exämple.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://ex&mple.com'); $coid = new IRI('coid://ex&mple.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
} }
@@ -27,34 +35,41 @@ class COIDParserTest extends \PHPUnit\Framework\TestCase {
public function testInvalidCOID() { public function testInvalidCOID() {
$coid = new IRI('http://example.com'); $coid = new IRI('http://example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('example.com'); $coid = new IRI('example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('COID://example.com'); $coid = new IRI('COID://example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('Coid://example.com'); $coid = new IRI('Coid://example.com');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://EXAMPLE.COM'); $coid = new IRI('coid://EXAMPLE.COM');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://exAMPle.CoM'); $coid = new IRI('coid://exAMPle.CoM');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
} }
public function testUnversionedCOID() { public function testUnversionedCOID() {
$coid = new IRI('coid://example.com/Example'); $coid = new IRI('coid://subdomain.example.com/Example');
$this->assertEquals(COIDParser::COID_UNVERSIONED, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_UNVERSIONED, COIDParser::getType($coid));
} }
public function testInvalidUnversionedCOID() { public function testInvalidUnversionedCOID() {
$coid = new IRI('coid://example.com/Exümple'); $coid = new IRI('coid://example.com/Exümple');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Examp%e'); $coid = new IRI('coid://example.com/Examp%e');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
} }
public function testVersionedCOID() { public function testVersionedCOID() {
$coid = new IRI('coid://example.com/Example/1.0'); $coid = new IRI('coid://anotherlevel.subdomain.example.com/Example/1.0');
$this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/alpha');
$coid = new IRI('coid://subdomain.example.com/Example/alpha');
$this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_VERSIONED, COIDParser::getType($coid));
} }
@@ -66,8 +81,10 @@ class COIDParserTest extends \PHPUnit\Framework\TestCase {
public function testVersionWildcardCOID() { public function testVersionWildcardCOID() {
$coid = new IRI('coid://example.com/Example/^1.0'); $coid = new IRI('coid://example.com/Example/^1.0');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/~1.0'); $coid = new IRI('coid://example.com/Example/~1.0');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/1.*'); $coid = new IRI('coid://example.com/Example/1.*');
$this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_VERSION_WILDCARD, COIDParser::getType($coid));
} }
@@ -75,6 +92,7 @@ class COIDParserTest extends \PHPUnit\Framework\TestCase {
public function testInvalidVersionWildcardCOID() { public function testInvalidVersionWildcardCOID() {
$coid = new IRI('coid://example.com/Example/^1.*'); $coid = new IRI('coid://example.com/Example/^1.*');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
$coid = new IRI('coid://example.com/Example/1.a.*'); $coid = new IRI('coid://example.com/Example/1.a.*');
$this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid)); $this->assertEquals(COIDParser::COID_INVALID, COIDParser::getType($coid));
} }