Planète

Par FMB
Philippe Mané

Exploiter les données de biodiversité en PHP et avec Drupal grâce à la bibliothèque PHP GBIF

Exploiter les données de biodiversité en PHP et avec Drupal grâce à la bibliothèque PHP GBIF

Le projet Musa in situ, mené conjointement par le CIRAD et Bioversity, recueille des données sur les Musacées1 de par le monde, en conditions naturelles ou s'en approchant. L'objectif principal est d'obtenir une image la plus précise possible de la diversité géographique naturelle des Musacées. Il s'appuyait initialement sur un projet sur iNaturalist, mais par la suite il s'est ouvert à d'autres sources de données, notamment le GBIF (Global Biodiversity Information Facility), qui a pour but de mettre à disposition toute l'information connue sur la biodiversité. En particulier, ces données sont accessibles à travers une interface REST.

Le GBIF permet un accès à ces données via une interface web qui utilise en interne cette interface REST. Cependant, dans le cadre du travail effectué pour MGIS, il était souhaitable de pouvoir interroger ces données directement depuis ce site, idéalement au moyen d'une vue, afin de choisir quelles données importer en base, et assurer une cohérence avec ce qui avait déjà été importé, ou ce que l'on s'interdit d'importer.

Il se trouve que le langage R dispose d'une mise en œuvre de référence, rgbif. Ce client constitue une abstraction permettant d'interroger la base du GBIF sans avoir à entrer dans le détail des requêtes à effectuer en service web. Il a été porté de manière plus ou moins exhaustive en Python (pygbif) et Ruby (gbifrb). Il faut désormais compter avec PHP GBIF, développé dans le cadre de ce projet. Notre espoir est que ce projet libre2 puisse être utile à d'autres acteurs souhaitant interagir avec ce catalogue central de la biodiversité mondiale.

L'installer est aussi simple qu'un composer require restelae/php-gbif. Cette bibliothèque requiert la version 7.2 de PHP ou toute version supérieure. Vous trouverez sur sa page d'accueil toutes les informations nécessaires à son utilisation, complétées par une documentation générée automatiquement avec Doxygen.

Nous avons également écrit un module pour Drupal3 s'appuyant sur cette bibliothèque pour permettre d'afficher les occurrences du GBIF avec Views, uniquement en site building, par appels en service web, sans passer par la base locale ! Couplé avec Views Bulk Operations, on peut tout à fait s'en servir pour traiter en local les données du GBIF sélectionnées, par exemple les importer localement avec le module Migrate.

À l'heure actuelle, le projet permet uniquement de récupérer ou de rechercher des occurrences ou des espèces. Nous sommes à la recherche de sponsors et de contributeurs pour mettre en œuvre l'ensemble de l'API du GBIF, et de la sorte faciliter grandement l'accès à l'ensemble des données du GBIF à tous les projets écrits en PHP. N'hésitez pas à nous contacter si cela vous intéresse !


  1. La famille des Musacées regroupe notamment les genres Musa (bananiers) et Ensete↩︎

  2. Sous licence GPLv3. ↩︎

  3. Actuellement Drupal 7, en attendant que MGIS soit porté en Drupal 9. ↩︎

felip
01/06/2021

Par FMB
Philippe Mané

Exploiter les données de biodiversité en PHP et avec Drupal grâce à la bibliothèque PHP GBIF

Exploiter les données de biodiversité en PHP et avec Drupal grâce à la bibliothèque PHP GBIF

Le projet Musa in situ, mené conjointement par le CIRAD et Bioversity, recueille des données sur les Musacées1 de par le monde, en conditions naturelles ou s'en approchant. L'objectif principal est d'obtenir une image la plus précise possible de la diversité géographique naturelle des Musacées. Il s'appuyait initialement sur un projet sur iNaturalist, mais par la suite il s'est ouvert à d'autres sources de données, notamment le GBIF (Global Biodiversity Information Facility), qui a pour but de mettre à disposition toute l'information connue sur la biodiversité. En particulier, ces données sont accessibles à travers une interface REST.

Le GBIF permet un accès à ces données via une interface web qui utilise en interne cette interface REST. Cependant, dans le cadre du travail effectué pour MGIS, il était souhaitable de pouvoir interroger ces données directement depuis ce site, idéalement au moyen d'une vue, afin de choisir quelles données importer en base, et assurer une cohérence avec ce qui avait déjà été importé, ou ce que l'on s'interdit d'importer.

Il se trouve que le langage R dispose d'une mise en œuvre de référence, rgbif. Ce client constitue une abstraction permettant d'interroger la base du GBIF sans avoir à entrer dans le détail des requêtes à effectuer en service web. Il a été porté de manière plus ou moins exhaustive en Python (pygbif) et Ruby (gbifrb). Il faut désormais compter avec PHP GBIF, développé dans le cadre de ce projet. Notre espoir est que ce projet libre2 puisse être utile à d'autres acteurs souhaitant interagir avec ce catalogue central de la biodiversité mondiale.

L'installer est aussi simple qu'un composer require restelae/php-gbif. Cette bibliothèque requiert la version 7.2 de PHP ou toute version supérieure. Vous trouverez sur sa page d'accueil toutes les informations nécessaires à son utilisation, complétées par une documentation générée automatiquement avec Doxygen.

Nous avons également écrit un module pour Drupal3 s'appuyant sur cette bibliothèque pour permettre d'afficher les occurrences du GBIF avec Views, uniquement en site building, par appels en service web, sans passer par la base locale ! Couplé avec Views Bulk Operations, on peut tout à fait s'en servir pour traiter en local les données du GBIF sélectionnées, par exemple les importer localement avec le module Migrate.

À l'heure actuelle, le projet permet uniquement de récupérer ou de rechercher des occurrences ou des espèces. Nous sommes à la recherche de sponsors et de contributeurs pour mettre en œuvre l'ensemble de l'API du GBIF, et de la sorte faciliter grandement l'accès à l'ensemble des données du GBIF à tous les projets écrits en PHP. N'hésitez pas à nous contacter si cela vous intéresse !


  1. La famille des Musacées regroupe notamment les genres Musa (bananiers) et Ensete↩︎

  2. Sous licence GPLv3. ↩︎

  3. Actuellement Drupal 7, en attendant que MGIS soit porté en Drupal 9. ↩︎

felip
01/06/2021

Par Christophe MOLLET
Christophe Mollet

Quel site internet pouvons-nous créer sous Drupal ?

Si vous avez comme projet de créer un site internet pour votre activité, il faut savoir que le choix du CMS a un impact direct sur ce que vous souhaitez faire. En effet, il est important d’avoir à l’esprit que l’on ne choisit pas un CMS par hasard, mais parce qu’il correspond au besoin envisagé. Ici, nous allons vous parler de Drupal, un CMS open-source à la fois puissant et flexible.

Par kgaut
Kevin Gautreau

Drupal - Utiliser Devel Generate pour générer des entités personnalisées

Devel Generate est un sous module de Devel permettant de générer du contenu de test pour son site drupal, que cela soit des nœuds, des termes de taxonomy, des utilisateurs ou encore des éléments de menu.

Il est aussi possible de développer un petit plugin permettant de générer des entités d'un type custom, en renseignant ses champs mais aussi ses propriétés (basefield).

Voici le code du plugin de mon module me permettant de générer des entités de type « cadeau ». Attention, c'est fonctionnel, mais c'est du rapidos, la propreté du code est perfectible !

Fichier : modules/mon_module/src/Plugin/DevelGenerate/CadeauDevelGenerate.php

<?php
namespace Drupal\mon_module\Plugin\DevelGenerate;

use Drupal\Core\Field\Plugin\Field\FieldType\UriItem;
use Drupal\Core\Form\FormStateInterface;
use Drupal\devel_generate\DevelGenerateBase;
use Drupal\image\Plugin\Field\FieldType\ImageItem;
use Drupal\kebrina\Entity\Cadeau;
use Drupal\text\Plugin\Field\FieldType\TextLongItem;

/**
* Provides a ContentDevelGenerate plugin.
*
* @DevelGenerate(
*   id = "cadeau", // Le nom machine de mon type d'entité
*   label = @Translation("Cadeau"),
*   description = @Translation("Génère des cadeaux"),
*   url = "cadeau",
*   permission = "administer devel_generate",
*   settings = { // Les paramètres par défaut
*     "num" = 50,
*     "kill" = FALSE,
*   }
* )
*/
class CadeauDevelGenerate extends DevelGenerateBase {

  /**
   * Le formulaire à renseigner avant la génération du contenu
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {

    $form['num'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Combien de cadeaux voulez-vous générer ?'),
      '#default_value' => $this->getSetting('num'),
      '#size' => 10,
    ];

    $form['kill'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Supprimer tous les cadeaux en base avant la génération ?'),
      '#default_value' => $this->getSetting('kill'),
    ];

    return $form;
  }
  protected function generateElements(array $values) {
    $num = $values['num'];
    $kill = $values['kill'];

    if ($kill) {
      $nbDeletedItems = 0;
      // Suppression des contenus existants
      foreach (Cadeau::loadMultiple() as $cadeau) {
        $cadeau->delete();
        $nbDeletedItems++;
      }
      $this->setMessage($this->formatPlural($nbDeletedItems, '1 cadeau a été supprimé', '@count cadeaux supprimés'));
    }

    $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
    $entity_type = $definition_update_manager->getEntityType('cadeau'); // À modifier en fonction du nom machine de votre type d'entité
    for ($i = 1; $i <= $num; $i++) {
      // Création de l'entité avec des valeurs générée aléatoirement en fonction de leur type
      // ImageItem, TextLongItem, UriItem sont a adapter en fonction des types de vos propriétés
      $cadeau = Cadeau::create([
        'title' => $this->getRandom()->word(mt_rand(2, 50)),
        'photo' => ImageItem::generateSampleValue(Cadeau::baseFieldDefinitions($entity_type)['photo']),
        'description' => TextLongItem::generateSampleValue(Cadeau::baseFieldDefinitions($entity_type)['description']),
        'url' => UriItem::generateSampleValue(Cadeau::baseFieldDefinitions($entity_type)['url']),
      ]);
      // On renseigne aussi les champs s'il y'en a.
      $this->populateFields($cadeau);
      // Et on sauvegarde notre contenu
      $cadeau->save();
    }
  }

  public function validateDrushParams(array $args, array $options = []) {
    return [
      'num' => $options['num'],
      'kill' => $options['kill'],
    ];
  }
}

 

Un petit coup de vidage de cache, puis sur l'uri /admin/config/development/generate, vous aurez maintenant une nouvelle option :

Image

Devel Generate

Par Christophe MOLLET
Christophe Mollet

Installer Drupal 9 avec Composer

Si vous vous lancez dans la création de site web personnalisé, et souhaitez posséder d'un processus de création le plus professionnel possible, notre agence web vous recommande d'installer Drupal avec Composer. Cela vous permettra entre autres d'avoir le contrôle sur le versionning de la base de données et des extensions contrib de Drupal. Afin de vous accompagner au mieux dans votre projet web, un de nos experts Drupal vous a préparé un tutoriel.

Par Artusamak
Julien Dubois

Remplacer son code jQuery par du code natif "vanilla"

Remplacer son code jQuery par du code natif "vanilla"
Artusamak
jeu 08/04/2021 - 09:42

Drupal 9 a initié une tendance de fond depuis plusieurs années au sein de sa base de code qui consiste à retirer sa dépendance à jQuery afin d'alléger le poids des pages (en l'invoquant à la carte) puis en le remplaçant par des implémentations dites vanilla (en javascript natif pur).

Cette tendance de fond est possible car les navigateurs ont bien progressé et leurs implémentations sont uniformisées, au point que les années de jQuery soient comptées (pas seulement à cause de cela).

Par réflexe ou par habitude, beaucoup de développeurs (back) savent développer certains comportements interactifs avec jQuery mais ne savent pas le faire de façon vanilla. Ces liens recensent quelques techniques et snippets d'équivalence pour les taches les plus courantes.

 

Catégories
Auteur
Par kgaut
Kevin Gautreau

Drupal 8 & Drupal 9 - Importer de la config via un update

Il est parfois nécessaire d'importer de la config directement dans un HOOK_update().

Évidement il est préférable de respecter le process normal (avec par exemple la commande drush  deploy). Mais il peut arriver de ne pas avoir le choix, dans ce cas, voici comment faire :

/**
* Import config du dossier config/install de mon_super_module
*/
function mon_super_module_update_9001() {
  $configFolder = drupal_get_path('module', 'mon_super_module') . '/config/install';
  $configFileStorage = new \Drupal\Core\Config\FileStorage($config_path);
  \Drupal::service('config.installer')->installOptionalConfig($configFileStorage);
}

 

Par Mixalis44
Mickael Zafiriou
Développeur Drupal depuis 2013.

Quickie 02 : Ajouter une régle d'affichage personnalisée pour les blocs

Dans Drupal, les blocs sont les pierres angulaires de l'affichage des éléments du site. Bien-sûr en fonction des pages on n'affiche pas tous les blocs possible en même temps.
On peut paramétrer certaines règles d'affichage que le core certains modules proposent. Aujourd’hui je vais présenter comment créer des règles personnalisées.

Par kgaut
Kevin Gautreau

Drupal 8 & Drupal 9 - Entité - Champ de base « Numéro de téléphone »

Via le module core « telephone », il est possible de créer un champ de base (basefield) pour les numéros de téléphone. Rien de foufou au niveau de la validation, c'est uniquement au niveau de l'affichage que ce champ permettra d'afficher le numéro sous forme de lien.

    $fields['phone'] = BaseFieldDefinition::create('telephone')
      ->setLabel(t('Phone number'))
      ->setRequired(TRUE)
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

Il faut évidement que le module telephone soit activé afin que ce champ soit disponible.

Par Mixalis44
Mickael Zafiriou
Développeur Drupal depuis 2013.

Débbuger les mails sous Drupal 9 avec Mailcatcher

Lorsque l'on développe un site web, on a généralement une copie de ce dernier en local afin de pouvoir travailler en toute sérénité : possibilité d'afficher les erreurs, modification de la BDD pour des tests, CSS défectueux ou incomplet... Dans cet article j'aimerai présenter la solution que j'utilise afin d'avoir la même sérénité lorsque je travaille sur les mails. Ceci me permet de débugger, tester sans que les mails ne sortent de ma machine.

Par kgaut
Kevin Gautreau

Drupal 8 & Drupal 9 - Ajouter une balise meta dans le code

Aujourd'hui dans le genre pourquoi faire simple quand on peut faire compliqué, nous allons voir comment rajouter une balise meta dans le code source de nos pages de notre site Drupal 8.

Nous pourrions le faire évidement en copiant cette ligne dans un template, mais cela serait trop simple évidement...

Nous allons plutôt utiliser le hook HOOK_preprocess_html qui peut s'utiliser dans mon module ou un thème :

function mon_module_preprocess_html(&$variables) {
  $googleSiteVerification = [
    '#tag' => 'meta', // Type de balise que l'on souhaite insérer
    '#attributes' => [ // Attributs de la balise
      'name' => 'google-site-verification',
      'content' => 'mon-code-de-verif',
    ],
  ];
  $variables['page']['#attached']['html_head'][] = [$googleSiteVerification, 'google-site-verification'];
}

 

Par admin

Statistiques de notre espace Slack

À la demande d'un de nos membres, j'ai récupéré vendredi 12 mars 2021 quelques statistiques sur notre espace Slack, que je partage aujourd'hui avec vous ici pour plus de simplicité.

Membres actifs

Données des 30 derniers jours

(depuis le 12 mars donc)

Souscription (par semaine) - 30 derniers jours

Souscription (par jour) - 30 derniers jours

Toutes périodes confondues

Souscription (par semaine) - Toutes périodes confondues

Souscription (par jour) - Toutes périodes confondues

Utilisation des canaux

Toutes périodes confondues

Liste des canaux (1/4)  - Toutes périodes confondues

Liste des canaux (2/4) - Toutes périodes confondues

Liste des canaux (3/4) - Toutes périodes confondues

Liste des canaux (4/4) - Toutes périodes confondues

Répartition des messages

Toutes périodes confondues

Répartition des messages (lecture) - Toutes périodes confondues

Répartition des messages (écriture) - Toutes périodes confondues

Voilà, j'ai trouvé l'exercice intéressant et je pense refaire le point l'an prochain pour qu'on puisse comparer. Si vous avez des suggestions, n'oubliez pas que le canal #orga-slack est à votre disposition ! Le temps de traitement n'est pas garanti en revanche ;)

