YForm Table-Spalten und Feldtypen ermitteln

Quell-ID: GitHub Discussion #45

Use Case

Die Felddefinitionen einer YForm-Tabelle sollen programmatisch ausgelesen werden, um die Spaltentypen und weitere Metadaten zu erhalten.

Verwendete AddOns

  • YForm

Problemstellung

Für dynamische Ausgaben oder Validierungen benötigt man Informationen über die Feldtypen einer YForm-Tabelle.

Lösung

Über die Klasse rex_yform_manager_table können die Felddefinitionen abgerufen werden:

<?php
$table_name = rex::getTable('mytable');
$table = rex_yform_manager_table::get($table_name);

// Prüfen ob Tabelle existiert
if (!$table) {
    throw new RuntimeException('Tabelle nicht gefunden: ' . $table_name);
}

$columns = $table->getColumns();

// Einzelne Spalte abrufen
$xyzColumn = $columns['xyz'];

// Typ auslesen
echo $xyzColumn['type_name']; // z.B. 'text', 'choice', 'be_link'

Mit Model-Klasse

<?php
// Beispiel mit Geolocation-AddOn
use FriendsOfRedaxo\Geolocation\Mapset;

$table = Mapset::table();

if (!$table) {
    return;
}

$columns = $table->getColumns();
$layerCol = $columns['layer'];

Verfügbare Spalten-Informationen

Eigenschaft Beschreibung
type_name Feldtyp (text, textarea, choice, etc.)
name Feldname
label Beschriftung
db_type Datenbank-Typ (varchar, text, int, etc.)
default Standardwert
attributes Zusätzliche Attribute

Beispiele

Alle Felder einer Tabelle auflisten

<?php
$table = rex_yform_manager_table::get('rex_my_table');

if ($table) {
    foreach ($table->getColumns() as $name => $column) {
        echo $name . ': ' . $column['type_name'] . ' (' . $column['db_type'] . ')' . PHP_EOL;
    }
}

Felder nach Typ filtern

<?php
$table = rex_yform_manager_table::get('rex_my_table');

if (!$table) {
    return;
}

$columns = $table->getColumns();

// Nur Text-Felder
$textFields = array_filter($columns, fn($col) => $col['type_name'] === 'text');

// Nur Relationen
$relationFields = array_filter($columns, fn($col) => 
    in_array($col['type_name'], ['be_manager_relation', 'be_link', 'be_media'])
);

Besserer Ansatz

Helper-Klasse für Table-Metadaten

<?php
class TableMetadata
{
    private rex_yform_manager_table $table;
    
    public function __construct(string $tableName)
    {
        $this->table = rex_yform_manager_table::get($tableName);
        
        if (!$this->table) {
            throw new InvalidArgumentException("Table $tableName not found");
        }
    }
    
    /**
     * Gibt alle Spalten zurück
     */
    public function getColumns(): array
    {
        return $this->table->getColumns();
    }
    
    /**
     * Gibt Spalten eines bestimmten Typs zurück
     */
    public function getColumnsByType(string $type): array
    {
        return array_filter(
            $this->getColumns(),
            fn($col) => $col['type_name'] === $type
        );
    }
    
    /**
     * Prüft ob eine Spalte existiert
     */
    public function hasColumn(string $name): bool
    {
        return isset($this->getColumns()[$name]);
    }
    
    /**
     * Gibt die Such-relevanten Felder zurück (Text-basiert)
     */
    public function getSearchableColumns(): array
    {
        $searchable = ['text', 'textarea', 'choice'];
        return array_filter(
            $this->getColumns(),
            fn($col) => in_array($col['type_name'], $searchable)
        );
    }
    
    /**
     * Gibt alle Relationsfelder zurück
     */
    public function getRelationColumns(): array
    {
        $relationTypes = ['be_manager_relation', 'be_link', 'be_media', 'be_medialist'];
        return array_filter(
            $this->getColumns(),
            fn($col) => in_array($col['type_name'], $relationTypes)
        );
    }
    
    /**
     * Gibt die Datenbank-Typen als Array zurück (für Debugging)
     */
    public function getDbTypes(): array
    {
        $result = [];
        foreach ($this->getColumns() as $name => $column) {
            $result[$name] = $column['db_type'] ?? 'unknown';
        }
        return $result;
    }
}

// Verwendung
$meta = new TableMetadata('rex_products');

// Alle durchsuchbaren Felder
foreach ($meta->getSearchableColumns() as $name => $col) {
    echo "Suchfeld: $name ({$col['label']})\n";
}

// Alle Relationen
foreach ($meta->getRelationColumns() as $name => $col) {
    echo "Relation: $name -> {$col['table']}\n";
}

Für direkte SQL-Abfragen

Wenn die genauen Datenbank-Typen benötigt werden:

<?php
$sql = rex_sql::factory();
$columns = $sql->getArray('SHOW COLUMNS FROM ' . rex::getTable('my_table'));

foreach ($columns as $column) {
    echo $column['Field'] . ': ' . $column['Type'] . PHP_EOL;
}

Hinweis

Die Felddefinitionen über rex_yform_manager_table entsprechen der Konfiguration im Table Manager. Die tatsächlichen Datenbank-Spalten können leicht abweichen. Für exakte Datenbank-Informationen sollte SHOW COLUMNS oder DESCRIBE verwendet werden.