Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi db access #1437

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"psr/http-message": "*",
"psr/log": "*"
},
"require": {
"php": "^8.1"
},
"require-dev": {
"redaxo/php-cs-fixer-config": "^2.0",
"friendsofphp/php-cs-fixer": "v3.37.1",
Expand Down
27 changes: 27 additions & 0 deletions docs/09_multiple_db_usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Alternative DB aus config.yml nutzen

> Wenn in der `config.yml` mehrere Datenbankverbindungen eingerichtet sind, lässt sich YForm auch mit diesen
> Datenbanken nutzen.

## Verfügbarkeit der Funktion

Ist nur eine Datenbankverbindung in der `config.yml` eingerichteten, werden die Bedienelemente für multiple Datenbanken
nicht angezeigt. Erst wenn mehrere Verbindungen eingerichtet sind, aktivieren sich die Elemente automatisch.

### Im Migrator

In der Tabellen-Migration haben alle für die Migration verfügbaren Tabellen ein Prefix mit der Datenbank, in welcher sie
liegen vor ihrem Namen.

### Beim Erstellen

Beim Erstellen einer neuen Tabelle über den Table Manager lässt sich die gewünschte Datenbank auswählen. Wird eine
Tabelle im weiteren Verlauf bearbeitet, so wird die Datenbank, in welcher sie gespeichert ist, als Information
angezeigt.

## ⚠ Wichtige Hinweise

1. Relationstabellen müssen in derselben Datenbank liegen wie die verknüpfte Tabelle. Es erfolgt **keine
Überprüfung**, ob die Tabelle wirklich in derselben Datenbank liegt. Die Verantwortung dafür liegt beim
Datenbank-Designer, welcher die Relation erstellt.
2. Die Verwaltung der Daten liegt immer in Datenbank 1.
3 changes: 1 addition & 2 deletions lang/de_de.lang
Original file line number Diff line number Diff line change
Expand Up @@ -280,5 +280,4 @@ yform_docs_yorm = YOrm
yform_docs_email = E-Mail Templates
yform_docs_rest = REST-API
yform_docs_tools = Tools


yform_docs_multiple_db_usage = Nutzung mehrerer Datenbanken
2 changes: 1 addition & 1 deletion lang/en_gb.lang
Original file line number Diff line number Diff line change
Expand Up @@ -264,4 +264,4 @@ yform_docs_formbuilder = Form builder
yform_docs_demos = Demos
yform_docs_yorm = Yorm
yform_docs_plugins = Plugins

yform_docs_multiple_db_usage = Use multiple databases
2 changes: 1 addition & 1 deletion lang/es_es.lang
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,4 @@ yform_docs_formbuilder = Formbuilder
yform_docs_demos = Demos
yform_docs_yorm = Yorm
yform_docs_plugins = PlugIns

yform_docs_multiple_db_usage = Utilizar varias bases de datos
2 changes: 2 additions & 0 deletions lang/pt_br.lang
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,5 @@ yform_values_options_boolvalues = Valores Values (0,1 = não selecionado, sele

yform_geo_get_position = Obter a localização
yform_geo_clear_position = Criar localização

yform_docs_multiple_db_usage = Utilização de várias bancos de dados
3 changes: 1 addition & 2 deletions lang/sv_se.lang
Original file line number Diff line number Diff line change
Expand Up @@ -267,5 +267,4 @@ yform_docs_yorm = Yorm
yform_docs_email = E-Mail mallar
yform_docs_rest = REST-API
yform_docs_tools = Verktyg


yform_docs_multiple_db_usage = Använda flera databaser
34 changes: 33 additions & 1 deletion lib/yform.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public function __construct(array $params = [])
$this->objparams['main_where'] = ''; // like "id=12" for db
$this->objparams['main_id'] = -1; // unique Dataset ID
$this->objparams['main_table'] = ''; // for db and unique
$this->objparams['db_id'] = 1; // select alternative database
$this->objparams['sql_object'] = null; // rex_sql

$this->objparams['form_hiddenfields'] = [];
Expand Down Expand Up @@ -154,6 +155,20 @@ public function setDebug(bool $s = true): self
return $this;
}

/**
* Set an alternative database ID. The database with ID $databaseId must be configured and working in core Redaxo
* `config.yml`.
*
* @param int $databaseId
*
* @return $this
*/
public function setDatabaseId(int $databaseId): static
{
$this->objparams['db_id'] = $databaseId;
return $this;
}

public function addPostSaveFunction($callback): self
{
$this->postSaveFunctions[] = $callback;
Expand Down Expand Up @@ -294,7 +309,7 @@ public function executeFields(): self
// 2. setValue defaults via sql_object
if ($this->objparams['getdata']) {
if (!$this->objparams['sql_object'] instanceof rex_sql) {
$this->objparams['sql_object'] = rex_sql::factory();
$this->objparams['sql_object'] = rex_sql::factory($this->objparams['db_id']);
$this->objparams['sql_object']->setDebug($this->objparams['debug']);
$this->objparams['sql_object']->setQuery('SELECT * from ' . $this->objparams['main_table'] . ' WHERE ' . $this->objparams['main_where']);
}
Expand Down Expand Up @@ -816,4 +831,21 @@ public function hasWarnings(): bool
$hasWarningMessages = 0 != count($this->objparams['warning_messages']);
return $hasWarnings || $hasWarningMessages;
}

/**
* Return the database configurations from `config.yml`.
*
* @return array<int, array{
* host: string, login: string, password: string, name: string,
* persistent: bool, ssl_key: ?string, ssl_cert: ?string, ssl_ca: ?string
* }>
*/
public static function getDatabaseConfigurations()
{
// Only return entries from the db section, that actually contain real data, not empty stubs.
return array_filter(
rex::getProperty('db'),
fn($dbConfig) => !empty($dbConfig['host']) && !empty($dbConfig['login'])
);
}
}
9 changes: 5 additions & 4 deletions lib/yform/action/create_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ class rex_yform_action_create_table extends rex_yform_action_abstract
public function executeAction(): void
{
$table_name = $this->getElement(2);
$db_id = $this->params['db_id'] ?? 1;
$table_name = str_replace('%TABLE_PREFIX%', rex::getTablePrefix(), $table_name);
$table_exists = false;
$cols = [];

$tables = rex_sql::factory()->getArray('show tables');
$tables = rex_sql::factory($db_id)->getArray('show tables');
foreach ($tables as $table) {
if (current($table) == $table_name) {
$table_exists = true;
Expand All @@ -25,16 +26,16 @@ public function executeAction(): void
}

if (!$table_exists) {
rex_sql::factory()->setQuery('CREATE TABLE `' . $table_name . '` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;');
rex_sql::factory($db_id)->setQuery('CREATE TABLE `' . $table_name . '` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;');
}

foreach (rex_sql::factory()->getArray('show columns from ' . $table_name) as $k => $v) {
foreach (rex_sql::factory($db_id)->getArray('show columns from ' . $table_name) as $k => $v) {
$cols[] = $v['Field'];
}

foreach ($this->params['value_pool']['sql'] as $key => $value) {
if (!in_array($key, $cols)) {
rex_sql::factory()->setQuery('ALTER TABLE `' . $table_name . '` ADD `' . $key . '` TEXT NOT NULL;');
rex_sql::factory($db_id)->setQuery('ALTER TABLE `' . $table_name . '` ADD `' . $key . '` TEXT NOT NULL;');
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions lib/yform/action/db.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class rex_yform_action_db extends rex_yform_action_abstract
{
public function executeAction(): void
{
$sql = rex_sql::factory();
$db_id = $this->params['db_id'] ?? 1;
$sql = rex_sql::factory($db_id);
$sql->setDebug($this->params['debug']);

if (!$main_table = $this->getElement(2)) {
Expand Down Expand Up @@ -56,7 +57,7 @@ public function executeAction(): void
$action = 'update';

if ($this->params['main_id'] <= 0) {
$sql_id = rex_sql::factory();
$sql_id = rex_sql::factory($db_id);
$sql_id->setTable($main_table);
$sql_id->setWhere($where);
$sql_id->select('id');
Expand Down
3 changes: 2 additions & 1 deletion lib/yform/action/db_query.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class rex_yform_action_db_query extends rex_yform_action_abstract
{
public function executeAction(): void
{
$db_id = $this->params['db_id'] ?? 1;
$query = trim($this->getElement(2));
$labels = explode(',', $this->getElement(3));

Expand All @@ -22,7 +23,7 @@ public function executeAction(): void
}

try {
$sql = rex_sql::factory();
$sql = rex_sql::factory($db_id);
$sql->setDebug($this->params['debug']);

$params = [];
Expand Down
3 changes: 2 additions & 1 deletion lib/yform/action/readtable.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ class rex_yform_action_readtable extends rex_yform_action_abstract
{
public function executeAction(): void
{
$db_id = $this->params['db_id'] ?? 1;
if (!isset($this->params['value_pool']['email'][$this->getElement(4)])) {
return;
}
$value = $this->params['value_pool']['email'][$this->getElement(4)];

$gd = rex_sql::factory();
$gd = rex_sql::factory($db_id);
if ($this->params['debug']) {
$gd->setDebug();
}
Expand Down
6 changes: 4 additions & 2 deletions lib/yform/validate/in_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ class rex_yform_validate_in_table extends rex_yform_validate_abstract
{
public function enterObject()
{
$db = rex_sql::factory();
$table = $this->getElement(3);
$db_id = $this->params['db_id'] ?? 1;

$db = rex_sql::factory($db_id);
$db->setDebug($this->params['debug']);

$table = $this->getElement(3);
$labels = $this->getElement(2);
$fields = $this->getElement(4);

Expand Down
3 changes: 2 additions & 1 deletion lib/yform/validate/unique.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class rex_yform_validate_unique extends rex_yform_validate_abstract
{
public function enterObject()
{
$cd = rex_sql::factory();
$db_id = $this->params['db_id'] ?? 1;
$cd = rex_sql::factory($db_id);

$table = $this->params['main_table'];
if ('' != $this->getElement('table')) {
Expand Down
3 changes: 2 additions & 1 deletion lib/yform/value/choice.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ public static function getSearchFilter($params)
private static function createChoiceList($elements)
{
$self = new self();
$db_id = $self->params['db_id'] ?? 1;

$options = [
'choices' => [],
Expand Down Expand Up @@ -324,7 +325,7 @@ private static function createChoiceList($elements)
$choiceList = new rex_yform_choice_list($options);

if (is_string($choicesElement) && 'SELECT' == rex_sql::getQueryType($choicesElement)) {
$sql = rex_sql::factory();
$sql = rex_sql::factory($db_id);
$sql->setDebug($self->getParam('debug'));
$choiceList->createListFromSqlArray(
$sql->getArray($choicesElement),
Expand Down
2 changes: 1 addition & 1 deletion lib/yform/value/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private function addRelation(array &$relations, array $names)
private function getRelationValues(array $relations)
{
$table = rex_yform_manager_table::get($this->params['main_table']);
$sql = rex_sql::factory();
$sql = rex_sql::factory($table->getDatabaseId());
$sql->setDebug($this->params['debug']);

foreach ($relations as $name => $sub) {
Expand Down
2 changes: 1 addition & 1 deletion plugins/manager/fragments/yform/manager/page/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
$hasDataPageFunctions = $this->getVar('hasDataPageFunctions');

/** @var rex_yform_list $list */
$list = rex_yform_list::factory($query, $table->getListAmount());
$list = rex_yform_list::factory($query, $table->getListAmount(), db: $table->getDatabaseId());

$list->addTableAttribute('class', 'table-striped table-hover yform-table-' . rex_string::normalize($this->table->getTableName()));

Expand Down
1 change: 1 addition & 0 deletions plugins/manager/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
->ensurePrimaryIdColumn()
->ensureColumn(new rex_sql_column('status', 'tinyint(1)'))
->ensureColumn(new rex_sql_column('table_name', 'varchar(191)'))
->ensureColumn(new rex_sql_column('db_id', 'tinyint unsigned', false, 1))
->ensureColumn(new rex_sql_column('name', 'varchar(191)'))
->ensureColumn(new rex_sql_column('description', 'text'))
->ensureColumn(new rex_sql_column('list_amount', 'int(11)', false, '50'))
Expand Down
1 change: 1 addition & 0 deletions plugins/manager/lang/de_de.lang
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ yform_manager_table_enter_name = Bitte tragen Sie die Tabellenbezeichnung ein
yform_manager_table_enter_specialchars = Bitte tragen Sie beim Tabellenname nur Kleinbuchstaben und Zahlen ein. Das erste Zeichen muss ein Buchstabe sein
yform_manager_table_exists = Dieser Tabellenname ist bereits vorhanden

yform_manager_database_selection = Datenbank
yform_manager_table_prio = Priorität
yform_manager_table_prio_short = Prio
yform_manager_table_name = Name
Expand Down
1 change: 1 addition & 0 deletions plugins/manager/lang/en_gb.lang
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ yform_manager_table_enter_name = Please enter table name
yform_manager_table_enter_specialchars = Please enter only letters and numbers for the table name. The first character must be a letter
yform_manager_table_exists = This table name already exists

yform_manager_database_selection = Database
yform_manager_table_prio = Priority
yform_manager_table_prio_short = Prio
yform_manager_table_name = Name
Expand Down
1 change: 1 addition & 0 deletions plugins/manager/lang/es_es.lang
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ yform_manager_table_enter_name = Por favor ingrese el nombre de la tabla
yform_manager_table_enter_specialchars = Por favor ingrese solo letras y números para el nombre de la tabla. El primer personaje debe ser una letra
yform_manager_table_exists = Este nombre de tabla ya existe

yform_manager_database_selection = Base de datos
yform_manager_table_prio = Prioridad
yform_manager_table_prio_short = Prio
yform_manager_table_name = Nombre
Expand Down
1 change: 1 addition & 0 deletions plugins/manager/lang/pt_br.lang
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ yform_manager_table_enter_name = Por favor, insira um nome para a tabela
yform_manager_table_enter_specialchars = Por favor, insira somente letras e números no nome da tabela. O primeiro caractere deve ser uma letra.
yform_manager_table_exists = Esse noem já existe.

yform_manager_database_selection = Bankco de dados
yform_manager_table_prio = Prioridade
yform_manager_table_prio_short = Prio
yform_manager_table_name = Nome
Expand Down
1 change: 1 addition & 0 deletions plugins/manager/lang/sv_se.lang
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ yform_manager_table_enter_name = Var god ange tabellnamnet
yform_manager_table_enter_specialchars = Var god ange endast bokstäver och siffror vid tabellnamnet. Första tecknet måste vara en bokstav.
yform_manager_table_exists = Tabellnamnet finns redan

yform_manager_database_selection = Databas
yform_manager_table_prio = Prioritet
yform_manager_table_prio_short = Prio
yform_manager_table_name = Namn
Expand Down
6 changes: 4 additions & 2 deletions plugins/manager/lib/yform/action/manage_db.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ public function executeAction(): void
// ********************************* TABLE A

// $this->params["debug"]= TRUE;
$sql = rex_sql::factory();
$sql->setDebug($this->params['debug']);

$main_table = '';
if ('' != $this->getElement(2)) {
$main_table = $this->getElement(2);
} else {
$main_table = $this->params['main_table'];
}
$db_id = $this->params['db_id'] ?? 1;
$sql = rex_sql::factory($db_id);
$sql->setDebug($this->params['debug']);


if ('' == $main_table) {
$this->params['form_show'] = true;
Expand Down
3 changes: 2 additions & 1 deletion plugins/manager/lib/yform/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,8 @@ public static function checkField($l, $v, $p)
public function createTable($mifix, $data_table, $params = [], $debug = false)
{
// Tabelle erstellen wenn noch nicht vorhanden
$c = rex_sql::factory();
$db_id = rex_yform_manager_table::get($data_table)->getDatabaseId();
$c = rex_sql::factory($db_id);
$c->setDebug($debug);
$c->setQuery('CREATE TABLE IF NOT EXISTS `' . $data_table . '` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;');

Expand Down