Jak přinutit punBB správně zvýrazňovat nepřečtené příspěvky
- 8. Září 2007
- Publikováno v Fóra
- Napište komentář
Fórum PunBB sice používá zvýrazňování témat s nepřečtenými příspěvky. To ale není prakticky použitelné. Jednak proto, že se označují pouze nepřečtená témata a nikoliv i příspěvky. A jednak proto, že označování nepracuje tak, jak by to člověk očekával.
Funguje totiž tak, že se do databáze uloží čas poslední návštěvy uživatele a s tímto časem se pak porovnává čas posledního příspěvku v tématu. Tím se zjístí, která támata se mají zvýraznit. Problém však je, že témata zůstanou zvýrazněná i po přečtení. K odznačení zvýraznění dojde teprve po vypršení určité doby(nastavuje administrátor), kdy se do databázové tabulky uživatele uloží aktuální čas jako čas poslední návštěvy. Po vypršení zmiňované doby dojde tedy k odznačení všech příspěvků, tedy i těch, které si člověk nestihl přečíst.
Řešit se to dá nastavním nesmyslně dlouhé prodlevy. Uživatelé pak mohou označit všechny příspěvky jako přečtené kliknutím na odkaz k tomu určený.
Tento článek rozebírá možnost jak upravit punBB fórum, aby zvýrazňovalo skutečně nepřečtená témata a navíc zvýraznilo i nepřečtené příspěvky v tématu.
Poznámka:
Tato úprava je testována a funkční v punBB fóru verze 1.2.15
Abychom toho dosáhli budeme potřebovat novou databázovou tabulku:
`id` int(10) NOT NULL,
`id_user` int(5) NOT NULL,
`last_visit` int(10) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Pokud používáte prefixy tabulek, tak si skript upravte do požadované podoby.
Dále bude potřeba modifikovat tyto soubory:
index.php - aby se správně označovala fóra
viewforum.php - aby se správně označovala témata
viewtopic.php - aby se také označovaly příspěvky a aby se provedlo odznačení přečteného tématu
misc.php - aby fungoval link pro označení všeho jako přečteného
search.php - aby fungovala funkce "Zobrazit nové příspěvky od poslední návštěvy" a také označení nových příspěvků ve výsledcích vyhledávání
include/function.php - aby v databázi nezůstavalo smetí, kvůli smazaným tématům + jedna pomocná funkce
Popis atributů tabulky notread
id - id nepřečteného tématu (odpovídá topics.id)
id_user - id uživatele, který nemá něco přečteno.
last_visit - časové razítko poslední návštěvy uživatele (pro představu - odpovídá času, kdy uživatel navštívil dané téma naposledy)
Úprava souboru index.php
Za řádek
doplníme příkaz pro zjíštění nepřečtených témat
Tuto pasáž
if (!$pun_user['is_guest'] && $cur_forum['last_post']> $pun_user['last_visit'])
{
$item_status = 'inew';
$icon_text = $lang_common['New icon'];
$icon_type = 'icon inew';
}
nahradíme novou
$r = $db->query("SELECT * FROM ".$db->prefix."notread AS n, ".$db->prefix."topics AS t WHERE n.id=t.id AND n.id_user=".$pun_user['id']." AND t.forum_id=".$cur_forum['fid']);
if ($r->num_rows>0){
$item_status = 'inew';
$icon_text = $lang_common['New icon'];
$icon_type = 'icon inew';
}
Úprava souboru viewforum.php
Tento sql dotaz
$sql = 'SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];
Nahradíme tímto
Před
// If there are topics in this forum.
Vložíme
Tento řádek
nahradíme za
Úprava souboru viewtopic.php
Před
if (!$pun_user['is_guest'])
$result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, s.user_id AS is_subscribed FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
else
$result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0 FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
doplníme
if ($id>0) $r = $db->query("SELECT last_visit FROM ".$db->prefix."notread WHERE id = ".$id." AND id_user = ".$pun_user['id']);
$tmp = $r->fetch_assoc();
$last_visit = $tmp['last_visit'];
Za
if ($cur_post['signature'] != '' && $pun_user['show_sig'] != '0')
{
if (isset($signature_cache[$cur_post['poster_id']]))
$signature = $signature_cache[$cur_post['poster_id']];
else
{
$signature = parse_signature($cur_post['signature']);
$signature_cache[$cur_post['poster_id']] = $signature;
}
}
doplníme
Řádek
upravíme takto
Před
$low_prio = ($db_type == 'mysql') ? 'LOW_PRIORITY ' : '';
$db->query('UPDATE '.$low_prio.$db->prefix.'topics SET num_views=num_views+1 WHERE id='.$id) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
doplníme
$db->query("DELETE FROM ".$db->prefix."notread WHERE id=".$id." AND id_user=".$pun_user['id']);
$db->query('UPDATE '.$db->prefix.'users SET last_visit='.time().' WHERE id='.$pun_user['id']) or error('Unable to update user last visit data', __FILE__, __LINE__, $db->error());
}
Úprava souboru misc.php
Obsluhu akce markread doplníme o řádek:
Úprava souboru include/function.php
Funkci delete_topic doplníme o řádek, který odstraní z databáze záznamy právě mazaných, nepřečtených témat.
Začátek funkce bude tedy vypadat takto:
{
global $db;
//smaze z databaze zaznamy o neprectenosti prave mazaneho topicu
$db->query('DELETE FROM '.$db->prefix.'notread WHERE id='.$topic_id);
Na konec souporu function.php přidáme funkci pro zaznamenání všech nepřečtených témat do databáze
global $db, $pun_config, $pun_user;
if (!$pun_user['is_guest']){
$r = $db->query("SELECT t.id FROM ".$db->prefix."topics AS t, ".$db->prefix."posts AS p WHERE t.last_post> ".$pun_user['last_visit']." AND t.last_post_id=p.id AND p.poster_id != ".$pun_user['id']." AND t.id NOT IN (SELECT id FROM ".$db->prefix."notread WHERE notread.id_user=".$pun_user['id'].")") ;
while($row = $r->fetch_array()){
$db->query("INSERT INTO ".$db->prefix."notread SET id=".$row['id'].", id_user=".$pun_user['id'].", last_visit = ".$pun_user['last_visit']);
}
}
}
Nyní si ještě upravíme styly pro zvýraznění nových příspěvků
Například pro styl cobalt dopíšeme na konec souboru style/imports/Cobalt_cs.css toto
Úprava souboru search.php
V souboru search.php najdeme část podobnou této:
if ($action == 'show_new')
{
if ($pun_user['is_guest'])
message($lang_common['No permission']);
//$result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
$result = $db->query('SELECT t.id FROM '.$db->prefix.'notread AS t WHERE id_user = '.$pun_user['id']) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
$num_hits = $db->num_rows($result);
if (!$num_hits)
message($lang_search['No new posts']);
}
Zakomentovaný SELECT (původní) nahradíme SELECTem, který vybere nepřečtená témata z databáze dle id přihlášeného uživatele.
Pro správné zvýrazňování nepřečtených príspěvků ve výsledcích vyhledávání a v seznamu nepřečtených témat, musíme provést ještě toto:
Část:
$icon = '<div class="icon inew"><div class="nosize">'.$lang_common['New icon'].'</div></div>'."\n";
Nahradit za:
$tmp = $r->fetch_assoc();
$last_visit = $tmp['last_visit'];
if (!$pun_user['is_guest'] && isset($last_visit) && $last_visit <$search_set[$i]['pposted'])
$icon = '<div class="icon inew"><div class="nosize">'.$lang_common['New icon'].'</div></div>'."\n";
Část:
Nahradit za:
if (!$pun_user['is_guest'] && $r->num_rows> 0)
Pokud máte jakékoliv problémy s implementací uvedeného řešení, můžete si napsat o radu do našeho fóra.
Funguje to i ve verzi 1.2.16 ?
Nevím, nezkoušel jsem.
Nam by stacilo i prodlouzit ten timeout administratorem, muzete poradit, kde presne se to da udelat? Diky.
Administratce -> Options -> Time and timeouts -> Visit timeout