Cover Image

Ich habe meine lokale Entwicklungumgebung seit einigen Wochen dockerisiert und in dem Zug alle meine MySQL Datenbanken auf einzelne Docker-Container aufgeteilt die ich bei bedarf starte und nach getaner Arbeit auch wieder stoppe.

Seit ein paar Tagen arbeite ich an einer Portierung meines Tools n98-magerun auf Magento 2. Als ich das Setup-Tool startete wunderte ich mich, dass man keinen abweichenden Datenbank TCP Port definieren konnte. In meinem Fall laufen alle Magento Datenbanken unter 127.0.0.1 Port 33310. Ein Blick in den Quellcode sorgte allerdings schnell für Ernüchterung. Ein abweichender Port scheint momentan nicht unterstützt zu sein.

Der Ablauf ist wie folgt…

In Schritt 2 werden die Datenbank Zugangsdaten eingetragen und man kann diese per XHR validieren lassen. Im Hintergrund des Setup-Tools arbeitet eine auf AngularJS basierende Zend Framework 2 App die auch gesondert über Composer installiert werden muss.

magento2_angular_installer_step2

Wir der Button gedrückt erfolgt ein Post-Request an “/setup/data”, welches die DB-Zugangsdaten annimmt und validiert.

host: "127.0.0.1:33310"
name: "magento2"
useAccess: 1
useExistingDb: 1
user: "root"

In meinem Fall wollte ich erreichen, dass das ergänzen des Hostname “127.0.0.1” um einen Doppelpunkt und der Portnummer “33310” verarbeitet wird.

Die Daten des Posts werden dann über die Factory \Magento\Setup\Module\Setup\ConnectionFactory verarbeitet. Diese ist noch nicht wirklich eine Factory und gibt immer ein MySQL DB-Adapter zurück. Hier werden allerdings die DB-Zugangsdaten verarbeitet.

Die Factory nutzt Konstanten aus der Konfigurationsklasse \Magento\Setup\Module\Setup\Config. Damit der Code konsistent ist, habe ich der Klasse eine neue Konstante KEY_DB_PORT eingetragen.

/**
 * Deployment configuration model
 */
class Config
{
    /**#@+
     * Possible variables of the deployment configuration
     */
    const KEY_DATE    = 'date';
    const KEY_DB_HOST = 'db_host';
    const KEY_DB_PORT = 'db_port'; // <-- Eingefügte Konstante
    const KEY_DB_NAME = 'db_name';
    const KEY_DB_USER = 'db_user';
    const KEY_DB_PASS = 'db_pass';

    // ....
}

Jetzt kann in die Factory ein kleines Code-Stück für die Verarbeitung des Ports übergeben werden.

Die Klasse \Magento\Setup\Module\Setup\ConnectionFactory sieht dann wie folgt aus:

class ConnectionFactory
{
    /**
     * Create DB adapter object
     *
     * @param \ArrayObject|array $config
     * @return \Magento\Setup\Framework\DB\Adapter\Pdo\Mysql
     */
    public function create($config)
    {
        $config[Config::KEY_DB_PORT] = 3306;
        if (strstr($config[Config::KEY_DB_HOST], ':')) {
            list($config[Config::KEY_DB_HOST], $config[CONFIG::KEY_DB_PORT]) = explode(':', $config[Config::KEY_DB_HOST]);
        }

        return new Mysql(
            [
                'driver' => 'Pdo',
                'dsn' => "mysql:dbname=" . $config[Config::KEY_DB_NAME] . ";host=" . $config[Config::KEY_DB_HOST] . ";port=" . $config['db_port'],
                'username' => $config[Config::KEY_DB_USER],
                'password' => isset($config[Config::KEY_DB_PASS]) ? $config[Config::KEY_DB_PASS] : null,
                'driver_options' => [\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"]
            ]
        );
    }
}

Danach funktioniert auch der 6. Schritt der die Setup-Skripte ausführt da dort die gleiche ConnectionFactory genutzt wird.

magneto2_angular_installer_step6

Abschließend muss man sagen, dass der neue Setup-Code schnell zu durchblicken ist. Ich denke es wäre besser man würde für den Port noch ein gesondertes Feld einführen. Alternativ könnte ich meinen Code auch an Magento schicken damit dieser in den neuen Installer aufgenommen wird.