L'implémentation de l'API se présente sous la forme d'un fichier unique qui comprend les différentes classes de l'API ainsi que des classes utilitaires. La dernière version stable de ce fichier est disponible à cette adresse : http://dataexport.scrutari.net/impl/php/scrutaridataexport.txt (remplacez .txt par .php pour l'exécution)
Toutes les classes et constantes de ce fichier commence par le suffixe SDE_ afin de minimiser le risque de conflits de noms avec d'autres classes PHP. Cette implémentation fonctionne avec PHP 5. Elle est sous licence MIT.
Ces scripts sont accessibles avec Git via https://framagit.org/Scrutari/export-php
Un autre accès avec Subversion :
svn co http://depot.exemole.fr/svn/web/apps/scrutari.net/php
L'exemple suivant est celui du site www.comedie.org. Celui-ci est en Wordpress. La structure des données de Wordpress étant assez simple, il a été choisi d'écrire un script interrogeant directement les données de la base MySQl plutôt que de passer par une procédure plus lourde d'extension Wordpress.
Outre le fichier scrutaridataexport.php, cette extraction est basé sur deux fichiers : comedie.scrutari-data.php qui comprend la configuration de l'accès (voir http://dataexport.scrutari.net/impl/php/comedie.scrutari-data.txt et ci-dessous) et comedie.php qui comprend l'extraction proprement dite (voir http://dataexport.scrutari.net/impl/php/comedie.txt).
Ce fichier contient les informations de la configuration (accès à la base de données).
<?php //Indication que les données transmises sont du XML header("content-type: text/xml;charset=UTF-8"); // Nom de la base de données de WordPress. define('DB_NAME', '*'); // Utilisateur de la base de données MySQL. define('DB_USER', '*'); // Mot de passe de la base de données MySQL. define('DB_PASSWORD', '*'); // Adresse de l'hébergement MySQL. define('DB_HOST', 'localhost'); // Jeu de caractères à utiliser par la base de données define('DB_CHARSET', 'utf8'); // Chaine vide pour SCRUTARIDATA_PATH, les données XML sont affichées directement en sortie define('SCRUTARIDATA_PATH', ''); // Appel de comedie.php require("comedie.php");
Si on avait voulu que l'extraction soit enregistrée dans un fichier, on aurait cette définition pour SCRUTARIDATA_PATH :
define('SCRUTARIDATA_PATH', '/path/to/directory/comedie.scrutari-data.xml');
Ce fichier (http://dataexport.scrutari.net/impl/php/comedie.txt) comprend plusieurs parties.
Le fichier commence par l'appel à scrutaridataexport.php
//Chargement de la bibliothèque ScrutariDataExport, supposée être dans le même répertoire que ce script require_once("scrutaridataexport.php");
Vient ensuite la déclaration d'une classe utilitaire :
/** * Recensement des posts Wordpress retenus pour l'extraction, avec indication du nom du corpus correspondant */ class PostCensus { private $map; function __construct() { $this->map = array(); } function put($id, $corpus) { $this->map["id_".$id] = $corpus; } function get($id) { return $this->map["id_".$id]; } }
Puis la définit des fonctions.
/** * Ajoute les posts appartenant à la catégorie indiquée par $termTaxonomyId, * ces posts étant destiné à être inclus dans le corpus de nom $corpusName */ function addPosts($pdo, $scrutariDataExport, $termTaxonomyId, $postCensus, $corpusName) { $statement = $pdo->query('SELECT object_id FROM `wp_term_relationships` WHERE `term_taxonomy_id` = '.$termTaxonomyId); $array = array(); while ($row = $statement->fetch(PDO::FETCH_NUM)) { $array[] = $row[0]; } foreach($array as $postId) { $postStatement = $pdo->query('SELECT * FROM `wp_posts` WHERE `ID` = '.$postId." AND post_status='publish'"); $postRow = $postStatement->fetch(PDO::FETCH_ASSOC); if ($postRow) { $postCensus->put($postId, $corpusName); $titre = $postRow['post_title']; $soustitre = ""; $date = ""; $auteurs = ""; $publication_annee = ""; $publication_auteur = ""; $publication_editeur = ""; $metaStatement = $pdo->query('SELECT * FROM `wp_postmeta` WHERE `post_id` = '.$postId); //Interrogation de postmeta pour récupérer les données associées au post $dateDone = false; while($metaRow = $metaStatement->fetch(PDO::FETCH_ASSOC)) { $metaKey = $metaRow['meta_key']; $value = $metaRow['meta_value']; if ($metaKey == 'sous-titre') { $soustitre = $value; } else if ($metaKey == 'annee_debut') { if ((!$dateDone) && (strlen($value) > 0)) { $date = $value; } } else if ($metaKey == 'annee_creation') { if (strlen($value) > 0) { $date = $value; $dateDone = true; } } else if ($metaKey == 'auteurs_plus') { $auteurs = $value; } else if ($metaKey == 'publication_annee_publication') { $publication_annee = $value; } else if ($metaKey == 'publication_auteur') { $publication_auteur = $value; } else if ($metaKey == 'publication_editeur') { $publication_editeur = $value; } } if ($corpusName == 'lecture') { //Traitement particulier au corpus des notes de lecture $titre = "Note de lecture : ".$titre; //le titre étant celui de l'ouvrage, Note de lecture est ajouté avant if (strlen($soustitre) > 0) { if (substr($titre, strlen($titre) -1,1) != ".") { $titre .= "."; } $titre .= " ".$soustitre; //le sous-titre étant celui de l'ouvrage, il est placé à la suite du titre $soustitre = ""; } $soustitre = appendInfo($soustitre, $publication_auteur); $soustitre = appendInfo($soustitre, $publication_editeur); $soustitre = appendInfo($soustitre, $publication_annee); } $ficheExport = $scrutariDataExport->newFiche($postId); $ficheExport->setTitre($titre); $ficheExport->setSoustitre($soustitre); $ficheExport->setHref("http://www.comedie.org/?p=".$postId); $ficheExport->setLang('fr'); if (strlen($date) > 0) { $ficheExport->setDate($date); } if (strlen($auteurs) > 0) { parseAuteurs($auteurs, $pdo, $ficheExport); } } } } /** * Ajoute $value à la fin de $text en rajoutant une virgule si nécessaire */ function appendInfo($text, $value) { $value = trim($value); $value = str_replace(" ;", ",", $value); if (substr($value, strlen($value) -1,1) == ".") { $value = substr($value, 0, strlen($value) -1); } if (strlen($value) == 0) { return $text; } if (strlen($text) > 0) { $text .= ", "; } $text .= $value; return $text; } /** * Récupère le nom des auteurs d'un post. Sur le site comedie.org, les véritables auteurs d'un post sont indiqués * par meta_key=auteurs_plus dans la table wp_postmeta et sous la forme a:1:{i:0;s:2:"67";}. 67 est ici * l'identifiant du post correspondant à l'auteur (le nom complet de l'auteur est le titre du post) */ function parseAuteurs($auteurs, $pdo, $ficheExport) { $idx1 = strpos($auteurs, "\""); if ($idx1 < 1) { return; } $idx2 = strpos($auteurs, "\"", $idx1 + 1); if ($idx2 < 1) { return; } $auteurId = substr($auteurs, $idx1 + 1, $idx2 - ($idx1 + 1)); if ($auteurId == 572) { //l'auteur générique Comédie est ignoré return; } $authorStatement = $pdo->query('SELECT post_title FROM `wp_posts` WHERE `ID` = '.$auteurId); $auteur = $authorStatement->fetchColumn(); if ($auteur) { $ficheExport->addAttributeValue("sct", "authors", $auteur); } } /** * Ajoute les termes de la taxonomie $taxonomy sous la forme de mots-clés du thésaurus de nom $thesaurusName, * la fonction récupère également les posts liés au terme et crée une indexation si le post a bien été recensé * préalablement dans $postCensus */ function addTerms($pdo, $scrutariDataExport, $taxonomy, $postCensus, $thesaurusName) { $statement = $pdo->query("SELECT wp_term_taxonomy.term_taxonomy_id, wp_terms.name FROM wp_terms,wp_term_taxonomy WHERE wp_term_taxonomy.term_id = wp_terms.term_id AND wp_term_taxonomy.taxonomy = '".$taxonomy."'"); $array = array(); while ($row = $statement->fetch(PDO::FETCH_NUM)) { $id = $row[0]; $name = $row[1]; if ((strlen($name) > 0) && (strpos($name, "MOT") !== 0)) { $array[] = $id; $motcleExport = $scrutariDataExport->newMotcle($id); $motcleExport->setLibelle("fr", $name); } } foreach($array as $termId) { $postStatement = $pdo->query("SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id=".$termId); while ($postId = $postStatement->fetchColumn(0)) { $corpusName = $postCensus->get($postId); if (strlen($corpusName) > 0) { $scrutariDataExport->addIndexation($corpusName, $postId, $thesaurusName, $termId,1); } } } }
C'est alors que commmence l'initialisation avec l'utilisation des constantes définies dans comedie.scrutari-data.php pour l'accès aux données :
//Test si l'extraction est écrite dans un fichier ou directement vers la sortie $file = false; if (strlen(SCRUTARIDATA_PATH) > 0) { $file = fopen(SCRUTARIDATA_PATH, "w"); } //Accès à la base de données $pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHARSET, DB_USER, DB_PASSWORD); // Instance de PostCensus recensant les posts inclus dans l'extraction $postCensus = new PostCensus(); // Instance de SDE_XmlWriter recensant les posts inclus dans l'extraction $xmlWriter = new SDE_XmlWriter($file, true, true); $scrutariDataExport = new SDE_ScrutariDataExport($xmlWriter);
Vient ensuite l'extraction proprement dite avec la définition des méta-données, des corpus et thésaurus et les appels aux fonctions pour la récupération des données et la fin de l'extraction.
//Démarrage de l'export avec la définition des méta-données $baseMetadataExport = $scrutariDataExport->startExport(); $baseMetadataExport->setAuthority("comedie.org"); $baseMetadataExport->setBaseName("site"); $baseMetadataExport->setBaseIcon("http://scrutari.coredem.info/comedie.png"); $baseMetadataExport->setIntitule(SDE_INTITULE_SHORT, "fr", "Comédie"); $baseMetadataExport->setIntitule(SDE_INTITULE_LONG, "fr", "Comédie - Concertation, participation et médiation appliquées à l’environnement et au territoire"); $baseMetadataExport->addLangUI("fr"); //Création du corpus experience correspondant aux fiches de http://www.comedie.org/ressources/fiches-experiences/ $corpusMetadataExport = $scrutariDataExport->newCorpus("experience"); $corpusMetadataExport->setIntitule(SDE_INTITULE_CORPUS, "fr","Expériences"); $corpusMetadataExport->setIntitule(SDE_INTITULE_FICHE, "fr", "Expérience n°"); //Ajout des posts des expériences (12 est l'identifiant du terme correspondant à la catégorie des expériences) addPosts($pdo, $scrutariDataExport, 12, $postCensus, "experience"); //Création du corpus monographie correspondant aux fiches de http://www.comedie.org/ressources/monographies/ $corpusMetadataExport = $scrutariDataExport->newCorpus("monographie"); $corpusMetadataExport->setIntitule(SDE_INTITULE_CORPUS, "fr","Monographies"); $corpusMetadataExport->setIntitule(SDE_INTITULE_FICHE, "fr", "Monographie n°"); //Ajout des posts des monographies addPosts($pdo, $scrutariDataExport, 15, $postCensus, "monographie"); //Création du corpus video correspondant aux fiches de http://www.comedie.org/ressources/videos/ $corpusMetadataExport = $scrutariDataExport->newCorpus("video"); $corpusMetadataExport->setIntitule(SDE_INTITULE_CORPUS, "fr","Vidéos"); $corpusMetadataExport->setIntitule(SDE_INTITULE_FICHE, "fr", "Vidéo n°"); //Ajout des posts des vidéos addPosts($pdo, $scrutariDataExport, 18, $postCensus, "video"); //Création du corpus lecture correspondant aux fiches de http://www.comedie.org/ressources/notes-de-lecture/ $corpusMetadataExport = $scrutariDataExport->newCorpus("lecture"); $corpusMetadataExport->setIntitule(SDE_INTITULE_CORPUS, "fr","Notes de lecture"); $corpusMetadataExport->setIntitule(SDE_INTITULE_FICHE, "fr", "Note de lecture n°"); //Ajout des posts des notes de lecture addPosts($pdo, $scrutariDataExport, 14, $postCensus, "lecture"); //Création du thésaurus motcle $thesaurusMetadataExport = $scrutariDataExport->newThesaurus("motcle"); $thesaurusMetadataExport->setIntitule(SDE_INTITULE_THESAURUS,"fr","Mots-clés"); //Ajout des termes, les mots-clés sont distingués des autres termes par la taxonomie mots-clefs addTerms($pdo, $scrutariDataExport, "mots-clefs", $postCensus, "motcle"); //Fin de l'export $scrutariDataExport->endExport();
Ce script peut facilement être adapté à un autre site sous Wordpress. Les grandes différences d'un site à l'autre sont la façon avec laquelle les posts que l'on veut extraire sont distingués des autres. Ici, la sélection se fait grâce à des termes (table wp_term et wp_term_taxonomy) spécifique.