Statistika přístupů v PHP – kalendář

26. června 2004

V tomto článku o statistice přístupů si povíme, jak vytvořit kalendář, na kterém si můžeme zvolit období, pro něž 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ů stránek http://www.czechia.cz/help/.

Kalendář

Ještě než se pustím do samotného kalendáře, popíšu funkci dateLink($from, $to, $text) vypisující odkazy na statistiku přístupů 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 kterého se počítá je menší nebo roven aktuálnímu datu. Pokud ne, vypíšeme samotný text bez odkazu.

// vypisuje odkazy pro zobrazeni statistiky za dane obdobi
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 . ‚&amp;year=‘ . $year . ‚&amp;from_date=‘ . $year . ‚-‚ . $month . ‚-‚ . $from . ‚&amp;to_date=‘ . $year . ‚-‚ . $month . ‚-‚ . $to . ‚“>‘;
    echo $text;
    echo ‚</a>‘;
  } else {
    echo $text;
  }
}

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“ respektive „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.

// pokud nejsou promenne zinicializovany, vlozi aktualni hodnoty
$month = date(‚m‘);
$year = date(‚Y‘);
if ( isset($_GET[‚month‘]) and ($_GET[‚month‘] <= 13) and ($_GET[‚month‘] >= 0) ) $month = $_GET[‚month‘];
if ( isset($_GET[‚year‘]) and ($_GET[‚year‘] <= 2035) and ($_GET[‚year‘] >= 1970) ) $year = $_GET[‚year‘];
// prevod na korektni hodnoty
$year = date(‚Y‘, mktime(0,0,0, $month, 1, $year));
$month = date(‚m‘, mktime(0,0,0, $month, 1, $year));

Pomocí parametru „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, zjistíme ještě číslo prvního dne v měsíci (1 = pondělí, 2 = úterý, …, 7 = neděle). Protože parametr „w“ použitý ve funkci date() přiřazuje k neděli „0“, musíme ji pomocí podmínky změnit na „7“.

// pocet dnu v danem mesici
$count_days = date(‚t‘, mktime(0,0,0, $month, 1, $year));
// cislo prvniho dne v mesici (1 = pondeli, …)
$first = date(‚w‘, mktime(0,0,0,$month,1,$year));
if ($first == 0) $first = 7;

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“ respektive „0“.

echo ‚<table cellspacing=“0″ class=“calendar“>‘;
echo ‚<tr><td align=“center“ colspan=“8″>‘;
// predchozi, aktualni a nasledujici mesic
echo ‚<a href=“stat.php?month=‘ . ($month-1) . ‚&year=‘ . $year . ‚“>&lt;&lt;</a>   ‚;
dateLink(1, $count_days, $month . “ / “ . $year);  // odkaz na mesicni statistiku
echo ‚   <a href=“stat.php?month=‘ . ($month+1) . ‚&year=‘ . $year . ‚“>&gt;&gt;</a>‘;
echo ‚</td></tr>‘;
echo ‚<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 šest (viz úvodní obrázek). Do prvního sloupečku zapíšeme číslo týdne ($x+1) a odkaz na týdenní statistiku. 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. Jednoduše si spočítáme dny ($day) odpovídající danému týdnu a s pomocí jednoduché podmínky (den nesmí být menší než „1“ a naopak větší než počet dní v měsíci) vypisujeme buď odkaz nebo nic. 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;
// cyklus pres tydny
for ($x = 0; $x <= 5;$x++) {
  echo ‚<tr><td align=“center“><strong>‘;
  // zjisti posledni den v danem tydnu
  if ($x == 0)  // prvni tyden
    $end = 7 – $first+1;
  elseif ($day+7 >= $count_days)  // posledni tyden
    $end = $count_days;
  else  // zbyle tydny
    $end = $day+7;
  // odkaz na tydenni statistiku
  dateLink($day+1, $end, $x+1);
  echo ‚</strong></td>‘;
  
  // cyklus pres dny v tydnu
  for ($i = 1;$i <= 7;$i++) {
    echo ‚<td>‘;
    $day = $x*7 + $i – $first+1; // spocti den
    
    // je to platne datum
    if ($day >= 1 and $day <= $count_days )
      dateLink($day, $day, $day); // odkaz na denni statistiku
    else
      echo „&nbsp;“;
    echo ‚</td>‘;
  }
  
  echo ‚</tr>‘;
  // pokud neexistuje nasledujici datum, ukonci cyklus
  if (!checkdate($month, $day+1, $year)) break;
}
echo ‚</table>‘;
?>

Jelikož kalendář je ve statistice přístupů víceméně samostatnou částí, 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.

Pozn. red.: Tento článek vyšel poprvé 30. 8. 2002. Původní verze článku a k němu vedené diskuse jsou vám k dispozici v ZIP archivech.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek Kam patří menu
Další článek Adobe Photoshop v praxi
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *