capdataopera / php-sdk
Development kit to expose and fetch CapData Opera ontology in RDF format.
Requires
- php: >=7.4
- ext-mbstring: *
- ext-pcre: *
- easyrdf/easyrdf: ^1.1
Requires (Dev)
- ml/json-ld: ^1.2
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6.16
README
Développements réalisés dans le cadre du projet CapData Opéra - France 2030, porté par la Réunion des Opéras de France. \ Opération soutenue par l'État dans le cadre du dispositif « Expérience augmentée du spectacle vivant » de France 2030, opéré par la Caisse des Dépôts. \ Information sur https://www.rof.fr/rof/capdata-opera.aspx.
Le SDK PHP permet :
- [x] d'exposer des données structurées modélisées selon l'ontologie CapData Opéra au format RDF.
- [ ] d'interroger ces données via le langage SPARQL et hydrater des objets PHP à partir des résultats de ces requêtes.
Sommaire
- Documentation
- Utilisation
- Plus en détails
- Choisir les ontologies pour la sérialisation
- Comment contribuer au projet
- Crédits
Documentation
Le SDK est développé avec un typage fort et des PHP-doc renseignant les types et des génériques. Nous vous conseillons de paramétrer votre IDE pour qu'il tire parti de ces informations. Cela vous permettra d'avoir une aide à la saisie et une documentation en temps réel.
Liens utiles
- Présentation du projet CapData Opéra : https://www.rof.fr/ROF/doc/SYRACUSE/89577/
- Référentiels : https://www.rof.fr/rof/capdata-opera-referentiels.aspx
- Ontologie : https://ontologie.capdataculture.fr/v1/
- Visualisation du modèle de données : https://ontologie.capdataculture.fr/v1/owl/webvowl/index.html#
- SPARQL EXPLORER : https://sparql.capdataculture.fr/
Utilisation
Installation dans un projet
composer require capdataopera/php-sdk
Exemple d'utilisation
Voici un exemple simpliste d'utilisation du SDK pour créer un graphe RDF et le sérialiser au format Turtle.
<?php
use CapDataOpera\PhpSdk\Graph\Graph;
use CapDataOpera\PhpSdk\Model\Collectivite;
use CapDataOpera\PhpSdk\Model\Isni;
use CapDataOpera\PhpSdk\Serializer\Serializer;
$serializer = new Serializer();
$graph = new Graph();
$ownOrg = new Collectivite('https://mon-opera.fr/organization/1');
$ownOrg->setNom('Mon opéra de test')
->setFacebook('https://facebook.com/mon-opera')
->setSiteWeb('https://mon-opera.fr')
->setCatalogageSourceAgence($ownOrg)
->setDateCreationRessource(new \DateTimeImmutable('2022-01-30T00:00:00+00:00'))
->setDateModificationRessource(new \DateTimeImmutable('2024-01-30T00:00:00+00:00'))
->setIsni(new Isni('https://isni.org/isni/0000000122982840'));
$graph->add($ownOrg);
/*
* On exporte le graph en RDF avec les ontologies capdata et schema.org pour obtenir un fichier Turtle
*/
echo $serializer->serialize($graph, 'turtle', ['capdata', 'schema']);
Classes supportées
- [x] Adresse postale: https://ontologie.capdataculture.fr/v1/owl/#Adresse
- [x] Categorie d'oeuvre: https://ontologie.capdataculture.fr/v1/owl/#CategorieOeuvre
- [x] Collectivité: https://ontologie.capdataculture.fr/v1/owl/#Collectivite
- [x] Fonction: https://ontologie.capdataculture.fr/v1/owl/#Fonction
- [x] Genre d'oeuvre: https://ontologie.capdataculture.fr/v1/owl/#GenreOeuvre
- [x] Historique de Production: https://ontologie.capdataculture.fr/v1/owl/#HistoriqueProduction
- [x] Lieu: https://ontologie.capdataculture.fr/v1/owl/#LieuGeographique
- [x] Media: https://ontologie.capdataculture.fr/v1/owl/#Media (Ne pas utiliser directement, utiliser les sous-classes)
- [x] Image: http://purl.org/dc/elements/1.1/Image
- [ ] MovingImage: http://purl.org/dc/elements/1.1/MovingImage
- [x] Sound: http://purl.org/dc/elements/1.1/Sound
- [x] Text: http://purl.org/dc/elements/1.1/Text
- [x] Image: http://purl.org/dc/elements/1.1/Image
- [x] Oeuvre: https://ontologie.capdataculture.fr/v1/owl/#Oeuvre
- [x] Participation: https://ontologie.capdataculture.fr/v1/owl/#Participation
- [x] Auteur: https://ontologie.capdataculture.fr/v1/owl/#Auteur
- [x] Collaboration technique et artistique: https://ontologie.capdataculture.fr/v1/owl/#Collaboration
- [x] Interprétation: https://ontologie.capdataculture.fr/v1/owl/#Interpretation
- [x] Maitrise d'oeuvre: https://ontologie.capdataculture.fr/v1/owl/#MaitriseOeuvre
- [x] Mention de production: https://ontologie.capdataculture.fr/v1/owl/#MentionProduction
- [x] Partenariat: https://ontologie.capdataculture.fr/v1/owl/#Partenariat
- [x] Programmation: https://ontologie.capdataculture.fr/v1/owl/#Programmation
- [x] Pays: https://ontologie.capdataculture.fr/v1/owl/#Pays
- [x] Personne: https://ontologie.capdataculture.fr/v1/owl/#Personne
- [x] Production Primaire: https://ontologie.capdataculture.fr/v1/owl/#ProductionPrimaire
- [x] Production: https://ontologie.capdataculture.fr/v1/owl/#Production
- [x] Rôle: https://ontologie.capdataculture.fr/v1/owl/#Role
- [x] Saison: https://ontologie.capdataculture.fr/v1/owl/#Saison
- [x] Statut juridique: https://ontologie.capdataculture.fr/v1/owl/#StatutJuridique
- [x] Type d'oeuvre: https://ontologie.capdataculture.fr/v1/owl/#TypeOeuvre
- [x] Type d'événement: https://ontologie.capdataculture.fr/v1/owl/#TypeEvenement
- [x] Type de production: https://ontologie.capdataculture.fr/v1/owl/#TypeProduction
- [x] Type de public: https://ontologie.capdataculture.fr/v1/owl/#TypePublic
- [x] Événement: https://ontologie.capdataculture.fr/v1/owl/#Evenement
Pour les médias, il est recommandé d'utiliser les sous-classes Image
, Sound
et Text
.
Plus en détails
Immutabilité des données
Les données primitives de chaque classe sont représentées par un Value Object pour valider les données et les rendre immutables.
Cardinalité
En utilisant les Value Object pour représenter les données, on peut gérer la cardinalité des propriétés d'une classe, en construisant un Value Object qui représente une collection de valeurs plutôt qu'une valeur unique.
Tous les ValueObject
peuvent accepter une primitive ou bien un tableau de primitives. Les méthodes __toString
et
__serialize
permettent de récupérer la valeur primitive ou le tableau de valeurs primitives de manière forcée.
Le Value Object est responsable de la validation des données en entrée.
<?php
$simpleString = new StringObject('foo');
$multipleString = new StringObject(['foo', 'bar']);
echo $simpleString; // 'foo'
echo $multipleString; // 'foo, bar' (concaténation des valeurs avec une virgule)
var_dump($simpleString->__serialize()); // ['foo']
var_dump($multipleString->__serialize()); // ['foo', 'bar']
Correspondance avec schema.org
Le SDK permet de construire automatiquement certaines correspondances entre les ontologies CapData Opéra et schema.org.
<https://mon-opera.fr/production/1>
a schema:Thing, rof:Production, schema:CreativeWork ;
rof:aPourInterpretation <https://mon-opera.fr/interpretation/1>, <https://mon-opera.fr/interpretation/2> ;
Propriétés de classes
Toutes les propriétés des classes héritant OntologyClass
sont des ValueObject. Ainsi, les setter
acceptent soit :
- une valeur primitive
- un tableau de valeurs primitives
- un
ValueObject
représentant une valeur - un
ValueObject
représentant une collection de valeurs
Le getter
retourne toujours un ValueObject
.
<?php
use CapDataOpera\PhpSdk\ValueObject\StringObject;
use CapDataOpera\PhpSdk\Model\Personne;
$personne = new Personne('https://mon-opera.fr/person/1');
// Appels possibles pour ajouter une propriété :
// - Le setter wrap la valeur dans un ValueObject
$personne->setNom('foo');
// - On peut aussi passer un tableau de valeurs
$personne->setNom(['foo', 'bar']);
// - On passe directement un ValueObject
$personne->setNom(new StringObject('foo'));
// - On passe directement un ValueObject avec le tableau de valeurs
$personne->setNom(new StringObject(['foo', 'bar']));
// Le getter retourne toujours un ValueObject
$personne->getNom(); // StringObject('foo')
Relations entre objets
Les relations entre objets sont représentées par des RelationObject qui sont des ValueObject qui représentent une collection.
Les RelationObject
sont typés dès leur construction pour valider les données en entrée.
<?php
use CapDataOpera\PhpSdk\ValueObject\RelationObject;
use CapDataOpera\PhpSdk\Model\Fonction;
use CapDataOpera\PhpSdk\Model\Personne;
$fonction = new Fonction('https://mon-opera.fr/fonction/1');
$fonction2 = new Fonction('https://mon-opera.fr/fonction/2');
$personne = new Personne('https://mon-opera.fr/person/1');
// Appels possibles pour ajouter une relation :
// - Le setter wrap l'objet dans un RelationObject en définissant le type
$personne->setAPourFonction($fonction);
// - On peut aussi passer un tableau de valeurs
$personne->setAPourFonction([$fonction, $fonction2]);
// - On passe directement un RelationObject
$personne->setAPourFonction(new RelationObject($fonction, Fonction::class));
// - On passe directement un RelationObject avec le tableau de valeurs
$personne->setAPourFonction(new RelationObject([$fonction, $fonction2], Fonction::class));
Relations externes
Toutes les méthodes acceptant des RelationObject
acceptent aussi des URI de ressources externes via
la class ExternalThing
.
<?php
use CapDataOpera\PhpSdk\Model\Personne;
use CapDataOpera\PhpSdk\Model\ExternalThing;
$personne = new Personne('https://mon-opera.fr/person/1');
$personne->setAPourFonction(new ExternalThing('http://capdataculture.fr/graph/FONCTION/230'));
Voici les classes disponibles pour les relations externes :
CapDataOpera\PhpSdk\Model\ExternalThing
CapDataOpera\PhpSdk\Model\Isni
CapDataOpera\PhpSdk\Model\ArkBnf
Les objets créés avec ces classes n'ont pas besoin d'être ajoutés au graph pour être sérialisés.
Serialization des objets
Une fois les objets construits, vous devrez ajouter chaque objet à un Graph
.
$graph = new Graph();
$address = new AdressePostale('https://mon-opera.fr/adresse/1');
$address
->setAdressePostale('1 place de la Comédie')
->setCodePostal('69001')
->setCommune('Lyon')
;
$ownOrg = new Collectivite('https://mon-opera.fr/organization/1');
$ownOrg->setNom('Mon opéra de test')
->setFacebook('https://facebook.com/mon-opera')
->setSiteWeb('https://mon-opera.fr')
->setAdresse($address)
->setCatalogageSourceAgence($ownOrg)
->setDateCreationRessource(new \DateTimeImmutable('2022-01-30T00:00:00+00:00'))
->setDateModificationRessource(new \DateTimeImmutable('2024-01-30T00:00:00+00:00'))
->setIsni(new Isni('https://isni.org/isni/0000000122982840'));
$graph->add($address);
$graph->add($ownOrg);
Le graph enregistre chaque URI d'objet ajouté pour éviter les doublons, mais aussi pour valider si chaque relation vers une ressource interne est bien enregistrée dans le graph.
Une fois le graph construit, le serializer va convertir chaque objet en RDF via la librairie EasyRdf
et créer les triplets selon les ontologies https://ontologie.capdataculture.fr/v1/, https://schema.org/, etc.
Cette étape est opérée par les Converter
et les LiteralConverter
qui sont responsables de la conversion via le
pattern Chain of Responsibility.
La classe CapDataOpera\PhpSdk\Serializer\Serializer
est, par défaut, configurée avec une liste de Converter
et de LiteralConverter
. Mais vous pouvez
configurer vos propres Converter
et LiteralConverter
pour ajouter des propriétés ou des classes à votre RDF.
<?php
use CapDataOpera\PhpSdk\Serializer\Serializer;
// Serializer avec les converters par défaut
$serializer = new Serializer();
// Serializer des converters personnalisés
$serializer = new Serializer(
[
new MyCustomObjectConverter(),
],
[
new MyCustomLiteralConverter(),
]
);
Enfin, une fois le graph convertit en RDF, vous pouvez le sérialiser dans le format de votre choix. Il s'agit des formats supportés par EasyRdf : https://www.easyrdf.org/docs/api/EasyRdf/Serialiser.html#method_serialise
<?php
// La méthode serialize effectue la conversion, la validation puis la sérialisation
echo $serializer->serialize($graph, 'turtle', ['capdata']);
Ajouter des propriétés personnalisées
Vous avez la possibilité d'ajouter des propriétés personnalisées n'importe où
dans votre Graph en utilisant la méthode addResource
:
<?php
use CapDataOpera\PhpSdk\Graph\Graph;
use CapDataOpera\PhpSdk\Model\Collectivite;
use CapDataOpera\PhpSdk\Model\Isni;
use CapDataOpera\PhpSdk\Serializer\Serializer;
$serializer = new Serializer();
$graph = new Graph();
$ownOrg = new Collectivite('https://mon-opera.fr/organization/1');
$ownOrg->setNom('Mon opéra de test')
->setFacebook('https://facebook.com/mon-opera')
->setSiteWeb('https://mon-opera.fr')
->setCatalogageSourceAgence($ownOrg)
->setDateCreationRessource(new \DateTimeImmutable('2022-01-30T00:00:00+00:00'))
->setDateModificationRessource(new \DateTimeImmutable('2024-01-30T00:00:00+00:00'))
->setIsni(new Isni('https://isni.org/isni/0000000122982840'));
$graph->add($ownOrg);
/**
* Ajout d'une propriété personnalisée sur l'objet Collectivite
*/
$graph->addResource(
'https://mon-opera.fr/organization/1',
'https://schema.org/startDate',
new Literal('2016-04-21T20:00', null, 'xsd:dateTime')
);
echo $serializer->serialize($graph, 'turtle', ['capdata']);
Choisir les ontologies pour la sérialisation
La méthode serialize
accepte un tableau de chaînes de caractères pour choisir les ontologies à utiliser pour la sérialisation.
Les ontologies disponibles sont :
capdata
: https://ontologie.capdataculture.fr/v1/schema
: https://schema.org/
Par défaut, le serializer utilise l'ontologie capdata
uniquement.
<?php
use CapDataOpera\PhpSdk\Serializer\Serializer;
$serializer = new Serializer();
$graph = new Graph();
// ...
// Par défaut, exporte uniquement les classes et propriétés de l'ontologie capdata au format Turtle
echo $serializer->serialize($graph, 'turtle'/*, ['capdata'] */);
// les 2 ontologies sont utilisées
echo $serializer->serialize($graph, 'turtle', ['capdata', 'schema']);
// Exporte uniquement les classes et propriétés de l'ontologie schema.org au format LD-JSON pour le web sémantique
// L'export au format LD-JSON nécessite la librairie ml/json-ld: composer require ml/json-ld
echo $serializer->serialize($graph, 'jsonld', ['schema']);
Comment contribuer au projet
Veuillez lire CONTRIBUTING.md pour plus de détails sur notre code de conduite, et le processus pour soumettre une pull-request ou une issue.
Crédits
Développements réalisés dans le cadre du projet CapData Opéra - France 2030, porté par la Réunion des Opéras de France. Opération soutenue par l'État dans le cadre du dispositif « Expérience augmentée du spectacle vivant » de France 2030, opéré par la Caisse des Dépôts. Information sur https://www.rof.fr/rof/capdata-opera.aspx.
Conception et développement du SDK PHP : Rezo Zero - https://www.rezo-zero.com/