<?php // diese Seite stellt Orga-Funktionen 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 // + diese Seite fragt ein Authentifikationspasswort ab // + die Authentifikation läuft nach einer gewissen Zeitspanne (Konstante) ab // + es dürfen von dieser Seite aus keine anderen orga-spezifischen Seiten aufgerufen werden, // da dies eventuell eine Umgehungsmöglichkeit der Authentifizierung zur Folge haben könnte /* 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 gültigen Loginstatus, inkl. Timeout = OK => continue = FAIL => Authentifizierungsformular, Abbruchmeldung und Schlußverarbeitung + Prüfung auf Wartungsstatus = OK => continue = FAIL => Abbruchmeldung und Schlußverarbeitung + Login = OK => continue = FAIL => Authentifizierungsformular, Abbruchmeldung und Schlußverarbeitung + Verarbeitung der Submit-Aktionen (POST), Anzeige der einzelnen Orga-Formulare */ /* known bugs / todo - Script rennt in einen Loop-of-Death, wenn man auf einen Button klickt, während die Seite (z.B. wegen dem Fahrplan-Editor) noch nicht fertig aufgebaut war -> Session hängt sich auf. Dieses Problem taucht auf webtest.hamburg.ccc.de auf, ist aber lokal (auf Rainers Notebook) nicht reproduzierbar. -> php-Version oder "nur" Config-Problem? (deadlock-timeout?) */ // this script needs following additional server modules for PHP // - Database: (e.g. pgsql) // 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(); // include library files // ja genau, die ist hier jetzt auch direkt aus dem htdocs abrufbar; // ist aber egal, denn da steht nix kritisches drin und die Seite ist auch rein passiv require("inc_db.php"); // define general server constants define( "SERVER_SITE_MAINTENANCE", false ); // 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_MYSELF", "orga.php" ); // submit target of forms = this file itself define( "SERVER_FILE_TEMPLATE", "template.shtml" ); // template file define( "SERVER_FILE_WORKSHOPS", "workshops.shtml" ); // workshops file define( "SERVER_FILE_FAHRPLAN", "fahrplan.shtml" ); // fahrplan 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 display constants define( "DISPLAY_TEXT_NONE", " " ); define( "DISPLAY_VALUE_SEPARATOR", chr(9)); // define auth constants define( "AUTH_TIMEOUT_MINUTES", 10 ); // idle timeout for login session define( "AUTH_SERVER_PASS", "?AdminOsterhase#2007" ); // login password, [todo:] should be outsourced to an external, secured data file // define constants for database data define( "DB_ID_NONE", 0 ); define( "DB_ID_NEW", -1 ); // define constants for database access // define SERVER_DB_TYPE as supported type in library db.php define( "SERVER_DB_TYPE", constant("DB_TYPE_POSTGRESQL") ); define( "SERVER_DB_HOST", "localhost" ); define( "SERVER_DB_PORT", 5432 ); define( "SERVER_DB_NAME", "eh2007" ); define( "SERVER_DB_USER", "eh2007" ); define( "SERVER_DB_PASS", "Osterhase2007" ); // // init references to $_SESSION variables ($sxxx) $sbolauthloggedin = & $_SESSION['bolauthloginok']; $sintauthprevtime = & $_SESSION['intauthprevtime']; // init session variables if ( !isset($sbolauthloggedin) ) $sbolauthloggedin = false; if ( !isset($sintauthprevtime) ) $sintauthprevtime = time(); // init references to $_POST variables ($pxxx) $pstrauth = & $_POST['txtauth']; $pbollogin = & $_POST['cmdlogin']; $pbollogout = & $_POST['cmdlogout']; $pbolmakeworkshops = & $_POST['cmdmakeworkshops']; $pbolmakefahrplan = & $_POST['cmdmakefahrplan']; $pbolrunsql = & $_POST['cmdrunsql']; $pbolwsupdate = & $_POST['cmdwsupdate']; $pbolsdactivate = & $_POST['cmdsdactivate']; $pbolsdupdate = & $_POST['cmdsdupdate']; $plstschedule = & $_POST['cboschedule']; $pintwsid = & $_POST['txtwsid']; if ( !isset( $pintwsid ) ) { $pintwsid = & $_POST['cboworkshop']; } $pstrwsname = & $_POST['txtwsname']; $pstrwsspeakers = & $_POST['txtwsspeakers']; $pintwsduration = & $_POST['txtwsduration']; $pstrwscontent = & $_POST['txtwscontent']; $pstrwscomment = & $_POST['txtwscomment']; $pstrsql = & $_POST['txtsql']; // init post variables (only for mandatory variables, ignore variables submitted by special forms!) if ( !isset($pstrauth) ) $pstrauth = ''; if ( !isset($pintwsid) ) $pintwsid = constant("DB_ID_NONE"); if ( !isset($pstrwsname) ) $pstrwsname = ''; if ( !isset($pstrwsspeakers) ) $pstrwsspeakers = ''; if ( !isset($pintwsduration) ) $pintwsduration = 0; if ( !isset($pstrwscontent) ) $pstrwscontent = ''; if ( !isset($pstrwscomment) ) $pstrwscomment = ''; if ( !isset($pstrsql) ) $pstrsql = ''; if ( !isset($plstschedule) ) $plstschedule = array(); // init instance variables $intnow = time(); $strmsg = ''; // (status/error/etc.) message to user $bolauthabort = false; // auth check will be aborted: show authentication page $bolauthlogoutnow = false; // user will be logged out $intdbconnid = 0; $intdbresult = 0; $lngdbrows = 0; $strdbfields = array(); $strdberror = ''; $strdbsql = ''; $strdbrow = ''; $strdbsql2 = ''; $strweekdayname = array (0 => 'Sonntag', 1 => 'Montag', 2 => 'Dienstag', 3 => 'Mittwoch', 4 => 'Donnerstag', 5 => 'Freitag', 6 => 'Samstag'); $strvalue = ''; $intindex = 0; $intcolrotate = 1; $strinput = ''; $stroutput = ''; $intfileid = 0; $intcount = 0; $strauth = ''; $bollogin = false; $bollogout = false; $bolmakefahrplan = false; $bolmakeworkshops = false; $bolrunsql = false; $bolwsupdate = false; $bolsdactivate = false; $bolsdupdate = false; $strtablehead = ''; $intcolrot = 0; $intsdyear = 0; $intsdmonth = 0; $intsdday = 0; $intsdhour = 0; $strroname = ''; $boleof = false; $strworkshoplist = ''; $intwsid = constant("DB_ID_NONE"); $strwsname = ''; $strwsspeakers = ''; $intwsduration = 0; $strwscontent = ''; $strwscomment = ''; $strsql= ''; $strdbfields = ''; $lstschedule = array(); $strscheduleindex = ''; $intscheduleindex = constant("DB_ID_NONE"); $intschedulevalue = constant("DB_ID_NONE"); $bolok = false; // 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"> <h3 class="'; if ( $bolok ) { echo 'confirmation'; } else { echo 'warning'; } echo '">Feedback</h3> <ul>' . $strmsg . '</ul> </div> '; $strmsg = ''; $bolok = false; } } function selectws ( $intwsid ) { // selects workshop with $intwsid of $strworkshoplist global $strworkshoplist; return str_replace( '<option value="' . $intwsid . '">', '<option value="' . $intwsid . '" selected="selected">', $strworkshoplist ); } // check input variables //$bollogin = isset( $pbollogin ); // does not work in IE when submitted from within a text field by pressing Return key, reason unknown $bollogin = ( isset( $pbollogin ) || $pstrauth != '' ); //workaround for IE problem, see line above $bollogout = ( isset( $pbollogout ) || $bollogin ); //also fire a logout before (re-)login $bolmakefahrplan = ( isset( $pbolmakefahrplan ) ); $bolmakeworkshops = ( isset( $pbolmakeworkshops ) ); $bolrunsql = ( isset( $pbolrunsql ) ); $bolwsupdate = ( isset( $pbolwsupdate ) ); $bolsdactivate = ( isset( $pbolsdactivate ) ); $bolsdupdate = ( isset( $pbolsdupdate ) ); $intwsid = $pintwsid; $strwsname = $pstrwsname; $strwsspeakers = $pstrwsspeakers; $intwsduration = $pintwsduration; $strwscontent = $pstrwscontent; $strwscomment = $pstrwscomment; $strsql = $pstrsql; // todo: check control lists for invalid values! $lstschedule = $plstschedule; // defuse input variables $strauth = trim( htmlentities( $pstrauth, ENT_QUOTES )); $intwsid = intval( $intwsid ); $strwsname = trim( htmlentities( $strwsname, ENT_QUOTES )); $strwsspeakers = trim( htmlentities( $strwsspeakers, ENT_QUOTES )); $intwsduration = intval( $intwsduration ); $strwscontent = trim( htmlentities( $strwscontent, ENT_QUOTES )); $strwscomment = trim( htmlentities( $strwscomment, ENT_QUOTES )); $strsql = trim( htmlentities( $strsql, ENT_QUOTES )); // shorten input variables if ( strlen( $strauth ) > 255 ) $strauth = substr( $strauth, 0, 255 ); //cut it, do not modify if ( strlen( $strwsname ) > 255 ) $strwsname = substr( $strwsname, 0, 252 ) . "..."; if ( strlen( $strwsspeakers ) > 255 ) $strwsspeakers = substr( $strwsspeakers, 0, 252 ) . "..."; if ( strlen( $strwscontent ) > 4095 ) $strwscontent = substr( $strwscontent, 0, 4092 ) . "..."; if ( strlen( $strwscomment ) > 4095 ) $strwscomment = substr( $strwscomment, 0, 4092 ) . "..."; if ( strlen( $strsql ) > 4095 ) $strsql = substr( $strsql, 0, 4095 ); //cut it, do not modify 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 ( 'Dein Verbindungsprotokoll ist HTTP. Bitte verwende für die Orga-Seite Verschlüsselung mittels HTTPS.' ); $bolauthabort = true; } // check auth timeout // possible results: // - auth active => continue // - auth timeout => force logout ($bolauthlogoutnow), prepare message ($strmsg) and continue if ( $sbolauthloggedin && !$bolauthlogoutnow && ( $intnow > ( $sintauthprevtime + 60 * constant("AUTH_TIMEOUT_MINUTES") ))) { // 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ät.</div><br>'; $bolauthlogoutnow = true; addmsg ( 'Du wirst ausgeloggt wegen mehr als ' . constant("AUTH_TIMEOUT_MINUTES") . ' Minuten Inaktivitä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 addmsg ( 'Die Orga-Seite ist zurzeit wegen Wartungsarbeiten deaktiviert. Bitte später wiederkommen. Danke.' ); $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 && $bollogin && $strauth > '' ) { if ( $strauth == constant("AUTH_SERVER_PASS") ) { // login accepted $sbolauthloggedin = true; } else { // login failed $sbolauthloggedin = false; addmsg ( 'Das klappt so nicht. Vermutlich hast Du Dich vertippt.' ); } } // prepare orga 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 - Orga</title> <!-- end of specific page header --> '; readfile( constant("SERVER_FILE_INTRO") ); echo ' <!-- begin of specific page content --> '; echo ' <div class="announcement"> <h3 class="announcement">interne Orga</h3> </div> '; // show msg, if available if ( $strmsg != '' ) { echo ' <div class="announcement"> <h3 class="warning">Authentifizierungshinweis:</h3> <ul>' . $strmsg . '</ul> </div> '; $strmsg = ''; } if ( !$sbolauthloggedin ) { // show authentication page and then die if ( !$bolauthabort ) { // show login form echo ' <div class="chapter"> <h4>*knock-knock*</h4> <form id="loginform" name="loginform" action="' . constant("SERVER_FILE_MYSELF") . '" method="post"> <input name="txtauth" type="password"> <input name="cmdlogin" type="submit" value="Lass mich rein!"> </form> </div> '; } // 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 logout chapter echo ' <div class="chapter"> <h4>Logout</h4> </div>'; showmsg(); echo ' <div> <form id="logoutform" name="logoutform" action="' . constant("SERVER_FILE_MYSELF") . '" method="post"> <p> <input name="cmdlogout" type="submit" value="Bin fertig!" /> </p> </form> </div> '; showmsg(); // show make workshops chapter echo ' <div class="chapter"> <h4>make install Workshops</h4> </div> '; if ( $bolmakeworkshops ) { //make workshops $bolok = false; $stroutput = ''; // read workshops $strdbsql = " select ws_id, ws_name, ws_speakers, ws_content" . " from tbl_workshops ws" . " order by ws_name"; addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // workshops found // -> use them while ( db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror )) { // for each workshop: $stroutput = $stroutput . ' <div class="chapter"> <a id="ws' . $strdbrow['ws_id'] . '" class="linktarget"> </a> <h4>' . $strdbrow['ws_name'] . '</h4> <p> <span class="topic">' . $strdbrow['ws_speakers'] . '</span> </p> <div class="chaptercontent"> ' . html_entity_decode( $strdbrow['ws_content'], ENT_QUOTES ) . ' </div> </div> '; } // don't allow to finish properly until finished developing! $bolok = true; } else { // no workshops found // -> hmm, that should not happen, but even then there should be no data anyway... } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Abfrage der Workshops verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } if ( $bolok ) { // operation has succeeded -> now generate workshop file $stroutput = ' <div class="announcement"> <h3 class="announcement">Workshops</h3> Stand: ' . date( "d.m.Y H:i:s", $intnow ) . ' </div> <div> ' . $stroutput . ' </div> '; // add autogeneration-warning $stroutput = file_get_contents( constant("SERVER_FILE_AUTOGEN") ) . $stroutput; $strinput = file_get_contents( constant("SERVER_FILE_TEMPLATE") ); $strinput = str_replace( "[%title%]", "Workshops", $strinput ); $stroutput = str_replace( "[%content%]", $stroutput, $strinput ); if ( is_writable( constant("SERVER_FILE_WORKSHOPS") )) { // file_put_contents does not work with PHP 4.x, so use instead: fopen, fwrite, fclose // file_put_contents( constant("SERVER_FILE_WORKSHOPS"), $stroutput ); $intfileid = fopen( constant("SERVER_FILE_WORKSHOPS"), "w" ); fwrite( $intfileid, $stroutput ); fclose( $intfileid ); $bolok = true; } else { addmsg ( 'Die Workshopdatei "' . constant("SERVER_FILE_WORKSHOPS") . '" konnte nicht geschrieben werden. (Rechteproblem?)'); $bolok = false; } } // write result if ( $bolok ) { addmsg ( 'Die Workshopdatei wurde erfolgreich aktualisiert.' ); } else { addmsg ( 'Die Workshopdatei wurde nicht aktualisiert.' ); } } showmsg(); echo ' <div> <form id="makeworkshopsform" name="makeworkshopsform" action="' . constant("SERVER_FILE_MYSELF") . '" method="post"> <p> Hier wird die (statische) Workshopseite auf Basis der aktuellen Datenbank neu erstellt. <br /> Achtung: Die alte Workshopseite wird dabei unwiderruflich überschrieben! </p> <p> <input name="cmdmakeworkshops" type="submit" value="Workshopdatei jetzt erstellen!" /> </p> </form> </div> '; showmsg(); // show make fahrplan chapter echo ' <div class="chapter"> <h4>make install Fahrplan</h4> </div> '; if ( $bolmakefahrplan ) { //make fahrplan $bolok = false; $stroutput = ''; // prepare table header with room names // read rooms $strdbsql = " select ro_name" . " from tbl_rooms ro" . " order by ro_schedpos"; addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // rooms found // -> use them $strtablehead = ''; while ( db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror )) { // for each room: $strtablehead = $strtablehead . ' <td class="db">' . $strdbrow['ro_name'] . '</td> '; } $bolok = true; } else { // no rooms found // -> hmm, that should not happen, but even then there should be no data anyway... } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Abfrage der Raumliste verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } if ( $bolok ) { // read schedule slots with workshops $strdbsql = " select extract(hour from sd_begintime) as sd_begintime_hour, extract(day from sd_begintime) as sd_begintime_day," . " extract(month from sd_begintime) as sd_begintime_month, extract(year from sd_begintime) as sd_begintime_year," . " extract(dow from sd_begintime) as sd_begintime_weekday, sd_begintime," . " ws_id, ws_name, ws_speakers,". " ro_name" . " from tbl_schedule sd" . " left join tbl_workshops ws on sd.sd_ws_id = ws.ws_id" . " left join tbl_rooms ro on sd.sd_ro_id = ro.ro_id" . " order by sd_begintime, ro_schedpos"; addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // scheduled events found // -> use them // es folgt: Gruppenwechsel über Tag, Timeslot, Raum, Schedule-Event // Gesamtvorlauf $intsdyear = 0; $intsdmonth = 0; $intsdday = 0; $intsdhour = 0; $strroname = ''; $boleof = false; $boleof = !db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror ); while ( !$boleof ) { // Gruppenvorlauf Tag $intsdyear = $strdbrow['sd_begintime_year']; $intsdmonth = $strdbrow['sd_begintime_month']; $intsdday = $strdbrow['sd_begintime_day']; // neue Tabelle initialisieren $intcolrot = 1; $stroutput = $stroutput . ' <div class="chapter"> <table class="db"> <tr class="dbhead"> <td class="db"> ' . $strweekdayname[ $strdbrow['sd_begintime_weekday'] ] . '<br /> ' . $intsdday . '.' . $intsdmonth . '. </td> '; $stroutput = $stroutput . $strtablehead; $stroutput = $stroutput . ' </tr> '; while ( !$boleof && ( $intsdyear == $strdbrow['sd_begintime_year'] && $intsdmonth == $strdbrow['sd_begintime_month'] && $intsdday == $strdbrow['sd_begintime_day'] ) ) { // Gruppenvorlauf Timeslot $intsdhour = $strdbrow['sd_begintime_hour']; // neue Tabellenzeile initialisieren $intcolrot = abs( $intcolrot - 1 ); $stroutput = $stroutput . ' <tr class="db' . $intcolrot . '"> <td class="db"> ' . $intsdhour . '<span class="small">:00</span> </td> '; while ( !$boleof && ( $intsdyear == $strdbrow['sd_begintime_year'] && $intsdmonth == $strdbrow['sd_begintime_month'] && $intsdday == $strdbrow['sd_begintime_day'] ) && ( $intsdhour == $strdbrow['sd_begintime_hour'] ) ) { // Gruppenvorlauf Schedule-Event $strroname = $strdbrow['ro_name']; // neue Tabellenzelle initialisieren $stroutput = $stroutput . ' <td class="db"> '; while ( !$boleof && ( $intsdyear == $strdbrow['sd_begintime_year'] && $intsdmonth == $strdbrow['sd_begintime_month'] && $intsdday == $strdbrow['sd_begintime_day'] ) && ( $intsdhour == $strdbrow['sd_begintime_hour'] ) && ( $strroname == $strdbrow['ro_name'] ) ) { // Datensatz (Schedule-Event) verarbeiten if ( $strdbrow['ws_name'] > '') { $stroutput = $stroutput . '<a class="db" href="' . constant("SERVER_FILE_WORKSHOPS") . '#ws' . $strdbrow['ws_id'] . '">' . $strdbrow['ws_name']; if ( $strdbrow['ws_speakers'] > '') { $stroutput = $stroutput . '<span class="line small"> (' . $strdbrow['ws_speakers'] . ')</span>'; } $stroutput = $stroutput . '</a>'; } // neuen Datensatz lesen $boleof = !db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror ); } // Gruppennachlauf Schedule-Event // Tabellenzelle finalisieren $stroutput = $stroutput . ' </td> '; } // Gruppennachlauf Timeslot // Tabellenzeile finalisieren $stroutput = $stroutput . ' </tr> '; } // Gruppennachlauf Tag // Tabelle finalisieren $stroutput = $stroutput . ' </table> </div> '; } // Gesamtnachlauf // Gesamtausgabe finalisieren addmsg ( 'Die Fahrplandaten wurden erfolgreich zusammengestellt. Die Fahrplandatei kann jetzt geschrieben werden.' ); $bolok = true; } else { // no scheduled events found // -> hmm, that should not happen, but even then there should be no data anyway... } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Abfrage des Fahrplans verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } } if ( $bolok ) { // operation has succeeded -> now generate schedule file $stroutput = ' <div class="announcement"> <h3 class="announcement">Fahrplan</h3> Stand: ' . date( "d.m.Y H:i:s", $intnow ) . ' </div> ' . $stroutput . ' <div class="chapter"> <h4>feste Einrichtungen</h4> <p> <span class="topic">Projektleitung:</span> NOC (OG), POC (OG) </p> <p> <span class="topic">CERT (Rot-Kreuz):</span> Flur (OG) </p> <p> <span class="topic"><a href="workshops.shtml#ws3">CAcert</a>:</span> Work3 (OG), bei den Funkamateuren </p> <p> <span class="topic">Freifunker:</span> Werkstatt (OG), hinter Work3 </p> <p> <span class="topic">Fest- und Flüssignahrung:</span> Cafe, vorderer Teil (EG) </p> </div> '; // add autogeneration-warning $stroutput = file_get_contents( constant("SERVER_FILE_AUTOGEN") ) . $stroutput; $strinput = file_get_contents( constant("SERVER_FILE_TEMPLATE") ); $strinput = str_replace( "[%title%]", "Fahrplan", $strinput ); $stroutput = str_replace( "[%content%]", $stroutput, $strinput ); if ( is_writable( constant("SERVER_FILE_FAHRPLAN") )) { // file_put_contents does not work with PHP 4.x, so use instead: fopen, fwrite, fclose // file_put_contents( constant("SERVER_FILE_FAHRPLAN"), $stroutput ); $intfileid = fopen( constant("SERVER_FILE_FAHRPLAN"), "w" ); fwrite( $intfileid, $stroutput ); fclose( $intfileid ); $bolok = true; } else { addmsg ( 'Die Fahrplandatei "' . constant("SERVER_FILE_FAHRPLAN") . '" konnte nicht geschrieben werden. (Rechteproblem?)'); $bolok = false; } } // write result if ( $bolok ) { addmsg ( 'Die Fahrplandatei wurde erfolgreich aktualisiert.' ); } else { addmsg ( 'Die Fahrplandatei wurde nicht aktualisiert.' ); } } showmsg(); echo ' <div> <form id="makefahrplanform" name="makefahrplanform" action="' . constant("SERVER_FILE_MYSELF") . '" method="post"> <p> Hier wird die (statische) Fahrplanseite auf Basis der aktuellen Datenbank neu erstellt. <br /> Achtung: Die alte Fahrplanseite wird dabei unwiderruflich überschrieben! </p> <p> <input name="cmdmakefahrplan" type="submit" value="Fahrplandatei jetzt erstellen!" /> </p> </form> </div> '; showmsg(); // show workshop editor chapter echo ' <div class="chapter"> <h4>Workshop Editor</h4> </div> <a id="wseditor"'; if ( $intwsid != constant("DB_ID_NONE") ) { echo ' class="linktarget" '; } echo '><!-- space to avoid anchor being displayed below topbars --></a> '; if ( $bolwsupdate && $intwsid != constant("DB_ID_NONE") ) { // update workshop // if $intwsid == constant("DB_ID_NEW") create new workshop else update existing $bolok = false; if ( $intwsid != constant("DB_ID_NEW") ) { // update existing workshop $strdbsql = " ws_name = '" . $strwsname . "'," . " ws_speakers = '" . $strwsspeakers . "'," . " ws_content = '" . $strwscontent . "'," . " ws_comment = '" . $strwscomment . "',"; if ( $intwsduration != '' ) { $strdbsql = $strdbsql . " ws_duration = " . $intwsduration . ","; } else { $strdbsql = $strdbsql . " ws_duration = NULL,"; } $strdbsql = " update tbl_workshops set " . substr( $strdbsql, 0, strlen( $strdbsql ) - 1 ) . " where ws_id = " . $intwsid; addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // update successful addmsg ( 'Erfolgreich aktualisiert: ' . $lngdbrows . ' Workshop(s).' ); $bolok = true; } else { // update failed addmsg ( 'Aktualisierung fehlgeschlagen!<br />Die Datenbank sagt: ' . $strdberror ); } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Workshop-Aktualisierung verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } } else { // insert new workshop $strdbsql = ''; if ( $strwsname != '' ) { $strdbfields = $strdbfields . " ws_name,"; $strdbsql = $strdbsql . " '" . $strwsname . "',"; } if ( $intwsduration != '' ) { $strdbfields = $strdbfields . " ws_duration,"; $strdbsql = $strdbsql . " " . $intwsduration . ","; } if ( $strwsspeakers != '' ) { $strdbfields = $strdbfields . " ws_speakers,"; $strdbsql = $strdbsql . " '" . $strwsspeakers . "',"; } if ( $strwscontent != '' ) { $strdbfields = $strdbfields . " ws_content,"; $strdbsql = $strdbsql . " '" . $strwscontent . "',"; } if ( $strwscomment != '' ) { $strdbfields = $strdbfields . " ws_comment,"; $strdbsql = $strdbsql . " '" . $strwscomment . "',"; } if ( $strdbsql != '' ) { // get nextval $strdbsql2 = "select nextval('seq_ws_id')"; addmsg ( 'Running SQL: ' . $strdbsql2 ); if ( db_sql( $intdbconnid, $strdbsql2, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { if ( db_row ( $intdbresult, $strdbrow, constant("DB_ROW_FIRST"), $strdberror )) { // nextval succeeded addmsg ( 'Nextval erhalten: ' . $strdbrow['nextval'] ); $intwsid = $strdbrow['nextval']; $strdbfields = " ws_id," . $strdbfields; $strdbsql = " " . $intwsid . "," . $strdbsql; } else { // this should never happen, at all addmsg ( 'Keinen Nextval erhalten!<br />Die Datenbank sagt: ' . $strdberror ); } } else { // nextval failed addmsg ( 'Keinen Nextval erhalten!<br />Die Datenbank sagt: ' . $strdberror ); } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Workshop-Erstellung verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } if ( $intwsid != constant("DB_ID_NEW") ) { // nextval available $strdbsql = " insert into tbl_workshops (" . substr( $strdbfields, 0, strlen( $strdbfields ) - 1 ) . ") values (" . substr( $strdbsql, 0, strlen( $strdbsql ) - 1 ) . ")"; addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // insert successful addmsg ( 'Erfolgreich erstellt: ' . $lngdbrows . ' Workshop(s).' ); $bolok = true; } else { // insert failed addmsg ( 'Erstellung fehlgeschlagen!<br />Die Datenbank sagt: ' . $strdberror ); } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Workshop-Erstellung verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } if ( !$bolok ) { $intwsid = constant("DB_ID_NEW"); } } } else { // no fields filled addmsg ( 'Wenn Du einen neuen Workshop anlegen willst, wäre es geschickt, zumindest schonmal den Namen auszufüllen. ;o) ' ); } } } showmsg(); echo ' <div> <p> Hier können Workshops manuell bearbeitet - oder eben auch kaputtgemacht - werden, bitte also aufpassen ;) </p> '; echo ' <form id="wsselectform " '; echo ' name="wsselectform" action="' . constant("SERVER_FILE_MYSELF") . '#wseditor" method="post"> <div> '; $bolok = false; // read workshops $strdbsql = " select *" . " from tbl_workshops ws" . " order by ws_name"; if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // workshops found // -> use them $strworkshoplist = '<option value="' . constant("DB_ID_NONE") . '"'; if ( $intwsid == constant("DB_ID_NONE") || $intwsid == constant("DB_ID_NEW") ) { // extracted to function "selectws": $strworkshoplist = $strworkshoplist . ' selected="selected"'; if ( !$bolwsupdate ) { // clear workshop fields, except user tried to update $strwsname = ''; $strwsspeakers = ''; $intwsduration = 0; $strwscontent = ''; $strwscomment = ''; } } $strworkshoplist = $strworkshoplist . '>' . constant("DISPLAY_TEXT_NONE") . '</option>'; while ( db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror )) { // for each workshop: $strworkshoplist = $strworkshoplist . '<option value="' . $strdbrow["ws_id"] . '"'; if ( $intwsid == $strdbrow["ws_id"] ) { // extracted to function "selectws": $strworkshoplist = $strworkshoplist . ' selected="selected"'; // init workshop fields $intwsid = $strdbrow["ws_id"]; $strwsname = $strdbrow["ws_name"]; $strwsspeakers = $strdbrow["ws_speakers"]; $intwsduration = $strdbrow["ws_duration"]; $strwscontent = $strdbrow["ws_content"]; $strwscomment = $strdbrow["ws_comment"]; } $strworkshoplist = $strworkshoplist . '>' . $strdbrow["ws_name"] . '</option>'; } echo ' <span class="topic">Auswahl:</span><select name="cboworkshop" onchange="document.wsselectform.submit();">' . selectws( $intwsid ) . '</select> '; $bolok = true; } else { // no workshops found // -> hmm, that should not happen, but even then there should be no data anyway... } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Abfrage der Workshopliste verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } echo ' </div> </form> <form id="wscreateform" name="wscreateform" action="' . constant("SERVER_FILE_MYSELF") . '#wseditor" method="post"> <div> <input name="txtwsid" type="hidden" value="' . constant("DB_ID_NEW") . '" /> <input name="cmdwscreate" type="submit" value="Neuen Workshop erstellen..." /> </div> </form> '; if ( $intwsid != constant("DB_ID_NONE") ) { // show workshop update form with selected workshop echo ' <form id="wsupdateform" name="wsupdateform" action="' . constant("SERVER_FILE_MYSELF") . '#wseditor" method="post"> <div class="box"> <input name="txtwsid" type="hidden" value="' . $intwsid . '" /> <span class="topic">Name:</span><input class="db" name="txtwsname" type="text" value="' . $strwsname . '" /> <span class="topic">Referenten:</span><input class="db" name="txtwsspeakers" type="text" value="' . $strwsspeakers .'" /> <span class="topic">Dauer (Min.):</span><input class="db" name="txtwsduration" type="text" value="' . $intwsduration .'" /> <span class="topic">Inhalt:</span><textarea class="db verybig" name="txtwscontent">'. $strwscontent .'</textarea> <span class="topic">Bemerkung:</span><textarea class="db" name="txtwscomment">'. $strwscomment .'</textarea> <input name="cmdwsupdate" type="submit" value="Workshop jetzt aktualisieren!" /> </div> </form> '; } echo ' </div> '; showmsg(); // show fahrplan editor chapter echo ' <div class="chapter"> <h4>Fahrplan Editor</h4> </div> '; // update fahrplan if ( $bolsdupdate ) { // save all selected workshops (from downlists) into schedule $bolok = true; $intcount = 0; reset( $lstschedule ); foreach ( $lstschedule as $strscheduleindex => $intschedulevalue) { $intscheduleindex = intval( substr( $strscheduleindex, 0, strpos( $strscheduleindex . constant("DISPLAY_VALUE_SEPARATOR"), constant("DISPLAY_VALUE_SEPARATOR") ))); if ( $intschedulevalue != intval( substr( $strscheduleindex, strpos( $strscheduleindex . constant("DISPLAY_VALUE_SEPARATOR"), constant("DISPLAY_VALUE_SEPARATOR") ) + 1 ))) { // dropdownbox had been changed // -> update $strdbsql = "NULL"; if ( $intschedulevalue != constant("DB_ID_NONE") ) { $strdbsql = strval( intval( $intschedulevalue )); } $strdbsql = " update tbl_schedule " . " set sd_ws_id = " . $strdbsql . " where sd_id = " . strval( intval( $intscheduleindex )); addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // schedule updated // continue $intcount = $intcount + 1; } else { // schedule not updated addmsg ( 'Sorry, die Scheduleposition mit der ID ' . strval( intval( $intscheduleindex )) . ' konnte nicht geschrieben werden.<br />Die Datenbank sagt: ' . $strdberror ); $bolok = false; } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Aktualisierung des Schedules verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); $bolok = false; } } else { // dropdownbox had not been changed // -> ignore } } addmsg ( 'Es wurden ' . $intcount . ' Slots erfolgreich aktualisiert.' ); showmsg(); } if ( $bolsdupdate || $bolsdactivate ) { $bolok = false; $strtablehead = ''; // prepare table header with room names // read rooms $strdbsql = " select ro_name" . " from tbl_rooms ro" . " order by ro_schedpos"; //addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // rooms found // -> use them $strtablehead = ''; while ( db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror )) { // for each room: { $strtablehead = $strtablehead . ' <td class="db">' . $strdbrow['ro_name'] . '</td> '; } } $bolok = true; } else { // no rooms found // -> hmm, that should not happen, but even then there should be no data anyway... } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Abfrage der Raumliste verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } // Achtung: // Der "Fahrplan Editor" benötigt für die Dropdownlisten auch die Variable $strworkshoplist, // welche weiter oben im Rahmen des Kapitels "Workshop Editor" erstellt wurde. showmsg(); } echo ' <div> <form id="sdeditorform" name="sdeditorform" action="' . constant("SERVER_FILE_MYSELF") . '" method="post"> <p> Hier kann der Fahrplan bearbeitet werden, der anschließend mittels "make install Fahrplan" veröffentlicht werden kann. <br /> Achtung: Der alte Fahrplan wird dabei in der Datenbank unwiderruflich überschrieben! <br /> </p> '; //write fahrplan if ( $bolsdupdate || $bolsdactivate ) { $stroutput = ''; if ( $bolok ) { // read schedule slots with workshops $strdbsql = " select extract(hour from sd_begintime) as sd_begintime_hour, extract(day from sd_begintime) as sd_begintime_day," . " extract(month from sd_begintime) as sd_begintime_month, extract(year from sd_begintime) as sd_begintime_year," . " extract(dow from sd_begintime) as sd_begintime_weekday, sd_begintime," . " sd_id, ws_id, ws_name, ws_speakers,". " ro_name" . " from tbl_schedule sd" . " left join tbl_workshops ws on sd.sd_ws_id = ws.ws_id" . " left join tbl_rooms ro on sd.sd_ro_id = ro.ro_id" . " order by sd_begintime, ro_schedpos"; //addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { if ( $lngdbrows > 0 ) { // scheduled events found // -> use them // es folgt: Gruppenwechsel über Tag, Timeslot, Raum, Schedule-Event // Gesamtvorlauf $intsdyear = 0; $intsdmonth = 0; $intsdday = 0; $intsdhour = 0; $strroname = ''; $boleof = false; $boleof = !db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror ); while ( !$boleof ) { // Gruppenvorlauf Tag $intsdyear = $strdbrow['sd_begintime_year']; $intsdmonth = $strdbrow['sd_begintime_month']; $intsdday = $strdbrow['sd_begintime_day']; // neue Tabelle initialisieren $intcolrot = 1; $stroutput = $stroutput . ' <div class="chapter"> <table class="db"> <tr class="dbhead"> <td class="db"> ' . $strweekdayname[ $strdbrow['sd_begintime_weekday'] ] . '<br /> ' . $intsdday . '.' . $intsdmonth . '. </td> '; $stroutput = $stroutput . $strtablehead; $stroutput = $stroutput . ' </tr> '; while ( !$boleof && ( $intsdyear == $strdbrow['sd_begintime_year'] && $intsdmonth == $strdbrow['sd_begintime_month'] && $intsdday == $strdbrow['sd_begintime_day'] ) ) { // Gruppenvorlauf Timeslot $intsdhour = $strdbrow['sd_begintime_hour']; // neue Tabellenzeile initialisieren $intcolrot = abs( $intcolrot - 1 ); $stroutput = $stroutput . ' <tr class="db' . $intcolrot . '"> <td class="db"> ' . $intsdhour . '<span class="small">:00</span> </td> '; while ( !$boleof && ( $intsdyear == $strdbrow['sd_begintime_year'] && $intsdmonth == $strdbrow['sd_begintime_month'] && $intsdday == $strdbrow['sd_begintime_day'] ) && ( $intsdhour == $strdbrow['sd_begintime_hour'] ) ) { // Gruppenvorlauf Schedule-Event $strroname = $strdbrow['ro_name']; // neue Tabellenzelle initialisieren $stroutput = $stroutput . ' <td class="dbdata"> '; while ( !$boleof && ( $intsdyear == $strdbrow['sd_begintime_year'] && $intsdmonth == $strdbrow['sd_begintime_month'] && $intsdday == $strdbrow['sd_begintime_day'] ) && ( $intsdhour == $strdbrow['sd_begintime_hour'] ) && ( $strroname == $strdbrow['ro_name'] ) ) { // Datensatz (Schedule-Event) verarbeiten $stroutput = $stroutput . '<select class="dbdata" name="cboschedule[' . $strdbrow["sd_id"] . constant("DISPLAY_VALUE_SEPARATOR") . $strdbrow['ws_id'] . ']">' . selectws( $strdbrow['ws_id'] ) . '</select>'; // neuen Datensatz lesen $boleof = !db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror ); } // Gruppennachlauf Schedule-Event // Tabellenzelle finalisieren $stroutput = $stroutput . ' </td> '; } // Gruppennachlauf Timeslot // Tabellenzeile finalisieren $stroutput = $stroutput . ' </tr> '; } // Gruppennachlauf Tag // Tabelle finalisieren $stroutput = $stroutput . ' </table> </div> '; } // Gesamtnachlauf // Gesamtausgabe finalisieren //addmsg ( 'Die Fahrplandaten wurden erfolgreich zusammengestellt. Die Fahrplandatei kann jetzt geschrieben werden.' ); $bolok = true; } else { // no scheduled events found // -> hmm, that should not happen, but even then there should be no data anyway... } } else { // error accessing database addmsg ( 'Sorry, die Datenbank ist momentan nicht für die Abfrage der Workshops verfügbar.<br />Die Datenbank sagt: ' . $strdberror ); } } if ( $bolok ) { // operation has succeeded -> now write fahrplan echo ' <div class="box">' . $stroutput . ' <p> <input name="cmdsdupdate" type="submit" value="Fahrplan jetzt aktualisieren!" /> </p> </div> '; } } else { echo ' <p> <input name="cmdsdactivate" type="submit" value="Fahrplan editieren..." /> </p> '; } echo ' </form> </div> '; showmsg(); // show run SQL chapter echo ' <div class="chapter"> <h4>run SQL</h4> </div> '; $bolok = false; if ( $bolrunsql && $strsql != '' ) { // runs SQL statement // be careful now: // fire raw sql statement to database $strdbsql = $pstrsql; // write defused sql statement to screen addmsg ( 'Running SQL: ' . $strdbsql ); if ( db_sql( $intdbconnid, $strdbsql, $intdbresult, $lngdbrows, $strdberror ) ) { addmsg ( $lngdbrows . ' records found.' ); if ( db_fields ( $intdbresult, $strdbfields, $strdberror )) { echo ' <div> <table class="db"> <tr class="dbhead"> '; foreach ( $strdbfields[constant("DB_FIELD_NAME")] as $intindex => $strvalue ) { echo ' <td class="db">' . $strvalue . '</td> '; } echo ' </tr> '; //if ( db_row ( $intdbresult, $strdbrow, constant("DB_ROW_FIRST"), $strdberror )) $intcolrot = 0; while ( db_row ( $intdbresult, $strdbrow, constant("DB_ROW_NEXT"), $strdberror )) { echo ' <tr class="db' . $intcolrot . '"> '; $intindex = 1; foreach ( $strdbfields[constant("DB_FIELD_NAME")] as $intindex => $strvalue ) { echo ' <td class="db">' . $strdbrow[ $strvalue ] . '</td> '; } echo ' </tr> '; $intcolrot = abs( $intcolrot - 1 ); } echo '</table></div>'; $bolok = true; } else { addmsg ( 'Error reading the fields!<br />Database says: ' . $strdberror ); } } else { addmsg ( 'Error accessing the database!<br />Database says: ' . $strdberror ); } } showmsg(); echo ' <div> <form id="runsqlform" name="runsqlform" action="' . constant("SERVER_FILE_MYSELF") . '" method="post"> <p> Hier können beliebige SQL-Kommandos (getrennt durch Semikoli, Zeilenumbrüche möglich) auf die Datenbank abgesetzt werden.<br /> Vorsicht: Dabei lässt sich auf sehr einfache und hochperformante Weise die Datenbank schrotten. ;-) <br /> <span class="line important"><span class="topic">Erste und einzige Regel:</span>Prüfe immer zuerst mit SELECT, was Du mit UPDATE oder DELETE anfassen willst!</span> </p> <p> <span class="topic">SQL:</span><textarea class="db" name="txtsql">'. $strsql .'</textarea> <input name="cmdrunsql" type="submit" value="Three-Two-One...Fire!" /> </p> </form> </div> '; showmsg(); // close page and stoprun. echo ' <!-- end of specific page content --> '; readfile( constant("SERVER_FILE_EXTRO") ); die(); ?>