Statistika přístupů v PHP – kalendář
Seriál o statistice přístupů se pomalu blíží ke konci. V dnešním pokračování si povíme, jak vytvořit kalendář, na kterém si můžeme zvolit období, pro které se zpracuje statistika. Věřím, že se vám kalendář bude hodit i v jiných aplikacích, a proto si ho již dnes budete moci stáhnout.
Nebudu se příliš rozepisovat o tom, jak bude kalendář vypadat, mnohem lepší bude ukázka v podobě obrázku a možnost prohlédnout si kalendář v ukázkové verzi statistiky přístupů.
Pro přechod mezi jednotlivými měsíci budeme používat proměnné $month a $year. Jestliže však pomocí odkazu přecházíme z prosince na leden (následujícího roku) a naopak, máme v proměnných $month a $year nekorektní hodnoty (v $month je 13 resp. 0 a $year zůstává stejné). O převod na správné hodnoty se postará funkce Date() v kombinaci s funkcí MkTime(), která přijímá i nekorektně zadané datum.
if(!IsSet($month)) $month = Date("m");
if(!IsSet($year)) $year = Date("Y");
// převod na korektní hodnoty
$year = Date("Y", MkTime(0,0,0, $month, 1, $year));
$month = Date("m", MkTime(0,0,0, $month, 1, $year));
Pomocí znaku "t" použitého ve funkci Date() získáme počet dnů v daném měsíci. Abychom každé datum mohli v další části skriptu zapsat do správného řádku a sloupečku, přiřadíme nyní ke každému dni jeho číslo v týdnu (1 = pondělí, 2 = úterý, ..., 7 = neděle). Protože znak "w" použitý ve funkci Date() přiřazuje k neděli 0, musíme pomocí podmínky změnit tuto 0 na 7. Do proměnné $first uložíme číslo prvního dne v měsíci.
// ke každému dni přiřadí jeho číslo v týdnu (1 = pondělí, ...)
for($i=1;$i<=$count_days;$i++):
$date[$i] = Date("w", MkTime(0,0,0,$month,$i,$year));
if($date[$i]==0) $date[$i] = 7;
endfor;
$first = $date[1]; // číslo prvního dne v měsíci (1 = pondělí, ...)
Protože vytvoření odkazů pro zobrazení statistiky za určité období není úplně jednoduchá záležitost, popíšu nejdříve kalendář bez těchto odkazů. Na první řádek tabulky zapíšeme právě zobrazený měsíc a rok a na každou stranu odkazy pro přechod na předchozí a následující měsíc. Ještě jednou se vrátím k problematice popsané v úvodu. Právě v těchto odkazech máme při přechodech prosinec - leden a naopak v proměnné $month nekorektní hodnoty 13 resp. 0.
<tr><td align="center" colspan="8">
<?
// předchozí, aktuální a následující měsíc
echo '<a href="stat.php?month=' . ($month-1) . '&year=' . $year . '"><<</a> ';
echo $month . " / " . $year;
echo ' <a href="stat.php?month=' . ($month+1) . '&year=' . $year . '">>></a>';
?>
</td></tr>
<tr><td>T</td><td>Po</td><td>Út</td><td>St</td><td>Čt</td>
<td>Pá</td><td>So</td><td>Ne</td></tr>
Kalendář vytvoříme pomocí cyklu postupně vytvářejícího jednotlivé řádky kalendáře, kterých může být nejvýše 6 (viz úvodní obrázek). Do prvního sloupečku zapíšeme číslo týdne ($x+1). Další sloupečky vyplníme pomocí druhého cyklu. Zde se uplatní výše zmíněná proměnná $first obsahující číslo prvního dne v měsíci (1 = pondělí, ...) a pole $date, kde u každého dne máme jeho pořadí v týdnu. Vzorec, který počítá obsah proměnné $day, se dá slovy popsat jen velmi zdlouhavě a složitě. Mnohem lepší bude uvést jeden příklad. Řekněme, že měsíc začíná nedělí (viz úvodní obrázek), $first je tedy 7. Při prvních šesti průchodech cyklem obsahuje proměnná $day hodnoty -5 až 0, a proto nemůže platit rovnost $date[$day] == $i, prvních šest "buněk" kalendáře tak bude prázdných. Pro $i=7 však dostáváme $day = 0*7+7-7+1 = 1. Rovnost $date[$day] == $i nebo-li $date[7] == 1 pak platí a do buňky můžeme zapsat první den. Do dalších řádků se poté bez problémů zapíší následující dny. Obdobná situace jako v úvodu nastává až v šestém řádku, kdy při posledních pěti průchodech cyklem obsahuje proměnná $day hodnoty 32-36, rovnost neplatí a buňky zůstanou prázdné. Na závěr je použita ještě jedna podmínka testující, zda následující den ve skutečnosti existuje. Pokud ne, je celý cyklus ukončen a tabulka s kalendářem uzavřena. Podmínka se uplatní v případech, kdy je kalendář jen na pěti řádcích, výjimečně i na čtyřech (když "nepřestupný" únor začíná v pondělí). V podmínce je použita funkce CheckDate(měsíc, den, rok) testující platnost data.
$day = 0;
for($x=0;$x<=5;$x++):
echo '<tr><td align="center"><b>';
echo $x+1;
echo '</b></td>';
for($i=1;$i<=7;$i++):
echo '<td align="center">';
$day = $x*7+$i-$first+1; // na základě obou cyklů postupně počítá den
if($date[$day] == $i)
echo $day;
else
echo " "
echo '</td>';
endfor;
echo '</tr>';
if(!CheckDate($month, $day+1, $year)) break; // pokud neexistuje následující datum, ukončí cyklus
endfor;
?>
</table>
Doufám, že všem je nyní jasné vytvoření kalendáře. Zbývá tedy doplnit odkazy pro zobrazení denní, týdenní a měsíční statistiky přístupů. Úvodní část skriptu zůstává stejná, přibyla nám funkce DateLink($from, $to, $text) vypisující odkazy pro zobrazení statistiky za dané období. První parametr označuje den, OD kterého se statistika počítá, druhý parametr den, DO kterého se počítá a třetí obsahuje text uvedený v odkazu. Abychom nedávali odkazy i k obdobím, která ještě nenastala, musíme použít podmínku zjišťující, zda datum OD je menší nebo roven aktuálnímu datu. Pokud ne, vypíšeme samotný text bez odkazu.
function DateLink($from, $to, $text)
{
global $month, $year;
if(MkTime(0,0,0,$month,$from,$year) <= MkTime(0,0,0, Date("m"), Date("d"), Date("Y"))):
echo '<a href="stat.php?month=' . $month . '&year=' . $year . '&from_date=' . $year . '-' . $month . '-' . $from . '&to_date=' . $year . '-' . $month . '-' . $to . '">';
echo $text;
echo '</a>';
else:
echo $text;
endif;
}
Funkci DateLink() použijeme nejprve pro odkaz na měsíční statistiku. Den OD je samozřejmě 1, den DO je pak proměnná $count_days obsahující počet dnů v měsíci.
<tr><td align="center" colspan="8">
<?
// předchozí, aktuální a následující měsíc
echo '<a href="stat.php?month=' . ($month-1) . '&year=' . $year . '"><<</a> ';
DateLink(1, $count_days, $month . " / " . $year); // odkaz na měsíční statistiku
echo ' <a href="stat.php?month=' . ($month+1) . '&year=' . $year . '">>></a>';
?>
</td></tr>
<tr><td>T</td><td>Po</td><td>Út</td><td>St</td><td>Čt</td>
<td>Pá</td><td>So</td><td>Ne</td></tr>
Nejproblematičtější je odkaz na týdenní statistiku. Pro výpočet posledního dne v daném týdnu použijeme podmínku. V prvním týdnu je poslední den roven vzorečku $end = 7-$first+1, pro ilustraci jeden příklad: začíná-li měsíc ve středu, $first je 3 a $end bude 4. V posledním týdnu je poslední den logicky roven počtu dní v daném měsíci. To, zda-li se jedná o poslední týden, zjistíme z podmínky $day+7>=$count_days, kde $day je naposled vypsaný den. Ve zbylých týdnech platí $end = $day+7. Do funkce DateLink() pak jako první parametr vložíme den následující po naposled vypsaném dni, o druhém parametru byla řeč před chvílí a třetí parametr bude číslo týdne v měsíci. Pro vytvoření odkazu na denní statistiku stačí do všech parametrů funkce DateLink() vložit tutéž proměnnou $day.
$day = 0;
for($x=0;$x<=5;$x++):
echo '<tr><td align="center"><b>';
// poslední den v týdnu
if($x==0) // první týden
$end = 7-$first+1;
elseif($day+7>=$count_days) // poslední týden
$end = $count_days;
else // zbylé týdny
$end = $day+7;
// odkaz na týdenní statistiku
DateLink($day+1, $end, $x+1);
echo '</td>';
for($i=1;$i<=7;$i++):
echo '<td align="center">';
$day = $x*7+$i-$first+1; // na základě obou cyklů postupně počítá den
if($date[$day] == $i)
DateLink($day, $day, $day); // odkaz na denní statistiku
else
echo " "
echo '</td>';
endfor;
echo '</tr>';
if(!CheckDate($month, $day+1, $year)) break; // pokud neexistuje následující datum, ukončí cyklus
endfor;
?>
</table>
Jelikož kalendář je ve statistice přístupů samostatným skriptem, můžete si ho stáhnout již nyní a použít třeba v úplně jiné aplikaci. K dispozici dávám dvě verze - bez odkazů a s odkazy. Příští článek bude zaměřen na tvorbu profesionálních grafů zachycujících různé statistické veličiny.
Předchozí díly:
Statistika přístupů v PHP – hodinová a denní návštěvnostStatistika přístupů v PHP – regionální lokalizace
Statistika přístupů v PHP – domény nejvyšší úrovně
Statistika přístupů v PHP – vyhledávací fráze
Statistika přístupů v PHP – odkud přicházejí návštěvníci
Statistika přístupů v PHP – rozlišení a barevná hloubka
Statistika přístupů v PHP – detekce operačního systému
Statistika přístupů v PHP – detekce prohlížeče
Statistika přístupů v PHP – počet unikátních návštěvníků