PS
Je n'ai pas eu le temps de récupérer les données autrement que via capture d'écran pour l'instant, j'ai bien conscience que ce n'est pas idéal. Si cela est bloquant, n'hésitez pas à nous demander des détails via bureau@drupal.fr.

Par admin

Statistiques de notre espace Slack

À la demande d'un de nos membres, j'ai récupéré vendredi 12 mars 2021 quelques statistiques sur notre espace Slack, que je partage aujourd'hui avec vous ici pour plus de simplicité.

Membres actifs

Données des 30 derniers jours

(depuis le 12 mars donc)

Souscription (par semaine) - 30 derniers jours

Souscription (par jour) - 30 derniers jours

Toutes périodes confondues

Souscription (par semaine) - Toutes périodes confondues

Souscription (par jour) - Toutes périodes confondues

Utilisation des canaux

Toutes périodes confondues

Liste des canaux (1/4)  - Toutes périodes confondues

Liste des canaux (2/4) - Toutes périodes confondues

Liste des canaux (3/4) - Toutes périodes confondues

Liste des canaux (4/4) - Toutes périodes confondues

Répartition des messages

Toutes périodes confondues

Répartition des messages (lecture) - Toutes périodes confondues

Répartition des messages (écriture) - Toutes périodes confondues

Voilà, j'ai trouvé l'exercice intéressant et je pense refaire le point l'an prochain pour qu'on puisse comparer. Si vous avez des suggestions, n'oubliez pas que le canal #orga-slack est à votre disposition ! Le temps de traitement n'est pas garanti en revanche ;)

PS
Je n'ai pas eu le temps de récupérer les données autrement que via capture d'écran pour l'instant, j'ai bien conscience que ce n'est pas idéal. Si cela est bloquant, n'hésitez pas à nous demander des détails via bureau@drupal.fr.

Par admin

Le bureau nouveau est arrivé !

Suite à l'Assemblé Générale Ordinaire du jeudi 11 mars 2021, un nouveau bureau a été élu :

Merci à nos membres pour leur présence lors de cet évènement important pour l'association !

Nous souhaitons aussi remercier particulièrement Alexane TRUBERT et Julien SOLEILHAVOUP pour leur travail au sein du précédent bureau. Merci à vous deux pour votre soutien au cours de cette année difficile pour tout le monde, c'est aussi grâce à vous si l'association a tenu le coup ! Encor bravo aussi à Alexane pour son nouveau mandat de présidente de WebAssoc !

Comme évoqué lors de l'AGO, le bureau compte cette année poursuivre sur la lancée du mandat précédent, fortement impacté par la crise du Covid-19 :

  • La traduction toujours ! D'ailleurs on a besoin de vous pour valider les traductions du guide
  • Gouvernance des outils :migration progressive des différents comptes de l'association vers un compte "bureau" non nominatif (quand c'est possible), pour simplifier la gestion et les passations
  • Amélioration de la communication
  • Crédit de toutes les contributions grâce à notre nouveau projet sur Drupal.org : organisation de Meetup, traduction, aide à la réalisation du site de l'association... Il n'y a pas que le code dans une communauté !
  • Organisation de DrupApéro en ligne plus réguliers
  • Test de nouveaux outils (WorkAdventure, outil de vote en ligne, migration possible de Meetup...)
  • Un gros travail d'ouverture à la francophonie au sens large, avec un rapprochement des autres associations locales francophones. Le bureau voudrait aussi pouvoir soutenir les communautés qui n'ont pas encore de structure à se développer
  • Et enfin, organisation d'un DrupalCamp en ligne cette année :)

En bref, il y a du pain sur la planche, mais l'équipe est motivée, et nous savons que vous aussi !

Le PV d'AGO sera prochainement finalisé et partagé ici.

Pour contacter le bureau de l'association, vous pouvez adresser un e-mail à l'adresse bureau@drupal.fr.

