Ve skupinách na Facebooku se nově zobrazuje (možná ještě ne všem) počet přečtení jednotlivých zpráv. Jak něco takového realizovat na svém webu?
Trivialita, řeknete si: mysql_query("UPDATE article SET reads = reads + 1 WHERE id = $id")
. Toto řešení ale má dva problémy:
V první řadě musíme zamezit vložení do (skrytého) rámu. Toho dosáhneme posláním hlavičky X-Frame-Options: deny
.
Dále se potřebujeme bránit proti CSRF. Abychom to mohli udělat, tak potřebujeme uživatele nějak identifikovat, zbytek článku tedy bude počítat s nastavenými proměnnými $_SESSION["user_id"]
a $_SESSION["csrf_token"]
.
Článek se má označit jako přečtený automaticky, takže se u takto jednoduchého problému kupodivu neobejdeme bez JavaScriptu:
<script type="text/javascript">
jQuery.post('read-article.php?id=<?php echo $id; ?>', {
csrf_token: '<?php echo $_SESSION["csrf_token"]; ?>'
});
</script>
Volání si můžeme ušetřit, pokud při zobrazování zjistíme, že aktuální uživatel už článek dříve četl.
Na straně serveru pak čtenáře uložíme (nad dvojicí cloupců article_id, user_id
je unikátní klíč):
<?php // read-article.php if ($_SESSION["csrf_token"] == $_POST["csrf_token"]) { mysql_query(" INSERT IGNORE INTO article_reads (article_id, user_id) VALUES (" . intval($_GET["id"]) . ", $_SESSION[user_id]) "); } ?>
Pokud je článek delší, tak ho můžeme chtít za přečtený označit až po nějaké době od focusu okna. Pokud si uživatel otevře odkaz do panelu na pozadí (což osobně dělám často), tak se článek jako přečtený zatím neoznačí:
<script type="text/javascript">
jQuery(window).one('focus', function () {
setTimeout(function () {
jQuery.post('read-article.php?id=<?php echo $id; ?>', {
csrf_token: '<?php echo $_SESSION["csrf_token"]; ?>'
});
}, 10000);
});
</script>
Přečtení se dá taky spustit po dojetí na konec článku. K tomu bych nejspíš využil nějaký jQuery plugin.
Diskuse je zrušena z důvodu spamu.