src/model/ConceptMappingPropertyValue.php
<?php
use EasyRdf\Resource;
/**
* Class for handling concept property values.
*/
class ConceptMappingPropertyValue extends VocabularyDataObject
{
/** property type */
private $type;
private $source;
private $clang;
private $labelcache;
/**
* ConceptMappingPropertyValue constructor.
*
* @param Model $model
* @param Vocabulary $vocab Target vocabulary
* @param Resource $target Target concept resource
* @param Resource $source Source concept resource
* @param string $prop Mapping property
* @param ?string $clang Preferred label language (nullable)
*/
public function __construct(Model $model, Vocabulary $vocab, Resource $target, Resource $source, string $prop, $clang = '')
{
parent::__construct($model, $vocab, $target);
$this->source = $source;
$this->type = $prop;
$this->clang = $clang;
$this->labelcache = array();
}
public function __toString()
{
$label = $this->getLabel();
$notation = $this->getNotation();
return ltrim($notation . ' ') . $label;
}
public function getType()
{
return $this->type;
}
public function getLabel($lang = '', $queryExVocabs = true)
{
if (isset($this->labelcache[$lang])) {
return $this->labelcache[$lang];
}
$label = $this->queryLabel($lang);
$this->labelcache[$lang] = $label;
return $label;
}
public function getSortKey()
{
return strtolower($this->getVocabName() . ": " . $this->getLabel());
}
private function queryLabel($lang = '', $queryExVocabs = true)
{
if ($this->clang) {
$lang = $this->clang;
}
$label = $this->getResourceLabel($this->resource, $lang);
if ($label) {
return $label;
}
// if multiple vocabularies are found, the following method will return in priority the current vocabulary of the mapping
$exvocab = $queryExVocabs ? $this->model->guessVocabularyFromURI($this->resource->getUri(), $this->vocab->getId()) : null;
// if the resource is from another vocabulary known by the skosmos instance
if ($exvocab) {
$label = $this->getExternalLabel($exvocab, $this->getUri(), $lang) ? $this->getExternalLabel($exvocab, $this->getUri(), $lang) : $this->getExternalLabel($exvocab, $this->getUri(), $exvocab->getConfig()->getDefaultLanguage());
if ($label) {
return $label;
}
}
// using URI as label if nothing else has been found.
return $this->resource->shorten() ? $this->resource->shorten() : $this->resource->getUri();
}
private function getResourceLabel($res, $lang = '')
{
if ($this->clang) {
$lang = $this->clang;
}
if ($res->label($lang) !== null) { // current language
return $res->label($lang);
} elseif ($res->label() !== null) { // any language
return $res->label();
} elseif ($res->getLiteral('rdf:value', $lang) !== null) { // current language
return $res->getLiteral('rdf:value', $lang);
} elseif ($res->getLiteral('rdf:value') !== null) { // any language
return $res->getLiteral('rdf:value');
}
return null;
}
public function getUri()
{
return $this->resource->getUri();
}
public function getExVocab()
{
return $this->model->guessVocabularyFromURI($this->getUri(), $this->vocab->getId());
}
public function getVocab()
{
return $this->vocab;
}
public function getVocabName($lang = '')
{
if ($this->clang) {
$lang = $this->clang;
}
// if multiple vocabularies are found, the following method will return in priority the current vocabulary of the mapping
$exvocab = $this->model->guessVocabularyFromURI($this->resource->getUri(), $this->vocab->getId());
if ($exvocab) {
return $exvocab->getTitle($lang);
}
// @codeCoverageIgnoreStart
$scheme = $this->resource->get('skos:inScheme');
if ($scheme) {
$schemeResource = $this->model->getResourceFromUri($scheme->getUri());
if ($schemeResource) {
$schemaName = $this->getResourceLabel($schemeResource);
if ($schemaName) {
return $schemaName;
}
}
}
// got a label for the concept, but not the scheme - use the host name as scheme label
return parse_url($this->resource->getUri(), PHP_URL_HOST);
// @codeCoverageIgnoreEnd
}
public function getNotation()
{
if ($this->resource->get('skos:notation')) {
return $this->resource->get('skos:notation')->getValue();
}
$exvocab = $this->getExvocab();
// if the resource is from a another vocabulary known by the skosmos instance
if ($exvocab) {
return $this->getExternalNotation($exvocab, $this->getUri());
}
return null;
}
/**
* Return the mapping as a JSKOS-compatible array.
* @return array
*/
public function asJskos($queryExVocabs = true, $lang = null, $hrefLink = null)
{
$propertyLabel = $this->getLabel($lang, $queryExVocabs);
$propertyLang = $lang;
if (!is_string($propertyLabel)) {
$propertyLang = $propertyLabel->getLang();
$propertyLabel = $propertyLabel->getValue();
}
$ret = [
// JSKOS
'uri' => $this->source->getUri(),
'notation' => $this->getNotation(),
'type' => [$this->type],
'prefLabel' => $propertyLabel,
'from' => [
'memberSet' => [
[
'uri' => (string) $this->source->getUri(),
]
]
],
'to' => [
'memberSet' => [
[
'uri' => (string) $this->getUri()
]
]
],
// EXTRA
'hrefLink' => $hrefLink, // link to resource as displayed in the UI
'lang' => $propertyLang, // TBD: could it be part of the prefLabel?
'vocabName' => (string) $this->getVocabName(), // vocabulary as displayed in the UI
'typeLabel' => $this->model->getText($this->type), // a text used in the UI instead of, for example, skos:closeMatch
];
$helpprop = $this->type . "_help";
// see if we have a translation for the property help text
$help = $this->model->getText($helpprop);
if ($help != $helpprop) {
$ret['description'] = $help;
}
$fromScheme = $this->vocab->getDefaultConceptScheme();
if (isset($fromScheme)) {
$ret['fromScheme'] = [
'uri' => (string) $fromScheme,
];
}
$exvocab = $this->getExvocab();
if (isset($exvocab)) {
$ret['toScheme'] = [
'uri' => (string) $exvocab->getDefaultConceptScheme(),
];
}
$notation = $this->getNotation();
if (isset($notation)) {
$ret['to']['memberSet'][0]['notation'] = (string) $notation;
}
$label = $this->getLabel($lang, $queryExVocabs);
if (isset($label)) {
if (is_string($label)) {
list($labelLang, $labelValue) = ['', $label];
} else {
list($labelLang, $labelValue) = [$label->getLang(), $label->getValue()];
}
// set the language of the preferred label to be whatever returned
$ret['lang'] = $labelLang;
if ($labelValue != $this->getUri()) {
// The `queryLabel()` method above will fallback to returning the URI
// if no label was found. We don't want that here.
$ret['to']['memberSet'][0]['prefLabel'] = [
$labelLang => $labelValue,
];
}
}
return $ret;
}
}