Changeset 115582 in spip-zone


Ignore:
Timestamp:
Jun 9, 2019, 7:12:39 PM (7 days ago)
Author:
eric@…
Message:

Refactoring complet du plugin pour accueillir les collections de SVP Typologie.

Location:
_plugins_/svp_api/trunk
Files:
3 added
5 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/svp_api/trunk/http/svp.php

    r96921 r115582  
    99        return;
    1010}
    11 
    1211
    1312/**
     
    3029function http_svp_erreur_dist($code, $requete, $reponse) {
    3130
    32         include_spip('inc/svpapi_reponse');
    33 
    3431        // Construction du contenu de la réponse:
    3532        // Comme l'erreur est détectée par le serveur HTTP abstrait, le contenu n'est pas initialisé.
    3633        // Il faut donc l'initialiser selon la structure imposée par l'API.
     34        include_spip('inc/svpapi_reponse');
    3735        $contenu = reponse_initialiser_contenu($requete);
    3836
     
    4341        $contenu['erreur']['detail'] = _T('http:erreur_' . $contenu['erreur']['status'] . '_message');
    4442
    45         // Détermination du format de la réponse. Etant donné que l'on traite déjà une erreur, on ne se préoccupe pas
    46         // pas d'une éventuelle erreur sur le format, on utilisera dans ce cas le JSON.
    47         $format_reponse = 'json';
    48         if (requete_verifier_format($contenu['requete']['format_contenu'], $erreur)) {
    49                 // On positionne le format de sortie car on sait que celui demandé est valide
    50                 $format_reponse = $contenu['requete']['format_contenu'];
    51         }
    52 
    5343        // Finaliser la réponse selon le format demandé.
    54         $reponse = reponse_construire($reponse, $contenu, $format_reponse);
     44        $reponse = reponse_construire($reponse, $contenu);
    5545
    5646        return $reponse;
     
    6151 * Fait un GET sur une collection de plugins ou de dépôts.
    6252 * La requête est du type `/svp/plugins` ou `/svp/depots` et renvoie les objets plugin contenus dans la base du serveur
    63  * (hors les plugins installés) ou les objets dépôt hébergés par le serveur.
    64  * Il est possible de filtrer la collection des plugins par catégorie et par compatibilité SPIP
    65  * `/svp/plugins&compatible_spip=2.1&categorie=outil`.
     53 * (hors les plugins installés) ou les objets dépôt hébergés par le serveur. Il est possible de filtrer la collection
     54 * des plugins par catégorie et par compatibilité SPIP `/svp/plugins&compatible_spip=2.1&categorie=outil`.
     55 *
     56 * Il est possible pour des plugins de rajouter des collections en utilisant le pipeline `declarer_collections_svp`
     57 * et en fournissant les fonctions de service associées.
    6658 *
    6759 * @api
     
    8072function http_svp_get_collection_dist($requete, $reponse) {
    8173
    82         include_spip('inc/svpapi_requete');
     74        // Initialisation du format de sortie du contenu de la réponse, du bloc d'erreur et de la collection.
    8375        include_spip('inc/svpapi_reponse');
    84 
    85         // Initialisation du format de sortie du contenu de la réponse, du bloc d'erreur et du format de sortie en JSON
    8676        $contenu = reponse_initialiser_contenu($requete);
    8777        $erreur = array();
    88         $format_reponse = 'json';
     78        $collection = '';
    8979
    9080        // Vérification du mode SVP du serveur : celui-ci ne doit pas être en mode runtime pour
    91         // renvoyer des données complètes
     81        // renvoyer des données complètes.
     82        include_spip('inc/svpapi_requete');
    9283        if (requete_verifier_serveur($erreur)) {
    93                 // Vérification du format demandé pour le contenu
    94                 if (requete_verifier_format($contenu['requete']['format_contenu'], $erreur)) {
    95                         // On positionne cette fois le format du contenu car on sait que celui demandé est valide
    96                         $format_reponse = $contenu['requete']['format_contenu'];
    97                         // Vérification du nom de la collection
    98                         if (requete_verifier_collection($contenu['requete']['collection'], $erreur)) {
    99                                 // On vérifie les critères de filtre additionnels si la requête en contient
    100                                 $where = array();
    101                                 if (requete_verifier_criteres($contenu['requete']['criteres'], $erreur)) {
    102                                         // Si il y a des critères additionnels on complète le where en conséquence
    103                                         if ($contenu['requete']['criteres']) {
    104                                                 foreach ($contenu['requete']['criteres'] as $_critere => $_valeur) {
    105                                                         if ($_critere == 'compatible_spip') {
    106                                                                 $f_critere = charger_fonction('where_compatible_spip', 'inc');
    107                                                                 $where[] = $f_critere($_valeur, 'spip_plugins', '>');
    108                                                         } else {
    109                                                                 $where[] = "spip_plugins.${_critere}=" . sql_quote($_valeur);
    110                                                         }
    111                                                 }
    112                                         }
    113 
    114                                         // Récupération de la collection spécifiée en fonction des critères appliqués
    115                                         $collectionner = 'reponse_collectionner_' . $contenu['requete']['collection'];
    116                                         $donnees = $collectionner($where);
    117 
    118                                         $contenu['donnees'] = $donnees;
     84                // Récupération de la liste des collections disponibles.
     85                $collections = requete_declarer_collections();
     86
     87                // Vérification du nom de la collection.
     88                $collection = $contenu['requete']['collection'];
     89                if (requete_verifier_collection($collection, $collections, $erreur)) {
     90                        // La collection étant correcte on extrait sa configuration.
     91                        $configuration = $collections[$collection];
     92
     93                        // Vérification des filtres, si demandés.
     94                        if (requete_verifier_filtres($contenu['requete']['filtres'], $configuration, $erreur)) {
     95                                // Détermination de la fonction de service permettant de récupérer la collection spécifiée
     96                                // filtrée sur les critères éventuellement fournis.
     97                                // -- la fonction de service est contenue dans un fichier du répertoire svpapi/.
     98                                $module = $configuration['module'];
     99                                include_spip("svpapi/${module}");
     100                                $collectionner = "${collection}_collectionner";
     101                                if (!function_exists($collectionner)) {
     102                                        $erreur = array(
     103                                                'status'  => 400,
     104                                                'type'    => 'fonction_nok',
     105                                                'element' => 'collection',
     106                                                'valeur'  => $collectionner
     107                                        );
    119108                                }
     109                                // -- on construit le contenu de la collection.
     110                                $contenu['donnees'] = $collectionner($contenu['requete']['filtres']);
    120111                        }
    121112                }
     
    126117        if ($erreur) {
    127118                $contenu['erreur'] = array_merge($contenu['erreur'], $erreur);
    128                 $contenu['erreur'] = reponse_expliquer_erreur($contenu['erreur']);
     119                $contenu['erreur'] = reponse_expliquer_erreur($contenu['erreur'], $collection);
    129120        }
    130121
    131122        // Construction de la réponse finale
    132         $reponse = reponse_construire($reponse, $contenu, $format_reponse);
     123        $reponse = reponse_construire($reponse, $contenu);
    133124
    134125        return $reponse;
     
    139130 * Fait un GET sur une ressource de type plugin identifiée par son préfixe.
    140131 * La requête est du type `/svp/plugins/prefixe` et renvoie l'objet plugin et les objets paquets associés.
     132 *
     133 * Il est possible de rajouter des ressources en utilisant le pipeline `declarer_ressources_svp`.
    141134 *
    142135 * @api
     
    155148function http_svp_get_ressource_dist($requete, $reponse) {
    156149
    157         include_spip('inc/svpapi_requete');
     150        // Initialisation du format de sortie du contenu de la réponse, du bloc d'erreur et du format de sortie en JSON
    158151        include_spip('inc/svpapi_reponse');
    159 
    160         // Initialisation du format de sortie du contenu de la réponse, du bloc d'erreur et du format de sortie en JSON
    161152        $contenu = reponse_initialiser_contenu($requete);
    162153        $erreur = array();
    163         $format_reponse = 'json';
     154        $collection = '';
    164155
    165156        // Vérification du mode SVP du serveur : celui-ci ne doit pas être en mode runtime pour
    166         // renvoyer des données complètes
     157        // renvoyer des données complètes.
     158        include_spip('inc/svpapi_requete');
    167159        if (requete_verifier_serveur($erreur)) {
    168                 // Vérification du format demandé pour le contenu
    169                 if (requete_verifier_format($contenu['requete']['format_contenu'], $erreur)) {
    170                         // On positionne le format du contenu qui sera utilisé car on sait que celui demandé est valide
    171                         $format_reponse = $contenu['requete']['format_contenu'];
    172                         // Vérification du nom de la collection
    173                         if (requete_verifier_ressource($contenu['requete']['collection'], $erreur)) {
    174                                 // Vérification du préfixe de la ressource
    175                                 if (requete_verifier_prefixe($contenu['requete']['ressource'], $erreur)) {
    176                                         $prefixe = strtoupper($contenu['requete']['ressource']);
    177                                         $donnees = array();
    178                                         // On recherche d'abord le plugin par son préfixe dans la table spip_plugins en vérifiant que
    179                                         // c'est bien un plugin fourni pas un dépôt et pas un plugin installé sur le serveur uniquement
    180                                         $from = array('spip_plugins', 'spip_depots_plugins AS dp');
    181                                         $select = array('*');
    182                                         $where = array(
    183                                                 'prefixe=' . sql_quote($prefixe),
    184                                                 'dp.id_depot>0',
    185                                                 'dp.id_plugin=spip_plugins.id_plugin'
     160                // Récupération de la liste des collections disponibles.
     161                $collections = requete_declarer_collections();
     162
     163                // Vérification du nom de la collection.
     164                $collection = $contenu['requete']['collection'];
     165                if (requete_verifier_collection($collection, $collections, $erreur)) {
     166                        // La collection étant correcte on extrait sa configuration.
     167                        $configuration = $collections[$collection];
     168
     169                        // Vérification de la ressource
     170                        $ressource = $contenu['requete']['ressource'];
     171                        if (requete_verifier_ressource($ressource, $configuration, $erreur)) {
     172                                // Détermination de la fonction de service permettant de récupérer la ressource spécifiée.
     173                                // -- la fonction de service est contenue dans un fichier du répertoire svpapi/.
     174                                $module = $configuration['module'];
     175                                include_spip("svpapi/${module}");
     176                                $ressourcer = "${collection}_ressourcer";
     177                                if (!function_exists($ressourcer)) {
     178                                        $erreur = array(
     179                                                'status'  => 400,
     180                                                'type'    => 'fonction_nok',
     181                                                'element' => 'ressource',
     182                                                'valeur'  => $ressourcer
    186183                                        );
    187                                         $group_by = array('spip_plugins.id_plugin');
    188                                         $plugin = sql_fetsel($select, $from, $where, $group_by);
    189                                         if ($plugin) {
    190                                                 // On refactore le tableau de sortie du fetsel en supprimant les colonnes id_depot et id_plugin qui ne
    191                                                 // sont d'aucune utilité pour le service.
    192                                                 unset($plugin['id_plugin']);
    193                                                 unset($plugin['id_depot']);
    194                                                 $donnees['plugin'] = normaliser_champs('plugin', $plugin);
    195 
    196                                                 // On recherche maintenant les paquets du plugin
    197                                                 $from = array('spip_paquets');
    198                                                 $select = array('*');
    199                                                 $where = array(
    200                                                         'prefixe=' . sql_quote($prefixe),
    201                                                         'id_depot>0'
    202                                                 );
    203                                                 $paquets = sql_allfetsel($select, $from, $where);
    204                                                 $donnees['paquets'] = array();
    205                                                 if ($paquets) {
    206                                                         // On refactore le tableau de sortie du allfetsel en un tableau associatif indexé par archives zip.
    207                                                         $champs_inutiles = array(
    208                                                                 'id_paquet', 'id_plugin', 'id_depot',
    209                                                                 'actif', 'installe', 'recent', 'maj_version', 'superieur', 'obsolete', 'attente', 'constante', 'signature'
    210                                                         );
    211                                                         foreach ($paquets as $_paquet) {
    212                                                                 foreach ($champs_inutiles as $_champ) {
    213                                                                         unset($_paquet[$_champ]);
    214                                                                 }
    215                                                                 $donnees['paquets'][$_paquet['nom_archive']] = normaliser_champs('paquet', $_paquet);
    216                                                         }
    217                                                 }
    218                                         } else {
    219                                                 // On renvoie une erreur 404 pour indiquer que le plugin n'existe pas
    220                                                 $erreur = array(
    221                                                         'status'  => 404,
    222                                                         'type'    => 'plugin_nok',
    223                                                         'element' => 'plugin',
    224                                                         'valeur'  => $contenu['requete']['ressource']
    225                                                 );
    226                                         }
    227                                         $contenu['donnees'] = $donnees;
    228184                                }
     185                                // -- on construit le contenu de la collection.
     186                                $contenu['donnees'] = $ressourcer($ressource);
    229187                        }
    230188                }
     
    235193        if ($erreur) {
    236194                $contenu['erreur'] = array_merge($contenu['erreur'], $erreur);
    237                 $contenu['erreur'] = reponse_expliquer_erreur($contenu['erreur']);
     195                $contenu['erreur'] = reponse_expliquer_erreur($contenu['erreur'], $collection);
    238196        }
    239197
    240198        // Construction de la réponse finale
    241         $reponse = reponse_construire($reponse, $contenu, $format_reponse);
     199        $reponse = reponse_construire($reponse, $contenu);
    242200
    243201        return $reponse;
  • _plugins_/svp_api/trunk/inc/svpapi_reponse.php

    r96918 r115582  
    1010}
    1111
    12 
    13 if (!defined('_SVPAPI_CHAMPS_MULTI_PLUGIN')) {
    14         /**
    15          * Liste des champs de l'objet plugin contenant un texte multi.
    16          */
    17         define('_SVPAPI_CHAMPS_MULTI_PLUGIN', 'nom,slogan');
    18 }
    19 if (!defined('_SVPAPI_CHAMPS_SERIALISES_PLUGIN')) {
    20         /**
    21          * Liste des champs de l'objet plugin contenant un tableau sérialisé.
    22          */
    23         define('_SVPAPI_CHAMPS_SERIALISES_PLUGIN', '');
    24 }
    25 if (!defined('_SVPAPI_CHAMPS_VERSION_PLUGIN')) {
    26         /**
    27          * Liste des champs de l'objet plugin contenant un numéro de version pouvant être
    28          * normalisé (exemple: 012.001.023 au lieu de 12.1.23).
    29          */
    30         define('_SVPAPI_CHAMPS_VERSION_PLUGIN', 'vmax');
    31 }
    32 if (!defined('_SVPAPI_CHAMPS_LISTE_PLUGIN')) {
    33         /**
    34          * Liste des champs de l'objet plugin contenant un texte au format liste dont chaque
    35          * élément est séparé par une virgule.
    36          */
    37         define('_SVPAPI_CHAMPS_LISTE_PLUGIN', 'branches_spip,tags');
    38 }
    39 
    40 if (!defined('_SVPAPI_CHAMPS_MULTI_PAQUET')) {
    41         /**
    42          * Liste des champs de l'objet paquet contenant un texte multi.
    43          */
    44         define('_SVPAPI_CHAMPS_MULTI_PAQUET', 'description');
    45 }
    46 if (!defined('_SVPAPI_CHAMPS_SERIALISES_PAQUET')) {
    47         /**
    48          * Liste des champs de l'objet paquet contenant un tableau sérialisé.
    49          */
    50         define('_SVPAPI_CHAMPS_SERIALISES_PAQUET', 'auteur,credit,licence,copyright,dependances,procure,traductions');
    51 }
    52 if (!defined('_SVPAPI_CHAMPS_VERSION_PAQUET')) {
    53         /**
    54          * Liste des champs de l'objet paquet contenant un numéro de version pouvant être
    55          * normalisé (exemple: 012.001.023 au lieu de 12.1.23).
    56          */
    57         define('_SVPAPI_CHAMPS_VERSION_PAQUET', 'version, version_base');
    58 }
    59 if (!defined('_SVPAPI_CHAMPS_LISTE_PAQUET')) {
    60         /**
    61          * Liste des champs de l'objet paquet contenant un texte au format liste dont chaque
    62          * élément est séparé par une virgule.
    63          */
    64         define('_SVPAPI_CHAMPS_LISTE_PAQUET', 'branches_spip');
    65 }
    66 
    6712/**
    6813 * Initialise le contenu d'une réponse qui se présente comme un tableau associatif.
    6914 * En particulier, la fonction stocke les éléments de la requête, positionne le bloc d'erreur
    70  * par défaut à ok, et récupère le schéma de données du plugin SVP.
     15 * par défaut à ok, et récupère le schéma de données lié à SVP.
    7116 *
    7217 * @param Symfony\Component\HttpFoundation\Request $requete
     
    7419 *
    7520 * @return array
    76  *      Le contenu d'une réponse de l'API SVP est un tableau associatif à 4 entrées:
     21 *      Le contenu d'une réponse de l'API SVP est un tableau associatif à 5 entrées:
    7722 *      - `requete` : sous-tableau des éléments de la requête
    7823 *      - `erreur`  : sous-tableau des éléments descriptifs d'une erreur (status 200 par défaut)
     
    9540        // -- Les éléments format, collection et ressource
    9641        $demande = array_merge($demande, $requete->attributes->all());
    97         // -- Les critères additionnels comme la catégorie ou la compatibilité SPIP fournis comme paramètres de l'url
    98         $parametres = $requete->query->all();
    99         $demande['criteres'] = array_intersect_key($parametres, array_flip(array('categorie', 'compatible_spip')));
    100         // -- Le format du contenu de la réponse fourni comme paramètre de l'url
    101         $demande['format_contenu'] = isset($parametres['format']) ? $parametres['format'] : 'json';
     42        // -- Les critères de filtre comme la catégorie ou la compatibilité SPIP fournis comme paramètres de l'url.
     43        //    Si on utilise une URL classique avec spip.php il faut exclure certains paramètres.
     44        $demande['filtres'] = $requete->query->all();
     45        $demande['filtres'] = array_diff_key(
     46                $demande['filtres'],
     47                array_flip(array('action', 'arg', 'lang', 'var_zajax'))
     48        );
     49        // -- Le format du contenu de la réponse est toujours le JSON
     50        $demande['format_contenu'] = 'json';
    10251
    10352        // Initialisation du bloc d'erreur à ok par défaut
     
    12574
    12675/**
    127  * Récupère la liste des plugins de la table spip_plugins éventuellement filtrés par les critères
    128  * additionnels positionnés dans la requête.
    129  * Les plugins fournis sont toujours issus d'un dépôt hébergé par le serveur ce qui exclu les plugins
    130  * installés sur le serveur et non liés à un dépôt (par exemple un zip personnel).
    131  * Chaque objet plugin est présenté comme un tableau dont tous les champs sont accessibles comme un
    132  * type PHP simple, entier, chaine ou tableau.
    133  *
    134  * @uses normaliser_champs()
    135  *
    136  * @param array $where
    137  *      Tableau des critères additionnels à appliquer au select.
    138  *
    139  * @return array
    140  *      Tableau des plugins dont l'index est le préfixe du plugin.
    141  *      Les champs de type id ou maj ne sont pas renvoyés.
    142  */
    143 function reponse_collectionner_plugins($where) {
    144 
    145         // Initialisation de la collection
    146         $plugins = array();
    147 
    148         // Récupérer la liste des plugins (filtrée ou pas).
    149         // Les plugins appartiennent forcément à un dépot logique installés sur le serveur. Les plugins
    150         // installés directement sur le serveur, donc hors dépôt sont exclus.
    151         $from = array('spip_plugins', 'spip_depots_plugins AS dp');
    152         $select = array('*');
    153         $where = array_merge(array('dp.id_depot>0', 'dp.id_plugin=spip_plugins.id_plugin'), $where);
    154         $group_by = array('spip_plugins.id_plugin');
    155         $collection = sql_allfetsel($select, $from, $where, $group_by);
    156 
    157         // On refactore le tableau de sortie du allfetsel en un tableau associatif indexé par les préfixes.
    158         // On transforme les champs multi en tableau associatif indexé par la langue et on désérialise les
    159         // champs sérialisés.
    160         if ($collection) {
    161                 foreach ($collection as $_plugin) {
    162                         unset($_plugin['id_plugin']);
    163                         unset($_plugin['id_depot']);
    164                         $plugins[$_plugin['prefixe']] = normaliser_champs('plugin', $_plugin);
    165                 }
    166         }
    167 
    168         return $plugins;
    169 }
    170 
    171 
    172 /**
    173  * Récupère la liste des dépôts hébergés par le serveur.
    174  * Contrairement aux plugins et paquets les champs d'un dépôt ne nécessitent aucun formatage.
    175  *
    176  * @param array $where
    177  *      Tableau des critères additionnels à appliquer au select (non utilisé).
    178  *
    179  * @return array
    180  *      Tableau des dépôts.
    181  *      Les champs de type id ou maj ne sont pas renvoyés.
    182  */
    183 function reponse_collectionner_depots($where) {
    184 
    185         // Initialisation de la collection
    186         $depots = array();
    187 
    188         // Récupérer la liste des dépôts
    189         $from = array('spip_depots');
    190         $select = array('*');
    191         $collection = sql_allfetsel($select, $from, $where);
    192 
    193         // Refactorer le tableau de sortie du allfetsel en supprimant
    194         // les champs id_depot et maj.
    195         if ($collection) {
    196                 foreach ($collection as $_depot) {
    197                         unset($_depot['id_depot']);
    198                         unset($_depot['maj']);
    199                         $depots[] = $_depot;
    200                 }
    201         }
    202 
    203         return $depots;
    204 }
    205 
    206 
    207 /**
    208  * Transforme, pour un objet plugin ou paquet, les champs sérialisés, multi et liste (chaine d'éléments séparés
    209  * par une virgule) en tableau et supprime des champs de type version les 0 à gauche des numéros.
    210  *
    211  * @uses normaliser_multi()
    212  * @uses denormaliser_version()
    213  *
    214  * @param string $type_objet
    215  *              Type d'objet à normaliser, soit `plugin` ou `paquet`.
    216  * @param array  $objet
    217  *              Tableau des champs de l'objet `plugin` ou `paquet` à normaliser.
    218  *
    219  * @return array
    220  *              Tableau des champs de l'objet `plugin` ou `paquet` normalisés.
    221  */
    222 function normaliser_champs($type_objet, $objet) {
    223 
    224         $objet_normalise = $objet;
    225 
    226         // Traitement des champs multi et sérialisés
    227         $champs_multi = explode(',', constant('_SVPAPI_CHAMPS_MULTI_' . strtoupper($type_objet)));
    228         $champs_serialises = explode(',', constant('_SVPAPI_CHAMPS_SERIALISES_' . strtoupper($type_objet)));
    229         $champs_version = explode(',', constant('_SVPAPI_CHAMPS_VERSION_' . strtoupper($type_objet)));
    230         $champs_liste = explode(',', constant('_SVPAPI_CHAMPS_LISTE_' . strtoupper($type_objet)));
    231 
    232         if ($objet) {
    233                 include_spip('plugins/preparer_sql_plugin');
    234                 include_spip('svp_fonctions');
    235                 foreach ($objet as $_champ => $_valeur) {
    236                         if (in_array($_champ, $champs_multi)) {
    237                                 // Passer un champ multi en tableau indexé par la langue
    238                                 $objet_normalise[$_champ] = normaliser_multi($_valeur);
    239                         }
    240 
    241                         if (in_array($_champ, $champs_serialises)) {
    242                                 // Désérialiser un champ sérialisé
    243                                 $objet_normalise[$_champ] = unserialize($_valeur);
    244                         }
    245 
    246                         if (in_array($_champ, $champs_version)) {
    247                                 // Retourne la chaine de la version x.y.z sous sa forme initiale, sans
    248                                 // remplissage à gauche avec des 0.
    249                                 $objet_normalise[$_champ] = denormaliser_version($_valeur);
    250                         }
    251 
    252                         if (in_array($_champ, $champs_liste)) {
    253                                 // Passer une chaine liste en tableau
    254                                 $objet_normalise[$_champ] = $_valeur ? explode(',', $_valeur) : array();
    255                         }
    256                 }
    257         }
    258 
    259         return $objet_normalise;
    260 }
    261 
    262 /**
    26376 * Complète le bloc d'erreur avec le titre et l'explication de l'erreur.
    26477 *
     
    26982 *              Tableau de l'erreur complété avec le titre (index `title`) et le descriptif (index `detail`).
    27083 */
    271 function reponse_expliquer_erreur($erreur) {
     84function reponse_expliquer_erreur($erreur, $collection) {
    27285
     86        // Calcul des paramètres qui seront passés à la fonction de traduction.
     87        // -- on passe toujours la collection qui est vide uniquement pour l'erreur de serveur.
     88        $parametres = array(
     89                'element'    => $erreur['element'],
     90                'valeur'     => $erreur['valeur'],
     91                'collection' => $collection
     92        );
     93        // -- on complète avec une chaine extra si elle existe que l'on supprime ensuite comme index de la réponse.
     94        if (isset($erreur['extra'])) {
     95                $parametres['extra'] = $erreur['extra'];
     96                unset($erreur['extra']);
     97        }
     98
     99        // Traduction du libellé de l'erreur et du message complémentaire.
    273100        $prefixe = 'svpapi:erreur_' . $erreur['status'] . '_' . $erreur['type'];
    274         $parametres = array(
    275                 'element' => $erreur['element'],
    276                 'valeur'  => $erreur['valeur']
    277         );
    278 
    279101        $erreur['title'] = _T("${prefixe}_titre", $parametres);
    280102        $erreur['detail'] = _T("${prefixe}_message", $parametres);
     
    286108/**
    287109 * Finalise la réponse à la requête en complétant le header et le contenu mis au préalable
    288  * au format demandé.
     110 * au format JSON.
    289111 *
    290112 * @param Symfony\Component\HttpFoundation\Response $reponse
    291113 *      Objet réponse tel qu'initialisé par le serveur HTTP abstrait.
    292114 * @param array                                     $contenu
    293  *              Tableau du contenu de la réponse qui sera retourné selon le format défini.
    294  * @param string                                    $format_reponse
    295  *              Format de la réponse. Seul le format JSON est supporté.
     115 *              Tableau du contenu de la réponse qui sera retourné en JSON.
    296116 *
    297117 * @return Symfony\Component\HttpFoundation\Response $reponse
    298118 *      Retourne l'objet réponse dont le contenu et certains attributs du header sont mis à jour.
    299119 */
    300 function reponse_construire($reponse, $contenu, $format_reponse) {
     120function reponse_construire($reponse, $contenu) {
    301121
     122        // Si pas d'erreur et que la collection est vide on renvoie le code idoine.
     123        if (($contenu['erreur']['status'] == 200)
     124        and empty($contenu['donnees'])) {
     125                $contenu['erreur']['status'] = 204;
     126        }
     127
     128        // Charset UTF-8 et statut de l'erreur.
    302129        $reponse->setCharset('utf-8');
    303130        $reponse->setStatusCode($contenu['erreur']['status']);
    304131
    305         if ($format_reponse == 'json') {
    306                 $reponse->headers->set('Content-Type', 'application/json');
    307                 $reponse->setContent(json_encode($contenu));
    308         }
     132        // Format JSON exclusif pour les réponses.
     133        $reponse->headers->set('Content-Type', 'application/json');
     134        $reponse->setContent(json_encode($contenu));
    309135
    310136        return $reponse;
  • _plugins_/svp_api/trunk/inc/svpapi_requete.php

    r96896 r115582  
    88if (!defined('_ECRIRE_INC_VERSION')) {
    99        return;
     10}
     11
     12/**
     13 * Déclare les collections accessibles via HTTP GET.
     14 * Par défaut, le plugin propose les collections `plugins` et `depots`.
     15 *
     16 * @pipeline declarer_collections_svp
     17 *
     18 * @return array
     19 *                 Description des collections.
     20**/
     21function requete_declarer_collections() {
     22
     23        // Les index désignent les collections, le tableau associé contient les filtres admissibles.
     24        // -- Par défaut, svpapi fournit deux collections, plugins et depots.
     25        $collections = array(
     26                'plugins' => array(
     27                        'module'    => 'svpapi',
     28                        'filtres'   => array('categorie', 'compatible_spip'),
     29                        'ressource' => 'prefixe'
     30                ),
     31                'depots'  => array(
     32                        'module'    => 'svpapi',
     33                        'filtres'   => array('type')
     34                )
     35        );
     36
     37        $collections = pipeline('declarer_collections_svp', $collections);
     38
     39        return $collections;
    1040}
    1141
     
    2656 *        - `valeur`  : la valeur du mode runtime
    2757 *
    28  * @return boolean
     58 * @return bool
    2959 *        `true` si la valeur est valide, `false` sinon.
    3060 */
    3161function requete_verifier_serveur(&$erreur) {
    32         $valide = true;
     62
     63        // Initialise le retour à true par défaut.
     64        $est_valide = true;
    3365
    3466        include_spip('inc/svp_phraser');
     
    4072                        'valeur'  => _SVP_MODE_RUNTIME
    4173                );
    42                 $valide = false;
    43         }
    44 
    45         return $valide;
    46 }
    47 
    48 
    49 /**
    50  * Détermine si la valeur du format de sortie est valide.
    51  * Seul le format JSON est accepté.
    52  *
    53  * @param string $valeur
    54  *        La valeur du format de sortie
    55  * @param &array    $erreur
    56  *        Tableau initialisé avec les index identifiant l'erreur ou vide si pas d'erreur.
    57  *        Les index mis à jour sont:
    58  *        - `status`  : le code de l'erreur HTTP, soit 400
    59  *        - `type`    : chaine identifiant l'erreur plus précisément, soit format_nok
    60  *        - `element` : type d'objet sur lequel porte l'erreur, soit format
    61  *        - `valeur`  : la valeur du format
    62  *
    63  * @return boolean
    64  *        `true` si la valeur est valide, `false` sinon.
    65  */
    66 function requete_verifier_format($valeur, &$erreur) {
    67         $valide = true;
    68 
    69         if (!in_array($valeur, array('json'))) {
    70                 $erreur = array(
    71                         'status'  => 400,
    72                         'type'    => 'format_nok',
    73                         'element' => 'format',
    74                         'valeur'  => $valeur
    75                 );
    76                 $valide = false;
    77         }
    78 
    79         return $valide;
     74                $est_valide = false;
     75        }
     76
     77        return $est_valide;
    8078}
    8179
     
    8583 * Le service ne fournit que les collections plugins (`plugins`) et dépôts (`depots`).
    8684 *
    87  * @param string $valeur
     85 * @param string $collection
    8886 *        La valeur de la collection demandée
     87 * @param array  $collections
     88 *        Configuration des collections disponibles.
    8989 * @param &array    $erreur
    9090 *        Tableau initialisé avec les index identifiant l'erreur ou vide si pas d'erreur.
     
    9595 *        - `valeur`  : la valeur de la collection
    9696 *
    97  * @return boolean
    98  *        `true` si la valeur est valide, `false` sinon.
    99  */
    100 function requete_verifier_collection($valeur, &$erreur) {
    101         $valide = true;
    102 
    103         if (!in_array($valeur, array('plugins', 'depots'))) {
     97 * @return bool
     98 *        `true` si la valeur est valide, `false` sinon.
     99 */
     100function requete_verifier_collection($collection, $collections, &$erreur) {
     101
     102        // Initialise le retour à true par défaut.
     103        $est_valide = true;
     104
     105        // Vérification de la disponibilité de la collection demandée.
     106        if (!in_array($collection, array_keys($collections))) {
    104107                $erreur = array(
    105108                        'status'  => 400,
    106109                        'type'    => 'collection_nok',
    107110                        'element' => 'collection',
    108                         'valeur'  => $valeur
     111                        'valeur'  => $collection,
     112                        'extra'   => implode(', ', array_keys($collections))
    109113                );
    110                 $valide = false;
    111         }
    112 
    113         return $valide;
     114                $est_valide = false;
     115        }
     116
     117        return $est_valide;
     118}
     119
     120
     121/**
     122 * Détermine si la valeur de chaque critère de filtre d'une collection est valide.
     123 * Si plusieurs critères sont fournis, la fonction s'interromp dès qu'elle trouve un
     124 * critère non admis ou dont la valeur est invalide.
     125 *
     126 * @param array  $filtres
     127 *        Tableau associatif des critères de filtre (couple nom du critère, valeur du critère)
     128 * @param array  $configuration
     129 *        Configuration de la collection concernée. L'index `filtres` contient la liste des critères admissibles
     130 *        et l'index `module` contient le nom du fichier des fonctions de service.
     131 * @param &array $erreur
     132 *        Tableau initialisé avec les index identifiant l'erreur ou vide si pas d'erreur.
     133 *        Les index mis à jour sont:
     134 *        - `status`  : le code de l'erreur HTTP, soit 400
     135 *        - `type`    : chaine identifiant l'erreur plus précisément, soit critere_nok
     136 *        - `element` : nom du critère en erreur
     137 *        - `valeur`  : valeur du critère
     138 *
     139 * @return bool
     140 *        `true` si la valeur est valide, `false` sinon.
     141 */
     142function requete_verifier_filtres($filtres, $configuration, &$erreur) {
     143
     144        $est_valide = true;
     145        $erreur = array();
     146
     147        if ($filtres) {
     148                // On arrête dès qu'une erreur est trouvée et on la reporte.
     149                foreach ($filtres as $_critere => $_valeur) {
     150                        $extra = '';
     151                        // On vérifie si le critère est admis.
     152                        if (!in_array($_critere, $configuration['filtres'])) {
     153                                $erreur = array(
     154                                        'status'  => 400,
     155                                        'type'    => 'critere_nom_nok',
     156                                        'element' => 'critere',
     157                                        'valeur'  => $_critere,
     158                                        'extra'   => implode(', ', $configuration['filtres'])
     159                                );
     160                                $est_valide = false;
     161                                break;
     162                        } else {
     163                                // On vérifie si la valeur du critère est valide :
     164                                // -- le critère est vérifié par une fonction spécifique. Si elle n'existe pas le critère est
     165                                //    réputé valide.
     166                                $module = $configuration['module'];
     167                                include_spip("svpapi/${module}");
     168                                $verifier = "critere_${_critere}_verifier";
     169                                if (function_exists($verifier)
     170                                and !$verifier($_valeur, $extra)) {
     171                                        $erreur = array(
     172                                                'status'  => 400,
     173                                                'type'    => 'critere_valeur_nok',
     174                                                'element' => $_critere,
     175                                                'valeur'  => $_valeur,
     176                                                'extra'   => $extra
     177                                        );
     178                                        $est_valide = false;
     179                                        break;
     180                                }
     181                        }
     182                }
     183        }
     184
     185        return $est_valide;
    114186}
    115187
     
    119191 * Le service ne fournit que des ressources de type plugin (`plugins`).
    120192 *
    121  * @param string $valeur
    122  *        La valeur de la collection demandée
     193 * @param string $ressource
     194 *        La valeur de la ressource demandée. La ressource appartient à une collection.
     195 * @param array  $configuration
     196 *        Configuration de la collection de la ressource. L'index `ressource` identifie le champ attendu pour désigner
     197 *        la ressource et l'index `module` contient le nom du fichier des fonctions de service.
    123198 * @param &array    $erreur
    124199 *        Tableau initialisé avec les index identifiant l'erreur ou vide si pas d'erreur.
     
    129204 *        - `valeur`  : la valeur de la ressource
    130205 *
    131  * @return boolean
    132  *        `true` si la valeur est valide, `false` sinon.
    133  */
    134 function requete_verifier_ressource($valeur, &$erreur) {
    135         $valide = true;
    136 
    137         if (!in_array($valeur, array('plugins'))) {
     206 * @return bool
     207 *        `true` si la valeur est valide, `false` sinon.
     208 */
     209function requete_verifier_ressource($ressource, $configuration, &$erreur) {
     210
     211        // Initialise le retour à true par défaut.
     212        $est_valide = true;
     213
     214        // Vérification de la disponibilité de l'accès à une ressource pour la collection concernée
     215        if (empty($configuration['ressource'])) {
    138216                $erreur = array(
    139217                        'status'  => 400,
    140218                        'type'    => 'ressource_nok',
    141219                        'element' => 'ressource',
    142                         'valeur'  => $valeur
     220                        'valeur'  => $ressource,
     221                        'extra'   => 'plugins'
    143222                );
    144                 $valide = false;
    145         }
    146 
    147         return $valide;
    148 }
    149 
    150 
    151 /**
    152  * Détermine si la valeur du préfixe de plugin est valide.
    153  * La fonction compare uniquement la structure de la chaine passée qui doit être cohérente avec
    154  * celui d'un nom de variable.
    155  *
    156  * @param string $valeur
    157  *        La valeur du préfixe
    158  * @param &array    $erreur
    159  *        Tableau initialisé avec les index identifiant l'erreur ou vide si pas d'erreur.
    160  *        Les index mis à jour sont:
    161  *        - `status`  : le code de l'erreur HTTP, soit 400
    162  *        - `type`    : chaine identifiant l'erreur plus précisément, soit prefixe_nok
    163  *        - `element` : type d'objet sur lequel porte l'erreur, soit prefixe
    164  *        - `valeur`  : la valeur du préfixe
    165  *
    166  * @return boolean
    167  *        `true` si la valeur est valide, `false` sinon.
    168  */
    169 function requete_verifier_prefixe($valeur, &$erreur) {
    170         $valide = true;
    171 
    172         if (!preg_match('#^(\w){2,}$#', strtolower($valeur))) {
    173                 $erreur = array(
    174                         'status'  => 400,
    175                         'type'    => 'prefixe_nok',
    176                         'element' => 'prefixe',
    177                         'valeur'  => $valeur
    178                 );
    179                 $valide = false;
    180         }
    181 
    182         return $valide;
    183 }
    184 
    185 
    186 /**
    187  * Détermine si la valeur de chaque critère de filtre d'une collection est valide.
    188  * Si plusieurs critères sont fournis, la fonction s'interromp dès qu'elle trouve un
    189  * critère invalide.
    190  *
    191  * @uses verifier_critere_categorie()
    192  * @uses verifier_critere_compatible_spip()
    193  *
    194  * @param array $criteres
    195  *        Tableau associatif des critères (couple nom du critère, valeur du critère)
    196  * @param &array    $erreur
    197  *        Tableau initialisé avec les index identifiant l'erreur ou vide si pas d'erreur.
    198  *        Les index mis à jour sont:
    199  *        - `status`  : le code de l'erreur HTTP, soit 400
    200  *        - `type`    : chaine identifiant l'erreur plus précisément, soit critere_nok
    201  *        - `element` : nom du critère en erreur
    202  *        - `valeur`  : valeur du critère
    203  *
    204  * @return boolean
    205  *        `true` si la valeur est valide, `false` sinon.
    206  */
    207 function requete_verifier_criteres($criteres, &$erreur) {
    208 
    209         $valide = true;
    210         $erreur = array();
    211 
    212         if ($criteres) {
    213                 // On vérifie pour chaque critère :
    214                 // -- si le critère est valide
    215                 // -- si la valeur du critère est valide
    216                 // On arrête dès qu'une erreur est trouvée et on la reporte
    217                 foreach ($criteres as $_critere => $_valeur) {
    218                         $verifier = "verifier_critere_${_critere}";
    219                         if (!$verifier($_valeur)) {
    220                                 $erreur = array(
    221                                         'status'  => 400,
    222                                         'type'    => 'critere_nok',
    223                                         'element' => $_critere,
    224                                         'valeur'  => $_valeur
    225                                 );
    226                                 $valide = false;
    227                                 break;
    228                         }
     223                $est_valide = false;
     224        } else {
     225                // Vérification de la validité de la ressource demandée.
     226                // -- la ressource est vérifiée par une fonction spécifique. Si elle n'existe pas la ressource est
     227                //    réputée valide.
     228                $module = $configuration['module'];
     229                include_spip("svpapi/${module}");
     230                $verifier = "ressource_{$configuration['ressource']}_verifier";
     231                if (function_exists($verifier)
     232                and !$verifier($ressource)) {
     233                        $erreur = array(
     234                                'status'  => 400,
     235                                'type'    => 'ressource_valeur_nok',
     236                                'element' => 'ressource',
     237                                'valeur'  => $ressource,
     238                                'extra'   => $configuration['ressource']
     239                        );
     240                        $est_valide = false;
    229241                }
    230242        }
    231243
    232         return $valide;
    233 }
    234 
    235 
    236 /**
    237  * Détermine si la valeur de la catégorie est valide.
    238  * La fonction récupère dans le plugin SVP la liste des catégories autorisées.
    239  *
    240  * @param string $valeur
    241  *        La valeur du critère catégorie
    242  *
    243  * @return boolean
    244  *        `true` si la valeur est valide, `false` sinon.
    245  */
    246 function verifier_critere_categorie($valeur) {
    247         $valide = true;
    248 
    249         include_spip('inc/svp_phraser');
    250         if (!in_array($valeur, $GLOBALS['categories_plugin'])) {
    251                 $valide = false;
    252         }
    253 
    254         return $valide;
    255 }
    256 
    257 
    258 /**
    259  * Détermine si la valeur du critère compatibilité SPIP est valide.
    260  * La fonction compare uniquement la structure de la chaine passée qui doit être cohérente avec
    261  * un numéro de version ou de branche.
    262  *
    263  * @param string $valeur
    264  *        La valeur du critère compatibilite SPIP
    265  *
    266  * @return boolean
    267  *        `true` si la valeur est valide, `false` sinon.
    268  */
    269 function verifier_critere_compatible_spip($valeur) {
    270         $valide = true;
    271 
    272         if (!preg_match('#^(\d+)(\.\d+){0,2}$#', $valeur)) {
    273                 $valide = false;
    274         }
    275 
    276         return $valide;
    277 }
     244        return $est_valide;
     245}
  • _plugins_/svp_api/trunk/lang/svpapi_fr.php

    r96896 r115582  
    88
    99        // E
    10         'erreur_200_ok_message'             => 'La ressource ou la collection que vous avez demandée a bien été fournie par le service. Vous pouvez la consulter dans l\'index « donnees ».',
    11         'erreur_200_ok_titre'               => 'La requête a été traité avec succès',
    12         'erreur_400_collection_nok_message' => 'Vous avez demandé une collection qui n\'est pas supportée par ce service. SVP ne fournit que des collections de plugins (/svp/plugins) et de dépôts (/svp/depots).',
    13         'erreur_400_collection_nok_titre'   => 'La collection« « @valeur@ » n\'est pas fournie par ce service',
    14         'erreur_400_format_nok_message'     => 'Vous avez demandé de renvoyer les données dans un format qui n\'est pas supportée par ce service. SVP n\'utilise que les formats de sortie JSON et XML.',
    15         'erreur_400_format_nok_titre'       => 'Le format « @valeur@ » n\'est pas supporté par ce service',
    16         'erreur_400_critere_nok_message'    => 'Vous avez demandé de filtrer une collection avec un critère dont la valeur est invalide. Veuillez consulter la documentation pour spécifier un critère valide.',
    17         'erreur_400_critere_nok_titre'      => 'La valeur « @valeur@ » du critère « @element@ » est invalide',
    18         'erreur_400_prefixe_nok_message'    => 'Vous avez demandé un plugin mais le préfixe spécifié « @valeur@ » est invalide. Un préfixe ne peut contenir que des caractères alphanumériques et le souligné.',
    19         'erreur_400_prefixe_nok_titre'      => 'La valeur « @valeur@ » du préfixe de plugin est invalide',
    20         'erreur_400_ressource_nok_message'  => 'Vous avez demandé un type de ressource qui n\'est pas supporté par ce service. SVP ne fournit que des ressources de type plugin (/svp/plugins/prefixe).',
    21         'erreur_400_ressource_nok_titre'    => 'Le type de ressource « @valeur@ » n\'est pas fourni par ce service',
    22         'erreur_404_plugin_nok_message'     => 'Vous avez demandé un plugin mais le préfixe spécifié ne correspond à aucun plugin enregistré dans la base de données du serveur. Soit vous avez fait une erreur sur le préfixe, soit le plugin spécifié n\'est pas fourni par un des dépôts enregistrés sur le serveur',
    23         'erreur_404_plugin_nok_titre'       => 'Le plugin de préfixe « @valeur@ » n\'est pas disponible sur le serveur',
    24         'erreur_501_serveur_nok_message'    => 'Vous avez essayé d\'utiliser l\'API SVP sur un serveur qui n\'est pas correctement configuré. En effet, ce serveur est actuellement en mode « SVP runtime » incompatible avec le service REST SVP.',
    25         'erreur_501_serveur_nok_titre'      => 'Le serveur n\'est pas correctement configuré',
     10        'erreur_200_ok_message'                   => 'Vous pouvez consulter la ressource ou la collection demandée dans l\'index « donnees ».',
     11        'erreur_200_ok_titre'                     => 'La requête a été traitée avec succès',
     12        'erreur_400_collection_nok_message'       => 'SVP fournit les collections suivantes : @extra@.',
     13        'erreur_400_collection_nok_titre'         => 'La collection « @valeur@ » n\'est pas fournie par ce service',
     14        'erreur_400_critere_nom_nok_message'      => 'La collection  « @collection@ » supporte les critères suivants : @extra@.',
     15        'erreur_400_critere_nom_nok_titre'        => 'Le critère « @valeur@ » n\'est pas supporté par la collection « @collection@ »',
     16        'erreur_400_critere_valeur_nok_message'   => 'Veuillez consulter la documentation pour spécifier une valeur valide pour le critère @element@ (@extra@).',
     17        'erreur_400_critere_valeur_nok_titre'     => 'La valeur « @valeur@ » du critère « @element@ » est invalide',
     18        'erreur_400_prefixe_nok_message'          => 'Vous avez demandé un plugin mais le préfixe spécifié « @valeur@ » est invalide. Un préfixe ne peut contenir que des caractères alphanumériques et le souligné.',
     19        'erreur_400_prefixe_nok_titre'            => 'La valeur « @valeur@ » du préfixe de plugin est invalide',
     20        'erreur_400_ressource_nok_message'        => 'SVP ne fournit des ressources que pour les collections suivantes : @extra@.',
     21        'erreur_400_ressource_nok_titre'          => 'La collection « @collection@ » n\autorise pas l\'accès à une ressource',
     22        'erreur_400_ressource_valeur_nok_message' => 'Veuillez consulter la documentation pour spécifier une valeur valide pour une ressource de la collection @collection@ (@extra@).',
     23        'erreur_400_ressource_valeur_nok_titre'   => 'La ressource « @valeur@ » de la collection « @collection@ » est invalide',
     24        'erreur_404_plugin_nok_message'           => 'Vous avez demandé un plugin mais le préfixe spécifié ne correspond à aucun plugin enregistré dans la base de données du serveur. Soit vous avez fait une erreur sur le préfixe, soit le plugin spécifié n\'est pas fourni par un des dépôts enregistrés sur le serveur',
     25        'erreur_404_plugin_nok_titre'             => 'Le plugin de préfixe « @valeur@ » n\'est pas disponible sur le serveur',
     26        'erreur_501_serveur_nok_message'          => 'Le serveur est actuellement en mode « SVP runtime » incompatible avec le service REST SVP.',
     27        'erreur_501_serveur_nok_titre'            => 'Le serveur n\'est pas correctement configuré',
     28        'extra_critere_compatible_spip'           => 'version SPIP comme « 3.2.0 » ou branche comme « 2.1 » ou liste de branches comme « 2.1,3.0,3.1 »'
    2629);
  • _plugins_/svp_api/trunk/paquet.xml

    r107431 r115582  
    22        prefix="svpapi"
    33        categorie="outil"
    4         version="0.4.4"
     4        version="0.5.0"
    55        etat="test"
    66        compatibilite="[3.0.0;3.2.*]"
     
    1515        <licence lien="http://www.gnu.org/licenses/gpl-3.0.html">GNU/GPL</licence>
    1616
     17        <pipeline nom="declarer_collections_svp" action="" />
     18
    1719        <necessite nom="svp" compatibilite="[0.78.11;[" />
    1820        <necessite nom="http" compatibilite="[1.2.0;]" />
Note: See TracChangeset for help on using the changeset viewer.