PHP Webradio Streamplan

Hallo zusammen,

ich habe aktuell nun ein etwas größeres Projekt am Laufen und befinde mich vermutlich in einer gedanklichen Einbahnstraße.
Ich habe gestern einen dynamischen Streamplan aufgebaut, der mir für die aktuelle Woche jeweils alle Stunden (jeweils in 15 Minuten-Schritten) anzeigt.
Dies funltioniert auch soweit, mit folgendem Code:
PHP:
// Wie viel Minuten soll eine Einheit (Tabellenzelle) haben
                $minutes    = 15;
                $cellsperhr = (60/$minutes);
                
                // Aktuelle Einheit der Stunde
                $currentquarter = ceil(date("i", time())/$minutes);
                
                // Interval
                $interval    = 1;
                
                // Tage der aktuellen Woche
                $weekdays    = $common->getDaysInWeek(date("W", time()), date("YY", time()));
                
                // Datum der Tage
                $datesinweek = array();
                foreach($weekdays as $day){
                    array_push($datesinweek, date("d.m.Y", time()+$day));    
                }     
                
                // Zeiten zusammenbauen
                $hrs = array();
                for($i = 0; $i <= 23; $i+=$interval){
                    array_push($hrs, ((strlen($i) == 1) ? "0".$i : $i).":00");
                }  
                                
                // Tabellenkopf
                $plantable    = '<table border="1" id="streamplan" cellpadding="0" cellspacing="0">';
                $plantable .= '<tr><td width="200px"></td>';
                
                // Wochentags-Anzeige
                foreach($weekdays as $day){
                    $id = ($day == 0 ? 'today' : 'other');
                    $plantable .= "<th width='200px' class='".$id."'>".date("D", $day+time())."</th>";
                }
                $plantable .= '</tr>';
                
                // Stunden-Anzeige
                
                // Show der aktuellen Woche aus der DB holen
                $dayshows = Model::getDataset(date("W", time()), "ShowsPerWeeknumber", true, "", true);
                
                foreach($hrs as $hr){
                    
                    $blocks =     ceil($show['TimeDifference']/$minutes);
                    
                    // Skalierung der Stunden durchlaufen
                    for($i = 1; $i <= $cellsperhr; $i++){
                        $plantable .= '<tr>';
                        
                        
                        
                        // Ausgabe der Stunden
                        $plantable .= ($i == 1 ? '<th height="100px" valign="top" rowspan="'.$cellsperhr.'">'.$hr.'</th>' : '');
                        
                        foreach($datesinweek as $day){
                            $currinterval = 0;
                            // Prüfen ob der aktuelle Tag heute ist
                            $today    = ($day == date("d.m.Y", time()) ? 'today' : 'other');
                            
                            // Aktuelle Stunde ermitteln
                            if($hr == date("H:00", time()) AND $currentquarter == $i ) {
                                $now = 'now';
                            }else{
                                $now = '';
                            }
                            $plantable .= '<td width="200px" class="'.$today.'" id="'.$now.'">';
                            //if($currinterval <= $show['TimeDifference']){
                                foreach($dayshows as $show){
                                    //$users = array();
                                    //$arraypush = array_push($users, $show['UserName']);
                                    //var_dump($arraypush);
                                    
                                    if($show['StartDay'] == $day or $show['EndDay'] == $day){
                                        
                                        $showhrs = array();
                                        
                                        for($l = $show['StartHour']; $l <= $show['EndHour']; $l++){
                                            array_push($showhrs, $l.":00");
                                        }
                                        
                                        //echo $show['UserName']." on ".$show['StartDay']." @ ".$show['StartHour']." - ".$show['EndHour']."<br>";
                                        //
                                        
                                        if(in_array($hr, $showhrs) AND $show['StartDay'] == $day){
                                            $plantable .= "".$show['UserName']." ";
                                            
                                            //$plantable .= $showblocks;
                                            //$markedblocks += $minutes;
                                            //echo "<script type='text/javascript'>console.log('Show: ".$show['UserName']." | Aktueller Block: ".$currinterval." - Bloecke gesamt: ".$show['TimeDifference']."');</script>";
                                        }else{
                                            //$plantable .= $i;    
                                        }
                                    }
                                }
                            //}
                            $plantable .= '</td>';
                            
                            
                        }
                        $plantable .= '</tr>';
                        $showblocks += $i;
                    }
                }
                
                $plantable .= '</table>';
            
                $view->assign('WeekNumber', date("W", time()));
                $view->assign('DateSpan', date("d.m.Y", time()+$weekdays[0])." - ". date("d.m.Y", time()+$weekdays[6]));
                $view->assign('PlanTable', $plantable);
                
                $titlename = "Week ".date("W", time());

Das Ergebnis sieht dann in etwa so aus (siehe Anhang).
Nun habe ich aber folgendes Problem.
Die Shows können in dem besagten Interval (alle 15 Minuten) enden oder anfangen.
Jedoch gibt er mir immer nur für jede Stunde alle aus.
Beispiel: Disane hat eine Show am Sonntag (letzte Spalte) von 20.00-22.15 eingetragen, die Show wird aber bis 23 Uhr eingetragen.

Habt ihr da eventuell eine Lösung, oder Verbesserungsvorschläge?
Aktuell weiß ich echt nicht mehr weiter.
Schon dumm, wenn man seinen eigenen Quellcode nicht mehr blickt :(.

Die Datenbank-Tabelle der Shows, ist im Anhang aufgeschlüsselt mit entsprechenden Spalten.

Über jede Hilfe wäre ich echt dankbar!

Liebe Grüße
- reaL-Insanity

EDIT:
Auch nach Umbauen etc. bekomm ich es zum Verrecken nicht hin.
Vermutlich habe ich wirklich einen echt krassen Logikfehler da drin.
 
Zuletzt bearbeitet:
Auch wenn ich den Code nicht Prüfen kann, vermute ich den Fehler hier:
Bin mir aber ehrlichgesagt auch nur zu 50% sicher...

Code:
for($l = $show['StartHour']; $l <= $show['EndHour']; $l++){
    array_push($showhrs, $l.":00");
}
                                        
//echo $show['UserName']." on ".$show['StartDay']." @ ".$show['StartHour']." - ".$show['EndHour']."<br>";
                                        
if(in_array($hr, $showhrs) AND $show['StartDay'] == $day){
    $plantable .= "".$show['UserName']." ";

Du prüfst nämlich nur, ob die Show in der Aktuellen Stund estattfindet. Du zählst ja bereits die Viertelstunden in $i hoch - fasst aber $i seitdem nichtmehr an. In dem ganzen Script sehe ich, dass du nur auf volle Stunden prüfst. Auch in der for-schleife schaust du nur, ob die Show in der Aktuellen Stunde stattfindet. Aber nicht, ob sie auch in der aktuellen Viertelstunde noch läuft (in_array($hr, $showhrs))
 
Also ich habs mal nun umgebaut. Vorher stell ich mir eine "Matrix" zusammen in der alle Tage der Woche, alle Stunden bzw. halbe Stunden (einstellbar) ein false oder ein Shownamen haben (sofern sie einen beinhalten).

Das Array sieht dann im Dump so aus (Auszug):
PHP:
array   '00:00' =>      array       '23.10.2010' =>          array           'Show' => string 'CJJ' (length=3)       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false   '00:30' =>      array       '23.10.2010' =>          array           'Show' => string 'CJJ' (length=3)       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false   '01:00' =>      array       '23.10.2010' =>          array           'Show' => string 'CJJ' (length=3)       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false   '01:30' =>      array       '23.10.2010' =>          array           'Show' => boolean false       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false   '02:00' =>      array       '23.10.2010' =>          array           'Show' => boolean false       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false   '02:30' =>      array       '23.10.2010' =>          array           'Show' => boolean false       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false   '03:00' =>      array       '23.10.2010' =>          array           'Show' => boolean false       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false   '03:30' =>      array       '23.10.2010' =>          array           'Show' => boolean false       '24.10.2010' =>          array           'Show' => boolean false       '25.10.2010' =>          array           'Show' => boolean false       '26.10.2010' =>          array           'Show' => boolean false       '27.10.2010' =>          array           'Show' => boolean false       '28.10.2010' =>          array           'Show' => boolean false       '29.10.2010' =>          array           'Show' => boolean false

Folgende Variablen werden im künftigen Verlauf benötigt:
PHP:
// Wie viel Minuten soll eine Einheit (Tabellenzelle) haben
                $minutes    = 30;
                $cellsperhr = (60/$minutes);
                
                // Aktuelle Einheit der Stunde
                $currentquarter = ceil(date("i", time())/$minutes);
                
                // Interval
                $interval    = 1;
                
                // Tage der aktuellen Woche
                $weekdays    = $common->getDaysInWeek(date("W", time()), date("YY", time()));
                
                // Datum der Tage
                $datesinweek = array();
                foreach($weekdays as $day){
                    array_push($datesinweek, date("d.m.Y", time()+$day));    
                }     
                
                // Zeiten zusammenbauen
                $hrs = array();
                for($i = 0; $i <= 23; $i+=$interval){
                    array_push($hrs, ((strlen($i) == 1) ? "0".$i : $i).":00");
                }  
                
                // Zeiten nach dem gewählten Interval von x Minuten
                $hrsbyinterval = array();
                foreach($hrs as $hr)
                {
                    array_push($hrsbyinterval, $hr);
                    $minperhr = 0;
                    for($i = 1; $i < $cellsperhr; $i++){
                        
                        $minperhr += $minutes;
                        array_push($hrsbyinterval, str_replace(":00","",$hr.":".$minperhr));
                    }
                }

Aufgebaut wird das Array hiermit:
PHP:
$scheduleMatrix = array();
                foreach($hrsbyinterval as $hr){
                    $scheduleMatrix[$hr] = array();
                    for($i = 1; $i <= $cellsperhr; $i++){
                    
                        foreach($datesinweek as $day){    
                            $scheduleMatrix[$hr][$day] = array();
                            
                            $show = Model::GetShowByDateAndHour($day, $hr);
                            if($show != false){
                                $scheduleMatrix[$hr][$day]['Show'] = $show['UserName'];
                            }else{
                                $scheduleMatrix[$hr][$day]['Show'] = false;
                            }
                        }
                    }
                }

Das Array werte ich nu wie folgt aus:
PHP:
foreach($scheduleMatrix as $time => $day)
                {
                    $plantable .= '<th height="100px" valign="top">'.$time.'</th>';
                    list($hour, $min) = explode(":", $time);
                    foreach($day as $date => $Show){
                        $nextminutes = (string)($min + $minutes);
                        if($nextminutes == "60")
                        {
                            $nextminutes = "00";
                            $nexthour = "0".(string)($hour+1);    
                        }else{
                            $nextminutes = (string)$min;
                            $nexthour = (string)($hour);
                        }

                        $nexttime = (string)(($nexthour).":".$nextminutes);
                        if($day[$date]['Show'] != false){
                            $plantable .= '<td width="200px" class="'.$today.'" id="'.$now.'">'.$Show['Show'].'</td>';
                        }else{
                            $plantable .= '<td width="200px" class="'.$today.'" id="'.$now.'"></td>';
                        }
                    }
                    $plantable .= '</tr>';    
                }
                
                $plantable .= '</table>';

Wie mir aufgefallen ist, dürfte PHP eigentlich nur die ersten beiden 1/2 std. markieren da die Show von 00:00 - 01:00 geht (Show CJJ).
Jedoch wird auch Zeit praktisch von 01:00 - 01:30 uhr als Show markiert.

Irgendwo, in der Ermittlung der Matrix, habe ich wohl noch einen Fatzer drin, den ich unter Umständen nicht bedacht habe.

Achja, mit folgendem Statement hole ich mir die Daten aus der Tabelle:
Code:
SELECT 
    s.Title, g.Name AS Genre,
    s.ID AS ShowID,
    u.ID AS UserID,
    u.Name AS UserName,
    c.Countryname,
    s.Description AS ShowDescription,
    s.StartDatetime,
    s.EndDatetime,date_format(s.StartDateTime, '%H') AS StartHour,  
    date_format(s.StartDateTime, '%i') AS StartMinutes,    
    TIMESTAMPDIFF(MINUTE, s.StartDateTime, s.EndDateTime) as TimeDifference,
    date_format(s.EndDateTime, '%H') AS EndHour,  
    date_format(s.EndDateTime, '%i') AS EndMinutes 
    
FROM    shows s 
        INNER JOIN genre g ON g.ID = s.FK_Genre_ID 
        LEFT JOIN users u ON u.ID = s.FK_User_ID 
        LEFT OUTER JOIN pictures p ON p.ID = s.FK_Picture_ID 
        LEFT OUTER JOIN countries c ON u.FK_Country_ID = c.ID    
WHERE 
        (DATE_FORMAT(s.StartDateTime, '%e.%c.%Y') = '{0}') AND '{1}' 
        BETWEEN DATE_FORMAT(s.StartDateTime, '%H:%i') AND DATE_FORMAT(s.EndDateTime, '%H:%i') 
ORDER BY s.StartDatetime, s.EndDatetime

Vielleicht hilft das noch ein wenig weiter.
 
Zuletzt bearbeitet:
ich habe mal kurz drübergeschaut, und vermute den Fehler in der Ausgabe.
Es ist mehr eine Vermutung. Aber ich hätte da noch ein paar kleine Fragen:
* $minutes (in der Ausgabe) nimmst du wo her?
* Was machst du mit der daraus errechneten $nexttime?
* Wieso tust du dir das mit der Stringbearbeitung an? String erzeugen, zerlegen, anders wieder zusammensetzten. Für eine Aufgabe, die sich doch eigentlich auch mit Timestamps realisieren lassen müsste?
 
Ich habe den Fehler schon gefunden... total simpel eigentlich.

Lösung:
Die User legen ihre Shows praktisch immer in dem Format an:
12.00 - 12.30 etc.
In dem SQL-Statement habe ich, in dem BETWEEN, immer wieder bis 12.30 geprüft. Was aber falsch ist, da die Show prinzipiell nur bis 12.29 geht und ab 12.30 eine andere Show anfängt.

Die Lösung ist nun diese, dass ich von der Endzeit eine Minute abziehe:
Code:
SELECT 
                s.Title, 
                g.Name AS Genre,
                s.ID AS ShowID,
                u.ID AS UserID,
                u.Name AS UserName,
                c.Countryname,
                s.Description AS ShowDescription,
                s.StartDatetime,
                s.EndDatetime,
                date_format(s.StartDateTime, '%H') AS StartHour, 
                date_format(s.StartDateTime, '%i') AS StartMinutes,    
                TIMESTAMPDIFF(MINUTE, s.StartDateTime, s.EndDateTime) as TimeDifference,
                date_format(s.EndDateTime, '%H') AS EndHour,  date_format(s.EndDateTime, '%i') AS EndMinutes 
            FROM    
                shows s 
                INNER JOIN genre g ON g.ID = s.FK_Genre_ID 
                LEFT JOIN users u ON u.ID = s.FK_User_ID 
                LEFT OUTER JOIN pictures p ON p.ID = s.FK_Picture_ID 
                LEFT OUTER JOIN countries c ON u.FK_Country_ID = c.ID    
            WHERE 
                (DATE_FORMAT(s.StartDateTime, '%e.%c.%Y') = '{0}') AND 
                '{1}' BETWEEN DATE_FORMAT(s.StartDateTime, '%H:%i') AND DATE_FORMAT(DATE_ADD(s.EndDateTime, INTERVAL -1 MINUTE), '%H:%i') 
            ORDER BY s.StartDatetime, s.EndDatetime

Und siehe da, es klappt :-)
 
Zuletzt bearbeitet:
Zurück
Oben