Skip to content
Extraits de code Groupes Projets
Valider 2b1cddd0 rédigé par Eric Lupinacci's avatar Eric Lupinacci
Parcourir les fichiers

Un premier jet du formulaire de création d'un feed (sans enregistrement)

parent a0e6882a
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -216,6 +216,7 @@ function territoires_stats_item_completer(array $item, array $feed) : array {
$code
and isset($codes_to_iso[$code])
) {
// On ajoute un champ dans l'item pour retrouver le code primaire
$item['iso_feed'] = $codes_to_iso[$code];
} else {
// Le code primaire est introuvable, on ne retient pas cet item
......
<div class="formulaire_spip formulaire_editer formulaire_#FORM">
<h3 class="titrem"><:cartes_territoires:titre_etape_creer{etape=#ENV{_etape}, etapes=#ENV{_etapes}}:></h3>
<div class="formulaire_spip formulaire_#FORM">
<h3 class="titrem"><:territoires:titre_etape_en_cours{etape=#ENV{_etape}, etapes=#ENV{_etapes}}:></h3>
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
......@@ -13,7 +13,6 @@
label=<:territoires_stats:label_feed_type_territoire:>,
data=#ENV{_types_territoire},
defaut=#ENV{_type_territoire_defaut},
obligatoire=oui,
})]
<BOUCLE_pays_type(DATA) {source table, #ENV{_pays}}>
......@@ -43,7 +42,6 @@
type=file,
explication=<:territoires_stats:explication_feed_fichier:>,
label=<:territoires_stats:label_feed_fichier:>,
obligatoire=oui,
conteneur_class=bloc_fichier_source,
})]
......@@ -52,6 +50,16 @@
label=<:territoires_stats:label_feed_url:>,
conteneur_class=bloc_url_source,
})]
[(#SAISIE{input, extra,
explication=<:territoires_stats:explication_feed_extra:>,
label=<:territoires_stats:label_feed_extra:>,
})]
[(#SAISIE{input, titre_extra,
explication=<:territoires_stats:explication_feed_extra_titre:>,
label=<:territoires_stats:label_feed_extra_titre:>,
})]
</div>
</fieldset>
......
......@@ -12,6 +12,25 @@ if (!defined('_ECRIRE_INC_VERSION')) {
* @return array Tableau des données à charger par le formulaire.
*/
function formulaires_creer_feed_territoires_charger() : array {
// Etape 1
// Récupération des saisies éventuelles de l'étape 1
$valeurs = [
'type' => _request('type') ?? '',
'type_source' => _request('type_source') ?? '',
'fichier_source' => _request('fichier_source') ?? '',
'url_source' => _request('url_source') ?? '',
'extra' => _request('extra') ?? '',
'titre_extra' => _request('titre_extra') ?? '',
];
include_spip('inc/config');
$types_territoire = lire_config('territoires/types');
foreach ($types_territoire as $_type) {
if (lire_config("territoires/{$_type}/populated_by_country", false)) {
$variable_pays = 'pays_' . $_type;
$valeurs[$variable_pays] = _request($variable_pays) ?? '';
}
}
// Initialisation des paramètres de l'unité de peuplement
// -- Liste des types de territoire.
include_spip('inc/config');
......@@ -49,6 +68,27 @@ function formulaires_creer_feed_territoires_charger() : array {
];
$valeurs['_type_source_defaut'] = 'api';
// Etape 2
// Initialisation des saisies relatives au mapping et à l'identification du feed
// -- options de décodage : délimiteur si fichier CSV, racine à partir de laquelle paramétrer le mapping
$valeurs['_label_decodage'] = _request('_label_decodage');
$valeurs['_explication_decodage'] = _request('_explication_decodage');
// -- Type de code de territoire utilisé dans le jeu de données
$valeurs['_types_code'] = _request('_types_code');
$valeurs['_type_code_defaut'] = _request('_type_code_defaut');
// -- Format de la source et feed id par défaut
$valeurs['_format_source'] = _request('_format_source');
$valeurs['_feed_id_defaut'] = _request('_feed_id_defaut');
// Récupération des saisies éventuelles de l'étape 2
$valeurs['type_code'] = _request('type_code') ?? '';
$valeurs['decodage'] = _request('decodage') ?? '';
$valeurs['mapping_code'] = _request('mapping_code') ?? '';
$valeurs['mapping_valeur'] = _request('mapping_valeur') ?? '';
$valeurs['feed_id'] = _request('feed_id') ?? '';
$valeurs['titre'] = _request('titre') ?? '';
$valeurs['description'] = _request('description') ?? '';
// Préciser le nombre d'étapes du formulaire
$valeurs['_etapes'] = 2;
......@@ -65,19 +105,158 @@ function formulaires_creer_feed_territoires_verifier_1() : array {
// Initialisation des erreurs de vérification.
$erreurs = [];
// On collecte les paramètres de l'étape 1 soit pour vérification pour pour élaborer d'autres variables pour l'étape 2.
$type = _request('type');
$variable_pays = 'pays_' . $type;
$pays = _request($variable_pays) ?? '';
$type_source = _request('type_source');
$extra = _request('extra');
$titre_extra = _request('titre_extra');
// Vérification du choix d'un pays pour les types qui le requiert
if (
include_spip('inc/config')
and lire_config("territoires/{$type}/populated_by_country", false)
and !$pays
) {
$erreurs[$variable_pays] = _T('info_obligatoire');
}
// Vérification du choix d'un fichier valide ou d'une URL valide (on ne teste pas la validité du contenu
if ($type_source === 'api') {
$variable_source = _request('url_source');
if (empty($variable_source)) {
// Aucune URL saisie.
$erreurs['url_source'] = _T('info_obligatoire');
} elseif (
include_spip('inc/distant')
and (valider_url_distante($variable_source) === false)
) {
// URL distante non valide.
// TODO : voir aussi filter_var(url, FILTER_VALIDATE_URL)
$erreurs['url_source'] = _T('territoires_stats:erreur_feed_url_source');
}
} else {
$variable_source = 'fichier_source';
if (empty($_FILES[$variable_source]['name'])) {
// Aucun fichier choisi.
$erreurs[$variable_source] = _T('info_obligatoire');
} elseif (
empty($_FILES[$variable_source]['type'])
or (!in_array($_FILES[$variable_source]['type'], ['application/json', 'application/xml', 'text/csv']))
) {
// Format de fichier invalide
$erreurs[$variable_source] = _T('territoires_stats:erreur_feed_format_fichier');
}
}
// Vérification de la saisie d'un identifiant pour le type de données
if (empty($extra)) {
$erreurs['extra'] = _T('info_obligatoire');
} elseif (!preg_match('#^[\w]+$#i', $extra)) {
$erreurs['extra'] = _T('territoires_stats:erreur_feed_extra');
}
// Vérification de la saisie d'un titre pour le type de données
if (empty($titre_extra)) {
$erreurs['titre_extra'] = _T('info_obligatoire');
}
// Constitution des variables et paramètres d'affichage de l'étape 2
if (!$erreurs) {
// -- Types de code possibles pour les territoires concernés
$types_code['iso_territoire'] = _T('territoire:champ_iso_territoire_label') . ' (iso_territoire)';
$where = [
'type_extra=' . sql_quote('code'),
'type=' . sql_quote($type),
'iso_pays=' . sql_quote($pays),
];
$ids_code = sql_allfetsel('extra', 'spip_territoires_extras', $where, 'extra');
if ($ids_code) {
foreach (array_column($ids_code, 'extra') as $_code) {
$types_code[$_code] = _T('territoire_extra:extra_' . $_code) . " ({$_code})";
}
}
set_request('_types_code', $types_code);
set_request('_type_code_defaut', 'iso_territoire');
// -- Option de décodage de la source : pour une api on s'attend toujours à du JSON, pour un fichier à du JSON, XML ou CSV
$format = 'json';
if ($type_source === 'file') {
// Extraire l'extension pour déterminer l'option de décodage à présenter
[, $format] = explode('/', $_FILES[$variable_source]['type']);
}
set_request('format_source', $format);
if ($format === 'csv') {
set_request('_label_decodage', _T('territoires_stats:label_feed_decodage_delimiteur'));
set_request('_explication_decodage', _T('territoires_stats:explication_feed_decodage_delimiteur'));
} else {
set_request('_label_decodage', _T('territoires_stats:label_feed_decodage_racine'));
set_request('_explication_decodage', _T('territoires_stats:explication_feed_decodage_racine'));
}
// -- Identifiant proposé pour le feed
include_spip('inc/ezmashup_feed');
$prefixe = "{$type}_{$pays}_{$extra}";
foreach (['', '2', '3', '4', '5', '6', '7', '8', '9'] as $_suffixe) {
$id_feed = $prefixe . ($_suffixe ? '_' : '') . $_suffixe;
if (!feed_yaml_existe('territoires_stats', $id_feed)) {
break;
}
}
set_request('_feed_id_defaut', strtolower($id_feed));
}
return $erreurs;
}
/**
* Vérification du formulaire :.
* Vérification du formulaire : détection des erreurs de saisie de l'étape 2.
*
* @return array Message d'erreur si aucun pays choisi alors que la configuration du type de teritoire l'oblige.
* Sinon, chargement des champs utiles à l'étape 2 :
* @return array Message d'erreur ou vide sinon
*/
function formulaires_creer_feed_territoires_verifier_2() : array {
// Initialisation des erreurs de vérification.
$erreurs = [];
// On collecte les paramètres nécessaires de l'étape 1.
$format_source = _request('_format_source');
$id_feed = _request('feed_id');
// On collecte les paramètres de l'étape 2.
$decodage = _request('decodage');
$mapping_code = _request('mapping_code');
$mapping_valeur = _request('mapping_valeur');
// Vérification de la saisie des mappings qui ne doivent contenir qu'un ou plusieurs mots séparés par des '/'
if (!preg_match('#^[\w/]+$#i', $mapping_code)) {
$erreurs['mapping_code'] = _T('territoires_stats:erreur_feed_mapping_code');
}
if (!preg_match('#^[\w/]+$#i', $mapping_valeur)) {
$erreurs['mapping_valeur'] = _T('territoires_stats:erreur_feed_mapping_valeur');
}
// Vérification du décodage en fonction du type de source
// -- si fichier csv : on attend un délimiteur parmi ',', ';', '|' et '\t' ou vide (la valeur par défaut est la virgule)
// -- sinon : on attend un index comme pour le mapping ou vide
if ($decodage) {
if ($format_source === 'csv') {
if (!in_array($decodage, [',', ';', '|', "\t"])) {
$erreurs['decodage'] = _T('territoires_stats:erreur_feed_decodage');
}
} elseif (!preg_match('#^[\w/]+$#i', $decodage)) {
$erreurs['decodage'] = _T('territoires_stats:erreur_feed_mapping_code');
}
}
// Vérification de la saisie du feed id
include_spip('inc/ezmashup_feed');
if (!preg_match('#^[\w]+$#i', $id_feed)) {
$erreurs['feed_id'] = _T('territoires_stats:erreur_feed_id');
} elseif (feed_yaml_existe('territoires_stats', $id_feed)) {
$erreurs['feed_id'] = _T('territoires_stats:erreur_feed_id_existe');
}
return $erreurs;
}
......
<div class="formulaire_spip formulaire_editer formulaire_#FORM">
<h3 class="titrem"><:cartes_territoires:titre_etape_creer{etape=#ENV{_etape}, etapes=#ENV{_etapes}}:></h3>
<h3 class="titrem"><:territoires:titre_etape_en_cours{etape=#ENV{_etape}, etapes=#ENV{_etapes}}:></h3>
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
......@@ -7,136 +7,63 @@
<div>
#ACTION_FORMULAIRE{#ENV{action}}
<fieldset>
<legend><:territoires_stats:legende_feed_identite:></legend>
<legend><:territoires_stats:legende_feed_mapping:></legend>
<div class="editer-groupe">
[(#SAISIE{input, feed_id,
label=<:territoires_stats:label_feed_id:>,
explication=<:territoires_stats:explication_feed_id:>,
obligatoire=oui,
maxlength=255
})]
[(#SAISIE{input, titre,
explication=<:territoires_stats:explication_feed_titre:>,
label=<:territoires_stats:label_feed_titre:>,
obligatoire=oui,
[(#SAISIE{selection, type_code,
label=<:territoires_stats:label_feed_type_code:>,
data=#ENV{_types_code},
defaut=#ENV{_type_code_defaut},
cacher_option_intro=oui
})]
[(#SAISIE{textarea, description,
explication=<:territoires_stats:explication_feed_description:>,
label=<:territoires_stats:label_feed_description:>,
rows=5,
[(#SAISIE{input, decodage,
explication=#ENV{_explication_decodage},
label=#ENV{_label_decodage},
})]
</fieldset>
<fieldset>
<legend><:territoires_stats:legende_feed_unite_peuplement:></legend>
<div class="editer-groupe">
[(#SAISIE{radio, type,
label=<:territoires_stats:label_feed_type_territoire:>,
data=#ENV{_types_territoire},
defaut=#ENV{_type_territoire_defaut},
[(#SAISIE{input, mapping_code,
explication=<:territoires_stats:explication_feed_mapping_code:>,
label=<:territoires_stats:label_feed_mapping_code:>,
obligatoire=oui,
})]
<BOUCLE_pays_type(DATA) {source table, #ENV{_pays}}>
<div id="pays_#CLE" class="editer-pays">
[(#SAISIE{radio_flex, pays_#CLE,
label=<:territoire:champ_iso_pays_label:>,
data=#VALEUR,
conteneur_class=#ENV{_classe_conteneur/#CLE},
multi_cols=#ENV{_choix_multi_col/#CLE},
extraire_multi=oui,
})]
</div>
</BOUCLE_pays_type>
</div>
</fieldset>
<fieldset>
<legend><:territoires_stats:legende_feed_source:></legend>
<div class="editer-groupe">
[(#SAISIE{radio, type_source,
label=<:territoires_stats:label_feed_type_source:>,
data=#ENV{_types_source},
defaut=#ENV{_type_source_defaut}
})]
[(#SAISIE{input, fichier_source,
type=file,
explication=<:territoires_stats:explication_feed_fichier:>,
label=<:territoires_stats:label_feed_fichier:>,
[(#SAISIE{input, mapping_valeur,
explication=<:territoires_stats:explication_feed_mapping_valeur:>,
label=<:territoires_stats:label_feed_mapping_valeur:>,
obligatoire=oui,
})]
[(#SAISIE{input, url_source,
explication=<:territoires_stats:explication_feed_url:>,
label=<:territoires_stats:label_feed_url:>,
})]
</div>
</fieldset>
<fieldset>
<legend><:territoires_stats:legende_feed_mapping:></legend>
<legend><:territoires_stats:legende_feed_identite:></legend>
<div class="editer-groupe">
[(#SAISIE{input, decodage,
explication=#ENV{_explication_decodage},
label=#ENV{_label_decodage},
defaut=#ENV{_decodage_defaut}
})]
[(#SAISIE{selection, type_code,
label=<:territoires_stats:label_feed_type_code:>,
data=#ENV{_types_code},
defaut=#ENV{_types_code_defaut}
[(#SAISIE{input, feed_id,
label=<:territoires_stats:label_feed_id:>,
explication=<:territoires_stats:explication_feed_id:>,
defaut=#ENV{_feed_id_defaut},
obligatoire=oui,
maxlength=255
})]
[(#SAISIE{input, extra,
explication=<:territoires_stats:explication_feed_extra:>,
label=<:territoires_stats:label_feed_extra:>,
[(#SAISIE{input, titre,
explication=<:territoires_stats:explication_feed_titre:>,
label=<:territoires_stats:label_feed_titre:>,
obligatoire=oui,
})]
[(#SAISIE{input, titre_extra,
explication=<:territoires_stats:explication_feed_extra_titre:>,
label=<:territoires_stats:label_feed_extra_titre:>,
[(#SAISIE{textarea, description,
explication=<:territoires_stats:explication_feed_description:>,
label=<:territoires_stats:label_feed_description:>,
rows=5,
})]
</div>
</fieldset>
<p class="boutons">
<input type="submit" class="submit" value="<:info_etape_suivante:>" />
#SET{etape_precedente, #ENV{_etape}|moins{1}}
<input type="submit" class="submit" name="_retour_etape_1" value="<:territoires:info_etape_precedente:>" />
<input type="submit" class="submit" value="<:bouton_enregistrer:>" />
</p>
</div>
</form>
</div>
<script type="text/javascript">
//<![CDATA[
jQuery(document).ready(function() {
// Liste des types associés à un pays
const types_pays = ['subdivision', 'infrasubdivision', 'protected_area'];
// Afficher le bloc correspondant au types de carte et de territoire passé ou rien sinon.
function afficher_bloc_pays(type_territoire) {
if (types_pays.includes(type_territoire)) {
for (let t of types_pays) {
let id = 'div#pays_' + t;
if (t === type_territoire) {
jQuery(id).show();
} else {
jQuery(id).hide();
}
}
} else {
jQuery("div.editer-pays").hide();
}
}
afficher_bloc_pays(jQuery("input[name='type']:checked").val());
jQuery("input[name='type']").change(function() {
afficher_bloc_pays(jQuery("input[name='type']:checked").val());
jQuery(this).blur();
});
});
//]]>
</script>
......@@ -9,13 +9,17 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'bouton_recharger' => 'Recharger la configuration des jeux de données',
// E
'explication_feed_id' => 'L\'identifiant est un mot sans espace composé uniquement de lettres, chiffres et du caractère "_" (tiret bas)',
'explication_feed_id' => 'L\'identifiant est un mot sans espace composé uniquement de lettres, chiffres et du caractère "_" (tiret bas). Il est initialisé avec une valeur unique non déjà utilisée mais vous pouvez néanmoins la modifier',
'explication_feed_titre' => 'Le titre peut-être écrit en utilisant la balise multilangues',
'explication_feed_description' => 'Le titre peut-être écrit en utilisant la balise multilangues et tous les raccourcis SPIP',
'explication_feed_fichier' => 'Le fichier source doit être disponible au format JSON, CSV ou XML',
'explication_feed_url' => 'L\'URL de la requête doit permettre de récupérer en une fois l\'ensemble des données au format JSON',
'explication_feed_extra' => 'L\'identifiant sert à reconnaitre le type de données du jeu. C\'est un mot sans espace composé uniquement de lettres, chiffres et du caractère "_" (tiret bas)',
'explication_feed_extra_titre' => 'Le titre sert à reconnaitre le type de données du jeu de façon plus lisible',
'explication_feed_extra_titre' => 'Le titre sert à reconnaitre le type de données du jeu de façon plus lisible. Il peut-être écrit en utilisant la balise multilangues',
'explication_feed_decodage_delimiteur' => 'Caractère utilisé comme séparateur des données dans le fichier CSV. Si vide, le délimiteur "," (virgule) sera utilisé par défaut',
'explication_feed_decodage_racine' => 'Cet index racine représente la partie commune qui est appliquée au mapping du code et de la valeur statistique dans le tableau des données source. Il est exprimé sous la forme index1/index2/index3',
'explication_feed_mapping_code' => 'Cet index racine représente la partie spécifique permettant d\'accéder au code de territoire dans le tableau des données source. Il est exprimé sous la forme index1/index2/index3',
'explication_feed_mapping_valeur' => 'Cet index racine représente la partie spécifique permettant d\'accéder à la valeur statistique dans le tableau des données source. Il est exprimé sous la forme index1/index2/index3',
// I
'icone_creer_feed' => 'Créer un jeu de données',
......@@ -25,6 +29,8 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'info_nb_feed' => '@nb@ jeux de données',
// L
'label_feed_decodage_delimiteur' => 'Délimiteur',
'label_feed_decodage_racine' => 'Index racine du mapping',
'label_feed_category_territory_data' => 'Données statistiques sur les territoires',
'label_feed_id' => 'Identifiant du jeu de données',
'label_feed_titre' => 'Titre',
......@@ -34,11 +40,13 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'label_feed_type_territoire' => 'Type de territoire',
'label_feed_type_source' => 'Source de données',
'label_feed_type_code' => 'Type d\'identifiant des territoires de la source',
'label_feed_extra' => 'Identifiant de la donnée',
'label_feed_extra_titre' => 'Titre de la donnée',
'label_feed_extra' => 'Identifiant du type de donnée',
'label_feed_extra_titre' => 'Titre du type de donnée',
'label_feed_mapping_code' => 'Index du code du territoire',
'label_feed_mapping_valeur' => 'Index de la valeur',
'legende_feed_identite' => 'Identification du jeu de données',
'legende_feed_unite_peuplement' => 'Territoires concernés',
'legende_feed_source' => 'Origine des données',
'legende_feed_source' => 'Origine & signification des données',
'legende_feed_mapping' => 'Interprétation des données',
// M
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter