PHP

Anwesenheitsliste in PHP (PHP Tutorial)

Tutorial erstellt von submarine in >= PHP 4, letzte Änderung am 02.11.2009

Vorüberlegungen

In quasi jedem Verein oder in jeder Mannschaft wird eine Anwesenheitsliste geführt.
Diese besteht meist aus den Mitgliedern, den Terminen und den Kürzeln (z.B. x | -). Um den Mitgliedern diesen Vorgang zu vereinfachen kann diese Liste bequem online im internen Bereich einer Website geführt werden.

Voraussetzungen

Um dieses System sinnvoll zu betreiben braucht ihr einen passwortgeschützten Bereich für die Mitglieder, einen PHP 5-fähigen Server und eine MySQL Datenbank.
Außerdem ist es wichtig, dass ihr die ID (Identifikationsnummer) des Benutzers, der gerade online ist, entweder über die URL oder über eine Session als Variable "user" übergebt, damit ein Benutzer auch nur seine eigenen Status ändern kann.

Datenbankstruktur

Wie schon angesprochen besteht die Anwesenheitsliste aus den Terminen, den Mitgliedern und den Status. Die Tabellen "Mitglieder" sowie "Termine" sollten bereits bestehen. Diese sollten mindestens folgende Felder in gleicher oder ähnlicher Weise beinhalten:

Mitglieder:
  • id (z.B. vom Typ INT)
  • name (VARCHAR)

  
Termine:
  • id (INT)
  • date (DATETIME)

  
Nun brauchen wir noch eine dritte Tabelle für die Daten. Sie sollte wie folgt angelegt werden:

Code:

CREATE TABLE `Anwesenheit` (
    `tid` INT(11) NOT NULL,
    `mid` INT(11) NOT NULL,
    `presence` INT(11) NOT NULL
);

Das Feld `tid` muss vom selben Typ sein, wie das Feld `id` in "Termine". Genauso muss mit dem Feld `mid` verfahren werden.

Die Tabelle `Anwesenheit` verknüpft die Tabellen `Mitglieder` und `Terminen` miteinander. Das bedeutet, dass ihre Datensätze einen Verweis auf Datensätze aus den beiden Tabellen beeinhaltet: `Anwesenheit.tid` -> `Termine.id`; `Anwesenheit.mid` -> `Mitglieder.id`. Es wird also pro Datum und Mitglied ein Eintrag erstellt.

Code:

  tid | mid | presence
  1   | 1   | 0
  1   | 2   | 0          
  2   | 1   | 0
  2   | 2   | 0



Aufbau der Anwesenheitsliste

Nachdem wir jetzt unsere Datenbank soweit vorbereitet haben, können wir damit beginnen, unsere Liste aufzubauen. Wir nutzen hierbei eine Tabelle, weil hiermit leicht ein dynamisches und übersichtliches Layout erzeugt werden kann.

Grundstruktur

Als erstes definieren wir eine Funktion zum Erstellen einer Tabelle.  
Code:

function echoTable() {
    echo '<table id="alist_table">';
    create_titlerow();
    get_maindata();  
    echo '</table>';
}


Jetzt generieren wir unsere Titelzeile, die die Namen der Mitglieder enthält. In der while-Schleife wird jeder Name einzeln ausgelesen und in eine Zelle geschrieben.  
Code:

function create_titlerow() {
    echo '<tr class="titlerow">';
    echo '<td>Name/Datum</td>';
  
    $result_name = mysql_query('SELECT DISTINCT(name) FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` ORDER BY `name`');
    while($row_name = mysql_fetch_array($result_name)) {
        echo '<td>'.$row_name['name'].'</td>';
    }

    echo '</tr>';
}


Nun wollen wir natürlich auch die Termine und die Status der Mitlieder zu den einzelnen Daten ausgeben. Als erstes definieren wir einen Query, der die ID, das Datum und dessen deutsche Formatierung ausliest. Danach kommt die Funktion str_replace() zum Einsatz, um aus den englischen Wochentagen die Deutschen zu machen.
Jetzt kommt der interessante Teil: Da die Mitglieder später ihren Status ja auch ändern können sollen, müssen wir zwei Arten der Ausgabe definieren. Zum Ersten die "normale" Ausgabe, in der der Status einfach ausgegeben wird. Hierfür nutzen wir später die Funktion create_datarow_passive().
Wollen die Benutzer einen Status ändern, geben wir ihnen die Möglichkeit, indem wir ihnen Dropdownlisten zur Verfügung stellen. Dafür nutzen wir dann die Funktion create_datarow_active(). Diese wird aber nur dann verwendet, wenn der Modus "edit" und die Termin-ID gleich der aktuellen (in der Schleife wird ja immer nur ein Termin ausgegeben) ist. Den Modus und die Termin-ID schicken wir später über die URL.

Code:

function get_maindata() {
    global $mode, $tid;
    $result_date = mysql_query('SELECT `id`, `date`, DATE_FORMAT(`date`, "%W. %D.%m.%Y") AS `germ_date` FROM `Termine` ORDER BY `date`');
    while($row_date = mysql_fetch_array($result_date)) {  
        $date_id = $row_date['id'];
        $date_origin = $row_date['date'];
        $date_new = array('So','Mo','Di','Mi','Do','Fr','Sa');
        $date_old = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
        $date_clear = str_replace($date_old, $date_new, $row_date['germ_date']);
  
        if($mode == 'edit' && $tid == $date_id) {
            create_datarow_active($date_id, $date_clear, $date_origin);
        }
        else {
            create_datarow_passive($date_id, $date_clear, $date_origin);
        }      
    }
}


Statusausgabe

Jetzt endlich geben wir das erste mal Daten aus. Das ist eigentlich recht einfach:
Als erstes geben wir eine Tabellenzeile aus, die als erste Zelle das deutsche Datum ($date_clear) enthält. Die nächsten Zellen enthalten die Status:
Wir lesen alles aus den Tabellen `Anwesenheit` und `Mitglieder` aus, verwenden hierbei die WHERE-Klausel um die `mid` aus `Anwesenheit` mit der `id` aus `Mitgliedern` zu verknüpfen.
Gleichzeitig wollen wir aber nur die Daten eines Termins auslesen, der in der Funktion get_maindata() in der Schleife festgelegt wird.  

Code:

function create_datarow_passive($date_id, $date_clear, $date_origin) {
    echo '<tr class="datarow">';  
    echo '<td class="datecell">'.$date_clear.'</td>'; //Ausgabe des Datums        
    $result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `ID` AND `tid` = "'.$date_id.'" ORDER BY `name`');
    while($row_presence = mysql_fetch_array($result_presence)) {
        echo '<td>';
        $old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
        $new = array('anwesend', 'entschuldigt'); //...mit den Stati zum lesen
        echo str_replace($old, $new, $row_presence['presence']);          
        echo '</td>';
    }
    echo '<td> <a href="DEINE_URL_VOM_INTERNEN_BEREICH?user='.$activeUser.'&mode=edit&tid='.$date_id.'">[ändern]</a></td>';
    echo '</tr>';
}

Das sollte jetzt ungefähr so aussehen:
    
Die etwas kompliziertere Ausgabe von Daten - der aktive Modus. Hier geben wir nicht wie in der vorherigen Funktion die Status einfach aus, sondern ermöglichen es dem Benutzer, seine Status zu ändern.
Step by step:
[list]
  • "um die Zeile herum" geben wir ein Formular aus, dass die Daten abschickt
  • [*]Nur wenn die ausgelesene Benutzer-ID auch mit der über die URL übergebenen ID ($activeUser) übereinstimmt, geben wir ein <select>-Element aus. Dieses ruft die Funktion option() auf.Wenn das nicht zutrifft, geben wir einfach den Status wie in create_datarow_passive() aus.    
    Am Ende fügen wir noch die inputs hinzu - hidden-Inputs für das bearbeitete Datum, den aktiven Benutzer und eine Kontrolle; einen Button zum Senden.  
    Code:

    function create_datarow_active($date_id, $date_clear, $date_origin) {
        global $activeUser;
        
        echo '<form name="editDate['.$date_id.']" action="URL_VOM_ÄNDERUNGS-SCRIPT" method="post">';
        echo '<tr id="date_'.$date_id.'">';  
        echo     '<td class="datecell">'.$date_clear.'</td>';          
        $result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` AND `tid` = "'.$date_id.'" ORDER BY `name`');
        while($row_presence = mysql_fetch_array($result_presence)) {
            $user_id = $row_presence['id'];
            if($user_id == $activeUser){    
                echo '<td>';
                echo   '<select name="date_single['.$row_presence['mid'].']" >';          
                switch($row_presence['presence']) {                          
                  case '0': option(0, 1); break;
                  case '1': option(1, 0); break;
                }
                echo   '</select>';        
                echo '</td>';
            }
            else {
             $old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
             $new = array('anwesend', 'entschuldigt'); //...mit den Status zum lesen    
             echo '<td>'. str_replace($old, $new, $row_presence['presence']).'</td>';
            }    
        }
        echo '<td>';    
        echo   '<input type="hidden" name="tid" value="'.$date_id.'" />';
        echo   '<input type="hidden" name="user" value="'.$activeUser.'" />';
        echo   '<input type="hidden" name="check" value="true" />';
        echo   '<input type="submit" value="speichern" />';  
        echo '</td>';
        echo '</tr>';  
        echo '</form>';
    }


    Die Funktion option() steuert die Ausgabe der Auswahlmöglichkeiten. In der vorigen Funktion haben wir mit dem switch festgelegt, welcher Status aktiv und welcher passiv ist. Das greifen wir hier wieder auf:
    Der aktive Status ist bereits ausgewählt, der passive kann ausgewählt werden.

    Code:

    function option($active, $passive) {
        $old = array('0', '1');
        $new = array('anwesend', 'entschuldigt');        
        $echo_option = '<option selected="selected" value="'.$active.'" >'.$active.'</option>';
        $echo_option .= '<option value="'.$passive.'">'.$passive.'</option>';      
        echo str_replace($old, $new, $echo_option);
    }


    Jetzt sollte die Tabelle wie folgt aussehen:

    Nun einmal der komplette Code. Am Anfang hab' ich noch die nötigen kleinen Sachen hinzugeschrieben, wie die Datenbankverbindung und die $_GETs für die Variablen aus der URL. Auch muss die Funktion echoTable() natürlich am Ende aufgerufen werden.

    Code:

    <?php

    include('dbconnect.php');
    $activeUser = $_GET['user'];
    $tid = $_GET['tid'];
    $mode = $_GET['mode'];

    function echoTable() {
        echo '<table id="alist_table">';
        create_titlerow();
        get_maindata();  
        echo '</table>';
    }

    function create_titlerow() {
        echo '<tr class="titlerow">';
        echo '<td>Name/Datum</td>';
      
        $result_name = mysql_query('SELECT DISTINCT(name) FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` ORDER BY `name`');
        while($row_name = mysql_fetch_array($result_name)){
            echo '<td>'.$row_name['name'].'</td>';
        }

        echo '</tr>';
    }

    function get_maindata() {
        global $mode, $tid;
        $result_date = mysql_query('SELECT `id`, `date`, DATE_FORMAT(`date`, "%W. %d.%m.%Y") AS `germ_date` FROM `Termine` ORDER BY `date`');
        while($row_date = mysql_fetch_array($result_date)) {  
          $date_id = $row_date['id'];
          $date_origin = $row_date['date'];
          $date_new = array('So','Mo','Di','Mi','Do','Fr','Sa');
          $date_old = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
          $date_clear = str_replace($date_old, $date_new, $row_date['germ_date']);
      
          if($mode == 'edit' && $tid == $date_id) {
              create_datarow_active($date_id, $date_clear, $date_origin);
          }
          else {
              create_datarow_passive($date_id, $date_clear, $date_origin);
          }      
      }
    }
      
    function create_datarow_passive($date_id, $date_clear, $date_origin){
        echo '<tr class="datarow" >';  
        echo '<td class="datecell">'.$date_clear.'</td>'; //Ausgabe des Datums        
        $result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` AND `tid` = "'.$date_id."' ORDER BY `name`');
        while($row_presence = mysql_fetch_array($result_presence)) {
            echo '<td>';
            $old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
            $new = array('anwesend', 'entschuldigt'); //...mit den Status zum Lesen
            echo str_replace($old, $new, $row_presence['presence']);          
            echo '</td>';
        }
        echo '<td> <a href="DEINE_URL_VOM_INTERNEN_BEREICH?user='.$activeUser.'&mode=edit&tid='.$date_id.'">[ändern]</a></td>';
        echo '</tr>';
    }
      
    function create_datarow_active($date_id, $date_clear, $date_origin) {
        global $activeUser;
        
        echo '<form name="editDate['.$date_id.']" action="URL_VOM_ÄNDERUNGS-SCRIPT" method="post">';
        echo '<tr id="date_'.$date_id.'">';  
        echo   '<td class="datecell">'.$date_clear.'</td>';          
        $result_presence = mysql_query('SELECT * FROM `Anwesenheit`, `Mitglieder` WHERE `mid` = `id` AND `tid` = "'.$date_id.'" ORDER BY `name`');
        while($row_presence = mysql_fetch_array($result_presence)) {
            $user_id = $row_presence['id'];
            if($user_id == $activeUser) {    
                echo '<td>';
                echo '<select name="date_single['.$row_presence2['uid'].']">';          
                switch($row_presence['presence']) {                          
                    case '0': option(0, 1); break;
                    case '1': option(1, 0); break;
                }
                echo '</select>';        
                echo '</td>';
            }
            else {
                $old = array('0', '1'); //Ersetzen der Ziffern aus der DB...
                $new = array('anwesend', 'entschuldigt'); //...mit den Status zum Lesen    
                echo '<td>'. str_replace($old, $new, $row_presence['presence']).'</td>';
            }    
        }
        echo '<td>';      
        echo   '<input type="hidden" name="tid" value="'.$date_id.'" />';
        echo   '<input type="hidden" name="user" value="'.$activeUser.'" />';
        echo   '<input type="hidden" name="check" value="true" />';
        echo   '<input type="submit" value="speichern" />';  
        echo '</td>';
        echo '</tr>';  
        echo '</form>';
    }
      
    function option($active, $passive) {
        $old = array('0', '1');
        $new = array('anwesend', 'entschuldigt');        
        $echo_option = '<option selected="selected" value="'.$active.'" >'.$active.'</option>';
        $echo_option .= '<option value="'.$passive.'">'.$passive.'</option>';      
        echo str_replace($old, $new, $echo_option);
    }
      
    echoTable();

    ?>



    Damit sind wir mit der Anwesenheitsliste auch schon fertig :)

    Aber es fehlt noch das Script zum Ändern der Daten - weiter geht's...

    Das Formular ruft diese Datei auf (bitte sowohl in der Datei für die Liste als auch hier auf den selben Namen achten), welche die Daten empfängt, auswertet und in die Datenbank schreibt. Danach wird der Benutzer wieder zurück geleitet.
    Code:

    <?php

    include('dbconnect.php');

    $get_tid = $_GET'tid'];
    $activeUser = $_GET['user'];
    $get_presence = $_GET['date_single'];

    $old = array('anwesend', 'entschuldigt');
    $new = array('0', '1');
    $get_presence = str_replace($old, $new, $get_presence);

    if($_GET['check']) {
        foreach($get_presence as $mid => $presence) {
          mysql_query('UPDATE `Anwesenheit`
                       SET `presence` = "'.$presence.'"
                       WHERE `tid` = '$get_tid' AND mid = "'.$mid.'"');
        }
    }
    header ('Location: URL_DES_INTERNEN_BEREICHS?user='.$activeUser);

    ?>


    HINWEIS: Bei jedem neuen Termin, der in die Datenbank eingefügt wird, muss darauf geachtet werden, dass auch die Tabelle `Anwesenheit` ergänzt wird!
    Dazu muss für jedes Mitglied ein neuer Eintrag mit der ID des neuen Datums, seiner ID und einem Standardwert für die Spalte `presence` erstellt werden. Das könnte so aussehen:
    Code:

    <?php

    $result_user = mysql_query('SELECT * FROM `Mitglieder`');
    while($row_user = mysql_fetch_array($result_user)) {
       $user_id = $row_user['id'];
       mysql_query('INSERT INTO `Anwesenheit`
                    SET
                        `tid` = "'.$id_date.'",
                        `mid` = "'.$id_user.'",
                        `presence` = "0"');    
    }

    ?>


    Nun sollte die Anwesenheitsliste voll funktionsfähig sein, bei Fragen einfach im Forum melden.
    Viel Spaß!

    >> Allgemeine Fragen oder Probleme mit dem Tutorial? Hier gehts zum Forum!

    Impressum / Datenschutzerklärung          © der-Webdesigner.net 2002 - 2011           top ▲