Ankety - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



PHP

Ankety

redakcni system

3. dubna 2003, 00.00 | V dnešním posledním díle umožníme v RS používat ankety. Na závěr si bude možno stáhnout kompletní zdrojový kód celého systému.

 V dnešním posledním díle si ukážeme, jak přidat do našeho systému ankety a na konec dám ke stažení dlouho očekávaný, opakávaný a vyprošovaný kompletní zdorojový kód.

Nejprve si musíme s souboru menu.php přidat tento odkaz.

.
.
.
echo "<A HREF=ankety.php target=main $click>Ankety</A><BR>\n";
.
.
.

Komu umožníte, aby mohl editovat, vytvářet a mazat ankety je na Vás.

První co budeme potřebovat, je databáze s touto strukturou.

CREATE TABLE ankety (
  id int(11) NOT NULL auto_increment,
  otazka text NOT NULL,
  odpovedi text NOT NULL,
  stav varchar(255) NOT NULL default '',
  zobrazit enum('a','n') NOT NULL default 'a',
  PRIMARY KEY  (id)
) 

Možná si říkáte, proč je zde místo jen pro jednu odpověď? Vše vysvětlím později.

Jako úvodní se nám po kliku na odkaz spustí následující script ankety.php.

<?
Header("Pragma: No-cache");
Header("Cache-Control: no-cache");
Header("Expires: ".GMDate("D, d M Y H:i:s")."GMT");

if (!isset($PHP_AUTH_USER)):
echo "Neautorizovaný přístup";
exit;
endif;

@include "../conn.php";
@include "../function.php";

auth();

if (isset($did) && $did > 0)
{
@$sql = mysql_query("DELETE FROM ankety WHERE id = $did");

}

head();
?>


<h3>Ankety</h3>

<P><A HREF="ankety_pridat.php">Přidat anketu</A></P>
<?
@$sql = mysql_query("SELECT id,otazka,zobrazit FROM ankety");

if (@mysql_num_rows($sql) == 0)
{
echo "<h3><b>Není definována žádná anketa !!!</b></h3>\n";
}
else
{
?>
<table border=0 cellspacing=0 cellpadding=1 WIDTH="100%">
<tr bgcolor=#C0C0C0>
<td bgcolor=#C0C0C0><b> Otázka</b></td>
<td bgcolor=#C0C0C0 align="center"><b> Zobrazena </b></td>
<td bgcolor=#C0C0C0 align="center"><b> Statistika </b></td>
<td bgcolor=#C0C0C0 align="center"><b> Smazat </b></td>
</tr>
<?
$i = 0;

while (@$row = mysql_fetch_row($sql))
{
if ($i%2==0) $bgcolor=''; 
else 
$bgcolor=" bgcolor=#C0C0C0";
?>
<tr<? echo $bgcolor; ?>>
<td<? echo $bgcolor; ?>> 
  <b><A HREF="ankety_editovat.php?id=<?=$row[0]?>">
  <? echo $row[1];?></A></b></td>
<td<? echo $bgcolor; ?> align="center"> <? echo $row[2];?></td>
<td<? echo $bgcolor; ?> align="center"> 
  <A HREF="statistika.php?id=<?=$row[0]?>">statistika</A></td>
<form method="get" action="ankety.php">
  <input type="hidden" name="did" value="<? echo $row[0]; ?>">
<td<? echo $bgcolor; ?> align="center"> 
  <input type="submit" value="Smazat" onclick="return 
    confirm('Opravdu chceš anketu smazat ?')"> </td>
</form>
</tr>
<?
// zvýšíme proměnnou i o 1.
$i++;
}
// uvolníme výsledek
mysql_free_result($sql);

echo "</TABLE>\n";
}
?>
<?
foot();
@mysql_close($conn);
?>

Zde se pro každou anketu opakuje smyčka, kde se zobrazí odkaz pro její editaci, zda je zobrazena (může být pouze jedna), odkaz na její statistiku a tlačítko pro smazání ankety.

Pro přidání ankety nám slouží script ankety_pridat.php.

<?
Header("Pragma: No-cache");
Header("Cache-Control: no-cache");
Header("Expires: ".GMDate("D, d M Y H:i:s")."GMT");

// pokud nenproběhla autorizace, ukončíme skript
if (!isset($PHP_AUTH_USER))
{
echo "Neautorizovaný přístup";
exit;
}

@include "../function.php";
@include "../conn.php";

// autorizace
auth();

$error = ''; // proměnná obsahuje případné chybové hlášení

if ($otazka != "")
{
$oddelovac="@@";
@$sql = mysql_query("SELECT id FROM ankety WHERE zobrazit='a'");
if (@mysql_num_rows($sql) > 0)
{
$error = "<DIV ALIGN=CENTER>Anketa, 
          nejde nastavit na zobrazení !!!</DIV>\n";
$zobrazit="n";
}
// updatujem anketu;
$ind=0;
while(list(,$b)=each($odpoved))
{
	if($b=="")
		continue;

	if($odpovedi!="")
		$odpovedi.=$oddelovac;

	$odpovedi.=$b;
$ind++;
}
$stav=0;
for($i=0;$i<$ind;$i++)
	$stav.=$oddelovac."0";
@mysql_query("INSERT INTO ankety VALUES('','$otazka','$odpovedi',
                        '$stav','$zobrazit')");

@mysql_close($conn);
header("Location: ./ankety.php");
exit;
}

// databázi již nebudeme potřebovat
@mysql_close($conn);

head()
?>

<H4 ALIGN="CENTER"><B>Přidání ankety</B></H4>

<? echo $error; ?>

<FORM METHOD="POST" ACTION="ankety_pridat.php">
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" ALIGN="CENTER">
<TR>
<TD>Otázka: * </TD>
<TD><INPUT TYPE="TEXT" NAME="otazka" MAXLENGTH="50" 
               SIZE="40" VALUE="<? echo $otazka; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50"
               SIZE="40" VALUE="<? echo $odpoved[0]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50"
               SIZE="40" VALUE="<? echo $odpoved[1]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50" 
               SIZE="40" VALUE="<? echo $odpoved[2]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50" 
               SIZE="40" VALUE="<? echo $odpoved[3]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50" 
               SIZE="40" VALUE="<? echo $odpoved[4]; ?>"></TD>
</TR>
<TR>
<TD>Zobrazit: </TD>
<TD><INPUT TYPE="CHECKBOX" NAME="zobrazit" VALUE="a" ></TD>
</TR>
<TR>
<TD COLSPAN="2" ALIGN="CENTER">
<INPUT TYPE="SUBMIT" VALUE="Přidat">
</TD>
</TR>
</TABLE>
</FORM>

<?
foot();
?>

Zde se budu muset trochu pozastavit. Jak ve formuláři vytvořím pole snad vysvětlovat nemusím. Možná vás trochu překvapuje proměnná $oddelovac. Pomocí ní spojíme odpovědi do jednoho řetězce a uložíme do databáze. Proč ke spojování nepoužívám funkci Join() nebo Implode()? Jednoduše proto, že funkce spojí všechny(!) prvky pole. Tedy i prázdné položky. což se konstrukci tohoto systému v enduser části nebude moc líbit. Něco podobného uděláme i u počtu hlasů s tím rozdílem, že nám zde pomůže proměnná $ind, ve které máme počet odpovědí. Na úplném začátku jsme si zjistili, jestli exsistuje nějaká ankety která je zobrazená. Pokud ano a právě zpracovávaná anketa je také nastavena na zobrazení, přepne se současná do režimu "nezobrazovat". Tento způsob nám umožňuje dát k jedné otázce až neomezený počet odpovědí. Já jsem to omezil na 5.

