Skip to content
This repository has been archived by the owner on Nov 3, 2023. It is now read-only.

DCA: findInSet + options_callback #1914

Closed
ghost opened this issue Nov 29, 2011 · 6 comments
Closed

DCA: findInSet + options_callback #1914

ghost opened this issue Nov 29, 2011 · 6 comments
Assignees
Labels
Milestone

Comments

@ghost
Copy link

ghost commented Nov 29, 2011

Hallo!

In Erweiterung von http://dev.typolight.org/issues/299 wäre es schön, wenn findInSet auch mit dem Ergebnis eines options_callback arbeiten könnte, statt nur mit hardkodierten options. Momentan wird in dem entsprechenden Code DC_Table.php (Zeile 3459-3470 in 2.8.3) für findInSet nur "options" ausgewertet. Eine Erweiterung im Stil "falls options_callback gesetzt ist, verwende das Ergebnis des Callback-Aufrufs anstatt des options-Felds" erscheint mir mit wenig Aufwand machbar. Wenn findInSet momentan auf true gesetzt wird, aber keine "options"-Angabe für das Feld existiert, provoziert das eine PHP-Fehlermeldung.

Danke.
Stefan

Related issues: #299, #2079

--- Originally created by dl1ely on May 2nd, 2010, at 12:39pm (ID 1914)

@ghost ghost assigned leofeyer Nov 29, 2011
@leofeyer
Copy link
Member

Wie lässt sich die Fehlermeldung reproduizeren? Kannst Du bitte ein konkretes Code-Beispiel für die Erweiterung posten?

--- Originally created on May 2nd, 2010, at 12:54pm

@ghost
Copy link
Author

ghost commented Nov 29, 2011

Klar.

Code aus meiner Turnierpaar-Verwaltung ("Tagebuch einer Extension-Entwicklung" im Forum):

    'fields' => array
    (
        'pid' => array
        (
            'label'                   => &$GLOBALS['TL_LANG']['tl_gw_meldungen']['pid'],
            'inputType'               => 'select',
            'options_callback'        => array('tl_gw_meldungen', 'getActiveCouples'),
            'search'                  => true,
            'sorting'                 => true,
            'eval'                    => array('mandatory'=>true, 'findInSet'=>true)
        ),
...

liefert:

<br /><strong>Warning</strong>: implode() [<a href='function.implode'>function.implode</a>]: Invalid arguments passed in <strong>/home/tscgw/www/tl/system/drivers/DC_Table.php</strong> on line <strong>3468</strong> 
#0 [internal function]: __error(2, 'implode() [<a h...', '/home/tscgw/www...', 3468, Array) 
#1 /home/tscgw/www/tl/system/drivers/DC_Table.php(3468): implode(',', NULL) 
#2 /home/tscgw/www/tl/system/drivers/DC_Table.php(325): DC_Table->listView()
#3 /home/tscgw/www/tl/system/modules/backend/Backend.php(210): DC_Table->showAll()
#4 /home/tscgw/www/tl/typolight/main.php(99): Backend->getBackendModule('gw_meldungen')
#5 /home/tscgw/www/tl/typolight/main.php(295): Main->run()
#6 {main}

Ein Blick an die entsprechende Stelle (DC_Table.php #3468 und davor) zeigt, dass das Argument des implode() nur aus dem Eintrag "options" des entsprechenden Felds erzeugt wird, "options_callback" wird nicht ausgewertet.

Mein options_callback tl_gw_meldungen::getACtiveCouples() liefert mir für die pid in Tabelle A einen zusammengesetzten String aus Tabelle B, mit A.pid = B.id. Da der Optionenwert aus mehreren Feldern der Tabelle B berechnet wird, ist ein "einfacher" foreignKey im DCA nicht ausreichend. Wenn nun in der Listview nach dem Feld "pid" sortiert wird, erfolgt die Sortierung nach dem numerischen Wert der pid. Ich hätte gerne die Sortierung nach den Values aus dem options_callback. Wenn ich es richtig verstehe, erlaubt fieldInSet genau das - aber bisher eben nur für hartkodierte "options".

Ist das ausreichend als Beschreibung?

Danke,
Stefan

--- Originally created by dl1ely on May 2nd, 2010, at 01:13pm

@leofeyer
Copy link
Member

Nein, leider nicht. Ich kann die Situation anhand dieser Informationen hier nicht nachstellen. Zudem fehlt der Code-Vorschlag für die DC_Table.php. Wie genau sieht die Callback-Funktion aus? Und wie sehen die Tabellen aus?

--- Originally created on May 2nd, 2010, at 01:27pm

@ghost
Copy link
Author

ghost commented Nov 29, 2011

OK...Irgendwie finde ich, dass das "Problem" im Code von DC_Table.php deutlich sichtbar ist, aber so ist das ja immer mit subjektiver Sichtweise ;-).

Unter http://dl.dropbox.com/u/804662/gw_turnierpaare_20100501.zip gibt es das ZIP meiner Extension, bitte im Modules-Verzeichnis auspacken, dann bitte in gw_turnierpaare/dca/tl_gw_meldungen.php in Zeile 122 "'findInSet' => false" in "'findInSet' => true" ändern.

Dann tritt der Fehler beim Aufruf des Backendmoduls "Paarverwaltung->Meldungen" auf. Der options_callback ist genau in derselben Datei definiert, die Tabellenstrukturen der beiden beteiligten Tabellen findest du im database.sql.

Einen konkreten Codevorschlag für DC_Table.php habe ich nicht zur Hand, muss mich da erst reindenken. Ich dachte, Featurewünsche könnten vielleicht auch ohne konkrete Implementation geäußert werden ;-). Ich weiss nicht genau, wie der options_callback sicher aufgerufen werden muss.

In Pseudocode:

Zeile 3461 entfernen, stattdessen dort:
Falls "options_callback" gesetzt:
   $keys = Ergebnis von Aufruf "options_callback"
Sonst
   $keys = "options"

Rest kann IMHO so bleiben.

Gerade doch mal eben einen Codevorschlag gebastelt...Statt Zeile 3461 folgendes einfügen:

                    // Load options callback
                if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options_callback']) && 

![]($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'])
                {
                    $strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options_callback'][0];
                    $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options_callback'][1];

                    $this->import($strClass);
                    $keys = $this->$strClass->$strMethod($this);
                }
                else
                {
                      $keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options'];
          }

Macht das, was ich will: Group-Header in List View werden nach dem value statt dem key sortiert, wenn fieldInSet=true ist, und ein options_callback verwendet wird.

Nochmal der Code mit mehr Context, ab Zeile 3459:

                if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['eval']['findInSet'])
                {
                    // Load options callback
                if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options_callback']) && )$GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['reference'])
                {
                    $strClass = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options_callback'][0];
                    $strMethod = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options_callback'][1];

                    $this->import($strClass);
                    $keys = $this->$strClass->$strMethod($this);
                }
                else
                {
                      $keys = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$v]['options'];
          }

                    if (array_is_assoc($keys))
                    {
                        $keys = array_keys($keys);
                    }

                    $orderBy[$k] = "FIND_IN_SET(" . $v . ", '" . implode(',', $keys) . "')";
                }

Stefan

--- Originally created by dl1ely on May 2nd, 2010, at 01:47pm

@leofeyer
Copy link
Member

Implementiert in 79b3a54.

--- Originally created on June 3rd, 2010, at 05:00pm

@leofeyer
Copy link
Member

--- Originally completed on June 3rd, 2010, at 05:00pm

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

1 participant