Browse Source

Amélioration des filtres dans la liste des territoires.

Ajout d'une option asynchrone pour le chargement des infradivisions (à consolider)
Items de langue de catégorie manquants.
Chargement des zones, pays et subdivisions ISO françaises (regions et départements) à l'installation.
master
Eric Lupinacci 2 months ago
parent
commit
d5594e2526
  1. 49
      action/peupler_territoires.php
  2. 20
      formulaires/peupler_territoires.php
  3. 113
      inc/territoire.php
  4. 9
      lang/territoire_fr.php
  5. 2
      lang/territoires_fr.php
  6. 2
      paquet.xml
  7. 14
      prive/objets/liste/territoires.html
  8. 2
      saisies/territoires_categories.html
  9. 14
      saisies/territoires_pays.html
  10. 11
      territoires_administrations.php
  11. 15
      territoires_autorisations.php
  12. 50
      territoires_fonctions.php

49
action/peupler_territoires.php

@ -0,0 +1,49 @@
<?php
/**
* Ce fichier contient l'action `peupler_territoires` lancée de façon asynchrone pour peupler certains
* ensembles de territoires contenant un nombre important d'éléments.
*
* @package SPIP\TERRITOIRES
*/
if (!defined('_ECRIRE_INC_VERSION')) return;
/**
* Cette action permet peupler certains ensembles de territoires contenant un nombre important d'éléments.
* Elle est appelée par l'API `territoire_peupler_asynchrone()`.
*
* Cette action est réservée aux utilisateurs pouvant utiliser le formulaire de peuplement.
* Elle ne nécessite les mêmes arguments que la fonction de peuplement.
*
* @return void
*/
function action_peupler_territoires_dist() {
// Securisation et autorisation.
// L'argument attendu est la page à recharger ou sinon vide pour toutes les pages.
$securiser_action = charger_fonction('securiser_action', 'inc');
$arguments = $securiser_action();
// Structuration des arguments de peuplement
$arguments = explode(':', $arguments);
if (
(count($arguments) > 1)
and ($type = $arguments[0])
and ($pays = $arguments[1])
) {
// Identification des options
$options = array();
unset($arguments[0], $arguments[1]);
foreach ($arguments as $_argument) {
if ($_argument === 'force') {
$options[$_argument] = true;
} else {
$options['extras'][] = $_argument;
}
}
// Chargement des territoires et autres extras requis par les arguments.
include_spip('inc/territoire');
territoire_peupler($type, $pays, $options);
}
}

20
formulaires/peupler_territoires.php

@ -181,6 +181,9 @@ function formulaires_peupler_territoires_traiter() {
}
} elseif ($_type === 'infrasubdivision') {
foreach ($pays_infra as $_pays) {
if ($action === 'peupler') {
$actionner .= '_asynchrone';
}
$statut[] = $actionner($_type, $_pays, $options);
}
} else {
@ -208,11 +211,13 @@ function formulaires_peupler_territoires_traiter() {
* `depeupler`.
* @param array $statuts Tableau résultant de l'action sur le type choisi. Peut-êre un tableau de statut pour les
* subdivisions (plusieurs pays).
* - `ok` : `true` si l'action a complètement réussi, `false` sinon (au moins une erreur).
* - `ok` : `true` si l'action ou la lancement du job a complètement réussi, `false` sinon (au moins une erreur).
* - `sha` : indique une sha identique donc pas chargement effectué.
* - `arg` : indique que le couple (type, pays) eest invalide (pas possible avec le formulaire).
* - `type` : type de territoire.
* - `pays` : code ISO alpha2 du pays si le type est subdivision.
* - `sync` : indique si le peuplement est synchrone ou asynchrone
* - `job` : id du job si asynchrone
*
* @return array
* Tableau des messages à afficher sur le formulaire:
@ -227,9 +232,10 @@ function formulaires_peupler_territoires_notifier($type, $messages, $action, $st
'sha' => array(),
);
$statut_global = array(
'ok' => false,
'nok' => false,
'sha' => false,
'ok' => false,
'nok' => false,
'sha' => false,
'sync' => true,
);
// On compile la liste des pays traités et un indicateur global pour chaque cas d'erreur.
@ -251,12 +257,18 @@ function formulaires_peupler_territoires_notifier($type, $messages, $action, $st
$variables['ok'][] = $_statut['pays'];
}
$statut_global['ok'] = true;
if (!$_statut['sync']) {
$statut_global['sync'] = false;
}
}
}
// Traitement des succès
if ($statut_global['ok']) {
$messages['message_ok'] .= _T("territoires:msg_${action}_${type}_succes", array('pays' => implode(', ', $variables['ok'])));
if (!$statut_global['sync']) {
$messages['message_ok'] .= '<br />' . _T("territoires:msg_succes_asynchrone");
}
}
// Traitement des erreurs

113
inc/territoire.php

@ -8,6 +8,15 @@ if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
if (!defined('_TERRITOIRE_ASYNCHRONE_PAR_JOB')) {
/**
* Mode de peuplement asynchrone:
* - `job`: utilisation de job_queue_add
* - `url`: utilisation d'une action.
*/
define('_TERRITOIRE_ASYNCHRONE_PAR_JOB', true);
}
/**
* Peuple soit les régions du monde, soit les pays ou soit les subdivisions d'un pays.
@ -33,7 +42,8 @@ function territoire_peupler($type, $pays, $options = array()) {
'arg' => false,
'sha' => false,
'type' => $type,
'pays' => $pays
'pays' => $pays,
'sync' => true
);
// Le peuplement dépend du type :
@ -42,6 +52,7 @@ function territoire_peupler($type, $pays, $options = array()) {
include_spip('inc/territoires_services');
include_spip('inc/territoires_utils');
if (type_pays_est_valide($type, $pays)) {
$timestamp['debut'] = microtime(true);
$erreur = true;
$type_identique = false;
@ -56,6 +67,7 @@ function territoire_peupler($type, $pays, $options = array()) {
// On récupère tous les index fournis par la collection et pas uniquement celui des territoires concernés.
// Ainsi, les autres index éventuels restent disponibles.
$collection = territoires_acquerir($type, $pays);
$timestamp['acquisition'] = microtime(true);
if (!empty($collection[$configuration['champs']['index']])) {
// On extrait que l'index correspondant au type demandé
$territoires = $collection[$configuration['champs']['index']];
@ -74,6 +86,7 @@ function territoire_peupler($type, $pays, $options = array()) {
// -- on préserve les éditions manuelles et les liens pour les réinjecter ensuite lors du
// rechargement
$sauvegardes = territoires_preserver($type, $pays);
$timestamp['preservation'] = microtime(true);
// -- on vide les territoires avant de les remettre (inutile de gérer les erreurs
// car l'insertion les détectera).
@ -86,6 +99,7 @@ function territoire_peupler($type, $pays, $options = array()) {
territoire_depeupler('infrasubdivision', $pays);
}
territoire_depeupler($type, $pays);
$timestamp['vidage'] = microtime(true);
// -- on insère chaque territoire comme un objet
include_spip('action/editer_objet');
@ -142,6 +156,7 @@ function territoire_peupler($type, $pays, $options = array()) {
break;
}
}
$timestamp['insertion'] = microtime(true);
if (!$erreur_insertion) {
// Traitements des extras
@ -166,6 +181,7 @@ function territoire_peupler($type, $pays, $options = array()) {
if ($extras) {
sql_insertq_multi('spip_territoires_extras', $extras);
}
$timestamp['extras'] = microtime(true);
}
// On rétablit les liens vers les territoires et les logos
@ -182,6 +198,7 @@ function territoire_peupler($type, $pays, $options = array()) {
'id_table' => 'id_objet'
);
liens_retablir('logos', $sauvegardes, $ids, $config_lien);
$timestamp['retablissement'] = microtime(true);
// Permettre à d'autres plugins de compléter le peuplement.
// -- par exemple le plugin Contours rétablit les liens vers les contours GIS (spip_liens_gis),
@ -206,15 +223,28 @@ function territoire_peupler($type, $pays, $options = array()) {
'ext' => $meta_extras,
);
ecrire_config("${meta}/${consigne}", $contenu);
$timestamp['fin'] = microtime(true);
$erreur = false;
}
spip_log("Les territoires (Type '${type}' - Pays '${pays}') ont été chargées", 'territoires' . _LOG_DEBUG);
foreach ($timestamp as $_periode => $_timestamp) {
if ($_periode === 'debut') {
$timestamp_debut = $_timestamp;
} else {
$timestamp_fin = $_timestamp;
$duree = ($timestamp_fin - $timestamp_debut) * 1000;
$timestamp_debut = $timestamp_fin;
spip_log("Période ${_periode}: ${duree} ms", 'territoires' . _LOG_DEBUG);
}
}
$duree = $timestamp['fin'] - $timestamp['debut'];
spip_log("Durée totale: ${duree} s", 'territoires' . _LOG_DEBUG);
}
} else {
spip_log("Aucun territoire pour (Type '${type}' - Pays '${pays}') retourné par Nomenclatures", 'territoires' . _LOG_ERREUR);
}
// Si le territoire est en erreur, on passe on stocke le cas d'erreur.
// Si le territoire est en erreur, on stocke le cas d'erreur.
if ($erreur) {
if ($type_identique) {
$retour['sha'] = true;
@ -233,16 +263,86 @@ function territoire_peupler($type, $pays, $options = array()) {
return $retour;
}
/**
* Appelle la fonction de peuplement de territoires en asynchrone.
*
* @api
*
* @param string $type Type de territoires. Prends les valeurs `zone`, `country`, `subdivision` ou `infrasubdivision`.
* @param string $pays Code ISO 3166-1 alpha2 du pays si le type est `subdivision` ou `infrasubdivision` sinon une chaine vide.
* @param array $options Tableau des options de peuplement:
* - `force` : si `true` force le repeuplement même si le sha est identique (`false` par défaut).
* - `extras`: tableau des types d'extras à peupler soit `code` pour les codes alternatifs
* et `info` pour le caractéristiques (table spip_territoires_extras)
*
* @return array Tableau retour de la fonction permettant de connaitre le résultat du traitement (utile pour l'affichage
* du message dans le formulaire de peuplement).
*/
function territoire_peupler_asynchrone($type, $pays, $options = array(), $mode_asynchrone = 'job') {
// On initialise le retour à une ok ce qui est le cas le plus fréquent car on ne fait que créer le job.
$retour = array(
'ok' => true,
'arg' => false,
'sha' => false,
'type' => $type,
'pays' => $pays,
'sync' => false
);
if (_TERRITOIRE_ASYNCHRONE_PAR_JOB) {
// Lancement du peuplement dans un job à déclenchement immédiat et de priorité maximale pour éviter d'attendre.
include_spip('inc/utils');
$arguments = array(
$type,
$pays,
$options
);
$retour['job'] = job_queue_add(
'territoire_peupler',
'Peuplement de territoires',
$arguments,
'inc/territoire',
true
);
if (!$retour['job']) {
$retour['ok'] = false;
}
} else {
// Construction de la chaine des arguments passés à l'action.
// -- type et pays sont toujours fournis même si le pays est la chaine vide.
$arguments = "${type}:${pays}";
// -- ajout des éventuelles options : on passe les options par leur identifiant
if (!empty($options['force'])) {
$arguments .= ":force";
}
if (!empty($options['extras'])) {
$arguments .= ':' . implode(':', $options['extras']);
}
// Génération de l'URL qui lancera le peuplement en asynchrone.
include_spip('inc/actions');
$url = generer_action_auteur('peupler_territoires', $arguments);
// Lancement du peuplement en asynchrone.
include_spip ('inc/queue');
$retour['ok'] = queue_lancer_url_http_async($url);
}
return $retour;
}
/**
* Supprime de la base soit les régions du monde, soit les pays ou soit les subdivisions d'un pays.
*
* @api
*
* @param string $type Type de territoires. Prends les valeurs `zone`, `country`, `subdivision` ou `infrasubdivision`.
* @param string $pays Code ISO 3166-1 alpha2 du pays si le type est `subdivision` ou `infrasubdivision` sinon une chaine vide.
* @param string $type Type de territoires. Prends les valeurs `zone`, `country`, `subdivision` ou `infrasubdivision`.
* @param string $pays Code ISO 3166-1 alpha2 du pays si le type est `subdivision` ou `infrasubdivision` sinon une chaine vide.
* @param array $options Tableau des options de dépeuplement:
* - `force` : si `true` force le vidage même si la meta n'est pas présente (cas d'erreur
* sur timeout par exemple. La valeur par défaut est `false`.
* sur timeout par exemple). La valeur par défaut est `false`.
*
* @return array Tableau retour de la fonction permettant de connaitre le résultat du traitement (utile pour l'affichage
* du message dans le formulaire de peuplement).
@ -255,7 +355,8 @@ function territoire_depeupler($type, $pays = '', $options = array()) {
'arg' => false,
'sha' => false,
'type' => $type,
'pays' => $pays
'pays' => $pays,
'sync' => true
);
// Le vidage dépend du type :

9
lang/territoire_fr.php

@ -10,8 +10,8 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'ajouter_lien_territoire' => 'Ajouter ce territoire',
// C
'categorie_arctic_region' => 'région arctique',
'categorie_administrative_region' => 'région administrative',
'categorie_arctic_region' => 'région arctique',
'categorie_area' => 'zone assimilée à un pays',
'categorie_arrondissement' => 'arrondissement',
'categorie_associated_commune' => 'commune associée',
@ -21,8 +21,8 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'categorie_autonomous_region' => 'région autonome',
'categorie_borough' => 'arrondissement',
'categorie_canton' => 'canton',
'categorie_census_area' => 'zone de recensement',
'categorie_capital_city' => 'ville capitale',
'categorie_census_area' => 'zone de recensement',
'categorie_city_and_borough' => 'ville & arrondissement',
'categorie_city_corporation' => 'corporation urbaine',
'categorie_city_municipality' => 'municipalité de ville',
@ -39,11 +39,12 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'categorie_district' => 'district',
'categorie_district_municipality' => 'municipalité de district',
'categorie_federal_district' => 'district fédéral',
'categorie_free_communal_consortia' => 'libre consortium communal',
'categorie_free_municipal_consortium' => 'libre consortium communal',
'categorie_governorate' => 'gouvernorat',
'categorie_independent_city' => 'ville indépendante',
'categorie_island' => 'île',
'categorie_land' => 'land',
'categorie_local_council' => 'conseil local',
'categorie_london_borough' => 'arrondissement de Londres',
'categorie_metropolitan_city' => 'ville métropolitaine',
'categorie_metropolitan_department' => 'département métropolitain',
@ -64,13 +65,13 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'categorie_region' => 'région',
'categorie_republican_city' => 'ville républicaine',
'categorie_rural_municipality' => 'municipalité rurale',
'categorie_urban_municipality' => 'municipalité urbaine',
'categorie_self_governed_part' => 'partie auto-gouvernée',
'categorie_special_municipality' => 'municipalité spéciale',
'categorie_state' => 'état',
'categorie_territory' => 'territoire',
'categorie_two_tier_county' => 'comté à 2 niveaux',
'categorie_unitary_authority' => 'autorité unitaire',
'categorie_urban_municipality' => 'municipalité urbaine',
'categorie_voivodship' => 'voïvodie',
'categorie_wilaya' => 'wilaya',
'categorie_world' => 'terre',

2
lang/territoires_fr.php

@ -45,6 +45,7 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'option_zone_territoire' => 'Toutes les régions du monde',
'option_country_territoire' => 'Tous les pays',
'option_categorie_toute' => 'Toutes les catégories',
'option_pays_tous' => 'Tous les pays',
'onglet_edite_oui' => 'Edités',
'onglet_edite_non' => 'Non édités',
'onglet_edite_tous' => 'Tous',
@ -79,6 +80,7 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'msg_peupler_infrasubdivision_erreur' => 'Une erreur s\'est produite lors du peuplement des infra-subdivisions du ou des pays « @pays@ ».',
'msg_peupler_infrasubdivision_notice' => 'Aucune mise à jour n\'est nécessaire pour les infra-subdivisions du ou des pays « @pays@ ».',
'msg_peupler_infrasubdivision_succes' => 'Les infra-subdivisions du ou des pays « @pays@ » ont bien été chargées.',
'msg_succes_asynchrone' => 'Certains peuplements ont été lancés en asynchrone. Ils seront disponibles dans quelques instants.',
// T
'territoires_titre' => 'Territoires',

2
paquet.xml

@ -1,7 +1,7 @@
<paquet
prefix="territoires"
categorie="divers"
version="1.0.2"
version="1.1.0"
etat="test"
compatibilite="[3.3.0-dev;3.3.*]"
logo="territoires_logo-xx.svg"

14
prive/objets/liste/territoires.html

@ -21,10 +21,22 @@
[(#SELF|parametre_url{categorie,''}|form_hidden)]
[(#SAISIE{territoires_categories, categorie,
type=#GET{type_territoire},
pays=#ENV{iso_pays, ''},
option_intro=<:territoires:option_categorie_toute:>,
})]
</form>
</div>]
</div>
[<div class="filtre">
(#ENV{type, country}|in_array{#LISTE{country, subdivision, infrasubdivision}}|oui)
<form method="GET" action="#SELF" onChange="this.submit(); return true;">
[(#SELF|parametre_url{iso_pays,''}|form_hidden)]
[(#SAISIE{territoires_pays, iso_pays,
type=#GET{type_territoire},
categorie=#ENV{categorie, ''},
option_intro=<:territoires:option_pays_tous:>,
})]
</form>
</div>]]
</caption>]
<thead>
<tr class="first_row">

2
saisies/territoires_categories.html

@ -6,7 +6,7 @@
[(#ENV{cacher_option_intro}|ou{#ENV{multiple}}|non)
<option value="">[(#ENV{option_intro})]</option>]
<BOUCLE_categories(DATA){source table, #GET{categories}}{par valeur}>
[(#SET{libelle, [(#VAL{territoire:categorie_}|concat{#VALEUR}|_T|ucfirst)]})]
[(#SET{libelle, [(#VAL{territoire:categorie_}|concat{#VALEUR}|_T|spip_ucfirst)]})]
[(#ENV{multiple}|oui)
<option value="#VALEUR"[(#VALEUR|in_array{#ENV{valeur_forcee,#GET{valeur,#ENV{defaut,#ARRAY}}}}|oui) selected="selected"]>#GET{libelle}</option>]
[(#ENV{multiple}|non)

14
saisies/territoires_pays.html

@ -0,0 +1,14 @@
[(#ENV{multiple}|oui)
[(#SET{valeur,[(#ENV*{valeur}|is_array|?{[(#ENV*{valeur})],[(#ENV*{valeur}|explode{','})]})]})]
]
#SET{pays, #ENV{type, ''}|territoire_lister_pays{#ENV{categorie, ''}}}
<select name="#ENV{nom}[(#ENV{multiple}|?{\[\]})]" id="champ_[(#ENV{nom}|saisie_nom2classe)]"[ class="(#ENV{class})"][(#ENV{multiple}|oui) multiple="multiple" size="#ENV{size,10}"][ disabled="(#ENV{disable})"]>
[(#ENV{cacher_option_intro}|ou{#ENV{multiple}}|non)
<option value="">[(#ENV{option_intro})]</option>]
<BOUCLE_categories(DATA){source table, #GET{pays}}{par valeur}>
[(#ENV{multiple}|oui)
<option value="#CLE"[(#CLE|in_array{#ENV{valeur_forcee,#GET{valeur,#ENV{defaut,#ARRAY}}}}|oui) selected="selected"]>#CLE[ - (#VALEUR|extraire_multi)]</option>]
[(#ENV{multiple}|non)
<option value="#CLE"[(#CLE|=={#ENV{valeur_forcee,#ENV{valeur,#ENV{defaut}}}}|oui) selected="selected"]>#CLE[ - (#VALEUR|extraire_multi)]</option>]
</BOUCLE_categories>
</select>

11
territoires_administrations.php

@ -139,8 +139,19 @@ function territoires_upgrade($nom_meta_base_version, $version_cible) {
)
);
// Création des tables et de la configuration du plugin
include_spip('base/upgrade');
maj_plugin($nom_meta_base_version, $version_cible, $maj);
// Peuplement minimal du plugin:
// - les zones du monde
// - les pays
// - les subdivisions françaises
include_spip('inc/territoire');
$options['extras'] = array('code', 'info');
territoire_peupler('zone', '', $options);
territoire_peupler('country', '', $options);
territoire_peupler('subdivision', 'FR', $options);
}

15
territoires_autorisations.php

@ -67,6 +67,21 @@ function autoriser_territoires_configurer_dist($faire, $type, $id, $qui, $opt) {
return autoriser('configurer');
}
/**
* Autorisation de peupler ou dépeupler des territoires.
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_territoires_peupler_dist($faire, $type, $id, $qui, $opt) {
return autoriser('configurer');
}
/**
* Autorisation de voir (territoire)
*

50
territoires_fonctions.php

@ -53,6 +53,56 @@ function territoire_informer_ascendance($iso_territoire, $iso_parent = null, $or
return $ascendance;
}
/**
* Fournit la liste des pays possédant des subdivisisions ou des infrasubdivisions en base de données.
* Il est aussi possible de renvoyer la liste des pays si ceux-ci sont aussi présents.
*
* @api
* @filtre
*
* @param string $type Type de territoires. Prends les valeurs `country`, `subdivision` ou `infrasubdivision`.
* La valeur par défaut est `country`.
* @param string $categorie Catégorie de territoire.
*
* @return array Liste des pays sous la forme [iso_pays] = nom usuel.
*/
function territoire_lister_pays($type = 'country', $categorie = '') {
// Initialisation d'un retour en erreur
$pays = array();
// Filtre sur la catégorie si demandé
$where = array();
if ($categorie) {
$where[] = 't1.categorie=' . sql_quote($categorie);
}
// On récupère :
// -- les pays possédant des subdivisions en base de donnés (type = subdivision ou infrasubdivision)
// -- ou simplement tous les pays (type = country).
if ($type === 'country') {
$select = array('t1.iso_territoire as pays', 't1.nom_usage');
$where = 't1.type=' . sql_quote($type);
$pays = sql_allfetsel($select, 'spip_territoires as t1', $where);
} elseif (
include_spip('inc/territoires_utils')
and type_est_subdivision($type)
) {
$from = array('spip_territoires as t1', 'spip_territoires as t2');
$select = array('t1.iso_pays as pays', 't2.nom_usage');
$where[] = 't1.type=' . sql_quote($type);
$where[] = 't1.iso_pays = t2.iso_territoire';
$group_by = array('t1.iso_pays');
$pays = sql_allfetsel($select, $from, $where, $group_by);
}
if ($pays) {
$pays = array_column($pays, 'nom_usage', 'pays');
}
return $pays;
}
/**
* Fournit la liste des catégories de territoire pour un type donné ou pour une subdivisision ou infrasubdivision donnée.

Loading…
Cancel
Save