FriendsOfREDAXO / adminer

Datenbank-Verwaltung in REDAXO und rex_sql-Code-Generator, ohne dass dafür Login-Daten eingegeben werden müssen.
MIT License
55 stars 1 forks source link

Integration / Verknüpfung mit YForm #37

Closed alxndr-w closed 2 years ago

alxndr-w commented 3 years ago

Wäre klasse, wenn man aus YForm heraus direkt in die passende Adminer-Tabelle springen kann - bspw. bei der Tabellenübersicht oder der Felddefinition. Ich müsste mal prüfen, ob es da einen passenden EP gibt.

Soweit ich weiß hast du @TobiasKrais doch schon einige Datentabellen im Backend manipuliert.

Oder wäre es andernfalls in Ordnung, in YForm in diesem speziellen Fall an entsprechender Stelle zu prüfen, ob Adminer installiert ist und dann einen passenden Link dazu darzustellen?

TobiasKrais commented 3 years ago

Mein Name ist gefallen? Ich komm gerade nicht drauf, was ich gemacht haben soll. Kannst du mir auf die Sprünge helfen?

gharlan commented 3 years ago

Oder wäre es andernfalls in Ordnung, in YForm in diesem speziellen Fall an entsprechender Stelle zu prüfen, ob Adminer installiert ist und dann einen passenden Link dazu darzustellen?

Ich fände das ok. Was meinst du dazu @dergel?

christophboecker commented 3 years ago

Ich hab mir das Feature eingebaut, indem ich den EP YFORM_DATA_LIST_GRID anzapfe:

$pos = stripos( $subject['content']['searchlist'], '<div class="rex-panel-options">' );
if( $pos ) {
    $item = [];
    $item['label'] = '<i class="rex-icon rex-icon-database"></i>';
    $item['url'] = rex_url::backendPage('adminer',['select'=>$ep->getParams()['table']->getTableName()]);
    $item['attributes']['class'][] = 'btn-default';
    $item['attributes']['target'][] = '_blank';
    $fragment = new rex_fragment();
    $fragment->setVar('size', 'xs', false);
    $fragment->setVar('buttons', [$item], false);
    $subject['content']['searchlist'] = substr_replace (
        $subject['content']['searchlist'],
        $fragment->parse('core/buttons/button_group.php'),
        $pos+31,0
    );
}

Nicht schön, aber es funktioniert. Schicker fände ich einen EP YFORM_DATA_LIST_LINKS, den man anzapfen und die Liste der $table_links bearbeiten - hier: ergänzen - könnte. Dann würde sich Adminer per boot.php einklinken. Für die obige Lösung reicht ein PR hier bei Adminer, für die andere halt zwei (YForm, Adminer). Könnte man ja in das nächste YForm-Release nehmen.

Der EP müsste hier eingefügt werden zwischen Zeile 672 und 673: https://github.com/yakamara/redaxo_yform/blob/4407527793c8c668bca175eddb47e647ea4e73b6/plugins/manager/lib/yform/manager.php#L666-L678

alxndr-w commented 3 years ago

Hast du einen Screenshot, wie das aussieht?

christophboecker commented 3 years ago

grafik

christophboecker commented 3 years ago

Ich habe die Idee mal fix als Proof of concept umgesetzt.

Die boot.php des Adminer wäre zu ändern auf

if ( \rex::isBackend() && \rex::getUser() && \rex::getUser()->isAdmin() ) {

    // Handle adminer calls with missing page parameter
    if( isset($_GET['username']) && isset($_GET['db']) ) {
        $page = \rex_be_controller::getCurrentPage();
        if (!$page || $page === (string) (int) $page) {
            \rex_be_controller::setCurrentPage('adminer');
        }
    }

    // Place Adminer-button in YForm-tables.
    \rex_extension::register('YFORM_DATA_LIST_LINKS', function( \rex_extension_point $ep){
        if( !$ep->getParam('popup') ) {
            $item = [
                'label'      => '<i class="rex-icon rex-icon-database" title="Adminer"></i>',
                'url'        => \rex_url::backendPage('adminer',['select'=>$ep->getParams()['table']->getTableName()]),
                'attributes' => [
                    'class'  => ['btn-default'],
                    'target' => ['_blank']
                ]
            ];
            $links = $ep->getSubject();
            array_unshift( $links['table_links'], $item );
            $ep->setSubject($links);
        }
    });
}

Im YForm-Manager würde ich etwas umbauen. Es werden ja zwei Link-Sets erzeugt ($table_links,$field_links). Bisher ist die Abfolge

Was ich ändern würde in

Das ergäbe diesen Code:

['table_links' => $table_links, 'field_links' => $field_links] = rex_extension::registerPoint(
    new rex_extension_point(
        'YFORM_DATA_LIST_LINKS',
        ['table_links' => $table_links, 'field_links' => $field_links],
        ['table' => $this->table, 'popup' => $popup]
    )
);
if (count($table_links) > 0) {
    $fragment = new rex_fragment();
    $fragment->setVar('size', 'xs', false);
    $fragment->setVar('buttons', $table_links, false);
    $panel_options .= '<small class="rex-panel-option-title">' . rex_i18n::msg('yform_table') . '</small> ' . $fragment->parse('core/buttons/button_group.php');
}
if (count($field_links) > 0) {
    $fragment = new rex_fragment();
    $fragment->setVar('size', 'xs', false);
    $fragment->setVar('buttons', $field_links, false);
    $panel_options .= '<small class="rex-panel-option-title">' . rex_i18n::msg('yform_manager_fields') . '</small> ' . $fragment->parse('core/buttons/button_group.php');
}

Den Button deshalb so weil er an das Adminer-Logo erinnert. Hätte dann im Ergebnis den Button da, wo er sachlogisch hingehört: grafik

Wenn gewünscht (@dergel, @gharlan) könnte ich die beiden PR im Laufe der Woche einstellen.

alxndr-w commented 3 years ago

Ah, ich hatte an einen Button hier erwartet: image

Aber der Button da oben ergibt natürlich auch Sinn.

christophboecker commented 3 years ago

Das ist doch auch einfach, Aufruf über die boot.php des Adminers

if( 'yform/manager/table_edit' === \rex_be_controller::getCurrentPage() ) {
    \rex_extension::register('REX_LIST_GET', function( \rex_extension_point $ep){
        $list = $ep->getSubject();
        $page = $list->getParams()['page'] ?: '';
        if( 'yform/manager/table_edit' === $page ){ # sicher ist sicher
            $columnName = md5('Adminer');
            $icon = '<i class="rex-icon rex-icon-database" title="Adminer"></i>';
            $url = \rex_url::backendPage('adminer');
            $list->addColumn( $columnName, '' );
            $list->setColumnLayout($columnName, [
                '<th class="rex-table-icon"><a href="'.$url.'" target="_blank">'.$icon.'</a></th>',
                '<td class="rex-table-icon"><a href="'.$url.'&select=###table_name###" target="_blank">'.$icon.'</a></td>'
            ]);
        }
    });
}

grafik

alxndr-w commented 3 years ago

Also, keine Kritik, sondern nur weitergehende Überlegung. Der Button sollte natürlich nicht für Redakteure, sondern nur für Admins sichtbar sein. Das wäre bei der Table Manager Tabellenansicht der Fall, nicht jedoch bei der Datenansicht.

alxndr-w commented 3 years ago

Man könnte da allerhand anstellen... Direkter Button mit SQL- oder CSV-Export, den sich andere in Slack schon gewünscht haben, wenn man die passenden Get-Parameter an Adminer übergibt. Wechsel zur Datenansicht dort oder eben zur Strukturansicht.

christophboecker commented 3 years ago

Der zweite EP kommt natürlich auch in die boot.php des Adminers und dort in die Berechtigungsabfrage. Somit nur für Admins.

Das ergäbe dann den Basis-Adminer-Button. Wer anderes benötigt kann sich dann ja selber helfen und sich gezielt in die EPs einklinken und weitere Features ermöglichen - hast ja einige Sachen vorgeschlagen. Hilfreich wäre dass Jan den EP YFORM_DATA_LIST_LINK genehmigt und man nicht mehr über den YFORM_DATA_LIST_GRID gehen muss.

alxndr-w commented 3 years ago

YFORM_DATA_LIST_GRID gehen muss, der nur verfügbar ist, wenn man die Suche aktiviert hat.

Ah! Das hatte ich eben nicht verstanden. Tja, nun, ich denke, der EP würde eher angenommen, wenn @dergel ihn nicht einbauen muss...

christophboecker commented 3 years ago

Wieso? Jan muss den EP nur genehmigen. Und den PR mergen. Der Code ist ja fertig und läuft bei mir..

gharlan commented 3 years ago

Also ich hatte @dergel mal gefragt, was er so grundsätzlich von diesen Querverlinkungen hält. Und eigentlich finden wir es beide nicht richtig. Denn eigentlich soll yform ja in sich ein stimmiges System sein, und man soll gerade nicht selbst direkt in der DB rumwerkeln. Zum Beispiel bei den Daten greifen dort ja die Validierungen nicht etc.

Natürlich weiß ich auch, dass es eben doch immer mal nötig sein kann. Aber ob man wirklich es so direkt verknüpfen möchte, womit man ja ein bisschen suggeriert, es wäre legitim, in die adminer-ansicht zu wechseln, und dort weiter zu editieren, ist halt die Frage. Auch wenn die Buttons natürlich nur für Admins sichtbar wären. Bei der Tabellenstrukturverwaltung finde ich es noch verständlicher als bei der Datenverwaltung.

Insgesamt kann ich mich nicht ganz entscheiden, was ich machen würde. Wenn man Verknüpfungen setzt, würde ich es aber nicht übertreiben. Insbesondere bei den Daten würde ich es wohl eher weglassen.

christophboecker commented 3 years ago

Also: Querverlinkung zwischen zwei Addon ist immer problematisch. Bin ich auch kein Freund von. Aber wir reden hier im Grunde über zwei Themen, die nur eher zufällg miteinander verbunden sind.

Das ist m.E. keine Verdrahtung zwischen den Addons. Vielleicht sollten wir das auch mal gedanklich trennen und ich mache ein separates Issue bei YForm auf oder gleich einen PR(?), die nichts mit Adminer zu tun haben. Auch nicht als Use-Case!

gharlan commented 3 years ago

Ja, die YForm-Frage (unabhängig von adminer) lässt sich hier nicht klären. Musst du mit Jan im yform-repo ausklamüsern. ;)

alxndr-w commented 3 years ago

Ich fühle mich als Entwickler bevormundet mit der Perspektive, dass YForm über allem steht. Es gibt allerhand, das YForm nicht abdeckt, aber an Tabellen nun Mal anfallen kann. Da ist ein direkter Eingriff in die Datenbank absolut hilfreich und ein Shortcut wünschenswert.

christophboecker commented 3 years ago

Na jaaa, Alex, solange es den Entwickler/Admin betrifft: da kann man ja auch mit YFORM_DATA_LIST_GRID den Button in den Tabellenheader bauen und der Einbau in die Zeilen der Tabellenübersicht ist eh unabhängig weil via REX_LIST_GET/YFORM_DATA_LIST. Das kann man auch lösen, indem der Code im Projekt-Addon steht. Von daher ist das für mich eher eine kleine Lästigkeit. Und wir reden hier ja nicht über existenziell nötige Sachen, sondern eine Abkürzung beim Aufruf der Tabelle im Adminer. Convinience.

skerbis commented 3 years ago

Für mich ist der Adminer die absolute Notsituation, wenn es mal Probleme gibt oder wenn man mal eine Tabelle migrieren und für AddOns vorbereiten will. Ich sehe es ähnlich wie Gregor und würde auf eine solche Querverlinkung eher verzichten.

alxndr-w commented 3 years ago

Wie führst du SQL-Befehle sonst direkt an der DB aus? @skerbis über das Terminal?

skerbis commented 3 years ago

@alxndr-w es sollte nicht erforderlich sein dies bei laufenden Projekten zu tun, zumindest nicht, wenn die Tabellen durch YForm gemanaged werden. (Das wäre mir zu gefährlich) Adminer nutze ich meist nur zur Erstellung der rex_sql_table Definition oder wenn auf einem Fremdhosting was schief gelaufen ist und mir die direkten Zugangsdaten zur DB-Verwaltung des Hosters (egal ob Terminal oder GUI) fehlen.

christophboecker commented 3 years ago

Der eine so, der andere anders. Ich finde es nett, direkt in die jeweilige Tabelle springen zu können.

Mit YForm 4 (im Github ist es schon drin) kommt der neue EP YFORM_DATA_LIST_LINKS. Den Code, um einen Adminer-Button für Admins an den beschriebenen Stellen einzubauen, kann ich dann gerne in den Tricks bereitstellen. Ob der Code über die boot.php des Adminer-Addons oder aus dem Project-Addon gestartet wird, ist technisch eh egal.

christophboecker commented 3 years ago

Mit der aktuellen Github-Version (bzw. dem nächsten Release) liefe es so:

/**
 *      Adminer-Buttons in YForm-Tabellen einbauen
 */

if( ($user = \rex::getUser()) && $user->isAdmin() && \rex_addon::get('adminer')->isAvailable()) {

    \rex_extension::register('YFORM_DATA_LIST_LINKS', function( \rex_extension_point $ep){
        if( !$ep->getParam('popup') ) {
            $urlAttr = [
                'select'=> $ep->getParams()['table']->getTableName(),
                'username' => '',
                'db' => \rex::getDbConfig(1)->name,
            ];
            $item = [
                'label'      => '<i class="rex-icon rex-icon-database" title="Adminer"></i>',
                'url'        => \rex_url::backendPage('adminer',$urlAttr),
                'attributes' => [
                    'class'  => ['btn-default'],
                    'target' => ['_blank']
                ]
            ];
            $links = $ep->getSubject();
            array_unshift( $links['table_links'], $item );
            $ep->setSubject($links);
        }
    });

    if( 'yform/manager/table_edit' === \rex_be_controller::getCurrentPage() ) {
        \rex_extension::register('REX_LIST_GET', function( \rex_extension_point $ep){
            $list = $ep->getSubject();
            $page = $list->getParams()['page'] ?: '';
            if( 'yform/manager/table_edit' === $page ){ # sicher ist sicher
                $columnName = md5('Adminer');
                $icon = '<i class="rex-icon rex-icon-database"></i>';
                $urlAttr = '&select=###table_name###&username=&db='.rex::getDbConfig(1)->name;
                $url = \rex_url::backendPage('adminer');
                $list->addColumn( $columnName, '' );
                $list->setColumnLayout($columnName, [
                    '<th class="rex-table-icon"><a href="'.$url.'" target="_blank" title="Adminer">'.$icon.'</a></th>',
                    '<td class="rex-table-icon"><a href="'.$url.$urlAttr.'" target="_blank" title="Adminer: ###table_name###">'.$icon.'</a></td>'
                ]);
            }
        });
    }
}
skerbis commented 3 years ago

@christophboecker nach Tricks überführen?

christophboecker commented 3 years ago

Lohnt sich m.E. erst, wenn YForm 4 mit dem neuen EP raus kommt

skerbis commented 2 years ago

@christophboecker ... ich denke es ist so weit 👍🏻

alxndr-w commented 2 years ago

Wenn's in Adminer nicht gewünscht ist, integriere ich das als Option in yform_usability - auch wenn es hier m.E. besser aufgehoben ist.

es sollte nicht erforderlich sein dies bei laufenden Projekten zu tun, zumindest nicht, wenn die Tabellen durch YForm gemanaged werden.

Ich kann dir spontan mehrere Szenarien per Screencast zeigen, in denen das für mich als Entwickler ein legitimer Use Case ist. Gerade auf Live-Seiten, wenn ich mit personenbezogene Daten arbeite, die dort bleiben sollen.

christophboecker commented 2 years ago

https://github.com/FriendsOfREDAXO/tricks/pull/292

skerbis commented 2 years ago

Denn mal close