<?php


// diese Seite stellt die Anmeldefunktion für die eh2007-Seite zur Verfügung
// (Topics: ~ heißt geplant, - heißt im Bau, + heißt implementiert.)
// + diese Seite liegt im öffentlichen Serverbereich, dieser darf *.php nicht als plain/text ausliefern ;)
// + diese Seite verlangt zwingend https

/*
Struktur dieser Seite:
	+ write HTTP header
	+ recall session
	+ check, defuse and shorten input variables
	+ Prüfung auf https
	 = OK => continue
	 = FAIL => Session-Zwangslogout, Abbruchmeldung und Schlußverarbeitung
	+ Prüfung auf Wartungsstatus
	 = OK => continue
	 = FAIL => Abbruchmeldung und Schlußverarbeitung
	+ Verarbeitung der Submit-Aktionen (POST), Anzeige des Anmeldeformulars
*/



// this script needs following additional server modules for PHP
// (none)

// write HTTP header (anti-cache)
header('Expires: Sun,	31 Dec 1989	23:59:59 GMT');
header('Last-Modified: ' . gmdate('D,	d	M	Y	H:i:s')	.	'	GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0');
header('Pragma:	no-cache');

// recall session
session_cache_limiter('nocache');
session_cache_expire(1);
session_start();

//deactivate automatic use of addslashes
// set_magic_quotes_runtime(0);

// define general server constants
define( "SERVER_SITE_MAINTENANCE", true );               // maintenance state, set to TRUE to lock this page temporarily
define( "SERVER_LOCALHOST_IP", "127.0.0.1" );             // localhost IP, which does not need authentication
define( "SERVER_PROTOCOL_HTTPS", "HTTPS" );               // HTTPS protocol name

// define server file constants
define( "SERVER_FILE_TEMPLATE", "template.shtml" );       // template file
define( "SERVER_FILE_HEADER", "ssi_site_header.html" );   // SSI file for site header
define( "SERVER_FILE_INTRO", "ssi_site_intro.html" );     // SSI file for site intro
define( "SERVER_FILE_EXTRO", "ssi_site_extro.html" );     // SSI file for site extro
define( "SERVER_FILE_AUTOGEN", "ssi_site_autogen.html" ); // SSI file for site autogeneration warning

define( "SERVER_FILE_ANMELDUNGSLISTE", "anmeldung-data/anmeldung.csv" ); // path and file for registered participants

// define display constants
define( "DISPLAY_TEXT_NONE", " " );
define( "DISPLAY_VALUE_SEPARATOR", chr(9));


// init instance variables
$intnow = time();

$bolauthloggedin = false;

$strmsg = '';                     // (status/error/etc.) message to user
$bolauthabort = false;            // auth check will be aborted: show auth warning
$bolauthlogoutnow = false;        // user will be logged out

$strnomailconfirmation = '';
$bolok = true;                   // action feedback, triggers confirmation if true or warning if false


// function library

function addmsg ($straddmsg)
{
   // adds $straddmsg to $strmsg
   global $strmsg;
   if ( $straddmsg != '' )
   {
      $strmsg = $strmsg . '<li>' . $straddmsg . '</li>';
   }
}

function showmsg ()
{
   // shows messages in $strmsg if available
   global $strmsg, $bolok;
   if ( $strmsg != '' )
   {
      echo'
      <div class="announcement">
         <h1 class="';
         if ( $bolok )
         {
            echo 'confirmation';
         }
         else
         {
         echo 'warning';
         }
         echo '">Feedback</h1>
         <ul>' . $strmsg . '</ul>
      </div>';
      $strmsg = '';
      $bolok = false;
   }
}

// prepare input variables in six steps
// 1. init internal variable, e.g.:  $strparam = '';
// 2. execute step 3 up to 6 only if external variable exists, e.g.:  if ( isset($_GET['txt_param']) )
// 3. convert to correct type, e.g.:  $gstrparam = (string) $_GET['param'];
// 4. defuse dangerous content, e.g.:  $gstrparam = trim( addslashes( htmlentities( urldecode( $gstrparam ), ENT_QUOTES )));
// 5. limit allowed size, e.g.:  if ( strlen( $gstrparam ) > 255 ) $gstrparam = substr( $gstrparam, 0, 255 );
// 6. on demand evaluate content and overwrite respective internal variables, e.g. $strparam = $gstrparam;


$strnick = '';
if ( isset($_POST['txt_nick']) )
{
  $pstrnick = (string) $_POST['txt_nick'];
  $pstrnick = str_replace( chr(13) . chr(10), '\n', $pstrnick );
  $pstrnick = str_replace( chr(13), '\n', $pstrnick );
  $pstrnick = str_replace( chr(10), '\n', $pstrnick );
  $pstrnick = str_replace( chr(9), '\t', $pstrnick );
  $pstrnick = trim( stripslashes( htmlentities( $pstrnick, ENT_QUOTES )));
  if ( strlen( $pstrnick ) > 255 ) $pstrnick = substr( $pstrnick, 0, 255 );
  $strnick = $pstrnick;
  
  if ( $strnick == '' )
  {
    addmsg ( 'Bitte w&auml;hle einen Nickname, mit dem Du auf dem Easterhegg angesprochen werden m&ouml;chtest.' );
    $bolok = false;
	}
}

$stremail = '';
if ( isset($_POST['txt_email']) )
{
  $pstremail = (string) $_POST['txt_email'];
  $pstremail = str_replace( chr(13) . chr(10), '\n', $pstremail );
  $pstremail = str_replace( chr(13), '\n', $pstremail );
  $pstremail = str_replace( chr(10), '\n', $pstremail );
  $pstremail = str_replace( chr(9), '\t', $pstremail );
  $pstremail = trim( stripslashes( htmlentities( $pstremail, ENT_QUOTES )));
  if ( strlen( $pstremail ) > 255 ) $pstremail = substr( $pstremail, 0, 255 );
  $stremail = $pstremail;
}

$strstatus = 'Normal';
if ( isset($_POST['opt_status']) )
{
  $pstrstatus = (string) $_POST['opt_status'];
  $pstrstatus = trim( stripslashes( htmlentities( $pstrstatus, ENT_QUOTES )));
  if ( strlen( $pstrstatus ) > 255 ) $pstrstatus = substr( $pstrstatus, 0, 255 );
  $strstatus = $pstrstatus;

	// zusätzliche Engelprüfung, falls jemand die Sperre gehackt hat
	if ( $strstatus == 'Engel' )
	{
    addmsg ( 'Eine Anmeldung als Engel ist nicht mehr m&ouml;glich.<br />Falls Du der Meinung bist, dass dies in Deinem speziellen Fall nicht klug ist, wende Dich bitte an die Organisatoren.' );
		$strstatus = 'Hacker';
	  $bolok = false;
	}

	// validate -> schöner (und aufwendiger) wären dynamische Arrays, aber das funktioniert auch so gut genug...
	if ( $strstatus != 'Normal' && $strstatus != 'Mitglied'  && $strstatus != 'Engel' && $strstatus != 'Ermaeszigt' )
	{
	  $strstatus = 'Hacker';
	}

	// Look! Hacker ;-)
	if ( $strstatus == 'Hacker' )
	{
    addmsg ( 'Aufgrund Deiner (fast) erfolgreichen Hackversuche gehen wir davon aus, dass Du bereits CCC-Mitglied bist. ;-)' );
	  $strstatus = 'Mitglied';
	}
}

$intwurst = 0;
if ( isset($_POST['txt_wurst']) )
{
  $pintwurst = (integer) $_POST['txt_wurst'];
  if ( $pintwurst > 65535 ) $pintwurst = 0;
  if ( $pintwurst >= 0 and $pintwurst <= 9 )
	{
	  $intwurst = $pintwurst;
	}
	else
	{
    addmsg ( 'Bitte korrigiere die Anzahl der Wurstbr&ouml;tchen, eine einstellige Zahl sollte genügen. ;-)' );
    $bolok = false;
	}
}

$intkaese = 0;
if ( isset($_POST['txt_kaese']) )
{
  $pintkaese = (integer) $_POST['txt_kaese'];
  if ( $pintkaese > 65535 ) $pintkaese = 0;
  if ( $pintkaese >= 0 and $pintkaese <= 9 )
	{
	  $intkaese = $pintkaese;
	}
	else
	{
    addmsg ( 'Bitte korrigiere die Anzahl der K&auml;sebr&ouml;tchen, eine einstellige Zahl sollte genügen. ;-)' );
    $bolok = false;
	}
}

$intmarmelade = 0;
if ( isset($_POST['txt_marmelade']) )
{
  $pintmarmelade = (integer) $_POST['txt_marmelade'];
  if ( $pintmarmelade > 65535 ) $pintmarmelade = 0;
  if ( $pintmarmelade >= 0 and $pintmarmelade <= 9 )
	{
	  $intmarmelade = $pintmarmelade;
	}
	else
	{
    addmsg ( 'Bitte korrigiere die Anzahl der Marmeladenbr&ouml;tchen, eine einstellige Zahl sollte genügen. ;-)' );
    $bolok = false;
	}
}

$bolobst = false;
if ( isset($_POST['chk_obst']) )
{
  $pbolobst = (bool) $_POST['chk_obst'];
  $bolobst = $pbolobst;
}

$bolmuesli = false;
if ( isset($_POST['chk_muesli']) )
{
  $pbolmuesli = (bool) $_POST['chk_muesli'];
  $bolmuesli = $pbolmuesli;
}

$bolanmeldung = false;
if ( isset($_POST['cmd_anmeldung']) )
{
  $pbolanmeldung = (bool) $_POST['cmd_anmeldung'];
  $bolanmeldung = $pbolanmeldung;
}


if
(
   // localhost access
   (
      // direkter Aufruf von localhost
      htmlspecialchars( $_SERVER['HTTP_X_FORWARDED_FOR'], ENT_QUOTES ) == ''
      &&
      htmlspecialchars( $_SERVER['REMOTE_ADDR'], ENT_QUOTES ) == constant("SERVER_LOCALHOST_IP")
   )
  ||
   (
      // indirekter Aufruf (z.B. transparenter SSL-Proxy) mit übergebenem localhost
      htmlspecialchars( $_SERVER['HTTP_X_FORWARDED_FOR'], ENT_QUOTES ) == constant("SERVER_LOCALHOST_IP")
   )
)
{
   // localhost ist immer eingeloggt
   $sbolauthloggedin = true;
}
else
{
   // check protocol and timeout
   // check secure connection
   // possible results:
   // - secure => continue
   // - insecure => force logout ($bolauthlogoutnow), show error page and prepare message ($strmsg)
   if
   (
      (
         // direct connection without HTTPS
         $_SERVER['HTTPS'] == ''
         &&
         $_SERVER['HTTP_X_FORWARDED_PROTO'] == ''
      )
      ||
      (
         // indirect connection without local HTTPS proxy, e.g. orenosp
         strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) != strtolower(constant("SERVER_PROTOCOL_HTTPS"))
         && $_SERVER['HTTP_X_FORWARDED_PROTO'] != ''
      )
   )
   {
      // insecure connection -> abort
      if ( !$bolauthlogoutnow && $sbolauthloggedin )
      {
         // active login over insecure connection -> force logout
         $bolauthlogoutnow = true;
         addmsg ( 'Du wirst ausgeloggt, da Deine Verbindung unsicher (unverschlüsselt) geworden ist.' );
      }
      addmsg ( '<a href="https://' . $_SERVER['HTTP_HOST'] . $_SERVER["PHP_SELF"] . '">Dein Verbindungsprotokoll ist HTTP. Bitte verwende für die Anmeldung Verschlüsselung mittels HTTPS.</a>' );
      $bolauthabort = true;
      $bolok = false;
   }


   // check auth timeout
   // possible results:
   // - auth active => continue
   // - auth timeout => force logout ($bolauthlogoutnow), prepare message ($strmsg) and continue

   if ( $sbolauthloggedin && !$bolauthlogoutnow )
      {
         // write message on user authentication expired -> also fire a logout ($bolauthlogoutnow)
         // echo '<div class="warning">Du wurdest ausgeloggt wegen mehr als ' . constant("AUTH_TIMEOUT_MINUTES") . ' Minuten Inaktivit&auml;t.</div><br>';
         $bolauthlogoutnow = true;
         addmsg ( 'Du wirst ausgeloggt wegen mehr als ' . constant("AUTH_TIMEOUT_MINUTES") . ' Minuten Inaktivit&auml;t.' );
      }
   // restart timeout
   $sintauthprevtime = $intnow;
}

if ( $bolauthlogoutnow || $bollogout )
{
   // logout
   if ( $bolauthlogoutnow )
   {
      addmsg ( 'Du wurdest automatisch ausgeloggt. Bitte gegebenenfalls erneut einloggen.' );
   }
   $sbolauthloggedin = false;
}

// check maintenance state
if ( constant("SERVER_SITE_MAINTENANCE") )
{
   // cancel because of maintenance
   $strmsg = '';
	 addmsg ( 'Die Anmeldung ist zurzeit deaktiviert.' );
	 $bolok = false;
   $bolauthabort = true;
}

// Well, Checkpoint.
// Now a defined and normal state of checking has been reached.
// Possible states are now:
// - $sbolauthloggedin = true: user has successfully authenticated and is still logged in
// - $sbolauthloggedin = false: user is either not (yet) authenticated or authentication has been expired
// If there were any messages on the way up to here, they are stored as list items (<li>) in variable $strmsg.


// check auth phrase if user tries to login
if ( !$bolauthabort )
{
    // login accepted
    $sbolauthloggedin = true;
}


// prepare page
// assume that all ssi files are there. No, I won't check _that_ explicitely.
// If they ain't there, the user gets a partial page. ...so what? ;o)

readfile( constant("SERVER_FILE_HEADER") );
echo'
<!-- begin of specific page header -->
   <title>Easterhegg 2007 - Anmeldung</title>
<!-- end of specific page header -->';

readfile( constant("SERVER_FILE_INTRO") );
echo'
<!-- begin of specific page content -->
';

echo
'
    <div id="main">
    
      <h1>Anmeldung</h1>

';
showmsg();

if ( !$sbolauthloggedin )
{
   // show anmeldung page and then die

   if ( !$bolauthabort )
   {
      // show login page
  }

	// close page and stoprun.
	echo'
	  
	<!-- end of specific page content -->
	
	';
	readfile( constant("SERVER_FILE_EXTRO") );
	
	die();
}

// Well, Checkpoint.
// Now the user is proofed to be successfully logged in. (All others are wiped out.)
// From here on the user is authorized to enjoy all the following features.
// default sequence within each chapter:
// 1. headline
// 2. submit action
// 3. showmsg();
// 4. user forms
// 5. showmsg();
// 6. five empty rows to separate from next chapter ;)



// show anmeldung chapter

if ( $bolanmeldung )
{
	if ( $bolok )
	{
	  // prüfen, ob die Anmeldungsliste überhaupt vorhanden und beschreibbar ist
	  if ( !is_writable( constant("SERVER_FILE_ANMELDUNGSLISTE") ))
	  {
	     addmsg ( 'Die Anmeldungsliste ist zurzeit nicht verf&uuml;gbar bzw. gesperrt.<br />Falls Du das Gef&uuml;hl hast, da&szlig; dies nicht okay ist, kontaktiere bitte die Orga-Crew. Danke Dir.');
	     $bolok = false;
	  }
	}

	if ( $bolok )
	{
	  // prüfen, ob dieser Nickname bereits angemeldet ist
	  $strfile = file_get_contents( constant("SERVER_FILE_ANMELDUNGSLISTE") );
	  
		if ( stripos( $strfile, chr(10) . html_entity_decode( $strnick, ENT_QUOTES ) . chr(9) ) !== false )
		{
		  // Nickname existiert bereits
	    addmsg ( 'Mit diesem Nickname ist bereits ein Teilnehmer angemeldet.<br />Bitte w&auml;hle einen anderen Nickname.' );
	    $bolok = false;
		}
	}
	
	if ( $bolok )
	{
  	// Anmeldung speichern
		if ( $intfileid = fopen( constant("SERVER_FILE_ANMELDUNGSLISTE"), "a" ))
		{
			if ( !fwrite( $intfileid, html_entity_decode( $strnick, ENT_QUOTES ) . chr(9) . $strstatus . chr(9) . html_entity_decode ( $stremail, ENT_QUOTES ) . chr(9) . $intwurst . chr(9) . $intkaese . chr(9) . $intmarmelade . chr(9) . (integer) $bolobst . chr(9) . (integer) $bolmuesli . chr(9) . date( "Y.m.d-H:i:s", $intnow ) . chr(10) ))
			{
			  $bolok = false;
			};
		  
			if ( !fclose( $intfileid ))
			{
		  	$bolok = false;
			}
		}
		else
		{
	  	$bolok = false;
		}
		
		if ( $bolok )
		{
		  if ( $stremail != '' )
		  {
		  	$strnomailconfirmation = '<br />Hinweis: Es wird keine zusätzliche Bestätigungsmail verschickt.';
			}
	  	addmsg ( 'Deine Anmeldung ist hiermit erfolgt. (' . date( "d.m.Y H:i:s", $intnow ) . ')' . $strnomailconfirmation );
			addmsg ( 'Vielen Dank f&uuml;r Dein Interesse - Bis bald in Hamburg.' );
		}
		else
		{
	  	addmsg ( 'Deine Anmeldung konnte nicht gespeichert werden!<br />Bitte kontaktiere die Orga-Crew! Du bist nicht angemeldet!' );
		}
	}
}
showmsg();

echo
'
<form id="anmeldungform" name="anmeldungform" action="' . $_SERVER["PHP_SELF"] . '" method="post">

<p>
  <span class="topic">Dein Nickname:</span>
		<input class="db" name="txt_nick" type="text" value="' . $strnick. '" />
  <span class="topic">Deine Emailadresse (optional):</span>
		<input class="db" name="txt_email" type="text" value="' . $stremail . '" />
</p>

  <span class="topic">Du zahlst einmalig f&uuml;r den gesamten Zeitraum (vier Tage):</span>
  
	<span class="line"><input name="opt_status" id="opt_status" class="control" type="radio" style="width:20px" value="Normal"';
if ( $strstatus == 'Normal' ) echo ' checked="checked"';
echo ' />50 Euro als Normalsterblicher</span>

	<span class="line"><input name="opt_status" id="opt_status" class="control"  type="radio" style="width:20px" value="Mitglied"';
if ( $strstatus == 'Mitglied' ) echo ' checked="checked"';
echo ' />35 Euro als CCC-Mitglied</span>

	<span class="line"><input name="opt_status" id="opt_status" class="control" type="radio" style="width:20px" disabled="true" value="Engel"';
if ( $strstatus == 'Engel' ) echo ' checked="checked"';
echo ' /><strike>25 Euro als Engel (freiwillige Helfer)</strike> - Es haben sich ausreichend Engel angemeldet -&gt; Danke!<span class="line" style="margin-left:50px">Falls speziell Du unbedingt noch zu den Engeln geh&ouml;ren solltest, wende Dich bitte an die Organisatoren.</span></span>

	<span class="line"><input name="opt_status" id="opt_status" class="control" type="radio" style="width:20px" value="Ermaeszigt"';
if ( $strstatus == 'Ermaeszigt' ) echo ' checked="checked"';
echo ' />25 Euro als Sch&uuml;ler, erwerbslos etc. (nur gegen g&uuml;ltigen Nachweis)</span>

<p>
	<span class="line">Im Preis enthalten ist eine Easterhegg-Tasse sowie ein t&auml;gliches Frühstück (Br&ouml;tchen, Wurst, Obst, K&auml;se, M&uuml;sli) als auch jederzeit Tee und Kaffee (Flatrate).</span>
</p>

<p>
	<span class="line">Zur Kalkulation der ben&ouml;tigten Nahrungsmenge teile uns bitte mit, was und wieviel Du t&auml;glich zum Fr&uuml;hst&uuml;ck ben&ouml;tigst.</span>
</p>

<p>
';

echo
'
  <span class="topic">Wurstbr&ouml;tchen: </span>
		<input class="right" name="txt_wurst" type="text" value="' . $intwurst . '" />
  <span class="topic">K&auml;sebr&ouml;tchen: </span>
		<input class="right" name="txt_kaese" type="text" value="' . $intkaese . '" />
  <span class="topic">Marmeladenbr&ouml;tchen: </span>
		<input class="right" name="txt_marmelade" type="text" value="' . $intmarmelade . '" />
';
 
echo '<span class="line"><input id="chk_obst" name="chk_obst" class="control" type="checkbox" value="' . (string) true . '"';
if ( $bolobst ) echo ' checked="checked"';
echo ' /> Obst </span>';

echo '<span class="line"><input id="chk_muesli" name="chk_muesli" class="control" type="checkbox" value="' . (string) true . '"';
if ( $bolmuesli ) echo ' checked="checked"';
echo ' /> M&uuml;sli </span>';

echo
'
</p>

<p>
  <input name="cmd_anmeldung" type="submit" value="Anmeldung best&auml;tigen" />
</p>

</form>



</p>
';

showmsg();





// close page and stoprun.
echo
'
<!-- end of specific page content -->

';
readfile( constant("SERVER_FILE_EXTRO") );

die();

?>