server/src/app/Models/Document.php
author ymh <ymh.work@gmail.com>
Tue, 01 Dec 2015 13:33:08 +0100
changeset 20 a9b98b16b053
parent 19 eadaf0b8f02e
child 28 b0b56e0f8c7f
permissions -rw-r--r--
add contributor list + edition pane

<?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 $publishers = null;
    private $mediaArray = null;
    private $issued = null;
    private $modified = 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->publishers = null;
        $this->mediaArray = null;
        $this->issued = null;
        $this->modified = null;
    }

    public function getId() {
        if(is_null($this->id)) {
            $this->id = CocoonUtils::getIdFromCorpusUri($this->uri);
        }
        return $this->id;
    }

    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 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 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/WebResources>") 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() {
        return 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,
                                'url' => ($olacValue instanceof Resource)?$olacValue->getUri():null,
                                'role' => $olacRole
                            ];
                        },
                        $this->getProvidedCHO()->all("<$olacRole>")
                    )
                );
            },
            []
        );
    }

    /**
     * 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()
            );

            return [
                'id' => $this->getId(),
                'uri' => $this->getUri(),
                'title' => $this->getTitleValue(),
                'modified' => $this->getModifiedValue(),
                'publishers' => $publishers,
                'contributors' => $this->getContributors(),
                'mediaArray'=> $mediaArray
            ];
        }
    }

}