Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
scrutaridata:exportapi:php [2010/02/11 18:51]
vincent créée
scrutaridata:exportapi:php [2016/09/21 18:19] (Version actuelle)
vincent
Ligne 1: Ligne 1:
 ====== Implémentation de l'API en PHP ====== ====== Implémentation de l'API en PHP ======
 +
 +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
 +
 +
 +===== Exemple du site www.comedie.org =====
 +
 +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).
 +
 +=== Fichier comedie.scrutari-data.php ===
 +
 +Ce fichier contient les informations de la configuration (accès à la base de données).
 +
 +<code php>
 +<?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"​);​
 +</​code>​
 +
 +Si on avait voulu que l'​extraction soit enregistrée dans un fichier, on aurait cette définition pour //​SCRUTARIDATA_PATH//​ :
 +
 +<code php>
 +define('​SCRUTARIDATA_PATH',​ '/​path/​to/​directory/​comedie.scrutari-data.xml'​);​
 +</​code>​
 +
 +=== Fichier comedie.php ===
 +
 +Ce fichier (http://​dataexport.scrutari.net/​impl/​php/​comedie.txt) comprend plusieurs parties.
 +
 +Le fichier commence par l'​appel à scrutaridataexport.php
 +
 +<code php>
 +//​Chargement de la bibliothèque ScrutariDataExport,​ supposée être dans le même répertoire que ce script
 +require_once("​scrutaridataexport.php"​);​
 +</​code>​
 +
 +Vient ensuite la déclaration d'une classe utilitaire :
 +
 +<code php>
 +/**
 +* 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];​
 +    }
 +
 +}
 +</​code>​
 +
 +Puis la définit des fonctions.
 +
 +<code php>
 +/**
 +* 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);
 +            }
 +        }
 +    }
 +}
 +</​code>​
 +
 +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 :
 +
 +<code php>
 +//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);​
 +</​code>​
 +
 +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.
 +
 +<code php>
 +//​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();​
 +</​code>​
 +
 +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. ​
 +
 +
 +
 +
scrutaridata/exportapi/php.1265910663.txt.gz · Dernière modification: 2010/02/11 18:51 par vincent
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0