redakcni system
redakcni system
19. června 2001, 00.00 | Pokračujeme v seriálu o redakčním systému. Dnes probereme indexový skript
návštěvnické části redakčního systému a pár dalších drobností, které budou potřeba pro zobrazení stránek návštěvníkům.
V tomto díle seriálu o redakčním systému Vám popíši skript index.php,
který se bude starat o zobrazení seznamu článků a to buďto všech, nebo jen článků
v konkrétní rubrice či konkrétního autora. Skript se pak bude dále starat o
zobrazení samotného článku. Nejdříve si však popíšeme jeden zásah do skriptu
function.php, který rozšíříme o novou funkci a zbrusu nový skript
levy.php, který bude vkládan do hlavního skriptu a do skriptu forum.php,
který si popíšeme v příštím díle.
Do skriptu function.php přidáme funkci odkazy.php, která
bude sloužit k rozdělení seznamu článků do více stránek s předem určeným početem
článků na stránce. Tyto stránky budou mezi sebou vzájemně provázány odkazy. Funkce
se bude volat se třemi parametry. Jelikož tato funkce není s redakčním systémem
plně svázána a nedávno byl na serveru zveřejněn článek s touto tématikou
(Výpis seznamu po stránkách),
nebudu její popis příliš protahovat. Pro pochopení funkce jsou v kódu komentáře. Funkce
nám vrátí dvě důležité proměnné, a to: $odtud, která bude využita v
hlavních SQL dotazech a proměnnou $odkazy, která bude obsahovat část HTML
kódu s odkazy na další stránky seznamu...
// proměnná $pocet obsahuje počet nalezených záznmů v DB,
// $zpp je počet záznamů na stránce = $CL_PER_PAGE
// $url obsahuje základ url pro odkaz na další záznamy
// končí-li url nějakým předávaným parametrem uveďte na konec
// url adresy &, jinak url ukončete otazníkem
function odkazy($pocet,$zpp,$url)
{
global $odtud;
$odtud = 0;
// pokud je počet záznamů větší než počet záznamů na stránku,
// vytvoříme odkazy na další stránky
if ($pocet > $zpp)
{
// některé proměnné, které budeme používat
global $start,$odkazy;
$odkazy = '';
$starsi = 0;
$novejsi = 0;
$bufferek = 0;
$zbytek = $pocet % $zpp; // počet záznamů na poslední stránce
$bufferek = ($pocet - $zbytek) / $zpp; // počet stránek
// pokud je zbytek 0, bude počet stránek menší o 1
if ($zbytek == 0)
$bufferek--;
// pokud existuje proměnná $start, musíme spočítat
// které záznamy z databáze zobrazíme.
if ($start > 0)
{
// zaokrouklíme
$start = Round($start);
// idnex záznamu
$buffer = $start * $zpp;
// pokud je $buffer větší než $start, budeme
// zobrazovat poslední stránku
if ($buffer > $pocet)
$start = $bufferek;
}
// pokud $start neexsituje nastavíme jej na 0
else
{
$start = 0;
}
// od tohoto indexu výsledku databáze začneme zobrazovat
// data
$odtud = ($start * $zpp);
$odkazy = "<DIV ALIGN=CENTER><B>";
// pokud je uživatel na třetí stránce (číslováno od 0),
// bude vždy zobrazen odkaz na nejnovější záznamy
if ($start>1)
{
$odkazy .= "[ <A HREF=" . $url . "start=0>Nejnovější</A> ]";
$novejsi = 1;
}
// pokud je nastavena proměnná $start větší než 0, zobrazíme odkaz na
// novější záznamy
if ($start > 0)
{
// zobrazilo se už něco dříve, odkazy rozdělíme pomlčkou
if ($novejsi == 1)
$odkazy .= " - ";
$odkazy .= "[ <A HREF=" . $url . "start=" . ($start-1) . ">Novější</A> ]";
$novejsi = 1;
}
// je-li počet stránek rovný aktuální stránce+1, pak zobrazíme
// odkaz na starší záznamy
if (($start+1) <= $bufferek)
{
// zobrazilo se už něco dříve, odkazy rozdělíme pomlčkou
if ($novejsi == 1)
$odkazy .= " - ";
$odkazy .= "[ <A HREF=" . $url . "start=" . ($start+1) . ">Starší</A> ]";
$starsi = 1;
}
// je-li počet stránek větší než aktuální stránka+1, zobrazíme
// odkaz na nejstarší záznamy.
if (($start+1) < $bufferek)
{
// zobrazilo se už něco dříve, odkazy rozdělíme pomlčkou
if ($novejsi == 1 || $starsi == 1)
$odkazy .= " - ";
$odkazy .= "[ <A HREF=" . $url . "start=" . $bufferek . ">Nejstarší</A> ]";
}
// v proměnné odkazy budeme mít odkazy se stránkováním záznamů
$odkazy .= "</B></DIV>";
}
}
|
|
Dalším skriptem bude skript levy.php, který bude obsahovat levý sloupec
stránky, jež bude využívat jak hlavní stránka, tak i stránky s diskuzemi ke článkům.
Jeho strukturu jsem navrhl tak, aby zde byly všechny důležité informace - rubriky,
seznam aktuálních a nejčtenějších článků, kráté zprávy a seznam autorků k rychlé
volbě článků jednotlivých autorů. Samozřejmě, že uspořádání těchto informací je
na vás, rozdělení nemusí vyhovovat všem. Jelikož se jedná o triviální kód
(oproti předchozím skriptům), uvedu rovnou jeho komentovanou citaci:
levy.php (/levy.php)
<B>Rubriky:</B><BR>
<A HREF="index.php">Titulní stránka</A><BR>
<?
// vložíme seznam rubrik
include "./inc/rubriky";
?>
<BR>
<B>Aktuální články:</B><BR>
<TABLE BORDER="0">
<?
$cas = time();
// vybereme 5 nejnovějších článků. Článek musí být schválený
// a čas vydání musí být menší nebo shodný s aktuálním
@$sql = mysql_query("SELECT id,nadpis FROM clanky
WHERE stav = 'a' AND datum <= $cas
ORDER BY datum DESC LIMIT 0,5");
while ($data = mysql_fetch_row($sql))
{
// zobrazíme výsledek
?>
<TR>
<TD VALIGN="TOP">-</TD>
<TD VALIGN="TOP">
<A HREF="index.php?clanek=<? echo $data[0]; ?>"><? echo $data[1]; ?></TD>
</TR>
<?
}
@mysql_free_result($sql);
?>
</TABLE>
<BR>
<B>Nejčtenější články:</B><BR>
<TABLE BORDER="0">
<?
// vybereme 5 článků s nejvyšší čteností. Článek musí být schválený
// a čas vydání musí být menší nebo shodný s aktuálním
@$sql = mysql_query("SELECT id,nadpis FROM clanky
WHERE stav = 'a' AND datum <= $cas
ORDER BY counter DESC LIMIT 0,5");
while ($data = mysql_fetch_row($sql))
{
?>
<TR>
<TD VALIGN="TOP">-</TD>
<TD VALIGN="TOP">
<A HREF="index.php?clanek=<? echo $data[0]; ?>"><? echo $data[1]; ?></TD>
</TR>
<?
}
@mysql_free_result($sql);
?>
</TABLE>
<BR>
<B>Krátké zprávy:</B><BR>
<?
// vložíme krátké zprávy
include "./inc/kz";
?>
<BR>
<FORM METHOD="GET" ACTION="index.php">
<B>Články autora:</B>
<SELECT NAME="autor" ONCHANGE="submit();">
<OPTION VALUE="">Vyberte autora</OPTION>
<?
// vložíme seznam autorů
include "./inc/autori";
?>
</SELECT>
</FORM>
|
|
Nyní se dostáváme, pro návštěvníky serveru k nejdůležitějšímu skriptu, jimž je
index.php, který se stará o zobrazení seznamu článků, řazených dle
autorů či rubrik, dále pak se stará o zobrazení samotného článku. Začneme seznamy
rubrik, které jsou celkem tři. Jeden je seznam všech článků a bude se zobrazovat
na titulní stránce. Dále pak se jedná o seznam článků rozdělených do jednotlivých
rubrik a článků rozdělených dle autorů. O vytovření takovéhoto seznamu se bude starat
vždy jeden docela velký SQL dotaz. Každý bude mírně modifikován.
články na titulní stránce
SELECT C.id,C.nadpis,C.anotace,C.datum, A.jmeno,A.id,count(F.id),R.id,R.rubrika
FROM clanky C, rubriky R, autori A LEFT JOIN fora F ON F.id_clanku = C.id
WHERE C.id_rubrika = R.id AND C.id_autor = A.id AND C.stav = 'a'
AND C.datum <= $cas GROUP BY C.id ORDER BY C.datum DESC, C.priorita DESC
LIMIT $odtud,$CL_PER_PAGE
články v rubrice
SELECT C.id,C.nadpis,C.anotace,C.datum, A.jmeno,A.id,count(F.id)
FROM clanky C, autori A LEFT JOIN fora F ON F.id_clanku = C.id
WHERE C.id_rubrika = $rubrika AND C.id_autor = A.id
AND C.stav = 'a' AND C.datum <= $cas GROUP BY C.id
ORDER BY C.datum DESC, C.priorita DESC LIMIT $odtud,$CL_PER_PAGE
články autora
SELECT C.id,C.nadpis,C.anotace,C.datum,R.id,R.rubrika, count(F.id)
FROM clanky C, rubriky R LEFT JOIN fora F ON F.id_clanku = C.id
WHERE C.id_rubrika = R.id AND C.id_autor = $autor AND C.stav = 'a'
AND C.datum <= $cas GROUP BY C.id ORDER BY C.datum DESC, C.priorita DESC
LIMIT $odtud,$CL_PER_PAGE
Každý SQL dotaz obsahuje totožné části, kterými je LEFT JOIN spojení s tabulkou
fora, pomocí kterého vybereme z databáze i ten článek, který v diskuzi nemá
žádný příspěvek. Vybíráme články které jsou schváleny C.stav = 'a' a které
už byly publikovány C.datum <= $cas. Další společnou část mají třídění
C.datum DESC, C.priorita DESC (podle data a priority). Poslední je část
LIMIT $odtud,$CL_PER_PAGE, která slouží k selectu jen určitého počtu článků,
které budou na jedné stránce seznamu zobrazeny. Mění se pouze selectované položky
a případně i tabulky ze kterých se data tahají (jedná-li se o seznam článků v
konkrétní rubrice, pak nepotřebujeme znát rubriku, ve které je článek vystaven,
pokud vybíráme články dle jednotlivých autorů, nemusíme znát informace o autorovi).
Každý z výše uvedených SQL dotazů předchází SQL dotaz kratší, který spočítá buď
počet všech článků, počet článků autora nebo počet článků v rubrice (záleží na tom
co budeme zobrazovat). Do součtu jsou zařazovány pouze články, které jsou schváleny
a jejich čas publikace je stejný nebo nižší než aktuální. Výsledek tohoto dotazu
bude sloužit k rozpočítání hlavního výsledku do více stránek tak, aby se nezobrazoval
seznam všech článků najednou na jedné stránce. Dalším selectem je select samotného
článku, který jsme si popsali v minulém dílu seriálu. Tento dodaz bude opět mírně
modifikován - přibyde do něj podmínka, která bude zobrazovat jen aktivní a publikované
články.
index.php (/index.php)
<?
// vložíme soubory s funkcemi
include "./conn.php";
include "./function.php";
// zobrazíme hlavičku stránky
head();
?>
<TABLE BORDER="0" ALIGN="CENTER" WIDTH="100%">
<TR>
<TD VALIGN="TOP" WIDTH="200">
<!-- levý slopec -->
<?
// vložíme levý sloupec
include "./levy.php";
?>
<!-- levý slopec - konec -->
</TD>
<TD VALIGN="TOP">
<!-- pravý slopec -->
<?
// pokud existuje proměnná $clanek zobrazíme článek být schválený
// a čas vydání musí být menší nebo shodný s aktuálním
if ($clanek > 0)
{
// select článku. Článek musí být aktivní a musí
@$sql = mysql_query("SELECT C.nadpis,A.jmeno,A.email,R.rubrika,
C.datum,C.anotace,C.clanek,A.oautorovi
FROM clanky C, rubriky R, autori A
WHERE C.id_autor = A.id AND C.id_rubrika = R.id
AND C.stav = 'a' AND datum <= $cas
AND C.id = $clanek");
// pokud nalezneme v databízi jeden záznam, zobrazíme článek
if (mysql_num_rows($sql) == 1)
{
$data = mysql_fetch_row($sql);
// přičteme počítadlo přečtení
@$sql = mysql_query("UPDATE clanky SET counter = counter + 1
WHERE id = $clanek");
// spočítáme příspěvky v diskuzi
@$sql = mysql_query("SELECT count(*) FROM fora
WHERE id_clanku = $clanek");
$prispevku = mysql_result($sql,0,0);
@mysql_free_result($sql);
// zobrazíme článek
?>
<H3 ALIGN="CENTER"><? echo $data[0]; ?></H3>
<? echo $data[6]; ?>
<P>
Publikováno: <B><? echo date("d.m.Y",$data[4]); ?></B>
v rubrice <B><? echo $data[3]; ?></B>.
<BR>
<B>Diskuze:</B>
<A HREF="forum.php?clanek=<? echo $clanek; ?>">
<?
// pokud v diskuzi není příspěvek
if ($prispevku == 0)
{ echo "žádný příspěvek"; }
// pokud je v diskuzi jeden příspěvek
elseif ($prispevku == 1)
{ echo "jeden příspěvek"; }
// pokud jsou v diskuzi 2,3 nebo 4 příspěvky
elseif ($prispevku > 1 && $prispevku < 5)
{ echo $prispevku . "příspěvky"; }
// pokud je v diskuzi více než 4 příspěvky
else
{ echo $prispevku . "příspěvků"; }
?>
</A><BR>
<B>Autor:</B> <A HREF="mailto:<? echo $data[2]; ?>">
<? echo $data[1]; ?></A>
</P>
<P><? echo $data[7]; ?></P>
<?
}
// pokud v databázi nenalezneme žádný článek
else
{
?><H1 ALIGN="CENTER">Článek neexistuje !!!</H1><?
}
}
// pokud existuje proměnná $rubrika zobrazíme články rubriky
elseif ($rubrika > 0)
{
@$sql = mysql_query("SELECT * FROM rubriky WHERE id = $rubrika");
if (mysql_num_rows($sql) == 1)
{
@$data = mysql_fetch_row($sql);
?><H3 ALIGN="CENTER">Rubrika
<? echo $data[1]; ?></H3><?
// select přehledu článků
@$sql = mysql_query("SELECT count(*) FROM clanky
WHERE stav = 'a' AND datum <= $cas
AND id_rubrika = $rubrika
ORDER BY datum DESC, priorita DESC");
// pokud je v databázi alespoň jeden článek
if (mysql_result($sql,0,0) > 0)
{
odkazy(mysql_result($sql,0,0),$CL_PER_PAGE,
"index.php?rubrika=".$rubrika."&");
// select přehledu článků
@$sql = mysql_query("SELECT C.id,C.nadpis,C.anotace,C.datum,
A.jmeno,A.id,count(F.id)
FROM clanky C, autori A
LEFT JOIN fora F ON F.id_clanku = C.id
WHERE C.id_rubrika = $rubrika AND C.id_autor = A.id
AND C.stav = 'a' AND C.datum <= $cas
GROUP BY C.id
ORDER BY C.datum DESC, C.priorita DESC
LIMIT $odtud,$CL_PER_PAGE");
// pro každý záznam z databáze zobrazíme získaná data
while ($row = mysql_fetch_row($sql))
{
?>
<H3><A HREF="index.php?clanek=<? echo $row[0]; ?>">
<? echo $row[1]; ?></A></H3>
<DIV>
<? echo $row[2]; ?>
<BR>
<B>Publikováno:</B> <? echo date("d.m.Y",$row[3]); ?>.
<B>Autor</B>:
<A HREF="index.php?autor=<? echo $row[5]; ?>">
<? echo $row[4]; ?></A><BR>
<?
if ($row[6] > 0)
{
?>
<B>Diskuze:</B>
<A HREF="forum.php?clanek=<? echo $row[0]; ?>">
<?
// pokud je v diskuzi jeden příspěvek
if ($row[6] == 1)
{ echo "jeden příspěvek"; }
// pokud jsou v diskuzi 2,3 nebo 4 příspěvky
elseif ($row[6] > 1 && $row[6] < 5)
{ echo $row[6] . "příspěvky"; }
// pokud je v diskuzi více než 4 příspěvky
else
{ echo $row[6] . "příspěvků"; }
echo "</A>";
}
?>
</DIV>
<?
}
echo "<BR>".$odkazy;
@mysql_free_result($sql);
}
else
{
?><H1 ALIGN="CENTER">Nenalezeny žádné články !!!</H1><?
}
}
else
{
?><H1 ALIGN="CENTER">Rubrika neexistuje !!!</H1><?
}
}
// pokud existuje proměnná $autor zobrazíme články autora
elseif ($autor > 0)
{
@$sql = mysql_query("SELECT * FROM autori WHERE id = $autor");
if (mysql_num_rows($sql) == 1)
{
@$data = mysql_fetch_row($sql);
?>
<H3 ALIGN="CENTER">Autor:
<A HREF="mailto:<? echo $data[4]; ?>">
<? echo $data[3]; ?></A></H3>
<?
// select přehledu článků
@$sql = mysql_query("SELECT count(*) FROM clanky
WHERE stav = 'a' AND datum <= $cas
AND id_autor = $autor
ORDER BY datum DESC, priorita DESC");
// pokud je v databázi alespoň jeden článek
if (mysql_result($sql,0,0) > 0)
{
odkazy(mysql_result($sql,0,0),$CL_PER_PAGE,
"index.php?autor=".$autor."&");
// select přehledu článků
@$sql = mysql_query("SELECT C.id,C.nadpis,C.anotace,C.datum,R.id,
R.rubrika,count(F.id)
FROM clanky C, rubriky R
LEFT JOIN fora F ON F.id_clanku = C.id
WHERE C.id_rubrika = R.id AND C.id_autor = $autor
AND C.stav = 'a' AND C.datum <= $cas
GROUP BY C.id
ORDER BY C.datum DESC, C.priorita DESC
LIMIT $odtud,$CL_PER_PAGE") or die(mysql_error());
// pro každý záznam z databáze zobrazíme získaná data
while ($row = mysql_fetch_row($sql))
{
?>
<H3><A HREF="index.php?clanek=<? echo $row[0]; ?>">
<? echo $row[1]; ?></A></H3>
<DIV>
<? echo $row[2]; ?>
<BR>
<B>Publikováno:</B> <? echo date("d.m.Y",$row[3]); ?>
v <B>rubrice</B>:
<A HREF="index.php?rubrika=<? echo $row[4]; ?>">
<? echo $row[5]; ?></A><BR>
<?
if ($row[6] > 0)
{
?>
<B>Diskuze:</B>
<A HREF="forum.php?clanek=<? echo $row[0]; ?>">
<?
// pokud je v diskuzi jeden příspěvek
if ($row[6] == 1)
{ echo "jeden příspěvek"; }
// pokud jsou v diskuzi 2,3 nebo 4 příspěvky
elseif ($row[6] > 1 && $row[6] < 5)
{ echo $row[6] . "příspěvky"; }
// pokud je v diskuzi více než 4 příspěvky
else
{ echo $row[6] . "příspěvků"; }
echo "</A>";
}
?>
</DIV>
<?
}
echo "<BR>".$odkazy;
}
else
{
?><H1 ALIGN="CENTER">Nenalezeny žádné články !!!</H1><?
}
}
else
{
?><H1 ALIGN="CENTER">Autor neexistuje !!!</H1><?
}
}
// jinak zobrazíme články ze všech rubrik i autorů.
else
{
?><H3 ALIGN="CENTER">Hlavní stránka</H3><?
// select přehledu článků
@$sql = mysql_query("SELECT count(*) FROM clanky
WHERE stav = 'a' AND datum <= $cas
ORDER BY datum DESC, priorita DESC");
// pokud je v databázi alespoň jeden článek
if (mysql_result($sql,0,0) > 0)
{
odkazy(mysql_result($sql,0,0),$CL_PER_PAGE,"index.php?");
// select přehledu článků
@$sql = mysql_query("SELECT C.id,C.nadpis,C.anotace,C.datum,
A.jmeno,A.id,count(F.id),R.id,R.rubrika
FROM clanky C, rubriky R, autori A
LEFT JOIN fora F ON F.id_clanku = C.id
WHERE C.id_rubrika = R.id AND C.id_autor = A.id
AND C.stav = 'a' AND C.datum <= $cas
GROUP BY C.id
ORDER BY C.datum DESC, C.priorita DESC
LIMIT $odtud,$CL_PER_PAGE");
// pro každý záznam z databáze zobrazíme získaná data
while ($row = mysql_fetch_row($sql))
{
?>
<H3><A HREF="index.php?clanek=<? echo $row[0]; ?>">
<? echo $row[1]; ?></A></H3>
<DIV>
<? echo $row[2]; ?>
<BR>
<B>Publikováno:</B> <? echo date("d.m.Y",$row[3]); ?>
v <B>rubrice</B>:
<A HREF="index.php?rubrika=<? echo $row[7]; ?>">
<? echo $row[8]; ?></A><BR>
<B>Autor</B>:
<A HREF="index.php?autor=<? echo $row[5]; ?>">
<? echo $row[4]; ?></A><BR>
<?
if ($row[6] > 0)
{
?><B>Diskuze:</B>
<A HREF="forum.php?clanek=<? echo $row[0]; ?>"><?
// pokud je v diskuzi jeden příspěvek
if ($row[6] == 1)
{ echo "jeden příspěvek"; }
// pokud jsou v diskuzi 2,3 nebo 4 příspěvky
elseif ($row[6] > 1 && $row[6] < 5)
{ echo $row[6] . "příspěvky"; }
// pokud je v diskuzi více než 4 příspěvky
else
{ echo $row[6] . "příspěvků"; }
echo "</A>";
}
?></DIV><?
}
echo "<BR>".$odkazy;
@mysql_free_result($sql);
}
else
{
?><H1 ALIGN="CENTER">Nenalezeny žádné články !!!</H1><?
}
}
?>
<!-- pravý slopec - konec -->
</TD>
</TR>
</TABLE>
<?
foot();
mysql_close($conn);
?>
|
|
Na závěr chci říci, že stálé selectování z databáze není nejlepší řešení,
nicméně je nejjednoduchší k pochopení systému. Je jasné, že selectovat nejčtenější,
nejnovější články, stejně jako seznamy rubrik je celkem neefektivní a v případě
velké návštěvnosti serveru by mohlo docházet k přetížení serveru, pokud tedy
myslíte, že bude zátěž velká, budete muset připrogramovat skripty, které budou
generovat soubory obsahující právě tyto informace. Vše nechávám plně na vaší fantazii
a schopnostech. Jen pro představu uvádím jeden "místní"
zdroj inspirace.
Skripty function.php, levy.php a index.php si můžete stáhnot
v zazipovaném arcivu. V příštím
a asi už posledním díle seriálu si probereme diskuzní fóra ke článkům a jejich
generování.