Advertisement
Guest User

Sked Parser

a guest
Oct 20th, 2012
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 31.05 KB | None | 0 0
  1.     <?php
  2.     ob_start('ob_gzhandler');
  3.    
  4.     $allowed_formats = array("xml", "json", "csv");
  5.     $allowed_classes = array("#^(A|B|C|D|E)\d{2}$#", "#^(WI|WING)[[:alpha:]]{0,1}\d{2}$#", "#^MB[[:alpha:]]{0,1}\d{1,2}$#");
  6.     $format;
  7.     if (!isset($_GET["format"])) {
  8.         $format = "xml";
  9.     } else {
  10.         $format = strtolower($_GET["format"]);
  11.     }
  12.    
  13.     if (!in_array($format, $allowed_formats)) {
  14.         printError_XML("param_error", "Ungültiger Format-Parameter; Erlaubt sind: "
  15.                 . implode(", ", $allowed_formats));
  16.         exit();
  17.     }
  18.    
  19.     if (!isset($_GET["klasse"]) || is_array($_GET["klasse"])) {
  20.         if ($format == "xml" or $format == "csv") {
  21.             printError_XML("param_error", "Keine oder mehrere Klasse(n) angegeben");
  22.         } else if ($format == "json") {
  23.             printError_JSON("param_error", "Keine oder mehrere Klasse(n) angegeben");
  24.         }
  25.         exit();
  26.     }
  27.    
  28.     if (!isset($_GET["block"]) || is_array($_GET["block"])) {
  29.         if ($format == "xml" or $format == "csv") {
  30.             printError_XML("param_error", "Keine oder mehrere Block-Nummer(n) angegeben");
  31.         } else if ($format == "json") {
  32.             printError_JSON("param_error", "Keine oder mehrere Block-Nummer(n) angegeben");
  33.         }
  34.         exit();
  35.     }
  36.    
  37.     $block = $_GET["block"];
  38.     $i = intval($block);
  39.     if (!is_numeric($block) || $i < 1 || $i > 9) {
  40.         if ($format == "xml" or $format == "csv") {
  41.             printError_XML("param_error", "Ungültige Block-Nummer: Block-Nummern muessen Zahlen zwischen 1 und 6 sein");
  42.         } else if ($format == "json") {
  43.             printError_JSON("param_error", "Ungültige Block-Nummer: Block-Nummern muessen Zahlen zwischen 1 und 6 sein");
  44.         }
  45.         exit();
  46.     }
  47.     $klasse = strtoupper($_GET["klasse"]);
  48.     $classValid = FALSE;
  49.     foreach ($allowed_classes as $pattern) {
  50.         if (preg_match($pattern, $klasse) == 1) {
  51.             $classValid = TRUE;
  52.             break;
  53.         }
  54.     }
  55.    
  56.     if (!$classValid) {
  57.         if ($format == "xml" or $format == "csv") {
  58.             printError_XML("param_error", "Ungültige Klasse: Klassen müssen heißen, wie in der Stundenplanübersicht");
  59.         } else if ($format == "json") {
  60.             printError_JSON("param_error", "Ungültige Klasse: Klassen müssen heißen, wie in der Stundenplanübersicht");
  61.         }
  62.         exit();
  63.     }
  64.    
  65.     $GLOBALS["format"] = $format;
  66.     $GLOBALS["klasse"] = $klasse;
  67.     $GLOBALS["block"] = $block;
  68.    
  69.     $sced_url = "http://www.asw-berufsakademie.de/fileadmin/download/download/Sked%20Stundenplan/";
  70.     $sced_url .= $klasse . "-" . $block . ".%20Block.html";
  71.     $scedHtml = grabUrl($sced_url);
  72.     if ($scedHtml == FALSE || is_null($scedHtml) || strlen($scedHtml) < 1 || $scedHtml == 404) {
  73.         if ($format == "xml" or $format == "csv") {
  74.             printError_XML("error", "Download des Stundenplans nicht erfolgreich. Bitte ggf. die Klasse und den Block überprüfen!");
  75.         } else if ($format == "json") {
  76.             printError_JSON("error", "Download des Stundenplans nicht erfolgreich. Bitte ggf. die Klasse und den Block überprüfen!");
  77.         }
  78.         exit();
  79.     }
  80.     // Remove newlines, convert single quotes to double quotes
  81.     $scedHtml = (string) str_replace(array("\r", "\r\n", "\n"), "", $scedHtml);
  82.     $scedHtml = (string) str_replace("'", "\"", $scedHtml);
  83.     $stundenplan = parseAswSchedule($scedHtml);
  84.     if ($format == "xml") {
  85.         printDoc_XML(planToXML($stundenplan));
  86.     } else if ($format == "json") {
  87.         printDoc_JSON(planToJSON($stundenplan));
  88.     } else if($format == "csv") {
  89.         $filename = $stundenplan->getKlasse() . '_Block-' . $stundenplan->getBlock() . '.csv';
  90.         printDoc_CSV(planToCSV($stundenplan), $filename);
  91.     }
  92.    
  93.     class ParsingException extends Exception {
  94.        
  95.     }
  96.    
  97.     class Stundenplan {
  98.    
  99.         private $klasse;
  100.         private $block;
  101.         private $wochen;
  102.    
  103.         function __construct($_klasse, $_block) {
  104.             $this->klasse = $_klasse;
  105.             $this->block = $_block;
  106.             $this->wochen = array();
  107.         }
  108.    
  109.         public function addWoche($woche) {
  110.             $this->wochen[] = $woche;
  111.         }
  112.    
  113.         public function getWochen() {
  114.             return $this->wochen;
  115.         }
  116.    
  117.         public function getKlasse() {
  118.             return $this->klasse;
  119.         }
  120.    
  121.         public function getBlock() {
  122.             return $this->block;
  123.         }
  124.    
  125.     }
  126.    
  127.     class Woche {
  128.    
  129.         private $lfdNr;
  130.         private $startDatum;
  131.         private $endDatum;
  132.         private $kalendertage;
  133.    
  134.         function __construct($_lfdNr, $_startDatum, $_endDatum) {
  135.             $this->lfdNr = $_lfdNr;
  136.             $this->startDatum = $_startDatum;
  137.             $this->endDatum = $_endDatum;
  138.             $this->datums = array();
  139.         }
  140.    
  141.         public function addKalendertag($kalendertag) {
  142.             $this->kalendertage[] = $kalendertag;
  143.         }
  144.    
  145.         public function getKalendertage() {
  146.             return $this->kalendertage;
  147.         }
  148.    
  149.         public function getLfdNr() {
  150.             return $this->lfdNr;
  151.         }
  152.    
  153.         public function getStartDatum() {
  154.             return $this->startDatum;
  155.         }
  156.    
  157.         public function getEndDatum() {
  158.             return $this->endDatum;
  159.         }
  160.    
  161.     }
  162.    
  163.     class Kalendertag {
  164.    
  165.         private $timestamp;
  166.         private $termine;
  167.         private $isSorted = false;
  168.    
  169.         function __construct($_timestamp) {
  170.             $this->timestamp = $_timestamp;
  171.             $this->termine = array();
  172.         }
  173.    
  174.         public function addTermin($termin) {
  175.             $this->termine[] = $termin;
  176.         }
  177.    
  178.         public function addTermine($termine) {
  179.             $this->termine = array_merge($this->termine, $termine);
  180.         }
  181.    
  182.         public function getTermine() {
  183.             if (!$this->isSorted) {
  184.                 usort($this->termine, "compareTermin");
  185.             }
  186.             return $this->termine;
  187.         }
  188.    
  189.         public function getTimestamp() {
  190.             return $this->timestamp;
  191.         }
  192.    
  193.         public function getTerminCount() {
  194.             return count($this->termine);
  195.         }
  196.    
  197.     }
  198.    
  199.     class Termin {
  200.    
  201.         private $zeitVon;
  202.         private $zeitBis;
  203.         private $typ;
  204.         private $name;
  205.         private $saal;
  206.    
  207.         function __construct($_zeit_von, $_zeit_bis, $_typ, $_name, $_saal) {
  208.             $this->zeitVon = $_zeit_von;
  209.             $this->zeitBis = $_zeit_bis;
  210.             $this->typ = $_typ;
  211.             $this->name = $_name;
  212.             $this->saal = $_saal;
  213.         }
  214.    
  215.         public function getZeitVon() {
  216.             return $this->zeitVon;
  217.         }
  218.    
  219.         public function getZeitBis() {
  220.             return $this->zeitBis;
  221.         }
  222.    
  223.         public function getTyp() {
  224.             return $this->typ;
  225.         }
  226.    
  227.         public function getName() {
  228.             return $this->name;
  229.         }
  230.    
  231.         public function getSaal() {
  232.             return $this->saal;
  233.         }
  234.    
  235.     }
  236.    
  237.     class Doppeltermin {
  238.    
  239.         private $zeitVon;
  240.         private $zeitBis;
  241.         private $typen;
  242.         private $namen;
  243.         private $saele;
  244.    
  245.         function __construct($_zeit_von, $_zeit_bis, $_typen, $_namen, $_saele) {
  246.             $this->zeitVon = $_zeit_von;
  247.             $this->zeitBis = $_zeit_bis;
  248.             $this->typen = $_typen;
  249.             $this->namen = $_namen;
  250.             $this->saele = $_saele;
  251.         }
  252.    
  253.         public function getZeitVon() {
  254.             return $this->zeitVon;
  255.         }
  256.    
  257.         public function getZeitBis() {
  258.             return $this->zeitBis;
  259.         }
  260.    
  261.         public function getTypen() {
  262.             return $this->typen;
  263.         }
  264.    
  265.         public function getNamen() {
  266.             return $this->namen;
  267.         }
  268.    
  269.         public function getSaele() {
  270.             return $this->saele;
  271.         }
  272.    
  273.     }
  274.    
  275.     function grabUrl($submit_url) { // returns String
  276.         $curl = curl_init();
  277.         $url_parts = parse_url($submit_url);
  278.         $url = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'];
  279.         curl_setopt($curl, CURLOPT_HEADER, false);
  280.         if (isset($url_parts['query'])) {
  281.             curl_setopt($curl, CURLOPT_POST, true);
  282.             curl_setopt($curl, CURLOPT_POSTFIELDS, $url_parts['query']);
  283.         }
  284.         curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  285.         curl_setopt($curl, CURLOPT_URL, $url);
  286.    
  287.         $response = curl_exec($curl);
  288.         $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  289.         if ($httpCode == 404) {
  290.             return $httpCode;
  291.         }
  292.         curl_close($curl);
  293.         return $response;
  294.     }
  295.    
  296.     function planToXML(Stundenplan $plan) {
  297.         $doc = new DOMDocument();
  298.         $doc->formatOutput = true;
  299.         $planElm = $doc->createElement("stundenplan");
  300.         $planElm->setAttribute("klasse", $plan->getKlasse());
  301.         $planElm->setAttribute("block", $plan->getBlock());
  302.         foreach ($plan->getWochen() as $woche) {
  303.             $wocheElm = $doc->createElement("woche");
  304.             $wocheElm->setAttribute("von", $woche->getStartDatum());
  305.             $wocheElm->setAttribute("bis", $woche->getEndDatum());
  306.             $wocheElm->setAttribute("lfdnr", $woche->getLfdNr());
  307.    
  308.             foreach ($woche->getKalendertage() as $kalTag) {
  309.                 if ($kalTag->getTerminCount() < 1) {
  310.                     continue;
  311.                 }
  312.                 $kalTagElm = $doc->createElement("kalendertag");
  313.                 $kalTagElm->setAttribute("datum", $kalTag->getTimestamp());
  314.    
  315.                 foreach ($kalTag->getTermine() as $termin) {
  316.                     if ($termin instanceof Doppeltermin) {
  317.                         $terminElm = $doc->createElement("doppeltermin");
  318.                         $typen = $termin->getTypen();
  319.                         $namen = $termin->getNamen();
  320.                         $saele = $termin->getSaele();
  321.                         $terminElm->setAttribute("typ_a", $typen[0]);
  322.                         $terminElm->setAttribute("typ_b", $typen[1]);
  323.                         $terminElm->setAttribute("name_a", $namen[0]);
  324.                         $terminElm->setAttribute("name_b", $namen[1]);
  325.                         $terminElm->setAttribute("saal_a", $saele[0]);
  326.                         $terminElm->setAttribute("saal_b", $saele[1]);
  327.                     } else {
  328.                         $terminElm = $doc->createElement("termin");
  329.                         $terminElm->setAttribute("typ", $termin->getTyp());
  330.                         $terminElm->setAttribute("name", $termin->getName());
  331.                         $terminElm->setAttribute("saal", $termin->getSaal());
  332.                     }
  333.                     $terminElm->setAttribute("von", $termin->getZeitVon());
  334.                     $terminElm->setAttribute("bis", $termin->getZeitBis());
  335.                     $kalTagElm->appendChild($terminElm);
  336.                 }
  337.                 $wocheElm->appendChild($kalTagElm);
  338.             }
  339.             $planElm->appendChild($wocheElm);
  340.         }
  341.         $doc->appendChild($planElm);
  342.         return $doc->saveXML();
  343.     }
  344.    
  345.     function planToJSON(Stundenplan $plan) {
  346.         $jsonArr = array("stundenplan" => array());
  347.         $jsonArr["stundenplan"]["klasse"] = $GLOBALS["klasse"];
  348.         $jsonArr["stundenplan"]["block"] = intval($GLOBALS["block"]);
  349.         $jsonArr["stundenplan"]["wochen"] = array();
  350.    
  351.         foreach ($plan->getWochen() as $woche) {
  352.             $wocheElm = array();
  353.             $wocheElm["von"] = $woche->getStartDatum();
  354.             $wocheElm["bis"] = $woche->getEndDatum();
  355.             $wocheElm["lfdnr"] = intval($woche->getLfdNr());
  356.             $wocheElm["kalendertage"] = array();
  357.    
  358.             foreach ($woche->getKalendertage() as $kalTag) {
  359.                 if ($kalTag->getTerminCount() < 1) {
  360.                     continue;
  361.                 }
  362.                 $kalTagElm = array();
  363.                 $kalTagElm["datum"] = $kalTag->getTimestamp();
  364.                 $kalTagElm["termine"] = array();
  365.                 foreach ($kalTag->getTermine() as $termin) {
  366.                     $terminElm = array();
  367.                     if ($termin instanceof Doppeltermin) {
  368.                         $typen = $termin->getTypen();
  369.                         $namen = $termin->getNamen();
  370.                         $saele = $termin->getSaele();
  371.                         $terminElm["doppel"] = true;
  372.                         $terminElm["typ_a"] = $typen[0];
  373.                         $terminElm["typ_b"] = $typen[1];
  374.                         $terminElm["name_a"] = $namen[0];
  375.                         $terminElm["name_b"] = $namen[1];
  376.                         $terminElm["saal_a"] = $saele[0];
  377.                         $terminElm["saal_b"] = $saele[1];
  378.                     } else {
  379.                         $terminElm["typ"] = $termin->getTyp();
  380.                         $terminElm["name"] = $termin->getName();
  381.                         $terminElm["saal"] = $termin->getSaal();
  382.                     }
  383.                     $terminElm["von"] = $termin->getZeitVon();
  384.                     $terminElm["bis"] = $termin->getZeitBis();
  385.                     $kalTagElm["termine"][] = $terminElm;
  386.                 }
  387.                 $wocheElm["kalendertage"][] = $kalTagElm;
  388.             }
  389.             $jsonArr["stundenplan"]["wochen"][] = $wocheElm;
  390.         }
  391.         return json_encode($jsonArr);
  392.     }
  393.    
  394.     function planToCSV(Stundenplan $plan) {
  395.         // Kopf-Zeilen Schreiben
  396.         $out = '"Beginnt am","Endet am","Beginnt um","Endet um","Betreff","Ort"';
  397.         foreach ($plan->getWochen() as $woche) {
  398.             foreach ($woche->getKalendertage() as $kalTag) {
  399.                 if ($kalTag->getTerminCount() < 1) {
  400.                     continue;
  401.                 }
  402.                 $aDatum = $kalTag->getTimestamp();
  403.                 $aDatum = '"' . $aDatum .'","' . $aDatum . '"';
  404.                 foreach ($kalTag->getTermine() as $termin) {
  405.                     $aVon = $termin->getZeitVon();
  406.                     $aBis = $termin->getZeitBis();
  407.                     $aLine = $aDatum;
  408.                     $aLine .= ',"' . $aVon . '","' . $aBis . '"';
  409.                     $betreff;
  410.                     $ort;
  411.                         if ($termin instanceof Doppeltermin) {
  412.                             $typen = $termin->getTypen();
  413.                             $namen = $termin->getNamen();
  414.                             $betreff  = '"' . $typen[0] . ' ' . $namen[0] . ' / ';
  415.                             $betreff .= $typen[1] . ' ' . $namen[1] . '"';
  416.                             $ort = '"ASW ' . implode(" / ", $termin->getSaele()) . '"';
  417.                         } else {
  418.                             $typ = $termin->getTyp();
  419.                             $name = $termin->getName();
  420.                             $saal = $termin->getSaal();
  421.                             $betreff = '"' . $typ . ' ' . $name . '"';
  422.                             $ort = '"ASW ' . $saal . '"';
  423.                         }
  424.                     $aLine .= ',' . $betreff . ',' . $ort;
  425.                     $out  .= chr(10) . $aLine;
  426.                 }
  427.             }
  428.         }
  429.         return $out;
  430.     }
  431.    
  432.     function parseAswSchedule($htmlCont) {
  433.         // Extract single tables (=schedule weeks)
  434.         if (!preg_match_all("#<table.*?</table>#", $htmlCont, $tables)) {
  435.             return null;
  436.         }
  437.         // Extract consecutive numbers of the weeks
  438.         $lfdNrs = array();
  439.         if (preg_match_all("#<div class=\"w2\">(\d+)#", $htmlCont, $lfdNrs)) {
  440.             $lfdNrs = $lfdNrs[1];
  441.         }
  442.    
  443.         $tables = $tables[0];
  444.         $plan = new Stundenplan($GLOBALS["klasse"], $GLOBALS["block"]);
  445.         for ($i = 0; $i < count($tables); $i++) {
  446.             if (isset($lfdNrs[$i])) {
  447.                 $lfdNr = $lfdNrs[$i];
  448.             } else {
  449.                 $lfdNr = $i;
  450.             }
  451.             $table = $tables[$i];
  452.             $aWoche = parseSkedTable($table, $lfdNr);
  453.             if (is_null($aWoche)) {
  454.                 continue;
  455.             }
  456.             $plan->addWoche($aWoche);
  457.         }
  458.         return $plan;
  459.     }
  460.    
  461.     function parseSkedTable($htmlTable, $lfdNr) {
  462.         // Convert single quotes to double quotes
  463.         $htmlTable = (string) str_replace("'", "\"", $htmlTable);
  464.         // Normalize all td.class = r2, rz2, rdm2, rdl2, rdr2
  465.         $htmlTable = (string) str_replace("class=\"rz2", "class=\"rz1", $htmlTable);
  466.         $htmlTable = (string) str_replace("class=\"rdm2", "class=\"rdm1", $htmlTable);
  467.         $htmlTable = (string) str_replace("class=\"rdl2", "class=\"rdl1", $htmlTable);
  468.         $htmlTable = (string) str_replace("class=\"r2", "class=\"r1", $htmlTable);
  469.         $htmlTable = (string) str_replace("class=\"rdr2", "class=\"rdr1", $htmlTable);
  470.    
  471.         // Split table by time-of-the-day rows (08:00, 09:00 and so on)
  472.         $zeilen = explode("<tr><td class=\"rz1", $htmlTable);
  473.         // Extract dates of the weekdays in the first row
  474.         if (!preg_match_all("#<td class=\"t\".*?>.*?(\d+\.\d+\.\d+)#", $zeilen[0], $datums)) {
  475.             return null;
  476.         }
  477.         $datums = $datums[1];
  478.         // Convert dates from DD.MM.YYYY to YYYY-MM-DD
  479.         for ($i = 0; $i < count($datums); $i++) {
  480.             $tokens = explode(".", $datums[$i]);
  481.             $tokens = array_reverse($tokens);
  482.             $datums[$i] = implode("-", $tokens);
  483.         }
  484.    
  485.         $woche = new Woche($lfdNr, $datums[0], $datums[count($datums) - 1]);
  486.    
  487.         // Split rows into "Header" and "Content" areas
  488.         // First row will be irrelevant
  489.         // One Header will represent one time-of-the-day row
  490.         $headers = array();
  491.         $contents = array();
  492.         foreach ($zeilen as $zeile) {
  493.             $splitted = explode("</tr>", $zeile, 2);
  494.             $headers[] = $splitted[0];
  495.             $contents[] = $splitted[1];
  496.         }
  497.    
  498.         $daysWithDouble = array();
  499.         // Check for days with "double courses", indicated in the 08:00 row
  500.         $days = explode("class=\"r1", $headers[1]);
  501.         for ($i = 1; $i < count($days) && $i < 7; $i++) {
  502.             // If there are border-left/right style-tags
  503.             // => double courses on this day
  504.             if (strpos($days[$i], "style=\"border-right") !== FALSE) {
  505.                 $daysWithDouble[] = $datums[$i - 1];
  506.             }
  507.         }
  508.    
  509.         // Extract revelant data from the header:
  510.         //     $header["relDays"]     : Days, at which there are courses defined in the content area
  511.         //     $header["tage"]        : Assoc. Array: (date => array with "Termin" [=course])
  512.         //     $header["kein_doppel"] : Dates, at which there are no double courses
  513.         //                              though indicated
  514.    
  515.         $kein_doppel = array();
  516.         $tage = array();
  517.         $relTage = array();
  518.    
  519.         foreach ($datums as $datum) {
  520.             $tage[$datum] = new Kalendertag($datum);
  521.         }
  522.    
  523.         for ($i = 1; $i < count($headers); $i++) {
  524.             $aHour = $i + 7;
  525.             $header = parseHeader($headers[$i], $datums, $daysWithDouble);
  526.             foreach ($header["kein_doppel"] as $aDate) {
  527.                 if (!isset($kein_doppel[$aDate])) {
  528.                     $kein_doppel[$aDate] = array();
  529.                 }
  530.                 // Assign time of the day to the corresponding date
  531.                 $kein_doppel[$aDate][] = $aHour;
  532.             }
  533.    
  534.             foreach ($header["tage"] as $aDate => $termine) {
  535.                 if (count($termine) > 0) {
  536.                     $tage[$aDate]->addTermine($termine);
  537.                 }
  538.             }
  539.    
  540.             // Filter collisions of relevant days
  541.             // rdm/rdl tags become irrelevant (and error producing)
  542.             // if there already is a course at that exact point in time
  543.    
  544.             $relTage[$i] = array();
  545.             for ($j = 0; $j < count($header["relDays"]); $j++) {
  546.                 $aDate = $header["relDays"][$j];
  547.                 if (!isset($tage[$aDate])) {
  548.                     continue;
  549.                 }
  550.                 $termine = $tage[$aDate]->getTermine();
  551.                 $aVon = strtotime($aHour . ":00");
  552.                 $aBis = strtotime($aHour . ":59");
  553.                 foreach ($termine as $termin) {
  554.                     $tVon = strtotime($termin->getZeitVon());
  555.                     $tBis = strtotime($termin->getZeitBis());
  556.                     // Whole hour is blocked by another course
  557.                     // => discard
  558.                     if ($aVon >= $tVon && $aBis <= $tBis) {
  559.                         unset($header["relDays"][$j]);
  560.                     }
  561.                 }
  562.                 $relTage[$i] = array_values($header["relDays"]);
  563.             }
  564.         }
  565.    
  566.         // Extract courses from content (if necessary)
  567.         for ($i = 1; $i < count($contents); $i++) {
  568.             // If courses are indicated in header: parse, else: assign null
  569.             if (count($relTage[$i] > 0)) {
  570.                 $contents[$i] = parseContent($contents[$i]);
  571.                 if (is_null($contents[$i])) {
  572.                     $contents[$i] = null;
  573.                 }
  574.             } else {
  575.                 $contents[$i] = null;
  576.             }
  577.         }
  578.    
  579.    
  580.         // Assign found courses to the relevant days
  581.         for ($i = 1; $i < count($contents); $i++) {
  582.             if (is_null($contents[$i])) {
  583.                 continue;
  584.             }
  585.             $aVorl = $contents[$i];
  586.             $aRelTage = $relTage[$i];
  587.             $aHour = $i + 7;
  588.             $vorlInd = 0;
  589.             for ($d = 0; $d < count($aRelTage) && $vorlInd < count($aVorl); $d++) {
  590.                 $relTag = $aRelTage[$d];
  591.                 $termin = createNewTermin($aVorl[$vorlInd]);
  592.                 $tVon = strtotime($termin->getZeitVon());
  593.                 $tBis = strtotime($termin->getZeitBis());
  594.    
  595.                 // Check if date is already blocked...
  596.                 // if yes, discard
  597.                 $aTermine = $tage[$relTag]->getTermine();
  598.                 $belegt = false;
  599.                 for ($j = 0; $j < count($aTermine); $j++) {
  600.                     $aTermin = $aTermine[$j];
  601.                     $aVon = strtotime($aTermin->getZeitVon());
  602.                     $aBis = strtotime($aTermin->getZeitBis());
  603.                     if ($tBis < $aVon) {
  604.                         continue;
  605.                     }
  606.                     if ($tVon == $aVon) {
  607.                         $belegt = true;
  608.                         break;
  609.                     } else if ($tVon < $aVon && $tBis > $aVon) {
  610.                         $belegt = true;
  611.                         break;
  612.                     } else if ($tVon > $aVon && $tVon <= $aBis) {
  613.                         $belegt = true;
  614.                         break;
  615.                     }
  616.                 }
  617.                 if($belegt) {
  618.                     continue;
  619.                 }
  620.                
  621.                 // If double course was initially indicated and later not ruled out:
  622.                 // => Create "Doppeltermin" (double course) with the next two extracted courses
  623.    
  624.                 $isDoppel = false;
  625.                 if (in_array($relTag, $daysWithDouble)) {
  626.                     $isDoppel = true;
  627.                     foreach ($kein_doppel[$relTag] as $irelHour) {
  628.                         $aVon = strtotime($irelHour . ":00");
  629.                         $aBis = strtotime($irelHour . ":59");
  630.                         if ($tVon > $aBis) {
  631.                             continue;
  632.                         }
  633.                         if ($tBis < $aVon) {
  634.                             break;
  635.                         }
  636.                         if ($tVon == $aVon) {
  637.                             $isDoppel = false;
  638.                             break;
  639.                         } else if ($tVon < $aVon && $tBis > $aVon) {
  640.                             $isDoppel = false;
  641.                             break;
  642.                         } else if ($tVon > $aVon && $tVon <= $aBis) {
  643.                             $isDoppel = false;
  644.                             break;
  645.                         }
  646.                     }
  647.                 }
  648.    
  649.    
  650.                 if ($isDoppel) {
  651.                     $termin = createNewDoppeltermin($aVorl[$vorlInd], $aVorl[$vorlInd + 1]);
  652.                     $vorlInd += 2;
  653.                 } else { // Else keep simple course
  654.                     $vorlInd++;
  655.                 }
  656.    
  657.                 $tage[$relTag]->addTermin($termin);
  658.                 $pos;
  659.                 $aHourTmp;
  660.                 for ($j = $i + 1; $j < count($relTage); $j++) {
  661.                     $pos = array_search($relTag, $relTage[$j]);
  662.                     if ($pos == false) {
  663.                         continue;
  664.                     }
  665.                     $aHourTmp = $j + 7;
  666.                     $aVon = strtotime($aHourTmp . ":00");
  667.                     $aBis = strtotime($aHourTmp . ":59");
  668.                     if ($aVon >= $tVon && $aBis <= $tBis) {
  669.                         unset($relTage[$j][$pos]);
  670.                         $relTage[$j] = array_values($relTage[$j]);
  671.                     }
  672.                 }
  673.             }
  674.         }
  675.    
  676.         foreach ($tage as $kalTag) {
  677.             $woche->addKalendertag($kalTag);
  678.         }
  679.         return $woche;
  680.     }
  681.    
  682.     function parseHeader($header, $datums, $daysWithDouble) {
  683.         $relClasses = array("class=\"rdm", "class=\"rdl", "class=\"rdr");
  684.    
  685.         // Split Header in single days (separated by <td class="r1")
  686.         $days = explode("class=\"r1", $header);
  687.         // Look for courses in single days
  688.         // Courses exist, if:
  689.         // 1. directly defined in <td class="v", or
  690.         // 2. indicated by <td class="rd(l|m|r)1" (definition will then be in the content area)
  691.         $out = array();
  692.         $out["relDays"] = array();
  693.         $out["tage"] = array();
  694.         $out["kein_doppel"] = array();
  695.         foreach ($datums as $datum) {
  696.             $out["tage"][$datum] = array();
  697.         }
  698.         // Relevant Indices are 1 to 6, $j stands for the weekday
  699.         for ($j = 1; $j < count($days) && $j < 7; $j++) {
  700.             $aDate = $datums[$j - 1];
  701.             // If there is a border-left defined and no border-right (or the other way around): No double course
  702.             if (in_array($aDate, $daysWithDouble)) {
  703.                 if (strpos($days[$j], "style=\"border-left") != FALSE
  704.                         xor strpos($days[$j], "style=\"border-right") != FALSE) {
  705.                     $aDate = $datums[$j - 1];
  706.                     $out["kein_doppel"][] = $aDate;
  707.                 }
  708.             }
  709.    
  710.             // If directly defined, simple parse
  711.             if (strpos($days[$j], "class=\"v") !== FALSE) {
  712.                 $termin;
  713.                 // Extract course data
  714.                 $pattern = "#class=\"v.*?>(.*?)</td>#";
  715.                 if (preg_match_all($pattern, $days[$j], $vorl)) {
  716.                     $vorl = $vorl[1];
  717.                     $aDate = $datums[$j - 1];
  718.                     // If multiple matches -> double course
  719.                     if (count($vorl) > 1) {
  720.                         $termin = createNewDoppeltermin($vorl[0], $vorl[1]);
  721.                         $out["tage"][$aDate][] = $termin;
  722.                     } else { // simple course
  723.                         $termin = createNewTermin($vorl[0]);
  724.                         $out["tage"][$aDate][] = $termin;
  725.                     }
  726.                 }
  727.                 continue;
  728.             }
  729.    
  730.             foreach ($relClasses as $relClass) {
  731.                 // If class="rd(l|m|r)1" contained, save day index
  732.                 if (strpos($days[$j], $relClass) !== FALSE) {
  733.                     $aDate = $datums[$j - 1];
  734.                     $out["relDays"][] = $aDate;
  735.                     break;
  736.                 }
  737.             }
  738.         }
  739.         return $out;
  740.     }
  741.    
  742.     function parseContent($content) {
  743.         // Extract body of all <td class="v"> in content
  744.         // This body represents the courses
  745.         $pattern = "#class=\"v.*?>(.*?)</td>#";
  746.         if (preg_match_all($pattern, $content, $vorl) > 0) {
  747.             return $vorl[1];
  748.         } else {
  749.             return null;
  750.         }
  751.     }
  752.    
  753.     function createNewDoppeltermin($vorl_1_cont, $vorl_2_cont) {
  754.         $vorl_1 = parseVorlesung($vorl_1_cont);
  755.         $vorl_2 = parseVorlesung($vorl_2_cont);
  756.         $zeit = $vorl_1["zeit"];
  757.         $typen = array($vorl_1["typ"], $vorl_2["typ"]);
  758.         $namen = array($vorl_1["name"], $vorl_2["name"]);
  759.         $saele = array($vorl_1["saal"], $vorl_2["saal"]);
  760.         $termin = new Doppeltermin($zeit[0], $zeit[1], $typen, $namen, $saele);
  761.         return $termin;
  762.     }
  763.    
  764.     function createNewTermin($vorl_cont) {
  765.         $vorl = parseVorlesung($vorl_cont);
  766.         $termin = new Termin($vorl["zeit"][0], $vorl["zeit"][1],
  767.                         $vorl["typ"], $vorl["name"], $vorl["saal"]);
  768.         return $termin;
  769.     }
  770.    
  771.     function parseVorlesung($vorl) { // returns String-Array
  772.         // Split by <br> tags
  773.         $parts = preg_split("#<br\s*(/\s*|)>#", $vorl);
  774.         // Parse time of the day entries
  775.         $out["zeit"] = (string) str_replace("Uhr", "", $parts[0]);
  776.         $out["zeit"] = explode(" - ", $out["zeit"]);
  777.         $out["zeit"][0] = trim($out["zeit"][0]);
  778.         $out["zeit"][1] = trim($out["zeit"][1]);
  779.    
  780.         // Decode all left over html-entities
  781.         $out["typ"] = trim(html_entity_decode($parts[1], ENT_COMPAT | ENT_HTML401, "UTF-8"));
  782.         $out["name"] = trim(html_entity_decode($parts[2], ENT_COMPAT | ENT_HTML401, "UTF-8"));
  783.         if (isset($parts[3])) {
  784.             // Remove weird Anchor-Tag
  785.             $out["saal"] = strip_tags($parts[3]);
  786.             $out["saal"] = trim(html_entity_decode($out["saal"], ENT_COMPAT | ENT_HTML401, "UTF-8"));
  787.         } else {
  788.             $out["saal"] = "";
  789.         }
  790.         return $out;
  791.     }
  792.    
  793.     function compareTermin($terminA, $terminB) {
  794.         $tsA = strtotime($terminA->getzeitVon());
  795.         $tsB = strtotime($terminB->getzeitVon());
  796.         if ($tsA < $tsB) {
  797.             return -1;
  798.         } else if ($tsA == $tsB) {
  799.             return 0;
  800.         } else {
  801.             return 1;
  802.         }
  803.     }
  804.    
  805.     function printDoc_XML($xmlCont) {
  806.         header("Content-Type: text/xml");
  807.         echo trim($xmlCont);
  808.     }
  809.    
  810.     function printDoc_JSON($jsonCont) {
  811.         header("Content-Type: application/json");
  812.         echo $jsonCont;
  813.     }
  814.    
  815.     function printDoc_CSV($csvCont, $filename) {
  816.         header("Content-Type: text/csv");
  817.         header("Content-Disposition: attachment;filename=" . $filename);
  818.         echo $csvCont;
  819.     }
  820.    
  821.     function printError_XML($tagName, $message) {
  822.         header("HTTP/1.0 400 Bad Request");
  823.         header("Content-Type: text/xml");
  824.         $doc = new DOMDocument();
  825.         $doc->formatOutput = true;
  826.         $errTag = $doc->createElement($tagName);
  827.         $errMsg = $doc->createTextNode($message);
  828.         $errTag->appendChild($errMsg);
  829.         $doc->appendChild($errTag);
  830.         echo $doc->saveXML();
  831.     }
  832.    
  833.     function printError_JSON($tagName, $message) {
  834.         header("HTTP/1.0 400 Bad Request");
  835.         header("Content-Type: application/json");
  836.         $err = array();
  837.         $err[$tagName] = $message;
  838.         echo json_encode($err);
  839.     }
  840.    
  841.     ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement