Cookiesperre bis Mittwochs

Hi Sven,

irgendwie scheint das ganze noch net zu funktionieren. Die cookiesperre bis nächsten Mittwoch klappt wunderbar, aber die zurücksetzung der txt haut nicht hin.

Ich hab die ganze Zeit hin und her probiert. Systemzeit vor- und zurückgesetzt, mit anderen Daten also Datumsangaben rumprobiert. Wenn ich es schaffe, dass er bis zum array_fill kommt, löscht bzw. füllt er die Datei neu, aber mit leeren Werten. Also die Datei ist einfach leer und das neue Voting wird nicht gezählt.

Das ist das gesamte Umfrage-Script.

PHP:
<?php


/*if (isset ($_POST["ergebnis"])) {
	// Aktuelle Sperre 1 Minute
	// 30 Tage Sperre time()+60*60*24*30
	setcookie("abgestimmt", "ja", time() + 60);
}*/
if (isset ($_POST["ergebnis"])) {
	setcookie("abgestimmt", "ja", strtotime("next Wednesday"));
}

$thema = "Fussball-Umfrage | Wer kommt, wer nicht?";
$auswahl = array (
	"Ja, ich komme!",
	"Nein, ich kann nicht!"
);

$personen = array (
	"Stefan",
	"Jaspi",
	"Christoph",
	"Heinz",
	"Ralf 1",
	"Ralf 2",
	"Berti",
	"Olli",
	"Bossi",
	"Katze",
	"Tomi",
	"Manu"
);
$anzahl = count($auswahl);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Fussball</title>
<meta name="keywords" content="" />
<meta name="description" content="" />
<link href="default.css" rel="stylesheet" type="text/css" />

</head>
<body>
<div id="header">
	
</div>

<div id="content">
<h3><?php echo $thema ?></h3>
<div style="float:left;">
<form method='post' action='<?php echo $PHP_SELF; ?>'>
<p>
<?php


echo "Wir haben den " . date("d.m.Y") . ", es ist jetzt " . date("H:i") . "h";

echo "<table class='tabelle'>";
foreach ($personen as $key => $person) {
	echo "<tr><td>" . $person . "</td>";
	foreach ($auswahl as $key => $eintrag) {
		echo "<td><input type='radio' name='ergebnis' value='$key'>$eintrag</td>\n";
	}
	echo "</tr>";
}
echo "</table>";
?>
</p>
<?php


if (empty ($_COOKIE["abgestimmt"]) && !isset ($_POST["ergebnis"])) {

	// Submit nur zeigen, wenn Formular noch nicht abgeschickt wurde
	echo "<input type='submit' value='Daten senden'>";

} else {
	echo "<p>Danke f&uuml;r die &Uuml;bermittlung der Daten! Die Abstimmung wird n&auml;chsten Mittwochabend wieder freigeschaltet! </p>\n";

	// Formular abgeschickt? Aber bisher noch nicht abgestimmt?
	if (empty ($_COOKIE["abgestimmt"]) && isset ($_POST["ergebnis"])) {
		// Dateiname in Variable speichern
		$datei = "daten/stimmen.txt";
		// Datei vorhanden?
		if (file_exists($datei)) {
			$fp = fopen($datei, "r+");
		} else {
			$fp = fopen($datei, "w");
		}
		// Datei einlesen
		$stimmen = fread($fp, filesize($datei));

		// String aus Datei in Array zerlegen
		$stimmen = explode(",", $stimmen);
		
		if (strtotime("last Tuesday") != strtotime("last Tuesday", filemtime($datei))) {
			$stimmen = array_fill(0, $anzahl, '0');
			//$stimmen = fopen($datei, "w+");*/
		} else {
			$stimmen[$_POST["ergebnis"]]++;
		}
		// Stimmen in einem String zusammensetzen
		for ($i = 0; $i < $anzahl; $i++) {
			$total .= $stimmen[$i] . ",";
		}
		// Der gewählte Punkt wird um 1 erhöht!
		//$stimmen[$_POST["ergebnis"]]++;

		// Neuen String in Datei schreiben
		rewind($fp);
		fputs($fp, $total);
		fclose($fp);
	}
}
?>
</form>
<p> 
[ <a href='ergebnis.php' target='_blank'>Umfrageergebnisse betrachten</a> ]
</p>
</div>

<div style="float:left">
<div id="footer">
	<p id="legal">Copyright &copy; 2009 chris4life. All Rights Reserved.</p>
</div>
</body>
</html>

Es gibt noch eine ergebnis.php, aber die sollte hier aussen vor sein.

Ich finde meinen Fehler einfach nicht.

Danke
Gruß
Chris
 
Nein, das ist ganz schlicht und einfach aufgebaut.

Dieses Voting basiert auf Vertrauensbasis indem Sinne, dass jeder nur für seinen Namen votet.

Die Leute die dieses Voting benutzen sollen, sind die Generation 40+. Alles andere, mit Login oder gar Registrierung wäre zu aufwendig. Ganz schlicht und einfach.
Allerhöchstens könnte noch eine maximale Anzahl der Cookiesetzung bestimmt werden. Also, dass maximal 14 Votings oder so möglich sind.

Ich will dir nicht deine Zeit stehlen. Wenn du mir nen Ansatz gibst, probier ich selbst weiter. Gestern habe ich den ganzen Tag gesessen und versucht. Ich stehe halt immernoch in den Startlöchern :)

Danke nochmal!

Gruß
Chris
 
Mmhh, na gut, wenn du meinst :eek:
Aus eigener Erfahrung kann ich dir sagen, dass auch Leute 40+ viel Unsinn verzapfen :-)


Aber trotzdem erschliesst sich mir der Sinn der ganzen $namen nicht...da deine Checkboxen alle den selben Namen haben, kann man eh nur für 1 abstimmen, und bisher konnte ich dem Themenverlauf nicht entnehmen, dass irgendwie gespeichert werden soll, wer wofür abgestimmt hat.

Wieauchimmer, aus der Ferne ist das schwer zu Sagen, wo was schiefläuft.

Hier mal eine "Testversion".
PHP:
<?php
error_reporting(E_ALL);
define('TEST',1);

$datei    = "daten/stimmen.txt";
$log      = array();
$auswahl  = array('nein','ja');
//Der leere Array
$reset    =array_fill(0,count($auswahl),'0');

//wenn abgestimmt wurde
if(isset($_POST['ergebnis']))
{
  $log[]='Du hast versucht, abzustimmen, folgende Daten wurden gesendet:'.print_r($_POST,true);
  //neuen Cookie setzen
  //beachte, dass dieser neue Cookie in dieser Skriptinstanz noch nicht verfügbar ist
  setcookie("abgestimmt", date('r',strtotime("next Wednesday")), strtotime("next Wednesday"));
  $log[]='neuer Cookie wurde gesetzt mit Ablaufdatum '.date('r',strtotime("next Wednesday"));
}
else
{
  $log[]='Es wurden keine Daten gesendet, du wirst nicht abstimmen';
}


//mal gucken, ob die Datei schon existiert
if(file_exists($datei))
{
  $log[]=$datei .' existiert, ich schaue mal, was drinnen steht';
  if(count(explode(',',file_get_contents($datei)))!=count($auswahl))
  { 
     $log[]='das Datenformat stimmt nicht, ich versuche zu resetten';
     if(!file_put_contents($datei,implode(',',$reset)))
     {
      $log[]='resetten nicht möglich, die Datei scheint nicht schreibbar zu Sein';
      die('<ul><li>'.implode('</li><li>',$log).'</li></ul>');
     }
  }
}
else
{
  $log[]=$datei .' existiert noch nicht, versuche sie anzulegen';
  if(!file_put_contents($datei,implode(',',$reset)))
     {
      $log[]='anlegen nicht möglich, Zugriffsrechte überprüfen';
      die('<ul><li>'.implode('</li><li>',$log).'</li></ul>');
     }
}

//Testhalber touch'n bei Bedarf 
  if(isset($_POST['ergebnis']) && (TEST && isset($_POST['touch'])))
  {
    $log[]='Testhalber wird versucht, das Änderungsdatum zurückzusetzen';
    if(touch($datei,strtotime("last Tuesday")))
    {
      $log[]='touch() war erfolgreich';
    }
    else
    {
      $log[]='touch() fehlgeschlagen';
    }
  } 

//Aktueller Inhalt
$log[]='Momentan gespeichertes Ergebnis<pre>'.
        print_r(
                  array_combine(
                                $auswahl,
                                explode(',',file_get_contents($datei))
                              ),
                  true
                ).'</pre>';

//Cookie prüfen
if(isset($_COOKIE['abgestimmt']))
{
  $log[].='es existiert ein Cookie mit Ablaufdatum '.$_COOKIE['abgestimmt'];
}

//OK, dann los mit der Abstimmung
if(isset($_POST['ergebnis']))
{
  if(!isset($_COOKIE['abgestimmt'])  || (TEST && isset($_POST['nocookie'])))
  {
    if(isset($_COOKIE['abgestimmt']))
    {
      $log[].='du hast bereits abgestimmt, ich werde das testhalber ignorieren';
    }
    else
    {
      $log[].='du hast noch nicht abgestimmt';
    }
    
    //Abstimmung noch aktuell?
    if(strtotime("last Tuesday") != strtotime("last Tuesday",filemtime($datei)))
    {
      $log[]='Die Abstimmung ist abgelaufen, es wird eine neue begonnen';
      $stimmen=$reset;
    }
    else
    {
      $log[]='Die Abstimmung ist noch aktuell, sie wird geupdatet';
      $stimmen=explode(',',file_get_contents($datei));
    }
    //Ergebnis eintragen
    if(isset($stimmen[$_POST['ergebnis']]))
    {
      $stimmen[$_POST['ergebnis']]++;
      $log[]='Stimme <strong>'.$auswahl[$_POST['ergebnis']].'</strong> wurde gezählt';
      if(file_put_contents($datei,implode(',',$stimmen)))
      {
        $log[]='Stimmen wurden in Datei gespeichert';
        
        //Nochmal zur Kontrolle neues Ergebnis
        $log[]='Neu gespeichertes Ergebnis<pre>'.
                print_r(
                        array_combine(
                                      $auswahl,
                                      explode(',',file_get_contents($datei))
                                      ),
                        true
                      ).'</pre>';
      }
      else
      {
        $log[]='Stimmen konnten nicht in Datei gespeichert werden';
      }
    }
    else
    {
      $log[].='Es trat ein unerwarteter Fehler auf, 
               $_POST[ergebnis] enthält einen unerwarteten Wert';
    }
  }
  else
  {
    $log[].='<strong>du hast bereits abgestimmt, versuche es ab nächsten Mittwoch wieder</strong>';
    if(!TEST)echo end($log);
  }
}

if(TEST)echo('<ul><li>'.implode('</li><li>',$log).'</li></ul>');

?>
<form method="post">
<fieldset style="float:left;text-align:center;padding:12px;">
<fieldset style="float:left;text-align:left;">
  <legend>
    Abstimmung
  </legend>
  <?php
    foreach($auswahl as $key => $value)
    {
      echo '<input type="radio" name="ergebnis" value="'.$key.'" />'.$value.'<br />';
    }
  ?>
</fieldset>

<?php if(TEST){ ?>
<fieldset style="float:left;text-align:left;">
  <legend>
    Test-Optionen
  </legend>
  <input type="checkbox" name="nocookie" />Cookie&nbsp;ignorieren<br />
  <input type="checkbox" name="touch" />Dateidatum&nbsp;zurücksetzen<br />
</fieldset>
<?php } ?>


<br style="clear:both" /><input type="submit" />
</fieldset>
</form>

Keine Angst, sieht vielleicht nach viel aus, das meiste dient nur der Ablaufverfolgung.
Es loggt zu jedem wichtigen Vorgang das Geschehene und gibt es am Ende aus.
So kannst du verfolgen, was wo passiert, vor allem, wenn ein Fehler passiert.

Du findest im Formular 2 Optionen, darüber kannst du einstellen, ob:
1. Dein vorhandener Cookie ignoriert werden soll
2. Das Dateidatum auf den letzten Dienstag zurückgesetzt werden soll

...damit du das nicht immer von Hand machen musst.
So kannst du prüfen, ob alles unter den verschiedenen Fällen richtig reagiert,

Sollte etwas nicht so funktionieren, kannst du die Liste mit den Meldungen hier posten, das erleichtert die Diagnose.:)

Wenn du das ganze Testdrumherum nicht sehen willst, findest du oben eine Konstante "TEST", ändere ihren Wert auf 0.

P.S. Ich habe dort statt fopen() usw. file_get_contents() und file_put_content() verwendet.
Das ist bequemer, weil man mal schnell vergisst, eine per fopen() geöffnete Datei wieder zu Schliessen, file_put_contents() erfordert allerdings PHP5.
Checke das also besser vorher, wenn du nicht sicher bist, welche PHP-Version da läuft.
 
Hallo Sven,

sry, dass ich mich jetzt erst zurückmelde.

Das sieht sehr beeindruckend aus, was du da gemacht hast. Das hätte ich so nie und nimmer hinbekommen (zumindest jetzt noch nicht).

Könnte dieses Script vielleicht schon alles gewesen sein?

Viele Grüße
Christoph
 
Zurück