Bei einem Kunden hatte ich in den letzten Monaten die Aufgabe einen xt:Commerce-Shop mandantenfähig zu machen. Das heißt, es sollten mehrere Shops die unterschiedlich aussehen und unterschiedliche Preise haben auf dieselben Lagerbestände und Artikelinformationen zugreifen und über dasselbe Backend verwaltet werden. Nun ja, genau genommen war das vor vielen Jahren mal ein xt:Commerce der inzwischen aber massiv umgebaut wurde. Nichts desto trotz gab eis eine Eigenheit die mir anfangs ein wenig zu schaffen machte.

Ein Problem war, dass xt:Commerce eine ganze Menge Konstanten nutzt die aus Datenbankeinträgen generiert werden. Das heißt, es gibt eine Tabelle in der der Name der Konstante und der Wert hinterlegt sind. Die Tabelle wird dann komplett ausgelesen und die Konstanten werden einzeln mit define() deklariert:

$result = mysql_query ('SELECT * FROM configuration');
while ($row = mysql_fetch_assoc($result))
{
    define ($row['configuration_key'], $row['configuration_value']);
} 

Innerhalb des Shop-Bereichs ist das kein Problem. Im Administrationsbereich wird das allerdings schnell zum Problem, da beide Shops aber über denselben Administrationsbereich verwaltet werden sollten. Schließlich nutzen sie dieselben Konstantennamen, legen darin aber unterschiedliche Werte ab. Es musste eine Lösung her welche eine einfache und schnelle Lösung ermöglichte.

Um die Sache schnell in den Griff zu bekommen habe ich mich dafür entschieden die ID des Mandanten jeweils an den Namen der Konstante anzuhängen. Innerhalb des jeweiligen Shop-Bereichs ist das einfach machbar, da in jedem Shop die Mandanten-ID in einer Konstante abgelegt ist. Bei der Deklaration einer Konstante kann man also einfach ein Konstrukt wie das hier nutzen:

define ('TENANT_ID', 1);  // ID des Mandaten</code>
$sql = 'SELECT * 
              FROM configuration 
              WHERE tenant_id = '. TENANT_ID
$result = mysql_query ($sql);
while ($row = mysql_fetch_assoc($result))
{
    define ($row['configuration_key'] . TENANT_ID, 
                                     $row['configuration_value']);
} 

Dadurch muss man, wenn man einen neuen Shop für einen Mandanten anlegt nur die ID des Mandaten in der Konfigurationsdatei ändern und alles andere kann gleich bleiben. Natürlich musste auch die Tabelle configuration um die Spalte tenant_id ergänz werden. Alternativ hätte man auch für jeden Mandanten eine eigene Tabelle anlegen können.

Für die Shops ist der Drops damit gelutscht. Der Administrationsbereich ist aber ein Problem. Hier muss mal mit der einen oder er anderen Konstante gearbeitet werden. Dummerweise sieht PHP defaultmäßig keine Möglichkeit vor den Namen einer Konstante beim Zugriff dynamisch zu halten. Das dachte ich zumindest. Aber weit gefehlt, die Funktion constant() macht’s möglich. Anstelle von

echo "Shop Eigentümer: " . SHOP_OWNER_1;

kann man also auch

$tenant_id = 1;
echo "Shop Eigentümer: " . constant('SHOP_OWNER_' . $tenant_id);

schreiben. Durch diese Funktion kann man den Namen der Konstanten also dynamisch generieren. Zugegebenermaßen stellt diese Lösung ein gewisses Maß an Frickelei dar aber wenn man einen bestehenden Shop nachträglich Mandantenfähig machen muss hat man keine große Wahl 😉