Problema con l'ordine dei topic (Gdrcd5.1)
Problema con l'ordine dei topic (Gdrcd5.1) postato il 20/07/2012 15:39:10 nel forum programmazione, open source e hosting
Salve a tutti!
Ho notato che la bacheca del gdrcd5.1 non ordina bene le discussioni in ordine cronologico.
In pratica, se una persona risponde ad una discussione vecchia, questa discussione non viene riportata in cima, anche se risulta essere l'unica discussione attiva.
Per farvi capire meglio il problema, mi aiutero con la seguente immagine:
Come potete notare dalle date cerchiate in rosso, la discussione "2° Discussione" è nata dopo la discussione "1° Discussione". Però, non è la discussione in cui c'è stato l'intervento più recente: dalle date cerchiate in blu potrete notare che la discussione "1° Discussione" ha avuto l'ultimo intervento. Ed è qui che sorge il problema: se si risponde ad una vecchia discussione, questa non sale in cima.
Per quanto riguarda il forum ancora non ho modificato nulla, ogni file è identico e preciso a quello presente nella versione base e non modificata di gdrcd advanced. Ho provato a cercare le cause di questo motivo nel file forum.inc.php, ma non ne sono venuto a capo, non riesco a capire dov'è il problema. Qualsiasi tipo d'aiuto è ben accetto. Grazie per l'attenzione!
Pagine → 1
20/07/2012 17:19:23
eheh, i thread in gdrcd non sono ordinati per ultima risposta, sono ordinati per data di creazione, e da questo punto di vista funziona perfettamente.
Se vuoi fare in modo che vengano ordinati per ultima risposta devi aggiungere un campo nella tabella messaggioaraldo che tenga in memoria la data dell'ultimo post del thread in questione e ordinare in base a quella. Ogni volta che un nuovo post viene messo in un thread dovrai modificare il nuovo campo nel record del thread; e stai attento a gestire bene cosa deve accadere quando cancelli un post!
20/07/2012 18:07:17
leoblacksoul ha scritto: eheh, i thread in gdrcd non sono ordinati per ultima risposta, sono ordinati per data di creazione, e da questo punto di vista funziona perfettamente.
Grazie per aver risposto! Hai ragione, ora capisco perché funzionano così.
Però fammi capire meglio... Un campo che registra la data di creazione ogni messaggio esiste già, ma creando un altro campo che registra la data di creazione dell'ultimo messaggio del thread, e regolando i thread in ordine cronologico e riferiti a questo nuovo campo, dovrebbe funzionare. Però, questo nuovo campo dovrebbe registrare la data dell'ultima risposta al thread solo nei "messaggi padre", cioè nei messaggi iniziale del thread. È così?
20/07/2012 21:42:19
esatto. memorizzarlo per i messaggi non-padre non ha nessuna utilità
22/07/2012 20:31:03
È davvero una bella gatta da pelare, allora.
Ho creato un nuovo campo identico al campo "data_messaggio" (che è il campo che registra la data di creazione del messaggio) e l'ho chiamato "data_riferimento". Però non so come fare per registrare la data solo nei messaggi iniziali, e non ho idea di come fare per aggiornare questa data ogni volta che viene aggiunto un nuovo messaggio alla discussione.
Spulciando il codice del file "forum.inc.php", ho notato che dalla riga 157 (dove comincia la parte relativa alla nuova creazione di messaggi e topic) il titolo viene registrato solo se il messaggio è un messaggio iniziale, quindi volevo realizzare qualcosa di simile anche per la data di riferimento, ma non ci sono riuscito.
Sto brancolando nel buio, e da solo non ne riesco a venire a capo... Non so neanche se sto agendo nella parte corretta del file. Chi mi può dare una mano?
22/07/2012 22:06:49 e modificato da leoblacksoul il 22/07/2012 22:10:45
non andare così in fondo...il tuo problema risolve già alla riga 16 del file forum.inc.php:
gdrcd_query("INSERT INTO messaggioaraldo (id_messaggio_padre, id_araldo, titolo, messaggio, autore, data_messaggio ) VALUES (".gdrcd_filter('num',$_POST['padre']).", ".gdrcd_filter('num',$_POST['araldo']).", '".gdrcd_filter('in',$_POST['titolo'])."', '".gdrcd_filter('in',$_POST['messaggio'])."', '".gdrcd_filter('in',$_SESSION['login'])."', NOW())");
Questa è la query di inserimento di un messaggio nel forum. Bene facciamo qualche controllo sulla variabile $_POST['padre'] e il gioco dovrebbe essere molto semplice:
$query="INSERT INTO messaggioaraldo (id_messaggio_padre, id_araldo, titolo, messaggio, autore, data_messaggio,data_riferimento ) VALUES (".gdrcd_filter('num',$_POST['padre']).", ".gdrcd_filter('num',$_POST['araldo']).", '".gdrcd_filter('in',$_POST['titolo'])."', '".gdrcd_filter('in',$_POST['messaggio'])."', '".gdrcd_filter('in',$_SESSION['login'])."', NOW()";
if($_POST['padre']==-1){//Nuovo thread
$query.=', NOW()';
}
else{//Post Normale
$query.=', NULL';
//Già che ci siamo facciamo qui l'aggiornamento del messaggio padre
gdrcd_query("UPDATE messaggioaraldo SET data_riferimento=NOW() WHERE id_messaggio_padre=-1 AND id_messaggio=".$_POST['padre']);
}
$query.=")";
gdrcd_query($query);//Inserimento messaggio
Questo per quanto riguarda l'inserimento. Per la modifica di un post non dovrebbe esserci niente da fare. C'è invece da lavorare sul caso della cancellazione:
Alla riga 111 finiscono i casi di cancellazione vera a propria, visto che noi non vogliamo pasticciare troppo in quel codice facciamo un paio di query subito dopo quel pezzo:
$max_data=gdrcd_query("SELECT MAX(data_messaggio) AS data FROM messaggioaraldo WHERE id_messaggio_padre=".gdrcd_filter('num',$_REQUEST['padre']));
gdrcd_query("UPDATE messaggioaraldo SET data_riferimento=".$max_data['data']." WHERE id_messaggio_padre=-1 AND id_messaggio=".gdrcd_filter('num',$_REQUEST['padre']));
Dovrebbe andare, anche se non l'ho testato.
P.S.: non ho tenuto conto in questo codice della patch sicurezza che è stata pubblicata per correggere le voragini di sicurezza del forum di gdrcd. Spero vivamente che gli evidenti problemi siano stati corretti in quella patch...e quindi nel caso che abbiate installato quella patch forse questo codice potrebbe non andare. Boh non so....non oh letto la patch sicurezza.
22/07/2012 22:27:08 e modificato da dyrr il 22/07/2012 22:28:53
In teoria si potrebbe fare il tutto anche senza aggiungere un nuovo campo alla tabella semplicemente modificando la query che gestisce il recupero dei topic
la query in questione originaria è questa, circa a riga 490-500 di forum.inc.php.
"SELECT id_messaggio, titolo, autore, data_messaggio, importante, chiuso
FROM messaggioaraldo
WHERE id_messaggio_padre = -1 AND id_araldo = ".gdrcd_filter('num',$_REQUEST['what'])."
ORDER BY importante DESC, data_messaggio DESC LIMIT ".$pagebegin.", ".$pageend.""
dico circa perchè avendo modificato un paio di righe del codice di quella pagina non ricordo la riga esatta ma l'intervallo di irghe è quelle.
volendo far eil tutto modificando solo la query la quest in questione otrebbe diventare:
"SELECT N.id_messaggio, N.titolo, N.autore, N.data_messaggio, N.importante, N.chiuso, N.id_messaggio_padre, COALESCE( U.prova, N.data_messaggio ) AS ultimo_messaggio
FROM messaggioaraldo AS N
LEFT JOIN (
SELECT MAX( data_messaggio ) AS prova, id_messaggio_padre
FROM messaggioaraldo
WHERE id_messaggio_padre <> -1
GROUP BY id_messaggio_padre
) AS U ON N.id_messaggio = U.id_messaggio_padre
WHERE N.id_messaggio_padre = -1
AND N.id_araldo =".gdrcd_filter('num',$_REQUEST['what'])."
ORDER BY N.importante DESC , ultimo_messaggio DESC , N.data_messaggio DESC
LIMIT ".$pagebegin.", ".$pageend.""
In pratica la subquery:
SELECT MAX( data_messaggio ) AS prova, id_messaggio_padre
FROM messaggioaraldo
WHERE id_messaggio_padre <> -1
GROUP BY id_messaggio_padre
recupera la data dell'ultima risposta ad ogni topic usando id_messaggio_padre come raggruppatore. i risultati di questa "tebella" vengono associati tramite una LEFT JOIN all'a query principale associandola in questo modo:
AS U ON N.id_messaggio = U.id_messaggio_padre
in questo modo il campo:
COALESCE( U.prova, N.data_messaggio ) AS ultimo_messaggio
avrà l'ultima risposta nel caso il topic avesse una risposta o la data del topic nel caso non avesse avuto una risposta e quindi ilc ampo fosse risultato null per mancanza della join.
a questo punto l'order:
ORDER BY N.importante DESC , ultimo_messaggio DESC , N.data_messaggio DESC
ordina i messaggi per importanza e ultimo messaggio.
Ho provato a testare la query e funziona e dovrebbe essere anche abbastanza performante.
Fatemi sapere se può essere stata d'aiuto come idea
23/07/2012 13:20:48
Vi ringrazio moltissimo! Ho provato entrambe le soluzioni, e funzionano perfettamente sia sulla versione patchata che su quella non patchata del file forum.inc.php
La soluzione di Dyrr ci ho messo un po' a capirla; ho dovuto studiarla un po' prima di capire come funzionasse, perché non conoscevo la funzione COALISCE e non capivo che diavolo fosse. La soluzione di Leoblacksoul, invece l'avevo abbandonata perché non riuscivo a farci nulla, dalla riga 16 ero riuscito solo a creare al massimo un campo "doppione" di data_messaggio.
C'è però un'ultima cosa, che completerà la bacheca del gdrcd5.1 rendendolo un vero e proprio forum, su cui chiedo ancora una volta aiuto.
Studiando queste due soluzioni ho trovato il modo per sperimentare un piccolo script che segni quante volte è stata aperta la discussione, ma lo devo ancora perfezionare.
In pratica ho creato un nuovo campo nel database che ho chiamato "letto" (tipo: int(8), predefinito: 0), ed ho aggiunto il seguente script alla riga 540 (dove parte l'elenco delle discussioni):
<?php gdrcd_query("UPDATE messaggioaraldo SET letto = letto + '1' WHERE id_messaggio = ".gdrcd_filter('out',$row['id_messaggio']).""); ?>
In questo modo, il campo "letto" viene aggiornato... Ma purtroppo non aggiorna solo il topic aperto, ma tutti i topic presenti nella relativa bacheca.
Come posso fare per aggiornare solo il topic che viene aperto?
23/07/2012 14:04:11
Secondo me è sbagliato il punto dove inserisci la query. dovresti inserire una query simile intorno a riga 240 dove visualizza non l'elenco dei topic ma dei messaggi del topic.
Io ho provato con una simile query:
<?php /*Visualizzazione topic*/
if($_REQUEST['op']=='read')
{
$query = "UPDATE messaggioaraldo SET letto = letto + 1 WHERE messaggioaraldo.id_messaggio_padre = ".gdrcd_filter('num',$_REQUEST['what'])." OR messaggioaraldo.id_messaggio = ".gdrcd_filter('num',$_REQUEST['what'])."";
gdrcd_query($query);
e funziona perfettamente.
Volendo andrebbe fatto prima un controllo dell'esistenza del topic di cui si vuole incrementare il numero di letture facendo una query di select con le tesse condizioni nel where e facendo l'update dolo se il numero di righe risultanti è maggiore di 1
23/07/2012 22:25:14
dyrr ha scritto: Secondo me è sbagliato il punto dove inserisci la query. dovresti inserire una query simile intorno a riga 240 dove visualizza non l'elenco dei topic ma dei messaggi del topic.
Io ho provato con una simile query:
<?php /*Visualizzazione topic*/
if($_REQUEST['op']=='read')
{
$query = "UPDATE messaggioaraldo SET letto = letto + 1 WHERE messaggioaraldo.id_messaggio_padre = ".gdrcd_filter('num',$_REQUEST['what'])." OR messaggioaraldo.id_messaggio = ".gdrcd_filter('num',$_REQUEST['what'])."";
gdrcd_query($query);
e funziona perfettamente.
Volendo andrebbe fatto prima un controllo dell'esistenza del topic di cui si vuole incrementare il numero di letture facendo una query di select con le tesse condizioni nel where e facendo l'update dolo se il numero di righe risultanti è maggiore di 1
Confermo, funziona perfettamente. Con quest'ultima modifica, aggiungendo anche la patch di leoblacksoul che inserisce il sistema per quotare, si può creare un forum molto completo. Grazie ancora ad entrambi!
10/05/2018 12:19:51 e modificato da kyuren il 10/05/2018 12:21:40
Innanzitutto scusate se necroposto questo topic vecchissimo, ma sto cercando di applicare questa soluzione alla versione 5.4.
L'obiettivo è quello di ottenere l'ordinamento dei topic delle bacheche in base all'ultima risposta postata, e non la data di pubblicazione originaria del topic. Come avviene solitamente nei forum, insomma.
Ho cercato di adattare la soluzione di Dyrr:
"SELECT N.id_messaggio, N.titolo, N.autore, N.data_messaggio, N.importante, N.chiuso, N.id_messaggio_padre, COALESCE( U.prova, N.data_messaggio ) AS ultimo_messaggio
FROM messaggioaraldo AS N
LEFT JOIN (
SELECT MAX( data_messaggio ) AS prova, id_messaggio_padre
FROM messaggioaraldo
WHERE id_messaggio_padre <> -1
GROUP BY id_messaggio_padre
) AS U ON N.id_messaggio = U.id_messaggio_padre
WHERE N.id_messaggio_padre = -1
AND N.id_araldo =".gdrcd_filter('num',$_REQUEST['what'])."
ORDER BY N.importante DESC , ultimo_messaggio DESC , N.data_messaggio DESC
LIMIT ".$pagebegin.", ".$pageend.""
alla query della riga 748 del GDRCD 5.4 vanilla ( https://github.com/GDRCD/GDRCD/blob/1873f4e2eb75f538fe0ad3f09c1981877fdc34ee/pages/forum.inc.php#L748 ↗ ) ... senza ottenere risultati.
Pur usando la funzione cerca non ho trovato soluzioni più recenti per la versione GDRCD 5.4... se qualcuno ne linkasse oppure offrisse una dritta gliene sarei molto grata y.y
Discussione seguita da
Pagine → 1
Rispondi alla Discussione Segui Discussione Inoltra Discussione Forum Programmazione, Open Source e Hosting Elenco Forum
Articoli, Interviste e altre Risorse!
RAID Shadow Legends ↗
Seconda Era ↗
War Thunder ↗
New Orleans ↗
Enlisted ↗
World of the Sea Battle ↗
Sea of Conquest ↗
World of Tanks ↗