Skip to content

Commit

Permalink
Make the table manager forms aware of db_id
Browse files Browse the repository at this point in the history
Editing and migrating tables make use of db_id.
  • Loading branch information
dgrothaus-mc committed Apr 10, 2024
1 parent 46797c4 commit 1d7d4e6
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 11 deletions.
17 changes: 17 additions & 0 deletions lib/yform.php
Original file line number Diff line number Diff line change
Expand Up @@ -831,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'])
);
}
}
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
13 changes: 8 additions & 5 deletions plugins/manager/lib/yform/manager/table/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static function setTable(array $table, array $table_fields = []): ?rex_yf
$table_insert->setDebug(self::$debug);
$table_insert->setTable(rex_yform_manager_table::table());
$table_insert->setValue('table_name', $table_name);
$table_insert->setValue('db_id', $table['db_id'] ?? 1);

if (!isset($table['name']) || '' == $table['name']) {
$table['name'] = $table['table_name'];
Expand Down Expand Up @@ -245,9 +246,9 @@ public static function removeTablefield(string $table_name, string $field_name):
/**
* @throws rex_sql_exception
*/
public static function migrateTable(string $table_name, bool $schema_overwrite = false): void
public static function migrateTable(string $table_name, bool $schema_overwrite = false, int $db_id = 1): void
{
$columns = rex_sql::showColumns($table_name);
$columns = rex_sql::showColumns($table_name, $db_id);

if (0 == count($columns)) {
throw new Exception('`' . $table_name . '` does not exists or no fields available');
Expand All @@ -257,6 +258,7 @@ public static function migrateTable(string $table_name, bool $schema_overwrite =
'table_name' => $table_name,
'status' => 1,
'schema_overwrite' => $schema_overwrite ? 1 : 0,
'db_id' => $db_id,
];

$error = true;
Expand Down Expand Up @@ -393,7 +395,8 @@ public static function migrateField(string $table_name, array $column): array

case 'tinyint':
if (1 == $column['length']) {
$sql = rex_sql::factory();
$db_id = rex_yform_manager_table::get($table_name)->getDatabaseId();
$sql = rex_sql::factory($db_id);
$sql->setQuery('SELECT * FROM ' . $sql->escapeIdentifier($table_name) . ' WHERE ' . $sql->escapeIdentifier($column['name']) . ' NOT IN (0, 1) LIMIT 1');
if (!$sql->getRows()) {
$fields[] = [
Expand Down Expand Up @@ -562,7 +565,7 @@ public static function generateTableAndFields(rex_yform_manager_table $table, bo
return;
}

$c = rex_sql::factory();
$c = rex_sql::factory($table->getDatabaseId());
$c->setDebug(self::$debug);
$c->setQuery('CREATE TABLE IF NOT EXISTS `' . $table->getTableName() . '` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;');

Expand All @@ -573,7 +576,7 @@ public static function generateTableAndFields(rex_yform_manager_table $table, bo
// remember fields, create and in case delete
$savedColumns = $table->getColumns();

$EnsureTable = rex_sql_table::get($table->getTableName());
$EnsureTable = rex_sql_table::get($table->getTableName(), $table->getDatabaseId());

$EnsureTable
->ensurePrimaryIdColumn();
Expand Down
44 changes: 44 additions & 0 deletions plugins/manager/pages/table_edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,46 @@
* @author <a href="http://www.yakamara.de">www.yakamara.de</a>
*/

/**
* Add a database selection choice to $form if $fieldEnabled is true, show the configured database from $table by
* adding a hidden and a show value field to $form if $fieldEnabled is false.
*
* @param rex_yform $form Form to add the select field to.
* @param array<int, array{
* host: string, login: string, password: string, name: string,
* persistent: bool, ssl_key: ?string, ssl_cert: ?string, ssl_ca: ?string
* } $dbConfigs Array with DB configurations from rex_config
* @param bool $fieldEnabled [optional] Defaults to true. Set false to disable the select
* field.
* @param rex_yform_manager_table|null $table [optional] Defaults to null. Pass the table object, when
* $fieldEnabled is set to false
*
* @return void
*/
function databaseSelectionChoiceOrShow(rex_yform $form, array $dbConfigs, bool $fieldEnabled = true, ?rex_yform_manager_table $table = null): void
{
$databaseChoices = [];
foreach ($dbConfigs as $dbId => $dbConfig) {
$databaseChoices[$dbId] = "DB {$dbId}: Host »{$dbConfig['host']}«";
}

if (true !== $fieldEnabled) {
$form->setHiddenField('db_id', $table->getDatabaseId());
$form->setValueField('showvalue', [
'db_id',
rex_i18n::msg('yform_manager_database_selection'),
1,
$databaseChoices[$table->getDatabaseId()],
]);
} else {
$form->setValueField('choice', [
'name' => 'db_id',
'label' => rex_i18n::msg('yform_manager_database_selection'),
'choices' => $databaseChoices,
]);
}
}

echo rex_view::title(rex_i18n::msg('yform'));
$_csrf_key = 'yform_table_edit';

Expand Down Expand Up @@ -66,6 +106,7 @@
}
} elseif (('add' == $func || 'edit' == $func) && rex::getUser()->isAdmin()) {
$table = null;
$dbConfigs = rex_yform::getDatabaseConfigurations();
if ('edit' == $func) {
$table = rex_yform_manager_table::getById($table_id);
if (!$table) {
Expand All @@ -90,6 +131,9 @@
$yform->setValueField('html', ['html' => '<div class="row"><div class="col-md-6">']);
$yform->setValueField('html', ['html' => '<label>' . rex_i18n::msg('yform_manager_table_basic_info') . '</label>']);
$yform->setValueField('checkbox', ['status', rex_i18n::msg('yform_tbl_active')]);
if (count($dbConfigs) > 1) {
databaseSelectionChoiceOrShow($yform, $dbConfigs, 'add' === $func, $table);
}
$yform->setValueField('prio', ['prio', rex_i18n::msg('yform_manager_table_prio'), 'name']);

switch ($func) {
Expand Down
41 changes: 35 additions & 6 deletions plugins/manager/pages/table_migrate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,72 @@

$page = rex_request('page', 'string', '');

$available_tables = rex_sql::factory()->getTablesAndViews();
$dbConfigs = rex_yform::getDatabaseConfigurations();
/** @var array<int,array{db: int, table: string}> $available_tables */
$available_tables = [];
foreach ($dbConfigs as $dbId => $dbConfig) {
$available_tables = array_merge_recursive(
$available_tables,
array_map(
fn($tableName) => [
'db' => $dbId,
'table' => $tableName,
],
rex_sql::factory($dbId)->getTablesAndViews()
)
);
}

$yform_tables = [];
/** @var array<int,array{db: int, table: string}> $missing_tables */
$missing_tables = [];

foreach (rex_yform_manager_table::getAll() as $g_table) {
$yform_tables[] = $g_table->getTableName();
}

foreach ($available_tables as $a_table) {
if (!in_array($a_table, $yform_tables)) {
$missing_tables[$a_table] = $a_table;
if (!in_array($a_table['table'], $yform_tables)) {
$missing_tables[$a_table['table']] = $a_table;
}
}
$missingTableChoices = [];
$doPrefixDb = count($dbConfigs) > 1;
foreach ($missing_tables as $missingTable) {
$missingTableChoices[$missingTable['table']] = $doPrefixDb
? "DB{$missingTable['db']}: {$missingTable['table']}"
: $missingTable['table'];
}
asort($missingTableChoices);

$yform = new rex_yform();
$yform->setObjectparams('form_showformafterupdate', 1);
$yform->setObjectparams('form_name', $_csrf_key);
$yform->setHiddenField('page', $page);
$yform->setValueField('choice', ['name' => 'table_name', 'label' => rex_i18n::msg('yform_table'), 'choices' => $missing_tables]);
$yform->setValueField('choice', ['name' => 'table_name', 'label' => rex_i18n::msg('yform_table'), 'choices' => $missingTableChoices]);
$yform->setValueField('checkbox', ['schema_overwrite', rex_i18n::msg('yform_manager_table_schema_overwrite')]);
$form = $yform->getForm();

if ($yform->objparams['actions_executed']) {
$table_name = (string) $yform->objparams['value_pool']['sql']['table_name'];
$schema_overwrite = (int) $yform->objparams['value_pool']['sql']['schema_overwrite'];
$selectedTable = array_filter($missing_tables, fn($missingTable) => $missingTable['table'] === $table_name);
$databaseId = array_shift($selectedTable)['db'] ?? 1;

try {
rex_yform_manager_table_api::migrateTable($table_name, (0 == $schema_overwrite) ? false : true); // with convert id / auto_increment finder
rex_yform_manager_table_api::migrateTable(
$table_name,
(0 == $schema_overwrite) ? false : true, // with convert id / auto_increment finder
$databaseId
);
echo rex_view::success(rex_i18n::msg('yform_manager_table_migrated_success'));

unset($missing_tables[$table_name]);

$yform = new rex_yform();
$yform->setObjectparams('form_showformafterupdate', 1);
$yform->setHiddenField('page', $page);
$yform->setValueField('choice', ['name' => 'table_name', 'label' => rex_i18n::msg('yform_table'), 'choices' => $missing_tables]);
$yform->setValueField('choice', ['name' => 'table_name', 'label' => rex_i18n::msg('yform_table'), 'choices' => $missingTableChoices]);
$yform->setValueField('checkbox', ['schema_overwrite', rex_i18n::msg('yform_manager_table_schema_overwrite')]);
$form = $yform->getForm();
} catch (Exception $e) {
Expand Down

0 comments on commit 1d7d4e6

Please sign in to comment.