Par admin

Le bureau nouveau est arrivé !

Suite à l'Assemblé Générale Ordinaire du jeudi 11 mars 2021, un nouveau bureau a été élu :

Merci à nos membres pour leur présence lors de cet évènement important pour l'association !

Nous souhaitons aussi remercier particulièrement Alexane TRUBERT et Julien SOLEILHAVOUP pour leur travail au sein du précédent bureau. Merci à vous deux pour votre soutien au cours de cette année difficile pour tout le monde, c'est aussi grâce à vous si l'association a tenu le coup ! Encore bravo aussi à Alexane pour son nouveau mandat de présidente de WebAssoc !

Comme évoqué lors de l'AGO, le bureau compte cette année poursuivre sur la lancée du mandat précédent, fortement impacté par la crise du Covid-19 :

  • La traduction toujours ! D'ailleurs on a besoin de vous pour valider les traductions du guide
  • Gouvernance des outils :migration progressive des différents comptes de l'association vers un compte "bureau" non nominatif (quand c'est possible), pour simplifier la gestion et les passations
  • Amélioration de la communication
  • Crédit de toutes les contributions grâce à notre nouveau projet sur Drupal.org : organisation de Meetup, traduction, aide à la réalisation du site de l'association... Il n'y a pas que le code dans une communauté !
  • Organisation de DrupApéro en ligne plus réguliers
  • Test de nouveaux outils (WorkAdventure, outil de vote en ligne, migration possible de Meetup...)
  • Un gros travail d'ouverture à la francophonie au sens large, avec un rapprochement des autres associations locales francophones. Le bureau voudrait aussi pouvoir soutenir les communautés qui n'ont pas encore de structure à se développer
  • Et enfin, organisation d'un DrupalCamp en ligne cette année :)

En bref, il y a du pain sur la planche, mais l'équipe est motivée, et nous savons que vous aussi !

Le PV d'AGO sera prochainement finalisé et partagé ici.

Pour contacter le bureau de l'association, vous pouvez adresser un e-mail à l'adresse bureau@drupal.fr.

Par Christophe MOLLET
Christophe Mollet

Configuration d'un flux RSS sur Drupal

Qu'est-ce qu'un flux RSS ?

 

RSS signifie Really Simple Syndication. C'est une méthode simple et standardisée de distribution de contenu qui peut vous aider à être au courant des actualités, blogs, sites web et réseaux sociaux préférés, de façon centralisée.

Par kgaut
Kevin Gautreau

Drupal 8 & Drupal 9 - Changer l'ordre d'exécution des hooks

Pour un projet, je souhaiter alterer un type d'entité via HOOK_entity_type_alter. Problème un module du core effectuait une modification sur ce même type d'entité, et son hook était exécuté après celui de mon module. Les modifications de mon module n'étaient donc pas prise en compte.

Il y a plusieurs possibilités pour résoudre ce soucis, celle que j'ai utilisé ici est de forcer ce hook à être exécuté en dernier. Ceci en utilisant le HOOK_module_implements_alter (dans cet exemple, le nom machine de mon module est kgaut [oui, c'est vendredi, je ne suis pas très inspiré]).

function kgaut_module_implements_alter(&$implementations, $hook) {
  switch ($hook) {
    case 'entity_type_alter':
      $group = $implementations['kgaut'];
      unset($implementations['kgaut']);
      $implementations['kgaut'] = $group;
      break;
  }
}

Ce bout de code force le hook entity_type_alter à utiliser l'implémentation du module kgaut en dernier (et après donc toutes les autres implémentations des autres modules)

Prévenir des soumissions non sollicitées en masse sur son site Drupal 9 (ou Drupal 8)

Plusieurs solutions anti-spam existent sur Drupal pour prévenir les soumissions de formulaires (contact, abonnement newsletter, etc.) par des robots plus ou moins bien intentionnés. Sans vouloir être exhaustif, nous pouvons utiliser les modules Honeypot et Antibot qui fournissent des mécanismes de défense (différents) non intrusifs, ou encore les modules captcha ou recaptcha qui demandent au visiteur de répondre à différents challenges avant de lui permettre de soumettre le formulaire.

Pages