Suchfunktion funktioniert in Verbindung mit Fremdschlüssel nicht #4376

Closed
iCodr8 opened this Issue May 23, 2012 · 17 comments

Comments

Projects
None yet
5 participants

iCodr8 commented May 23, 2012

Die Suchfunktion im Backend funktioniert nicht in Verbindung mit Feldern, die einen Fremdschlüssel haben. Momentan wird der Fremdschlüssel nach der ID gesucht, was natürlich keinen Sinn macht.

iCodr8 commented May 23, 2012

Verwendet wurde Contao 2.11.3

Member

aschempp commented Jul 21, 2012

Dieses Problem ist leider seit jeher in Contao vorhanden und "by Design". Du kannst auch nicht nach einem Datum suchen, denn das wird als Timestamp gespeichert. Ev. verbessert sich das in Contao3?

iCodr8 commented Jul 21, 2012

Das wäre sinnvoll, denn sonst kann man die Suche für solche Felder ja gleich entfernen.

Owner

leofeyer commented Jul 24, 2012

Hab das Ticket der @contao/workgroup-core zugewiesen.

Owner

leofeyer commented Nov 24, 2012

Ergebnis der Besprechung in der AG Core: Bei einer Foreign-Key-Beziehung wie z.B. tl_member.name sollte es möglich sein, nach dem Name des Mitglieds zu suchen.

iCodr8 commented Jul 17, 2013

Und die Sortierung sollte auch funktionieren oder?

iCodr8 commented Jan 22, 2014

Prinzipiell müsste es doch so laufen:

  1. Contao erkennt, das Feld hat einen foreignKey
  2. Contao hängt einen JOIN an das SQL Statement dran
  3. Contao sortiert mit ORDER BY tl_foreigntable.field
  4. Contao sucht mit tl_foreigntable.field=?
Owner

leofeyer commented Apr 16, 2014

Die Umsetzung ist relativ simpel:

diff --git a/system/modules/core/drivers/DC_Table.php b/system/modules/core/drivers/DC_Table.php
index 3a0835e..d831664 100644
--- a/system/modules/core/drivers/DC_Table.php
+++ b/system/modules/core/drivers/DC_Table.php
@@ -4804,13 +4804,21 @@ class DC_Table extends \DataContainer implements \listable, \editable
        // Set the search value from the session
        elseif ($session['search'][$this->strTable]['value'] != '')
        {
+           $fld = $session['search'][$this->strTable]['field'];
+
+           if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$fld]['foreignKey']))
+           {
+               list($t, $f) = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$fld]['foreignKey']);
+               $fld = "(SELECT $f FROM $t WHERE $t.id={$this->strTable}.$fld)";
+           }
+
            if (substr(\Config::get('dbCollation'), -3) == '_ci')
            {
-               $this->procedure[] = "LOWER(CAST(".$session['search'][$this->strTable]['field']." AS CHAR)) REGEXP LOWER(?)";
+               $this->procedure[] = "LOWER(CAST($fld AS CHAR)) REGEXP LOWER(?)";
            }
            else
            {
-               $this->procedure[] = "CAST(".$session['search'][$this->strTable]['field']." AS CHAR) REGEXP ?";
+               $this->procedure[] = "CAST($fld AS CHAR) REGEXP ?";
            }

            $this->values[] = $session['search'][$this->strTable]['value'];

Das Problem daran ist, dass man nach der Änderung nicht mehr nach der eigentlichen, numerischen PID suchen kann. Wie lösen wir das?

@leofeyer leofeyer modified the milestones: 3.4.0, 3.3.0 May 2, 2014

Owner

leofeyer commented Sep 4, 2014

Gibt es dazu keine Ideen oder kann ich das Ticket schließen, weil es doch keiner braucht?

Member

aschempp commented Sep 4, 2014

Naja, ganz einfach, du musst eine OR-Bedingung für beides machen ;)

iCodr8 commented Sep 4, 2014

Wie wäre es mit einem weiteren Parameter?

... => array
(
    ...
    'search' => true, // Suche nach pid
    'searchByForeignKey' => 'tl_member.name', // Suche nach Name
    ...
)

Dadurch könnte man sogar beide Sucharten für ein Feld definieren.


oder die Möglichkeit, dass man dem "search" Parameter einen ForeignKey übergeben kann.

... => array
(
    ...
    'search' => true, // Alles wie bisher
    ...
)


... => array
(
    ...
    'search' => 'tl_member.name', // Suche über den übergebenen Foreign Key
    ...
)
Owner

leofeyer commented Sep 4, 2014

Naja, ganz einfach, du musst eine OR-Bedingung für beides machen ;)

Dann finde ich aber im Zweifel zu viel. Zum Beispiel wenn ich nach Datensätzen mit der PID "2014" suche möchte und Datensätze der verknüpften Tabelle zufällig die Jahreszahl "2014" enthalten.

Member

aschempp commented Sep 4, 2014

Dann liesse es sich nur wie von @iCodr8 lösen. Ich fände das mit 'search' => 'tl_member.name' sehr elegant, denn dann kann ich z.B. ein CONCAT machen und mehr als ein Feld abfragen.

Owner

leofeyer commented Sep 4, 2014

Beide Lösungen gehen meiner Meinung nach in eine falsche Richtung, weil sie eine der Varianten fest vorgeben. Wir bräuchten eher eine Möglichkeit, der Suche zu sagen, dass wir explizit nach der numerischen PID suchen wollen. So etwas wie pid:2014.

Member

Toflar commented Sep 5, 2014

Dann geb ich meinen Senf auch noch dazu :) Ich denke wir wissen alle, dass Suchabfragen beliebig komplex werden können. Der Core bietet die einfachsten paar Suchmöglichkeiten und sollte zusätzlich für Entwickler die Möglichkeit bieten, was eigenes zu bauen. Dazu haben wir definitiv genügen Callbacks und ich bin ehrlich gesagt der Meinung es ist einfacher, wenn man es selbst codet als wenn das DCA noch um 5 eher undurchsichtige Keys erweitert wird.
Es steht ja auch den Entwicklern frei sich zusammen zu tun und sowas wie ne extra_filter-Extension zu bauen.

Wenn wir was machen, dann eher sowas wie den DC_General in den Core bringen, welcher dann nochmal mehr Flexibilität bieten kann.

Owner

leofeyer commented Sep 9, 2014

Implementiert in f080d88. Dadurch neu im Core:

  • Events nach dem Namen des Autors durchsuchen
  • Artikel nach dem Namen des Autors durchsuchen
  • Seiten nach dem Namen des Besitzers durchsuchen
  • Seiten nach dem Namen der besitzenden Gruppe durchsuchen
  • FAQs nach dem Namen des Autors durchsuchen
  • Nachrichten nach dem Namen des Autors durchsuchen

Wie besprochen wurde die Oder-Suche umgesetzt und keine Magic (Stichwort "undurchsichtige Keys") hinzugefügt. Ein extra Feld im DCA braucht es IMHO nicht, da die Verknüpfung ja bereits dynamisch über foreignKey erfolgt.

@leofeyer leofeyer closed this Sep 9, 2014

Wie es aussieht, funktioniert die Suchfunktion nur bei 1:1 Relation (hasOne/belongsTo). Bei 1:n Verknüpfungen scheint die OR Verknüpfung nicht zu funktionieren. Ist meine Beobachtung korrekt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment