Drupal, Table_wizard, Views et les vues MySQL

  • warning: array_map(): Argument #2 should be an array in /var/www/titouille.ch/www/modules/system/system.module on line 1050.
  • warning: array_keys() expects parameter 1 to be array, null given in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
  • warning: Invalid argument supplied for foreach() in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
Portrait de titouille

Dans le cadre d'un projet multi-site, j'ai à mettre en place un site général, ainsi que plusieurs sites "secondaires" en tant que sous-domaines du domaine principal.

Certaines données du site principal doivent être accessibles sur les sites secondaires, et j'aimerai également permettre aux données des sites secondaires d'être listées sur le principal...

Le problème, dans tout ça, c'est que chaque site (principal et secondaires) possède sa propre base de données. Il y a quelques tables qui sont partagées, telles que "users", "sessions", etc... afin qu'une authentification sur n'importe quel site permette de naviguer sur les autres sans devoir à nouveau s'authentifier, mais les contenus sont pour chaque site différents. Ainsi un noeud possédant l'id 12 sur le sous-domaine "foo.mondomaine.com" ne sera pas le même que le noeud possédant l'id 12 sur le sous-domaine "bar.mondomaine.com"...



Vues MySQL

Bref chaque site possédant son propre contenu, comment partager les données entre les différents sites, ou tout du moins permettre certains listings... Les vues MySQL apportent une réponse à ce problème, mais pas encore une solution.
Une vue MySQL permet de piocher des données dans différentes tables (dans la même base de données ou dans plusieurs bases de données) pour en résulter une "simili" table. Le résultat est tabulaire, simplement ce n'est pas une vraie table mais un regroupement de données.

Sur mon site principal, je peux créer différentes vues (3 pour mes besoins). La première va servir à obtenir une liste de données issue de la base de données du site principal (main_list).
Les deux autres vues (contenttype1_list et contenttype2_list) vont récupérer les données sur les sous-domaines. ça sera une sorte de sélection avec le mot clé "union", genre select * from db_foo.mytable union select * from db_bar.mytable.



Table Wizard, les tables

Une fois ces 3 vues créées, je vais maintenant ajouter les modules schema et table_wizard. Schema est obligatoire pour utiliser table_wizard, mais c'est ce dernier qui nous intéresse vraiment.

Avant d'aller plus loin, il va également falloir modifier légèrement le fichier settings.php de chaque sous-domaine. C'est la variable $db_url qui nous intéresse. A la base, on l'utilise de la manière suivante :

$db_url = 'mysql://user:password@host/subdomain_db';

Mainenant, nous allons modifier les choses comme suivant :

$db_url['default'] = 'mysql://user:password@host/subdomain_db';
$db_url['base'] = 'mysql://user:password@host/domain_db';

Grâce à cette modification, j'indique à Drupal que la base de données par défaut est celle dans laquelle se trouvent toutes les données, mais qu'il doit également posséder un accès à la base de données du site principal (domain_db).
Sans table_wizard, cette manipulation ne sert à rien. Par contre, lorsqu'on installe table_wizard sur un sous-domaine et qu'on navigue vers /admin/content/tw, on va voir que les tables de la base de données principale sont désormais disponibles si nous cliquons sur le lien "Add existing tables".

Nous pouvons donc maintenant ajouter sur un sous-domaine l'accès à la vue "main_list". Une fois ajoutée, il est nécessaire de cliquer sur le bouton "analyze" afin de voir les champs. Le module nous informe qu'il manque une clé primaire. Ici, pas le choix... Soit il faut rajouter un champ dans notre vue pour qu'une clé unique soit générée automatiquement, soit, si c'est possible, nous allons utiliser un des champs disponible dans la vue en tant que clé primaire. Le seul problème, c'est que nous sommes obligé de mettre cette information manuellement dans la base de données. Dans la table "tw_columns", il va falloir trouver la colonne correspondante à notre future clé primaire et modifier la colonne "primarykey" pour y mettre un "1" à la place du "0". Retour dans Drupal : Attention. Si on clique sur le bouton "Reanalyze" les données seront réanalysées et nous perdront notre affectation de clé primaire.

Nous pouvons maintenant aller sur les visualisations (admin/build/views) et nous pourrons y trouver une nouvelle "vue" (module views) correspondant à la vue (mysql) que nous venons d'ajouter. Nous pouvons modifier les champs, les masquer, les ré-écrire, etc... Et notre vue va afficher les données disponibles provenant de la base de données principale, même si nous sommes sur un sous-domaine.



Table wizard, les relations

Mes deux autres vues utilisent des données récupérées sur les sous-domaines, et doivent les afficher uniquement sur le site principal. Je vais donc activer les modules "schema" et "table_wizard" sur le site principal, et ajouter la vue (mysql) dans table_wizard (admin/content/tw) puis indiquer manuellement la clé primaire de ma vue. Une fois ces éléments mis en place, une nouvelle vue (module views -> /admin/build/views) sera rajoutée dans ma liste des visualisations.

Chaque donnée correspond à certains champs d'un noeud (titre, teaser). Je récupère également le "uid" du noeud, c'est à dire l'identifiant utilisateur qui va m'indiquer qui est l'auteur du noeud.

Malheureusement, afficher un uid n'est pas très intéressant pour les visiteurs. Je préférerai afficher le nom de l'utilisateur, mais récupérer son nom via MySQL va encore compliquer ma requête.
Plutôt que de rajouter encore des jointures dans ma requête, je peux utiliser une particularité du module table_wizard : les relations.

Le but étant de trouver le nom d'utilisateur en possédant simplement son uid, je vais d'abord ajouter via table_wizard la table "users". Je vais ensuite cliquer sur le bouton "analyze" de ma vue "contenttype1_list" et cocher, pour le champ "uid", la colonne "Available key". Cette action indique que ce champ peut être utilisé pour créer une relation.
Je vais faire de même pour la table "users", puis passer à la gestion des relations (/admin/content/tw/relationships).

Ici, je peux voir maintenant que dans le formulaire du bas, deux listes déroulantes sont disponibles, chacune contenant les champs pouvant être associés en tant que relation.
Dans la première, je vais sélectionner le champ de ma vue (contenttype1_list.uid) et dans la seconde, je vais sélectionner le champ de la table "users" (users.uid). IMPORTANT : je vais également choisir le mode "manuel" pour l'incorporation de la table associée. Si je ne choisi pas manuel, je n'aurai pas accès aux champs que je désire dans la vue (module views) par la suite.

Je valide ma relation, je reviens sur table_wizard et j'analyse à nouveau la table "users".
je passe maintenant sur les visualisations, je choisi ma visualisation associée à "contenttype1_list" et je vais cliquer sur le petit + pour ajouter une nouvelle relation. Ici, le module views va me proposer le choix suivant :

contenttype1_list : uid (joins to users)
contenttype1_list.uid

Je le sélectionne et l'ajoute en tant que relation. Si je clique maintenant sur le petit + me permettant d'ajouter un nouveau champ, j'ai maintenant accès au type de champs "Utilisateur" et je vais pouvoir sélectionner "Utilisateur: Nom" qui va me permettre d'afficher le nom d'utilisateur plutôt que l'identifiant utilisateur.

Et voilà Smile