Page 1 of 1

plugin freetag - multimode

Posted: Tue Nov 03, 2015 11:12 am
by markus
Hallo,

wenn ich dem Freetag-Plugin über die URL mehrere Tags übergebe, kommen die Ergebnisse in einer OR-Verknüpfung daher. Diese ist nicht danach sortiert, dass zuerst die AND-verknüpften Ergebnisse gelistet werden, was mir am liebsten wäre, sondern es kommen so auch gleich am Anfang viele Ergebnisse, die nur eines der übergebenen Tags enthalten. Da ich mir erhofft hatte, darüber strukturierter Inhalte aufzeigen zu können, bin ich den Code gegangen und habe eine Variable "multimode" gefunden, die sich von "or" auf "and" umstellen ließ. Danach bekomme ich nun nur AND-verknüpfte Ergebnisse angezeigt, was super ist.

Leider bleibt aber der Seiten- und Ergebnis-Zähler unten OR-verknüpft. Was muss ich wo ändern, damit ich auch dort eine AND-Verknüpfung habe? Das finde ich nämlich irgendwie nicht.

Viele Grüße
Markus

Re: plugin freetag - multimode

Posted: Tue Nov 03, 2015 12:54 pm
by garvinhicking
Hi!

Gute Detektivarbeit ;)

Diese Lösung ist jedoch höchst komplex, dafür müsste man im Core etwas patchen. In der include/functions_entries.inc.php befindet sich die Funktion serendipity_gettotalEntries().

Diese zählt die insgesamt gefundenen Einträge und nutzt dafür Variablenteile, die anderswo im Code oder auch Plugins gesetzt werden.

Die Funktion sieht so aus (in der aktuellen github version):

Code: Select all

function serendipity_getTotalEntries() {
    global $serendipity;

    // The unique query condition was built previously in serendipity_fetchEntries()
    if ($serendipity['dbType'] == 'sqlite' || $serendipity['dbType'] == 'sqlite3' || $serendipity['dbType'] == 'pdo-sqlite' || $serendipity['dbType'] == 'sqlite3oo') {
        $querystring  = "SELECT count(e.id) {$serendipity['fullCountQuery']} GROUP BY e.id";
    } else {
        $querystring  = "SELECT count(distinct e.id) {$serendipity['fullCountQuery']}";
    }

    $query =& serendipity_db_query($querystring);

    if (is_array($query) && isset($query[0])) {
        if ($serendipity['dbType'] == 'sqlite' || $serendipity['dbType'] == 'sqlite3' || $serendipity['dbType'] == 'pdo-sqlite' || $serendipity['dbType'] == 'sqlite3oo') {
            return count($query);
        } else {
            return $query[0][0];
        }
    }

    return 0;
}
Dort fehlt im SQL-Teil der "having" Teil, der von der $multimode-Variable gesetzt wird.

Das Problem ist aber, dass der Aufruf dieser Funktion nichts von dem Event weiß, der beim Abrufen der Einträge gesetzt wird.

Man müsste also als erstes an der Stelle, wo die Einträge grundsätzlich geholt werden, diesen "having" Teil abspeichern, das macht man am besten nach folgender Zeile in der serendipity_fetchEntries() Funktion:

Code: Select all

    $serendipity['fullCountQuery'] .="
                    {$cond['joins']}
                    {$cond['and']}";
    $serendipity['havingQuery'] = $cond['having'];
Und dann muss man in der oben angesprochenen serendipity_gettotalEntries darauf zurückgreifen:

Code: Select all

    if ($serendipity['dbType'] == 'sqlite' || $serendipity['dbType'] == 'sqlite3' || $serendipity['dbType'] == 'pdo-sqlite' || $serendipity['dbType'] == 'sqlite3oo') {
        $querystring  = "SELECT count(e.id) {$serendipity['fullCountQuery']} {$serendipity['havingQuery']} GROUP BY e.id";
    } else {
        $querystring  = "SELECT count(distinct e.id) {$serendipity['fullCountQuery']} {$serendipity['havingQuery']} ";
    }
Ob das so klappt kann ich gerade nicht testen, es kann sein dass es unbequeme Seiteneffekte hat, wenn man Einträge ohne Tags versucht abzurufen. Aber evtl bringt Dir das etwas...

Grüße,
Garvin

Re: plugin freetag - multimode

Posted: Wed Nov 04, 2015 7:55 am
by markus
Danke für die ausführliche Antwort! :)

Ich glaube, dann wäre es schlauer, die OR-Verknüpfung beizubehalten, weil mir das zu tief in etwas reingeht, wo ich nicht gern dran rumspielen möchte.

Besteht die Möglichkeit, die Ausgabe der SQL-Verknüpfung so zu sortieren, dass zuerst diejenigen Ergebnisse gelistet werden, die alle angefragten Tags enthalten? Das würde ja die Anzahl nicht verändern, so dass die Zahlen der Paginierung gleich blieben.

Re: plugin freetag - multimode

Posted: Thu Nov 05, 2015 3:59 pm
by garvinhicking
Hi!

Du könntest in der serendipity_event_freetag.php versuchen den Code:

Code: Select all

                            if ($multimode == 'and') {
                                $eventData['having'] = " HAVING count(entrytags.tag) = $total";
                            }
zu ändern in:

Code: Select all

                            if ($multimode == 'and') {
                                $eventData['having'] = " HAVING count(entrytags.tag) = $total";
                            }
                            $eventData['orderby'] = "count(entrytags.tag)";
Das würde dann die Ergebnisse zuerst sortieren bei dem die meisten Tags vorhanden sind, ich glaube das könnte klappen...

Grüße,
Garvin

Re: plugin freetag - multimode

Posted: Fri Nov 06, 2015 10:08 am
by markus
Habe dem noch ein DESC gegönnt, nun geht es.

Danke! :)

Re: plugin freetag - multimode

Posted: Tue Dec 22, 2015 7:36 pm
by Timbalu
Announcement:

Aufgrund dieser Anfrage und Garvins Antworten habe ich mich seinerzeit mal wieder etwas mehr mit dem freetag Plugin beschäftigt. Dies ist nun optional eingebaut.

Leider vergaß ich diese Version mit dieser und weiteren Änderungen zu committen und so kam dann eine weitere tiefe Session im Dezember hinzu, die sich jetzt ihrem vorweihnachtlichen Ende neigt. Somit hat sich eine ganze Menge geändert, da das Plugin auch schon ein paar Jahre auf dem Buckel hatte und immer wieder hier und da geflickt wurde.

Ich fände es beruhigend, wenn jemand dies vorher auf ihrem/seinen (Test?) Blog mit ev. spezieller und/oder ausgiebiger Tag Benutzung einmal probefahren will und ich nicht mit dem eigenen Tunnelblick ein unvorbereitetes Update anstoße.

Ein frohes Fest!