Multi-boutiques avec partage de base de données

Information importante

En raison d'un grand nombre d'inscriptions de spammers sur notre site, polluant sans relache notre forum, nous suspendons la création de compte via le formulaire de "sign up".

Il est néanmoins toujours possible de devenir adhérent•e en faisant la demande sur cette page, rubrique "Inscription" : https://www.drupal.fr/contact


De plus, le forum est désormais "interdit en écriture". Il n'est plus autorisé d'y écrire un sujet/billet/commentaire.

Pour contacter la communauté, merci de rejoindre le slack "drupalfrance".

Si vous voulez contacter le bureau de l'association, utilisez le formulaire disponible ici, ou envoyez-nous un DM sur twitter.

Bonjour à tous !!

Le titre est déjà explicite... En gros, j'aimerai créer un site web de base (www.monsite.com) qui sera un site e-commerce.
Puis en amont de ce site seront créés différents sous-domaines (chaussures.monsite.com, vetements.monsite.com, etc...) qui seront créés sur la base du système multi-site de Drupal.

Bon, j'ai fait des recherches, j'ai également suivi le thread de zmove à ce sujet, et j'ai réussi à mettre en place différents sous-domaines.

Je me suis ensuite appliqué à recopier ma base de données principale dans une seconde base de données (chaussures) en omettant certaines tables (authmap, profile_values, profile_fields, role, sequences, sessions, users, users_roles) afin de centraliser ces données particulières, cette dernière manip permettant à tous les utilisateurs de se logger sur tous les sous-sites avec leur compte de base. Yeah, bonne idée me dis-je.

Seulement maintenant, le problème, c'est que tous les vendeurs peuvent se logger dans toutes les boutiques et avoir accès à toutes les données de leur concurrents, en quelque sorte... Vu que le système est basé sur le partage des utilisateurs, alors tous les utilisateurs ayant un role "vendeur" seront considérés comme tels sur tous les sous-sites, et là ça pose un gros problème...

Mes buts sont les suivants :

  1. faire en sorte de n'avoir qu'un seul vendeur (voire même plusieurs, pkoi pas) mais attaché sur un seul magasin. En gros, si le vendeur essaye de se logger sur un magasin autre que le sien, il sera considéré comme un simple client et non comme un "administrateur" de la boutique dans laquelle il s'est loggé.

  2. centraliser les commandes des clients dans leur compte global. Donc faire en sorte que les clients puissent voir leur achats dans tous les sites à partir d'une seule page. J'ai pu constater que les infos transactions vont dans différentes tables (ec_transaction, ec_transaction_address, ec_transaction_misc, ec_transaction_product) mais là encore, le problème est que si partage ces tables, alors j'imagine que tous les vendeurs auront accès à toutes les transactions :-(

Voilà... Pour le premier problème, j'imaginais peut être une table de conversion et hacker hook_user sur le login, pour tester si l'utilisateur + mot de passe correspond au vendeur du site en question afin de lui affecter à la volée un rôle de vendeur, qu'est-ce que vous en dites ?

Pour le second problème, je ne vois pas trop comment mettre en place cette solution, mis à part hacker le module "store" pour modifier la requête et aller chercher dans toutes les base de données disponibles pour voir si je trouve des transactions pour cet utilisateur précis.
[edit]
ou plutôt le contraire, sinon ça serait l'enfer pour récupérer les bonnes données dans la bonne base de données. Donc hacker le mode "store" coté vendeur pour qu'il n'affiche et ne donne accès qu'au transactions concernant son magasin.

Enfin, dernier problème dont je viens de me rendre compte, un utilisateur qui est loggé sur www.monsite.com et se déplace sur chaussures.monsite.com n'est plus loggé, il doit à nouveau insérer ses identifiants... Existe-t-il un moyen d'outrepasser ça et de permettre de naviguer entre les sites à l'aide de la même session ?
[/edit]

Si vous avez des idées je suis à l'écoute ;)

D'avance merci pour les suggestions.

Thierry

Version de Drupal : 

La solution passe peut-être par une unique base pour tous les magasins.... Après il faudra peut-être plusieurs modules "store" ayant chacun ses tables, produits etc... des droits différents selon les profils... mais un panier commun...

Hello sytav et merci pour ta réponse.

Une unique base pour tous les magasins j'ai quelques doutes. Car si je fais ça je me retrouve avec tous les produits qui peuvent être affichés sur tous les magasins, donc ce n'est pas très bon...

Au final, avoir plusieurs DB ou une seule avec des préfixes de tables ne change pas tellement le problème, mais j'ai ébauché une solution qui peut me sembler satisfaisante au niveau du problème de centralisation des transactions.

Créer un module qui va aller rechercher dans toutes les base de données existantes si il trouve des transactions pour l'utilisateur concerné et les afficher, permettant ensuite une redirection sur le sous-site concerné par la transaction choisie. Ceci permettrai de faire une centralisation des informations tout en évitant de devoir utiliser des hacks tordus pour obtenir les données et faire un affichage commun pour les clients.
Ainsi les données restent toujours dans leur sous-site propre, seule une page affichable sur tous les site permet de lister le tout et de rediriger vers le bon sous-site.

Maintenant mon problème se situe au niveau des droits du vendeur. Actuellement, si je suis vendeur, je peux aller dans n'importe quel magasin pour voir/ajouter/éditer/supprimer des produits et des transactions, avoir un contrôle total en tant que propriétaire du site, et ceci dans tous les sites...

Je pensais essayer d'affecter le rôle de vendeur à la volée :

  1. inclure une variable "drupal_subsite_key" dans la base de données du sous-domaine
  2. inclure la même clé dans un champs de profil du vendeur
  3. idéalement, à chaque changement de sous-domaine / domaine, tester la valeur de profil ainsi que la valeur du site pour voir si elles correspondent et ajouter/supprimer le rôle "vendeur".

Et je me demandais comment le faire, et je pense qu'a coup de cookies et de quelques tests, ça doit être faisable via un module perso, je vais tester tout ça.

A+

Thierry

pour garder des données d'un sous-domaine à un autre la solution passe surement par un cookie... Les variables de session en php ont souvent du mal à survivre aux changements de sous-domaines...

Hello,

Bon, résolution du problèmes de session avec le module singlesignon qui permet de garder la session existante sur tous les sous-sites.

Par contre je reste confronté à mon problème de droits sur les sous-sites... Un vendeur ne doit avoir accès en tant qu'administrateur qu'a son propre site, et actuellement ce n'est pas le cas :-|

J'ai tenté d'implémenter un système qui supprime le role vendeur à la volée comme je l'expliquait, mais impossible, la session garde une trace du role et je dois passer par le formulaire d'édition de l'utilisateur pour remettre en place les éléments correctement. J'ai tenté de passer par la méthode "user_save" du module user pour simuler une modification à partir du formulaire d'édition mais pas de changements, le problème persiste...

Je ne vois pas trop comment régler le truc, je reste donc à l'écoute de suggestions à ce propos, ça commence à me prendre la tête ce truc :-(

Salut,

J'ai déjà dû gérer le même genre de problématique sur un projet, et l'ajout/suppression de rôle à la volée a bien fonctionné :

  • j'ai utilisé le hook_init() pour effectuer mes ajouts/suppressions de rôle au début de chaque requête
  • j'ai manipulé directement la variable $GLOBALS['user'] qui contient l'utilisateur en cours

Je n'ai pas rencontré le problème de session que tu décris : la session stocke l'identité de l'utilisateur (le "uid"), pas ses rôles. Ainsi, une fois que Drupal sait à quel utilisateur il a affaire, c'est la variable globale $user qu'il manipule, et pas une variable de session. Si tu changes cette variable globale suffisamment tôt dans la requête (hook_init), tu ne devrais pas avoir de pb.

Salut Vincent ;)