<?
Header("Pragma: No-cache");
Header("Cache-Control: no-cache");
Header("Expires: ".GMDate("D, d M Y H:i:s")."GMT");

// pokud nenproběhla autorizace, ukončíme skript
if (!isset($PHP_AUTH_USER))
{
echo "Neautorizovaný přístup";
exit;
}

@include "../function.php";
@include "../conn.php";

// autorizace
auth();

$error = ''; // proměnná obsahuje případné chybové hlášení
$oddelovac="@@";
if ($otazka != "")
{
if($zobrazit=='')
	$zobrazit='n';
@$sql = mysql_query("SELECT id FROM ankety WHERE zobrazit='a'");
$b=mysql_fetch_row($sql);
if (@mysql_num_rows($sql) > 0 and $b[0]!=$id)
{
$error = " <DIV ALIGN=CENTER>Anketa, 
      nejde nastavit na zobrazení !!!</DIV>\n";
$zobrazit="n";
}
// updatujem anketu
$c=mysql_query("SELECT stav FROM ankety WHERE id='$id'");
$d=mysql_fetch_row($c);
$e=explode($oddelovac,$d[0]);
$odpovedi="";
$stav="";
while(list($a,$b)=each($odpoved))
{
	if($b=="")
		continue;

	if($odpovedi!="")
		$odpovedi.=$oddelovac;

	$odpovedi.=$b;

	if($stav!="")
		$stav.=$oddelovac;

	if($e[$a]=="")
		$stav.=0;

	$stav.=$e[$a];	
}


@mysql_query("UPDATE ankety SET otazka='$otazka',odpovedi='$odpovedi',
           stav='$stav',zobrazit='$zobrazit' WHERE id = $id");

@mysql_close($conn);
header("Location: ./ankety.php");
exit;
}

head();
@$sql = mysql_query("SELECT * FROM ankety WHERE id = $id");
if (@mysql_num_rows($sql) == 0)
{
echo "Neplatná anketa!!!";
foot();
exit;
}

@$row = mysql_fetch_array($sql);

// databázi již nebudeme potřebovat
@mysql_close($conn);



$odpoved=explode($oddelovac,$row[odpovedi]);
?>

<H4 ALIGN="CENTER"><B>Editace ankety</B></H4>

<? echo $error; ?>

<FORM METHOD="POST" ACTION="ankety_editovat.php">
<INPUT TYPE="HIDDEN" NAME="id" VALUE="<? echo $id; ?>">
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" ALIGN="CENTER">
<TR>
<TD>Otázka: * </TD>
<TD><INPUT TYPE="TEXT" NAME="otazka" MAXLENGTH="50" 
            SIZE="40" VALUE="<? echo $row[1]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50"
            SIZE="40" VALUE="<? echo $odpoved[0]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50"
            SIZE="40" VALUE="<? echo $odpoved[1]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50"
            SIZE="40" VALUE="<? echo $odpoved[2]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50"
            SIZE="40" VALUE="<? echo $odpoved[3]; ?>"></TD>
</TR>
<TR>
<TD>Odpověď: </TD>
<TD><INPUT TYPE="TEXT" NAME="odpoved[]" MAXLENGTH="50"
            SIZE="40" VALUE="<? echo $odpoved[4]; ?>"></TD>
</TR>
<TR>
<TD>Zobrazit: </TD>
<TD><INPUT TYPE="CHECKBOX" NAME="zobrazit" 
   VALUE="a" <? If($row[zobrazit]=="a") echo "CHECKED"; ?>></TD>
</TR>
<TR>
<TD COLSPAN="2" ALIGN="CENTER">
<INPUT TYPE="SUBMIT" VALUE="Editovat">
</TD>
</TR>
</TABLE>
</FORM>

<?
foot();
?>

Tady vysvětlím jen zpracování, neboť zbytek je podobný scriptu pro přidání ankety. Je zde trochu problém s tím, že pokud smažeme odpověď, na kterou kliklo několik hlasujících, tak nám procentuální rozložení hlasů nebude souhlasit. Z toho důvodu se s každou odpovědí edituje i počet jejích hlasů. Samozřejmě, že se poměr změní, ale bude vypočítáván jen z hlasů u platných odpovědí. Nebudou se započítávat hlasy u odpovědí, které jsme smazali.

Jak se dozvíme průběžné výsledky i nezobrazované ankety? Pomocí scriptu statistika.php.

<?
Header("Pragma: No-cache");
Header("Cache-Control: no-cache");
Header("Expires: ".GMDate("D, d M Y H:i:s")."GMT");

// pokud nenproběhla autorizace, ukončíme skript
if (!isset($PHP_AUTH_USER))
{
echo "Neautorizovaný přístup";
exit;
}

@include "../function.php";
@include "../conn.php";

// autorizace
auth();

$error = ''; // proměnná obsahuje případné chybové hlášení
$oddelovac="@@";

@$sql = mysql_query("SELECT * FROM ankety WHERE id = $id");
if (@mysql_num_rows($sql) == 0)
{
echo "Neplatná anketa!!!";
foot();
exit;
}

@$row = mysql_fetch_array($sql);

// databázi již nebudeme potřebovat
@mysql_close($conn);

head();

$odpoved=explode($oddelovac,$row[odpovedi]);
$stav=explode($oddelovac,$row[stav]);
?>

<H4 ALIGN="CENTER"><B>Výsledky ankety</B></H4>

<? echo $error; ?>


<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" ALIGN="CENTER">
<TR BGCOLOR="#C0C0FF">
<TD WIDTH=100>Otázka:</TD>
<TD><B><? echo $row[otazka]; ?></B></TD>
</TR>
<?
for($i=0;$i<count($odpoved);$i++)
{
if($i%2) $bg=' BGCOLOR="#FFFFFF" '; else $bg=' BGCOLOR="#DADADA" ';
if($odpoved[$i]=="")
	continue;
?>
<TR <?=$bg?>>
<TD WIDTH="70%"><? echo $odpoved[$i]." </TD>
  <TD>Počet hlasů: ".$stav[$i]; ?></TD>
</TR>
<?
}
?>
<TR BGCOLOR="#C0FFC0">
<TD>Zobrazit: </TD>
<TD><B><? echo $row[zobrazit]?></B></TD>
</TR>
<TR>
<TD COLSPAN="2" ALIGN="CENTER">
<A HREF="ankety.php">zpět</A>
</TD>
</TR>
</TABLE>

<?
foot();
?>

Princip je opět stejný jako u editace, a proto ho nebudu znovu vysvětlovat.

Nyní se dostáváme do uživatelské části. Je opět na vás kam si anketu umístíte. Já jsem ji dal do scriptu levy.php.

.
.
.
</TABLE>
* - nutno vyplnit
</FORM>
<P>
<?
include "./anketa.php";
?>

Jak jednoduché. Samotný script ankety.php vypadá následovně.

<?
$a=mysql_query("SELECT * FROM ankety WHERE zobrazit='a'");
if(mysql_num_rows($a)==1)
{
$b=mysql_fetch_array($a);
?>
<FORM METHOD="POST" ACTION="ankety_zapis.php">
<INPUT TYPE="HIDDEN" NAME="id" VALUE="<?=$b[id]?>">
<TABLE BORDER=0 WIDTH=185 ALIGN="CENTER" RULES="rows"
   FRAME="void" CELLPADDING=3 CELLSPACING=0>
<TR BGCOLOR="#CEB896" ALIGN="Center">
	<TD><B><?=$b[otazka]?></B></TD>
</TR>
<?
$oddelovac="@@";
$odpoved=explode($oddelovac,$b[odpovedi]);
$stav=explode($oddelovac,$b[stav]);
$celkem=array_sum($stav);
$procento=($celkem/100);
for($i=0;$i<count($odpoved);$i++)
{
if($odpoved=="")
	continue;
@$cast=round(($stav[$i]/$procento));
//zavináč je zde důležitý
$sirka=round($cast*1.8);
if($i%2) $bg=' BGCOLOR="#DEDFD6" ';
   else $bg=' BGCOLOR="#DBD1D5" ';
?>
<TR <?=$bg?>>
  <TD>
     <INPUT TYPE="RADIO" NAME="hlasovani" VALUE="<?=$i?>">
         <?=$odpoved[$i]?><BR>
       <IMG SRC="./images/enduser/cara.gif" WIDTH=<?=$sirka?>
         HEIGHT=10 ALIGN="left"><BR>
        Počet hlasů: <?=$stav[$i]?> (<?=$cast?>%)
        </TD>
</TR>
<?
}
?>
<TR>
   <TD ALIGN="Center" BGCOLOR="#C0C0C0">
   <? if($_COOKIE[anketa_rs]!="true"): ?>
      <INPUT TYPE="SUBMIT" VALUE="Hlasovat">
   <? else: ?>
      <CENTER>Již jste hlasoval(a)</CENTER>
   <? endif; ?>
   </TD>
</TR>
</TABLE>
</FORM> 
<?
}
?>

Vybereme anketu kterou zobrazíme (jak víme, může být jen jedna) a zobrazíme otázku. Následně si každou odpověď a hlasy k ní určené rozdělíme. Funkce Array_Sum() nám sečte hodnoty všech prvků v poli. Dostaneme celkový stav. Určíme si jedno procento (klasické počítání se senem pro X králíků na Y dní) a začneme zobrazovat. Spočítáme si délku čáry, jako podílu odpovědí. Soubor cara.gif budete mít v konečném balíčku. Proč je tam poznámka, že je zavináč důležitý? Je to prosté. Pokud se hlasuje prvně, je celkový součet odpovědí 0, to jest 1% z toho dostaneme 0 a jak vím, tak nulou se dělit nesmí. Číslo 1,8 je tam jen proto, aby to graficky trochu vypadalo a můžete si ho podle svého uvážení změnit. Za zmínku ještě stojí poslední podmínka. Ta uživateli zabrňuje, aby hlasoval vícekrát. Pokud má ovšem vyplý příjem cookies, je nám to k ničemu.

Poslední script, který si ukážeme je ankety_zapis.php, kterým nám zpracuje anketu.

<?
SetCookie("anketa_rs","true",time()+1800);
Header("Pragma: No-cache");
Header("Cache-Control: no-cache");
Header("Expires: ".GMDate("D, d M Y H:i:s")."GMT");

@include "./conn.php";

$a=mysql_query("SELECT stav FROM ankety WHERE id='$id'");
$b=mysql_fetch_array($a);

$oddelovac="@@";
$stav=explode($oddelovac,$b[stav]);

$stav[$hlasovani]++;

$st=implode($stav,$oddelovac);

@mysql_query("UPDATE ankety SET stav='$st' WHERE id='$id'");

Header("Location: ./index.php");
?>

Pošeleme cookies, která zabrání v hlasování na další půl hodinu. Délku platnosti cookies si můžete nastavit individuálně. Z databáze si zjistíme stav hlasování, rozdělíme pomocí oddělovačů a přičteme k příslušné hodnotě postinkrementací jedničku. Tuto hodnotu uložíme spolu se zbytkem znovu do databáze a přesměrujeme na úvodní stránku.

Tím jsme náš seriál zdárně zakončili a zde je ke stažení kompletní zdrojový kod, který byl tak dlouho žádaný. Přípdané dotazy k jeho úpravám, funkčnosti či nefunkčnosti, Vám zodpovím na svém e-mailu.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » PHP  

 » Rubriky  » Web  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: