<?php
namespace CorpusParole\Models;
use Config;
use CorpusParole\Libraries\Utils;
use CorpusParole\Libraries\CocoonUtils;
use CorpusParole\Libraries\RdfModel\RdfModelResource;
use JsonSerializable;
use Log;
use EasyRdf\Literal;
use EasyRdf\Resource;
use EasyRdf\Graph;
use EasyRdf\Isomorphic;
/**
* Model class for Document. Inherit from EasyRd\Resource
* SELECT DISTINCT ?g WHERE {GRAPH ?g {?s ?p ?o}}
*/
class Document extends RdfModelResource implements JsonSerializable {
public function __construct($uri, $graph = null) {
parent::__construct($uri, $graph);
}
private $id = null;
// memoization
private $providedCHO = null;
private $title = false;
private $lang = null;
private $publishers = null;
private $mediaArray = null;
private $issued = null;
private $modified = null;
private $contributors = null;
public function getProvidedCHO() {
if(is_null($this->providedCHO)) {
$this->providedCHO = $this->get("<http://www.europeana.eu/schemas/edm/aggregatedCHO>");
}
return $this->providedCHO;
}
private function clearMemoizationCache() {
$this->providedCHO = null;
$this->title = false;
$this->lang = null;
$this->publishers = null;
$this->mediaArray = null;
$this->issued = null;
$this->modified = null;
$this->contributors = null;
}
public function getId() {
if(is_null($this->id)) {
$this->id = $this->getProvidedCHO()->get('<http://purl.org/dc/terms/identifier>');
if(is_null($this->id)) {
$this->id = CocoonUtils::getIdFromCorpusUri($this->uri);
}
}
return $this->id;
}
public function getLanguage() {
if(is_null($this->lang)) {
try {
$langs = $this->getProvidedCHO()->all('<http://purl.org/dc/elements/1.1/language>');
if(count($langs) > 0) {
$this->lang = $langs[0];
}
} catch(\Exception $e) {
$this->lang = null;
}
}
return $this->lang;
}
public function getLanguageValue() {
$lang = $this->getLanguage();
if($lang instanceof Resource) {
return $lang->getUri();
} else if($lan instanceof Literal) {
return $lang->getValue();
}
return null;
}
public function getTitle() {
if($this->title === false) {
try {
$this->title = $this->getProvidedCHO()->getLiteral('<http://purl.org/dc/elements/1.1/title>');
} catch(\Exception $e) {
$this->title = null;
}
}
return $this->title;
}
public function setTitle($value, $lang="fr") {
$oldTitle = $this->getTitle();
if($oldTitle && $oldTitle->getValue() != $value && $oldTitle->getLang() != $lang) {
$literalTitle = new Literal($value, $lang, null);
$this->setSimpleProperty($this->getProvidedCHO(), 'http://purl.org/dc/elements/1.1/title', $oldTitle, $literalTitle);
//clear cache
$this->title = false;
}
}
public function getTitleValue() {
$title = $this->getTitle();
return is_null($title)?null:$title->getValue();
}
public function getPublishers() {
if(is_null($this->publishers)) {
try {
$this->publishers = $this->getProvidedCHO()->all('dc11:publisher');
} catch(\Exception $e) {
$this->publishers = [];
}
}
return $this->publishers;
}
public function getIssued() {
if(is_null($this->issued)) {
try {
$this->issued = $this->getProvidedCHO()->getLiteral("<http://purl.org/dc/terms/issued>");
} catch(\Exception $e) {
$this->issued = null;
}
}
return $this->issued;
}
public function getIssuedValue() {
$issued = $this->getIssued();
return is_null($issued)?null:$issued->getValue();
}
public function getModified() {
if(is_null($this->modified)) {
try {
$this->modified = $this->getProvidedCHO()->getLiteral("<http://purl.org/dc/terms/modified>");
if(is_null($this->modified)) {
$this->modified = $this->getIssued();
}
} catch(\Exception $e) {
$this->modified = null;
}
}
return $this->modified;
}
public function getModifiedValue() {
$modified = $this->getModified();
return is_null($modified)?null:$modified->getValue();
}
public function setModified($value) {
$modified = $this->getModified();
if($value && (!$modified || $modified->getValue() != $value) ) {
$newModified = new Literal($value, "http://purl.org/dc/terms/W3CDTF");
$this->setSimpleProperty($this->getProvidedCHO(), 'http://purl.org/dc/terms/modified', $modified, $newModified);
$this->modified = null;
}
}
public function getMediaArray() {
if(is_null($this->mediaArray)) {
//TODO: add media type
$this->mediaArray = [];
$master = $this->get('<http://www.europeana.eu/schemas/edm/isShownBy>');
$masterUrl = is_null($master)?null:$master->getUri();
foreach($this->graph->allOfType("<http://www.europeana.eu/schemas/edm/WebResource>") as $webResource) {
$extent = $webResource->getLiteral("<http://purl.org/dc/terms/extent>");
$extent = is_null($extent)?null:$extent->getValue();
$extent_ms = Utils::iso8601IntervalToMillis($extent);
$format = $webResource->getLiteral("dc11:format");
$this->mediaArray[$webResource->getUri()] = [
'url' => $webResource->getUri(),
'format' => is_null($format)?null:$format->getValue(),
'extent' => $extent,
'extent_ms' => $extent_ms,
'master' => (($webResource->getUri() === $masterUrl)?true:false)
];
}
}
return $this->mediaArray;
}
public function getTypes() {
return $this->getProvidedCHO()->all('dc11:type');
}
public function getDiscourseTypes() {
return array_values(array_filter($this->getTypes(), function($v) {
return $v instanceof Literal && $v->getDatatypeUri() === Config::get('corpusparole.olac_discourse_type')['uri'];
}));
}
public function getOtherTypes() {
$res = array_values(array_filter($this->getTypes(), function($v) {
return $v instanceof Resource || $v->getDatatypeUri() !== Config::get('corpusparole.olac_discourse_type')['uri'];
}));
return $res;
}
public function getContributors() {
if(is_null($this->contributors)) {
$this->contributors = array_reduce(
CocoonUtils::OLAC_ROLES,
function($res, $olacRole) {
return array_merge(
$res,
array_map(
function($olacValue) use ($olacRole) {
return [
'name' => ($olacValue instanceof Literal)?$olacValue->getValue():null,
'nameLiteral' => ($olacValue instanceof Literal)?$olacValue:null,
'url' => ($olacValue instanceof Resource)?$olacValue->getUri():null,
'role' => $olacRole
];
},
$this->getProvidedCHO()->all("<$olacRole>")
)
);
},
[]
);
}
return $this->contributors;
}
/**
* change contributors list
*/
public function setContributors($contributors) {
$delta = $this->startDelta();
//remove old,
foreach ($this->getContributors() as $contribDef) {
$value = null;
if (is_null($contribDef['url'])) {
if(is_null($contribDef['nameLiteral'])) {
$value = new Literal($contribDef['name']);
} else {
$value = $contribDef['nameLiteral'];
}
} else {
$value = new Resource($contribDef['url']);
}
$this->getProvidedCHO()->delete($contribDef['role'], $value);
$delta->getDeletedGraph()->add($this->getProvidedCHO(), $contribDef['role'], $value);
}
//put new
foreach ($contributors as $newContribDef) {
$value = null;
if (is_null($newContribDef['url'])) {
$value = new Literal($newContribDef['name'], "fr", null);
} else {
$value = new Resource($newContribDef['url']);
}
$this->getProvidedCHO()->add($newContribDef['role'], $value);
$delta->getAddedGraph()->add($this->getProvidedCHO(), $newContribDef['role'], $value);
}
$this->contributors = null;
}
/**
* change discourse type list
*/
public function updateDiscourseTypes(array $discoursesTypes) {
$this->startDelta();
//delete
foreach($this->getDiscourseTypes() as $discourseType) {
$literalValue = new Literal($discourseType, null, Config::get('corpusparole.olac_discourse_type')['uri']);
$this->getProvidedCHO()->delete('dc11:type', $literalValue);
$this->currentDelta->getDeletedGraph()->add($this->getProvidedCHO(), 'dc11:type', new Literal($discourseType, null, Config::get('corpusparole.olac_discourse_type')['uri']));
}
// and re-add them
foreach($discoursesTypes as $dType) {
$this->getProvidedCHO()->add('dc11:type', new Literal($dType, null, Config::get('corpusparole.olac_discourse_type')['uri']));
$this->currentDelta->getAddedGraph()->add($this->getProvidedCHO(), 'dc11:type', new Literal($dType, null, Config::get('corpusparole.olac_discourse_type')['uri']));
}
$this->clearMemoizationCache();
}
public function isIsomorphic($doc) {
return Isomorphic::isomorphic($this->graph, $doc->graph);
}
/*
* Clone document.
* clone also the innerDocumenent
*/
public function __clone() {
$this->graph = new Graph($this->graph->getUri(), $this->graph->toRdfPhp());
}
public function jsonSerialize() {
if(!$this->graph) {
return [
'id' => $this->getId(),
];
} else {
$mediaArray = array_map(
function($m) {
$f = Utils::processLiteralOrString($m['format']);
$res = $m;
$res['format'] = $f;
return $res;},
$this->getMediaArray()
);
$publishers = array_map(
function($v) { return Utils::processLiteralOrString($v); },
$this->getPublishers()
);
$contributors = array_map(
function($c) { unset($c['nameLiteral']); return $c; },
$this->getContributors()
);
return [
'id' => $this->getId(),
'uri' => $this->getUri(),
'title' => $this->getTitleValue(),
'language' => $this->getLanguageValue(),
'modified' => $this->getModifiedValue(),
'publishers' => $publishers,
'contributors' => $contributors,
'mediaArray'=> $mediaArray
];
}
}
}