Heu, bah justement, j'ai encore 1 peu de peine avec ces "hook"... Du genre quel hook j'utilise ? est-ce que je crée mon propre module et je lui fais son "monModule_init" ?
Parce que jusqu'à maintenant, je plaçais mon code dans le template.php, fonction _phptemplate_variables, dans le test "if( $hook == 'page')" mais c'est peut-être bien là que ça foire...

En tout cas si tu me dis que c'est faisable, alors je te fais confiance, je garde espoir d'y arriver :D

Donc en gros, je fais un hook_init dans mon propre module que j'active pour les utilisateurs anonymes et authentifiés (tout le monde quoi...), je récupère les infos, fais mes tests, ajoute / supprime les rôles au besoin...
Et pour ça je le fais à l'arrache avec juste une méthode sql ou bien j'utilise user_save ? y faudra surement que je mette à jour l'utilisateur et la session (session_regenerate, un truc du genre... avant de réaffecter l'utilisateur dans le tableau global, oui ?

Si tu peux m'orienter encore 1 tit peu ça me ferai bien avancer.

Merci déjà pour ces réponses, ça me réconforte, je commençais à perdre espoir et je commençais à regarder les OG pour gérer ça, mais ça a pas l'air mieux, lol.

Ben j'ai encore essayé en rajoutant un hook init, mais le résultat est le même... On dirait qu'il garde en mémoire certaines informations, et tant que je n'ai pas manuellement remis les rôles de mon utilisateur "vendeur" en passant par l'édition du compte de l'utilisateur, le compte réagit bizarrement...

Est-ce que tu pourrais développer un peu ta technique, au moins au niveau de l'affectation / suppression des rôles et de l'enregistrement des informations dans la db... enfin c'est surtout la mise à jour du compte utilisateur qui m'intéresse, car c'est ça qui semble ne pas fonctionner chez moi... J'ai essayé en faisant de simples requêtes sur la table users_roles, ou encore de passer par la méthode user_save de user.module, qui serait sensé mettre à jour tout le tremblement, mais rien n'y fait, ça ne veut pas fonctionner :-(

D'avance merci pour de quelconques suggestions ou pistes sur le sujet car là je commence à désespérer, 3 jours que je suis la dessus sans trouver de solution...

Re,

Si ça ne marche pas, 2 causes possibles : le hook_init(), ou le code qui change le rôle utilisateur.

Je te laisse vérifier que ton hook_init() est bien exécuté en ajoutant dedans une ligne du style :

<?php
drupal_set_message
('hello');
?>

Si le message "hello" n'apparaît pas à l'écran, c'est que ton hook est mal implémenté.

Maintenant, le changement de rôle. Je ne suis pas sûr d'avoir compris ce que tu voulais faire : le principe d'attribution d'un rôle à la volée consiste à affecter un rôle à un utilisateur (par ex, le rôle "admin") UNIQUEMENT SI et TANT QUE certaines conditions sont remplies (par ex, "être sur un certain sous-domaine"). Il n'est donc pas question d'utiliser user_save() car le changement de rôle serait enregistré en base et deviendrait permanent...

Pour affecter un rôle temporairement, il faut directement ajouter ce rôle dans la propriété "roles" de la variable globale $user (autrement dit : $user->roles). Je ne te garantis pas la syntaxe, mais ça devrait ressembler à ça :

<?php
// Implémentation du hook_init() dans un module "toto".
function toto_init() {
  global
$user// récupère la variable globale $user;
 
if ($subdomain == 'site1') {
   
$user->roles[4] = 'admin';
  }
}
?>

$user->roles contient un tableau associatif où les clés sont les ids des rôles, et les valeurs sont les noms des rôles. Tu remplaceras "4" et "admin" par les valeurs qui vont bien dans ton cas.

Hello Vincent,

Bon, le hook init sur mon module fonctionne, ça c'est clair, j'avais balançé des "echo" et ça m'affichait bien quelque chose.

Maintenant, je n'ai pas vu la chose de cette manière... Avec ton système, je devrai partir du principe que chaque utilisateur est un client, et seulement si il rempli les conditions nécessaires (être dans le sous-domaine lui appartenant), lui affecter temporairement le rôle de vendeur (ou tout autre rôle d'administrateur).

Pour moi, le vendeur était un vendeur 1 point c'est tout. Donc si il n'était pas dans son sous-domaine, je lui retirais ce rôle pour ajouter le rôle client, et vice-versa, et je validais tout ça dans la base de données.

Maintenant je viens de tester ta méthode :

  1. je me logge sur le domaine principal en tant que vendeur1. je suis un simple client : Array ( [2] => authenticated user [7] => customer )
  2. je navigue sur le sous-domaine xyz, dont je suis le "propriétaire" en tant que vendeur1. Le rôle est bien ajouté à la liste via hook_init, je fais un print_r des rôles, je peux bien voir Array ( [2] => authenticated user [7] => customer [5] => seller ) , mais rien a faire, je n'ai toujours pas accès au menu d'administration e-commerce, et pourtant le "vendeur" est censé avoir accès à l'administration de la boutique, des produits, etc...

Là je sèche... j'ai testé à peu près toutes les syntaxes que j'ai pu trouver dans certains threads, j'ai testé avec les méthodes du module user directement, plusieurs hooks différents, mais rien à faire... Est-ce que ça serait singlesignon qui fait foirer le truc ? je ne sais pas... mais si je ne l'ai pas ça fait s'écrouler tout le système, à ce moment là plus besoin de toutes ces difficultés si l'utilisateur est obligé de devoir se logger sur chaque domaine/sous-domaines...

Bref, je me sens un peu seul vis-à-vis de ce problème, ça va faire 4 jours que je suis dessus et je n'ai toujours rien trouvé de concluant, et c'est pourtant pas faute d'avoir cherché :-(

vala... Si quelqu'un a encore des idées à ce propos je suis preneur, sinon je vais peut-être essayer de gérer ça différement, par exemple avec OG, mais là aussi, j'ai quelques problèmes, je n'ai pas de type de contenu "groupe" (content/add/og) alors que dans la doc ils disent de naviguer sur cette url pour créer un nouveau groupe...

Bref... Je reste à l'écoute tout de même mais là je désespère un peu de trouver une solution... je ne pensais pas que c'était si difficile de mettre en place un multi-site / multi-utilisateurs avec partage de la DB pour les utilisateurs... Peut-être existe-t-il un module qui permette de restreindre les droits des admins selon l'url par exemple mais je n'ai rien trouvé de tel...

a++

Désolé mais je sèche aussi : j'ai appliqué la méthode que je t'ai décrite sur un projet, et ça marchait nickel. Maintenant, je t'ai décrit tout ça de mémoire, il est possible que j'ai oublié un détail (ou que ton site ait qqchose de différent du mien)...

oui, je capte pas non plus... la toute première idée que j'ai eu semblait être la bonne, j'ai fait pleins de recherches, et c'est toujours l'affectation de roles à la volée de cette manière, avec user_save ou sans...

Tu utilisais singlesignon également ? car sans, je vois pas comment gérer le login automatique, j'ai lu des trucs bien farfelus mais rarement exploitables... Donc si ce n'est pas singlesignon qui fait barrage, je ne vois pas trop... peut-être le module ecommerce, je ne sais pas... ça me désespère un peu, j'ai l'impression qu'il y a un truc qui reste en cache ou en session et qui fait foirer le processus...

Je viens encore d'essayer de supprimer le module ecommerce mais pas de changements... Je soupçonne également peut être un problème... windows ? je vais tenter de faire une install sur une dist linux (local si je suis motivé ou en ligne, on verra bien) histoire de voir si le problème persiste, et au pire je reprendrai le truc depuis la base histoire de savoir à quel moment ça commence à déconner.

Merci pour les pistes, a++ ;)