795 lines
30 KiB
PHP
795 lines
30 KiB
PHP
<?PHP
|
|
/**
|
|
* Represents an external norm data repository.
|
|
*
|
|
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
|
*/
|
|
declare(strict_types = 1);
|
|
|
|
/**
|
|
* Represents an external norm data repository.
|
|
*/
|
|
enum MDNodaRepository implements MDValueEnumInterface, JsonSerializable {
|
|
|
|
case allgemein; // General link to a good source
|
|
case aat;
|
|
case ackerbau;
|
|
case bne;
|
|
case bnf;
|
|
case cona;
|
|
case editionhumboldtdigital;
|
|
case gnd;
|
|
case grobsystematik;
|
|
case iconclass;
|
|
case klbb;
|
|
case lcsh;
|
|
case loc; // Duplicate?
|
|
case mindatorg;
|
|
case moebeltypologie;
|
|
case ndb_adb;
|
|
case ndl;
|
|
case ndp_ikmk;
|
|
case ndp_ikmk_persons;
|
|
case nomisma;
|
|
case npg;
|
|
case oberbegriffsdatei;
|
|
case orcid;
|
|
case osm;
|
|
case pim;
|
|
case pleiades;
|
|
case rkd;
|
|
case ulan;
|
|
case viaf;
|
|
case wikidata;
|
|
|
|
/**
|
|
* Returns a value of this type based on a string.
|
|
*
|
|
* @param string $input Input to get a value from.
|
|
*
|
|
* @return MDNodaRepository
|
|
*/
|
|
public static function fromString(string $input):MDNodaRepository {
|
|
|
|
return match($input) {
|
|
'allgemein' => self::allgemein, // General link to a good source
|
|
'aat' => self::aat,
|
|
'ackerbau' => self::ackerbau,
|
|
'bne' => self::bne,
|
|
'bnf' => self::bnf,
|
|
'cona' => self::cona,
|
|
'edition humboldt digital' => self::editionhumboldtdigital,
|
|
'gnd' => self::gnd,
|
|
'GND' => self::gnd,
|
|
'o-gnd' => self::gnd,
|
|
'O-GND' => self::gnd,
|
|
'pnd' => self::gnd,
|
|
'http://d-nb.info/gnd' => self::gnd,
|
|
'http://d-nb.info/gnd/' => self::gnd,
|
|
'd-nb.info' => self::gnd,
|
|
'd-nb' => self::gnd,
|
|
'https://portal.dnb.de' => self::gnd,
|
|
'https://explore.gnd.network/gnd/' => self::gnd,
|
|
'grobsystematik' => self::grobsystematik,
|
|
'iconclass' => self::iconclass,
|
|
'klbb' => self::klbb,
|
|
'kl-bb' => self::klbb,
|
|
'lcsh' => self::lcsh,
|
|
'loc' => self::loc, // Duplicate?
|
|
'mindat.org' => self::mindatorg,
|
|
'moebeltypologie' => self::moebeltypologie,
|
|
'ndb/adb' => self::ndb_adb,
|
|
'NDB/ADB' => self::ndb_adb,
|
|
'ndl' => self::ndl,
|
|
'ndp-ikmk' => self::ndp_ikmk,
|
|
'ndp-ikmk-persons' => self::ndp_ikmk_persons,
|
|
'nomisma' => self::nomisma,
|
|
'nomisma.org' => self::nomisma,
|
|
'npg' => self::npg,
|
|
'oberbegriffsdatei' => self::oberbegriffsdatei,
|
|
'orcid' => self::orcid,
|
|
'osm' => self::osm,
|
|
'pim' => self::pim,
|
|
'pleiades' => self::pleiades,
|
|
'rkd' => self::rkd,
|
|
'ulan' => self::ulan,
|
|
'ULAN' => self::ulan,
|
|
'viaf' => self::viaf,
|
|
'VIAF' => self::viaf,
|
|
'wikidata' => self::wikidata,
|
|
'Wikidata' => self::wikidata,
|
|
'www.wikidata.org' => self::wikidata,
|
|
'WIKIDATA' => self::wikidata,
|
|
default => throw new MDpageParameterNotFromListException("Unknown norm data repository: '" . $input . "'"),
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* Attempts to get a repository based on a provided link. This function is rather expensive
|
|
* and should be avoided as much as possible.
|
|
*
|
|
* @param string $input Input to get a value from.
|
|
*
|
|
* @return MDNodaRepository
|
|
*/
|
|
public static function fromUrl(string $input):MDNodaRepository {
|
|
|
|
$cases = self::cases();
|
|
foreach ($cases as $case) {
|
|
|
|
if ($case === self::allgemein) continue;
|
|
$output = $case->validateId($input);
|
|
if ($output !== false) return $case;
|
|
|
|
}
|
|
|
|
throw new MDInvalidNodaLink("Failed to get norm data repository based on the provided link");
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the name as stored in the DB.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function toDbName():string {
|
|
|
|
return match($this) {
|
|
self::allgemein => 'allgemein', // General link to a good source
|
|
self::aat => 'aat',
|
|
self::ackerbau => 'ackerbau',
|
|
self::bne => 'bne',
|
|
self::bnf => 'bnf',
|
|
self::cona => 'cona',
|
|
self::editionhumboldtdigital => 'edition humboldt digital',
|
|
self::gnd => 'gnd',
|
|
self::grobsystematik => 'grobsystematik',
|
|
self::iconclass => 'iconclass',
|
|
self::klbb => 'kl-bb',
|
|
self::lcsh => 'lcsh',
|
|
self::loc => 'loc',
|
|
self::mindatorg => 'mindat.org',
|
|
self::moebeltypologie => 'moebeltypologie',
|
|
self::ndb_adb => 'NDB/ADB',
|
|
self::ndl => 'ndl',
|
|
self::ndp_ikmk => 'ndp-ikmk',
|
|
self::ndp_ikmk_persons => 'ndp-ikmk-persons',
|
|
self::nomisma => 'nomisma',
|
|
self::npg => 'npg',
|
|
self::oberbegriffsdatei => 'oberbegriffsdatei',
|
|
self::orcid => 'orcid',
|
|
self::osm => 'osm',
|
|
self::pim => 'pim',
|
|
self::pleiades => 'pleiades',
|
|
self::rkd => 'rkd',
|
|
self::ulan => 'ulan',
|
|
self::viaf => 'viaf',
|
|
self::wikidata => 'wikidata',
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the name as stored in the DB.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function toFullName():string {
|
|
|
|
return match($this) {
|
|
self::allgemein => 'General', // General link to a good source
|
|
self::aat => 'Art & Architecture Thesaurus (AAT)',
|
|
self::ackerbau => 'Ackerbau-Thesaurus',
|
|
self::bne => 'Biblioteca Nacional de España (BNE)',
|
|
self::bnf => 'Bibliothèque nationale de France (BNF)',
|
|
self::cona => 'Cultural Objects Name Authority (CONA)',
|
|
self::editionhumboldtdigital => 'Edition Humboldt Digital',
|
|
self::gnd => 'GND (Gemeinsame Normdatei)',
|
|
self::grobsystematik => 'Grobsystematik',
|
|
self::iconclass => 'Iconclass',
|
|
self::klbb => 'Berlin-Brandenburgisches Künstlerlexikon',
|
|
self::lcsh => 'Library of Congress Subject Headings (LCSH)',
|
|
self::loc => 'Library of Congress (LOC)',
|
|
self::mindatorg => 'mindat.org',
|
|
self::moebeltypologie => 'Möbeltypologie',
|
|
self::ndb_adb => 'Neue / Allgemeine Deutsche Biographie',
|
|
self::ndl => 'National Diet Library, Japan (NDL)',
|
|
self::ndp_ikmk => 'IKMK (Places)',
|
|
self::ndp_ikmk_persons => 'IKMK (Persons)',
|
|
self::nomisma => 'Nomisma',
|
|
self::npg => 'National Portrait Gallery',
|
|
self::oberbegriffsdatei => 'Oberbegriffsdatei',
|
|
self::orcid => 'ORCID (Open Researcher and Contributor ID)',
|
|
self::osm => 'OpenStreetMap',
|
|
self::pim => 'Petőfi Irodalmi Múzeum',
|
|
self::pleiades => 'Pleiades',
|
|
self::rkd => 'RKDartists ID',
|
|
self::ulan => 'Union List of Artist Names',
|
|
self::viaf => 'VIAF (Virtual International Authority File)',
|
|
self::wikidata => 'Wikidata',
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the URL prefix for the current repository.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getUrlPrefix():string {
|
|
|
|
return match($this) {
|
|
self::allgemein => '',
|
|
self::aat => 'https://vocab.getty.edu/page/aat/',
|
|
self::ackerbau => 'https://term.museum-digital.de/ackerbau/tag/',
|
|
self::bne => 'http://datos.bne.es/persona/',
|
|
self::bnf => "https://catalogue.bnf.fr/ark:/12148/cb",
|
|
self::cona => 'https://vocab.getty.edu/page/cona/',
|
|
self::editionhumboldtdigital => 'https://edition-humboldt.de/register/personen/detail.xql?normid=http://d-nb.info/gnd/',
|
|
self::gnd => 'https://d-nb.info/gnd/',
|
|
self::grobsystematik => 'https://term.museum-digital.de/grobsystematik/tag/',
|
|
self::iconclass => 'http://iconclass.org/rkd/',
|
|
self::klbb => 'https://www.kl-bb.de/artist/',
|
|
self::lcsh => 'http://id.loc.gov/authorities/names/',
|
|
self::loc => 'http://id.loc.gov/authorities/names/',
|
|
self::mindatorg => 'https://www.mindat.org/min-', // Has suffix
|
|
self::moebeltypologie => 'https://term.museum-digital.de/moebel/tag/',
|
|
self::ndb_adb => 'https://www.deutsche-biographie.de/pnd',
|
|
self::ndl => 'https://id.ndl.go.jp/auth/ndlna/',
|
|
self::ndp_ikmk => 'https://ikmk.smb.museum/ndp/',
|
|
self::ndp_ikmk_persons => 'https://ikmk.smb.museum/ndp/person/',
|
|
self::nomisma => 'http://nomisma.org/id/',
|
|
self::npg => 'https://www.npg.org.uk/collections/search/person/',
|
|
self::oberbegriffsdatei => 'https://term.museum-digital.de/oberbegriffsdatei/tag/',
|
|
self::orcid => 'https://orcid.org/',
|
|
self::osm => 'https://www.openstreetmap.org/relation/',
|
|
self::pim => 'https://opac-nevter.pim.hu/en/record/-/record/',
|
|
self::pleiades => 'https://pleiades.stoa.org/places/',
|
|
self::rkd => 'https://rkd.nl/explore/artists/',
|
|
self::ulan => 'https://vocab.getty.edu/page/ulan/',
|
|
self::viaf => 'https://viaf.org/viaf/',
|
|
self::wikidata => 'https://www.wikidata.org/entity/',
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the base of the repository's entity page URLs.
|
|
*
|
|
* @param string $id Identifier to link to.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getEntityLink(string $id):string {
|
|
|
|
return match ($this) {
|
|
self::ndb_adb => 'https://www.deutsche-biographie.de/pnd' . $id . '.html',
|
|
self::mindatorg => 'https://www.mindat.org/min-' . $id . '.html',
|
|
default => $this->getUrlPrefix() . $id,
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns a link to search for a given search term.
|
|
*
|
|
* @param string $searchTerm Search term.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getSearchLink(string $searchTerm):string {
|
|
|
|
return match($this) {
|
|
self::allgemein => 'https://www.google.de/search?q=' . urlencode($searchTerm),
|
|
self::aat => 'https://www.getty.edu/vow/AATServlet?english=N&find=' . urlencode($searchTerm) . '&page=1¬e=',
|
|
self::ackerbau => 'https://term.museum-digital.de/redir.php?search=' . urlencode($searchTerm) . '&kind=tag|ackerbau',
|
|
self::bne => 'http://datos.bne.es/persona/' . urlencode($searchTerm),
|
|
self::bnf => 'https://catalogue.bnf.fr/resultats-auteur.do?nomAuteur=' . urlencode($searchTerm) . '+&filtre=1&pageRech=rau',
|
|
self::cona => 'http://vocab.getty.edu/page/cona/' . urlencode($searchTerm),
|
|
self::editionhumboldtdigital => 'https://edition-humboldt.de/suche/ergebnisRegistersuche.xql?indexType=&q_text=' . urlencode($searchTerm),
|
|
self::gnd => 'https://explore.gnd.network/search?term=' . urlencode($searchTerm),
|
|
self::grobsystematik => 'https://term.museum-digital.de/redir.php?search=' . urlencode($searchTerm) . '&kind=tag|grobsystematik',
|
|
self::iconclass => 'http://iconclass.org/rkd/48C51/?q=' . urlencode($searchTerm) . '&q_s=1',
|
|
self::lcsh => 'https://id.loc.gov/search/?q=cs:http://id.loc.gov/authorities/subjects&q=' . urlencode($searchTerm),
|
|
self::klbb => 'https://www.kl-bb.de/gezielte-suche?page=gezielte-suche&artist_name=' . urlencode($searchTerm),
|
|
self::loc => 'http://id.loc.gov/authorities/names/' . urlencode($searchTerm),
|
|
self::mindatorg => 'https://www.mindat.org/search.php?search=' . urlencode($searchTerm) . '&q_s=1',
|
|
self::moebeltypologie => 'https://term.museum-digital.de/redir.php?search=' . urlencode($searchTerm) . '&kind=tag|moebel',
|
|
self::ndb_adb => 'https://www.deutsche-biographie.de/search?name=' . urlencode($searchTerm),
|
|
self::ndl => 'https://id.ndl.go.jp/auth/ndlna/' . urlencode($searchTerm),
|
|
self::ndp_ikmk => 'https://ikmk.smb.museum/ndp/list?lang=de&q=' . urlencode($searchTerm),
|
|
self::ndp_ikmk_persons => 'https://ikmk.smb.museum/ndp/list?lang=de&q=' . urlencode($searchTerm),
|
|
self::nomisma => 'http://nomisma.org/browse?q=' . urlencode($searchTerm),
|
|
self::npg => 'https://www.npg.org.uk/collections/search/person/' . urlencode($searchTerm),
|
|
self::oberbegriffsdatei => 'https://term.museum-digital.de/redir.php?search=' . urlencode($searchTerm) . '&kind=tag|oberbegriffsdatei',
|
|
self::orcid => 'https://orcid.org/' . urlencode($searchTerm),
|
|
self::osm => 'https://www.openstreetmap.org/relation/' . urlencode($searchTerm),
|
|
self::pim => 'https://opac-nevter.pim.hu/en/record/-/results/' . urlencode($searchTerm),
|
|
self::pleiades => 'https://pleiades.stoa.org/search?SearchableText=' . urlencode($searchTerm),
|
|
self::rkd => 'https://rkd.nl/en/explore#query=' . urlencode($searchTerm),
|
|
self::ulan => 'http://www.getty.edu/vow/ULANServlet?english=Y&find=' . urlencode($searchTerm) . '&role=&page=1&nation=',
|
|
self::viaf => 'https://viaf.org/viaf/search?query=local.names+all+' . urlencode('"' . $searchTerm . '"') . '"&sortKeys=holdingscount&recordSchema=BriefVIAF',
|
|
self::wikidata => 'https://www.wikidata.org/w/index.php?search=&search=' . urlencode($searchTerm) . '&ns0=1&ns120=1',
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* Extension of PHP's built-in is_numeric() that also supports large numbers.
|
|
*
|
|
* @param string $value Input to check.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
private static function _is_numeric(string $value):bool {
|
|
|
|
// Strings starting with 0 are quite often linked, notably with the NDL.
|
|
// PHP's FILTER_VALIDATE_INT does not accept a leading 0 however, so it
|
|
// is stripped before checking.
|
|
if (filter_var(ltrim($value, '0'), FILTER_VALIDATE_INT) !== false) {
|
|
return true;
|
|
}
|
|
|
|
// FILTER_VALIDATE_INT fails on overly large IDs (e.g. VIAF IDs having
|
|
// more than 20 digits).
|
|
// In these cases, simply check for the existence of non-numeric characters.
|
|
if (strlen($value) > 9) {
|
|
if (empty(trim($value, '0123456789'))) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a numeric ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
* @param string[] $prefixes Prefixes to strip off.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateNumericId(string $id, array $prefixes):string|false {
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$toRemove = [];
|
|
foreach ($prefixes as $prefix) {
|
|
$toRemove[$prefix] = "";
|
|
}
|
|
$id = trim(strtr($id, $toRemove), '/');
|
|
}
|
|
|
|
if (!self::_is_numeric($id)) {
|
|
return false;
|
|
}
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a iconclass ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateIconclassId(string $id):string|false {
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$id = strtr($id, ['http://iconclass.org/rkd/' => '', 'http://iconclass.org/' => '', 'https://iconclass.org/' => '']);
|
|
}
|
|
|
|
if (preg_match("/^[0-9a-z\/]*$/", $id) === false) return false;
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a BNE ID, returning a string or false. The BNE is basically equalivalent to the
|
|
* GND, just that the X character can be prepended to the number.
|
|
*
|
|
* @param string $id ID to validate.
|
|
* @param string[] $prefixes Prefixes to strip off.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateBneId(string $id, array $prefixes):string|false {
|
|
|
|
return self::validateGndId($id, $prefixes);
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a GND ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
* @param string[] $prefixes Prefixes to strip off.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateGndId(string $id, array $prefixes):string|false {
|
|
|
|
if (str_contains($id, ' ')) {
|
|
$id = strtr($id, [' ' => '', "\t" => '']);
|
|
}
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$toRemove = [];
|
|
foreach ($prefixes as $prefix) $toRemove[$prefix] = "";
|
|
$id = strtr($id, $toRemove);
|
|
}
|
|
|
|
// There is an issue with this regex
|
|
if (preg_match("/^[0-9-X]*$/", $id) === false) {
|
|
return false;
|
|
}
|
|
if (self::_is_numeric(strtr($id, ['-' => '', 'X' => ''])) === false) {
|
|
return false;
|
|
}
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a Library of Congress name ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateLocId(string $id):string|false {
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$id = strtr($id, [
|
|
'http://id.loc.gov/authorities/names/' => '',
|
|
'https://id.loc.gov/authorities/names/' => '',
|
|
'http://id.loc.gov/authorities/subjects/' => '',
|
|
'https://id.loc.gov/authorities/subjects/' => '',
|
|
]);
|
|
}
|
|
|
|
if (in_array(substr($id, 0, 2), ['nr', 'nb', 'no'], true)) {
|
|
if (filter_var(trim(substr($id, 2), '0'), FILTER_VALIDATE_INT) === false) return false;
|
|
}
|
|
else if (substr($id, 0, 1) === 'n') {
|
|
if (filter_var(trim(substr($id, 1), '0'), FILTER_VALIDATE_INT) === false) return false;
|
|
}
|
|
else if (substr($id, 0, 2) === 'sh') {
|
|
throw new MDInvalidNodaLinkLocIdIsSh("The link to the Library of Congress authority files refers to the LOC Subject Headings. The subject headings are listed as a separate vocabulary.");
|
|
}
|
|
else throw new MDInvalidNodaLinkException("LOC IDs must start with n or nr or nb (provided: " . strip_tags($id) . ")");
|
|
|
|
return (string)$id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a LCSH ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateLcshId(string $id):string|false {
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$id = strtr($id, [
|
|
'http://id.loc.gov/authorities/names/' => '',
|
|
'https://id.loc.gov/authorities/names/' => '',
|
|
'http://id.loc.gov/authorities/subjects/' => '',
|
|
'https://id.loc.gov/authorities/subjects/' => '',
|
|
'.html' => '',
|
|
]);
|
|
}
|
|
|
|
if (substr($id, 0, 2) !== 'sh') {
|
|
if (str_starts_with(substr($id, 0, 1), 'n')) {
|
|
throw new MDInvalidNodaLinkLcshIdIsGeneralLoc("LCSH IDs must start with sh. ID started with n. Use general LOC link instead.");
|
|
}
|
|
throw new MDInvalidNodaLinkException("LCSH IDs must start with sh. ID provided is: " . $id);
|
|
}
|
|
|
|
if (filter_var(ltrim(substr($id, 2), "0"), FILTER_VALIDATE_INT) === false) {
|
|
return false;
|
|
}
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates an NDP-IKMK ID. The IKMK vocabularies for places are actually quite
|
|
* numerous, identifying places, countries, regions separately.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateNdpIkmkForPlaces(string $id):string|false {
|
|
|
|
$id = str_replace("https://ikmk.smb.museum/ndp/", "", trim($id, '/'));
|
|
|
|
$parts = explode('/', $id);
|
|
if (count($parts) !== 2) {
|
|
return false;
|
|
}
|
|
|
|
if (!in_array($parts[0], ['ort', 'land', 'region'], true)) {
|
|
return false;
|
|
}
|
|
|
|
// There is an issue with this regex
|
|
if (self::_is_numeric($parts[1]) === false) {
|
|
return false;
|
|
}
|
|
|
|
return $parts[0] . '/' . $parts[1];
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates OrCID IDs.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateOrcidId(string $id):string|false {
|
|
|
|
$id = strtr(trim($id, '/'), [
|
|
"http://orcid.org/" => "",
|
|
"https://orcid.org/" => "",
|
|
]);
|
|
|
|
return preg_match('/^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}$/', $id) ? $id : false;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a PIM ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validatePimId(string $id):string|false {
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$toRemove = [];
|
|
foreach ([
|
|
'https://opac-nevter.pim.hu/en/record/-/record/',
|
|
'https://resolver.pim.hu/auth/',
|
|
] as $prefix) {
|
|
$toRemove[$prefix] = "";
|
|
}
|
|
$id = strtr($id, $toRemove);
|
|
}
|
|
|
|
// There is an issue with this regex
|
|
if (preg_match("/^[0-9-PIM]*$/", $id) === false) {
|
|
return false;
|
|
}
|
|
if (self::_is_numeric(substr($id, 3)) === false) {
|
|
return false;
|
|
}
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates an NPG ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateNpgId(string $id):string|false {
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$id = strtr($id, ['https://www.npg.org.uk/collections/search/person/' => '']);
|
|
}
|
|
|
|
if (substr($id, 0, 2) === 'mp' && self::_is_numeric(substr($id, 2))) {
|
|
return $id;
|
|
}
|
|
|
|
if (self::_is_numeric($id) === false) {
|
|
return false;
|
|
}
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a wikidata ID, returning a string or false.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
private static function validateWikidataId(string $id):string|false {
|
|
|
|
if (filter_var($id, FILTER_VALIDATE_URL) !== false) {
|
|
$id = strtr($id, [
|
|
'http://www.wikidata.org/wiki/' => '',
|
|
'http://www.wikidata.org/entity/' => '',
|
|
'https://www.wikidata.org/wiki/' => '',
|
|
'https://www.wikidata.org/entity/' => '',
|
|
'https://www.wikidata.org/w/index.php?search=&search=' => '',
|
|
]);
|
|
|
|
if (str_starts_with($id, 'https://www.wikidata.org/w/index.php?title=')) {
|
|
$id = str_replace('https://www.wikidata.org/w/index.php?title=', '', $id);
|
|
if (($endPos = strpos($id, '&')) !== false) {
|
|
$id = substr($id, 0, $endPos);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (substr($id, 0, 1) !== 'Q') {
|
|
throw new MDInvalidNodaLinkException("Wikidata IDs must be Q IDs - and start with that letter (provided: $id)");
|
|
}
|
|
|
|
if (self::_is_numeric(substr($id, 1)) === false) {
|
|
return false;
|
|
}
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates a BNF ID. BNF IDs are either fully numeric or end on a single non-numeric character.
|
|
*
|
|
* @param string $id ID to validate.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
public static function validateBnfId(string $id):string|false {
|
|
|
|
if (!is_numeric(substr($id, -1))) {
|
|
$validation = self::validateNumericId(substr($id, 0, -1), ["https://catalogue.bnf.fr/ark:/12148/cb"]);
|
|
}
|
|
else $validation = self::validateNumericId($id, ["https://catalogue.bnf.fr/ark:/12148/cb"]);
|
|
|
|
if ($validation === false) return false;
|
|
|
|
return $id;
|
|
|
|
}
|
|
|
|
/**
|
|
* Validates an ID.
|
|
*
|
|
* @param string $id Identifier to link to.
|
|
*
|
|
* @return string|false
|
|
*/
|
|
public function validateId(string $id):string|false {
|
|
|
|
return match($this) {
|
|
self::allgemein => filter_var($id, FILTER_VALIDATE_URL),
|
|
self::aat => self::validateNumericId($id, [
|
|
'http://vocab.getty.edu/aat/',
|
|
'http://vocab.getty.edu/page/aat/',
|
|
'https://vocab.getty.edu/aat/',
|
|
'https://vocab.getty.edu/page/aat/',
|
|
]),
|
|
self::ackerbau => self::validateNumericId($id, ['https://term.museum-digital.de/ackerbau/tag/']),
|
|
self::bne => self::validateBneId($id, ['http://datos.bne.es/persona/', 'https://datos.bne.es/persona/']),
|
|
self::bnf => self::validateBnfId($id),
|
|
self::cona => self::validateNumericId($id, ['http://vocab.getty.edu/page/cona/', 'https://vocab.getty.edu/page/cona/']),
|
|
self::editionhumboldtdigital => self::validateGndId($id, ['https://edition-humboldt.de/register/personen/detail.xql?normid=http://d-nb.info/gnd/']),
|
|
self::gnd => self::validateGndId($id, ['http://d-nb.info/gnd/', 'https://d-nb.info/gnd/', 'https://explore.gnd.network/gnd/']),
|
|
self::grobsystematik => self::validateNumericId($id, ['https://term.museum-digital.de/grobsystematik/tag/']),
|
|
self::iconclass => self::validateIconclassId($id),
|
|
self::klbb => self::validateNumericId($id, ['https://www.kl-bb.de/artist/', 'https://www.kl-bb.de/?page=actor&subPage=']),
|
|
self::lcsh => self::validateLcshId($id),
|
|
self::loc => self::validateLocId($id),
|
|
self::mindatorg => self::validateNumericId($id, ['https://www.mindat.org/min-', '.html']),
|
|
self::moebeltypologie => self::validateNumericId($id, ['https://term.museum-digital.de/moebel/tag/']),
|
|
self::ndb_adb => self::validateGndId($id, ['https://www.deutsche-biographie.de/pnd', '.html', '#adbcontent', '#ndbcontent', '#indexcontent']),
|
|
self::ndl => self::validateNumericId($id, [
|
|
'http://id.ndl.go.jp/auth/ndlna/',
|
|
'https://id.ndl.go.jp/auth/ndlna/',
|
|
]),
|
|
self::ndp_ikmk => self::validateNdpIkmkForPlaces($id),
|
|
self::ndp_ikmk_persons => self::validateNumericId($id, ['https://ikmk.smb.museum/ndp/person/']),
|
|
self::nomisma => str_replace('http://nomisma.org/id/', '', $id),
|
|
self::npg => self::validateNpgId($id),
|
|
self::oberbegriffsdatei => self::validateNumericId($id, ['https://term.museum-digital.de/oberbegriffsdatei/tag/']),
|
|
self::orcid => self::validateOrcidId($id),
|
|
self::osm => self::validateNumericId($id, ['https://www.openstreetmap.org/relation/']),
|
|
self::pim => self::validatePimId($id),
|
|
self::pleiades => self::validateNumericId($id, ['https://pleiades.stoa.org/places/']),
|
|
self::rkd => self::validateNumericId($id, ['http://rkd.nl/explore/artists/', 'https://rkd.nl/explore/artists/']),
|
|
self::ulan => self::validateNumericId($id, [
|
|
'http://vocab.getty.edu/ulan/',
|
|
'http://vocab.getty.edu/page/ulan/',
|
|
'https://vocab.getty.edu/page/ulan/',
|
|
'http://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid=',
|
|
'https://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid=',
|
|
]),
|
|
self::viaf => self::validateNumericId($id, [
|
|
'https://viaf.org/viaf/',
|
|
'http://viaf.org/viaf/',
|
|
]),
|
|
self::wikidata => self::validateWikidataId($id),
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* Lists all available names.
|
|
*
|
|
* @return array<string>
|
|
*/
|
|
public static function caseNames():array {
|
|
|
|
$output = [];
|
|
|
|
$cases = self::cases();
|
|
foreach ($cases as $case) {
|
|
$output[] = $case->name;
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
/**
|
|
* Gets an unsorted list of the entries in a translated version.
|
|
*
|
|
* @param MDTlLoader $tlLoader Translation loader.
|
|
*
|
|
* @return array<string, string>
|
|
*/
|
|
public static function getUnsortedList(MDTlLoader $tlLoader):array {
|
|
return MDValueSet::getTlUnsortedList($tlLoader, self::caseNames(), "attendance_status_set", "attendance_status_set");
|
|
|
|
}
|
|
|
|
/**
|
|
* Gets a sorted list of the entries in a translated version.
|
|
*
|
|
* @param MDTlLoader $tlLoader Translation loader.
|
|
*
|
|
* @return array<string, string>
|
|
*/
|
|
public static function getSortedList(MDTlLoader $tlLoader):array {
|
|
return MDValueSet::getTlSortedList($tlLoader, self::caseNames(), "attendance_status_set", "attendance_status_set");
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the name of the current value in translation.
|
|
*
|
|
* @param MDTlLoader $tlLoader Translation loader.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getTledName(MDTlLoader $tlLoader):string {
|
|
|
|
return $tlLoader->tl("attendance_status_set", "attendance_status_set", $this->name);
|
|
|
|
}
|
|
|
|
/**
|
|
* Provides the option to serialize as a string during json_encode().
|
|
*
|
|
* @return string
|
|
*/
|
|
public function jsonSerialize():string {
|
|
|
|
return $this->name;
|
|
|
|
}
|
|
}
|