diff --git a/include/gebiet.class.php b/include/gebiet.class.php index 2491259c4..a83c3319c 100644 --- a/include/gebiet.class.php +++ b/include/gebiet.class.php @@ -1,889 +1,894 @@ -, - * Andreas Oesterreicher , - * Rudolf Hangl and - * Gerald Simane-Sequens - */ -/** - * Klasse fuer die Gebiete des Testtools (Reihungstesttool) - * - */ -require_once(dirname(__FILE__).'/basis_db.class.php'); - -class gebiet extends basis_db -{ - //Tabellenspalten - public $gebiet_id; - public $kurzbz; - public $bezeichnung; - public $beschreibung; - public $zeit; - public $multipleresponse; - public $kategorien; - public $maxfragen; - public $zufallfrage; - public $zufallvorschlag; - public $level_start; - public $level_sprung_auf; - public $level_sprung_ab; - public $levelgleichverteilung; - public $maxpunkte; - public $insertamum; - public $insertvon; - public $updateamum; - public $updatevon; - - // ErgebnisArray - public $result=array(); - public $new; - - /** - * Konstruktor - Laedt optional ein Gebiet - * @param $gebiet_id Gebiet das geladen werden soll (default=null) - */ - public function __construct($gebiet_id=null) - { - parent::__construct(); - - if(!is_null($gebiet_id)) - $this->load($gebiet_id); - } - - /** - * Laedt Gebiet mit der uebergebenen ID - * @param $gebiet_id ID des Gebiets das geladen werden soll - * @return true wenn ok, sonst false - */ - public function load($gebiet_id) - { - $sprache = new sprache(); - $bezeichnung_mehrsprachig = $sprache->getSprachQuery('bezeichnung_mehrsprachig'); - $qry = "SELECT *,$bezeichnung_mehrsprachig FROM testtool.tbl_gebiet WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); - - if($this->db_query($qry)) - { - if($row = $this->db_fetch_object()) - { - $this->gebiet_id = $row->gebiet_id; - $this->kurzbz = $row->kurzbz; - $this->bezeichnung = $row->bezeichnung; - $this->bezeichnung_mehrsprachig = $sprache->parseSprachResult('bezeichnung_mehrsprachig', $row); - $this->beschreibung = $row->beschreibung; - $this->zeit = $row->zeit; - $this->multipleresponse = $this->db_parse_bool($row->multipleresponse); - $this->kategorien = $this->db_parse_bool($row->kategorien); - $this->maxfragen = $row->maxfragen; - $this->zufallfrage = $this->db_parse_bool($row->zufallfrage); - $this->zufallvorschlag = $this->db_parse_bool($row->zufallvorschlag); - $this->level_start = $row->level_start; - $this->level_sprung_auf = $row->level_sprung_auf; - $this->level_sprung_ab = $row->level_sprung_ab; - $this->levelgleichverteilung = $this->db_parse_bool($row->levelgleichverteilung); - $this->maxpunkte = $row->maxpunkte; - $this->insertamum = $row->insertamum; - $this->insertvon = $row->insertvon; - $this->updateamum = $row->updateamum; - $this->updatevon = $row->updatevon; - $this->antwortenprozeile = $row->antwortenprozeile; - - return true; - } - else - { - $this->errormsg = "Gebiet nicht gefunden"; - return false; - } - } - else - { - $this->errormsg = "Fehler beim Laden des Gebiets"; - return false; - } - } - - /** - * Prueft die Variablen vor dem Speichern - * auf Gueltigkeit. - * @return true wenn ok, false im Fehlerfall - */ - private function validate() - { - if(mb_strlen($this->kurzbz)>10) - { - $this->errormsg = 'Kurzbz darf nicht laenger als 10 Zeichen sein'; - return false; - } - if(mb_strlen($this->bezeichnung)>50) - { - $this->errormsg = 'Bezeichnung darf nicht laenger als 50 Zeichen sein'; - return false; - } - if(!is_bool($this->multipleresponse)) - { - $this->errormsg = 'Multipleresponse muss ein boolscher Wert sein'; - return false; - } - if(!is_bool($this->kategorien)) - { - $this->errormsg = 'Kategorien muss ein boolscher Wert sein'; - return false; - } - if(!is_numeric($this->maxfragen) && $this->maxfragen!='') - { - $this->errormsg = 'maxfragen muss eine gueltige Zahl sein'; - return false; - } - if(!is_bool($this->zufallfrage)) - { - $this->errormsg = 'Zufallfrage muss ein boolscher Wert sein'; - return false; - } - if(!is_bool($this->zufallvorschlag)) - { - $this->errormsg = 'Zufallvorschlag muss ein boolscher Wert sein'; - return false; - } - if(!is_bool($this->levelgleichverteilung) && !is_null($this->levelgleichverteilung)) - { - $this->errormsg = 'Levelgleichverteilung ist ungueltig'; - return false; - } - if(!is_numeric($this->maxpunkte) && $this->maxpunkte!='') - { - $this->errormsg = 'Maxpunkte muss eine gueltige Zahl sein'; - return false; - } - if(!is_numeric($this->antwortenprozeile) || $this->antwortenprozeile<=0) - { - $this->errormsg = 'AntortenProZeile muss eine gueltige Zahl und groesser als 0 sein'; - } - - return true; - } - - /** - * Speichert das Gebiet in die Datenbank - * Wenn $new auf true gesetzt ist wird ein neuer Datensatz angelegt - * ansonsten der Datensatz aktualisiert - * @return true wenn erfolgreich, false im Fehlerfall - */ - public function save($new=null) - { - if(is_null($new)) - $new = $this->new; - - //Variablen auf Gueltigkeit pruefen - if(!$this->validate()) - return false; - - if($new) - { - $qry = 'BEGIN;INSERT INTO testtool.tbl_gebiet (kurzbz, bezeichnung, beschreibung, zeit, multipleresponse, - kategorien, maxfragen, zufallfrage, zufallvorschlag, level_start, level_sprung_auf, level_sprung_ab, - levelgleichverteilung, maxpunkte, antwortenprozeile, '; - - foreach($this->bezeichnung_mehrsprachig as $key=>$value) - { - $idx = sprache::$index_arr[$key]; - $qry.=" bezeichnung_mehrsprachig[$idx],"; - } - - $qry.='insertamum, insertvon , updateamum, updatevon) VALUES('. - - $this->db_add_param($this->kurzbz).','. - $this->db_add_param($this->bezeichnung).','. - $this->db_add_param($this->beschreibung).','. - $this->db_add_param($this->zeit).','. - $this->db_add_param($this->multipleresponse, FHC_BOOLEAN).','. - $this->db_add_param($this->kategorien, FHC_BOOLEAN).','. - $this->db_add_param($this->maxfragen).','. - $this->db_add_param($this->zufallfrage, FHC_BOOLEAN).','. - $this->db_add_param($this->zufallvorschlag, FHC_BOOLEAN).','. - $this->db_add_param($this->level_start).','. - $this->db_add_param($this->level_sprung_auf).','. - $this->db_add_param($this->level_sprung_ab).','. - $this->db_add_param($this->levelgleichverteilung, FHC_BOOLEAN).','. - $this->db_add_param($this->maxpunkte).','. - $this->db_add_param($this->antwortenprozeile).','; - foreach($this->bezeichnung_mehrsprachig as $key=>$value) - $qry.=$this->db_add_param($value).','; - - $qry .= $this->db_add_param($this->insertamum).','. - $this->db_add_param($this->insertvon). - ',null, null);'; - } - else - { - $qry = 'UPDATE testtool.tbl_gebiet SET'. - ' kurzbz='.$this->db_add_param($this->kurzbz).','. - ' bezeichnung='.$this->db_add_param($this->bezeichnung).','. - ' beschreibung='.$this->db_add_param($this->beschreibung).','. - ' zeit='.$this->db_add_param($this->zeit).','. - ' multipleresponse='.$this->db_add_param($this->multipleresponse, FHC_BOOLEAN).','. - ' kategorien='.$this->db_add_param($this->kategorien, FHC_BOOLEAN).','. - ' maxfragen='.$this->db_add_param($this->maxfragen).','. - ' zufallfrage='.$this->db_add_param($this->zufallfrage, FHC_BOOLEAN).','. - ' zufallvorschlag='.$this->db_add_param($this->zufallvorschlag, FHC_BOOLEAN).','. - ' level_start='.$this->db_add_param($this->level_start).','. - ' level_sprung_auf='.$this->db_add_param($this->level_sprung_auf).','. - ' level_sprung_ab='.$this->db_add_param($this->level_sprung_ab).','. - ' levelgleichverteilung='.$this->db_add_param($this->levelgleichverteilung, FHC_BOOLEAN).','. - ' maxpunkte='.$this->db_add_param($this->maxpunkte).','. - ' antwortenprozeile='.$this->db_add_param($this->antwortenprozeile).','. - ' updateamum='.$this->db_add_param($this->updateamum).','. - ' updatevon='.$this->db_add_param($this->updatevon).','; - foreach($this->bezeichnung_mehrsprachig as $key=>$value) - { - $idx = sprache::$index_arr[$key]; - $qry .= " bezeichnung_mehrsprachig[$idx]=".$this->db_add_param($value).","; - } - $qry = mb_substr($qry,0,-1); - $qry .= ' WHERE gebiet_id='.$this->db_add_param($this->gebiet_id, FHC_INTEGER, false).';'; - } - - if($this->db_query($qry)) - { - //aktuelle ID aus der Sequence holen - if($new) - { - $qry="SELECT currval('testtool.tbl_gebiet_gebiet_id_seq') as id;"; - if($this->db_query($qry)) - { - if($row = $this->db_fetch_object()) - { - $this->gebiet_id = $row->id; - $this->db_query('COMMIT'); - return true; - } - else - { - $this->errormsg = 'Fehler beim Lesen der Sequence'; - $this->db_query('ROLLBACK;'); - return false; - } - } - else - { - $this->errormsg = 'Fehler beim Lesen der Sequence'; - $this->db_query('ROLLBACK'); - return false; - } - } - else - return true; - } - else - { - $this->errormsg = 'Fehler beim Speichern der Frage'; - return false; - } - } - - /** - * prueft das Gebiet auf Gueltigkeit - * (diverse Plausichecks) - * - * @param $gebiet_id - */ - public function check_gebiet($gebiet_id) - { - $this->errormsg = ''; - $this->warningmsg = ''; - $this->load($gebiet_id); - - //wenn levels verwendet werden muss maxfragen gesetzt sein - if($this->level_start!='' && $this->maxfragen=='') - { - $this->errormsg .= "Wenn Levels verwendet werden, muss die maximale Fragenanzahl gesetzt sein.\n"; - } - - //Levelgleichverteilung gibt es nur bei nicht geleveltem ablauf - if($this->level_start!='' && $this->levelgleichverteilung) - { - $this->errormsg .= "Levelgleichverteilung ist nur dann erlaubt, wenn der Ablauf nicht gelevelt ist.\n"; - } - - //Von jedem level muessen mindestens maxfragen vorhanden sein wenn levels aktiv ist - if($this->level_start!='') - { - $qry = "SELECT count(*) as anzahl, level FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER, false)." GROUP BY level"; - if($this->db_query($qry)) - { - while($row = $this->db_fetch_object()) - { - if($row->anzahl<$this->maxfragen) - { - $this->errormsg .= "Es gibt nur $row->anzahl Fragen fuer das Level $row->level. Es muessen aber mindestens $this->maxfragen angelegt werden.\n"; - } - } - } - } - - //Pruefen ob jede Fragen mindestens 2 Vorschlaege hat - $qry = "SELECT frage_id, nummer FROM testtool.tbl_frage - WHERE (SELECT count(*) as anzahl FROM testtool.tbl_vorschlag WHERE frage_id=tbl_frage.frage_id)<2 - AND gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND NOT demo;"; - if($this->db_query($qry)) - { - while($row = $this->db_fetch_object()) - { - $this->errormsg .= "Frage Nummer $row->nummer (ID: $row->frage_id) hat weniger als 2 Vorschlaege.\n"; - } - } - - //Wenn Levels verwendet werden, muessen mindestens 2 Verschiedene Level vorhanden sein - if($this->level_start!='') - { - $qry = "SELECT level FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND level is not null GROUP by level"; - if($this->db_query($qry)) - { - if($this->db_num_rows()<2) - { - $this->errormsg .= "Wenn Levels verwendet werden, muessen mindestens 2 verschiedene Level vorhanden sein.\n"; - } - } - } - - // Wenn Levelgleichverteilung true ist, muss maxfragen mindestens so gross wie die Anzahl der level sein - if($this->levelgleichverteilung) - { - if($this->maxfragen!='' && $this->maxfragen!=0) - { - $qry = "SELECT count(*) as anzahl FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND not demo AND level is not null GROUP BY level"; - if($this->db_query($qry)) - { - if($this->db_num_rows() > $this->maxfragen) - { - $this->errormsg .= "Wenn Levelgleichverteilung gesetzt ist, muss maxfragen groesser als die Anzahl der verwendeten Levels sein\n"; - } - } - } - } - - // Wenn zufallsfrage=true und level_start!='' oder levelgleichverteilung - // dann darf die punkteanzahl pro level/Frage sich nicht unterscheiden - if($this->zufallfrage && ($this->level_start!='' || $this->levelgleichverteilung)) - { - $qry = "SELECT * FROM ( - SELECT level, count(*) as anzahl FROM ( - SELECT level, punkte, count(*) as anzahl FROM ( - SELECT level, sum(punkte) as punkte - FROM testtool.tbl_frage JOIN testtool.tbl_vorschlag USING(frage_id) - WHERE punkte>0 AND not demo AND gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." - GROUP BY frage_id, level) as a - GROUP BY level, punkte ) as b - GROUP BY level) as c - WHERE c.anzahl>1"; - if($this->db_query($qry)) - { - while($row = $this->db_fetch_object()) - { - $this->errormsg .= "Pro Level/Frage darf die positive Punkteanzahl nicht unterschiedlich sein wenn Zufallsfragen und Levels/Levelgleichverteilung verwendet wird. (Unterschiede in Level $row->level)\n"; - } - } - } - - // kein Multipleresponse bei gelevelten Gebieten - if($this->level_start!='' && $this->level_start!=0 && $this->multipleresponse) - { - $this->errormsg .= "Bei gelevelten Gebieten ist Multipleresponse nicht erlaubt\n"; - } - - // maxpunkte muss eingetragen sein - if($this->maxpunkte=='' || $this->maxpunkte==0) - { - $this->errormsg = "Es wurden keine Maximalpunkte fuer dieses Gebiet eingetragen\n"; - } - - // Pruefung, ob eine Frage mehrere gleiche Antworten oder gleiche Bilder hat - $qry = "SELECT text AS antwort, sprache, frage_id, tbl_frage.nummer, COUNT(text) AS Anz - FROM testtool.tbl_vorschlag_sprache - JOIN testtool.tbl_vorschlag USING (vorschlag_id) - JOIN testtool.tbl_frage USING (frage_id) - WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." - AND (bild IS NULL AND audio IS NULL) - GROUP BY antwort,frage_id,tbl_frage.nummer,sprache - HAVING ( COUNT(text) > 1 ) - - UNION - - SELECT bild AS antwort, sprache, frage_id, tbl_frage.nummer, COUNT(bild) AS Anz - FROM testtool.tbl_vorschlag_sprache - JOIN testtool.tbl_vorschlag USING (vorschlag_id) - JOIN testtool.tbl_frage USING (frage_id) - WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." - AND ((text IS NULL OR text='' OR text=' ') AND audio IS NULL) - GROUP BY antwort,frage_id,tbl_frage.nummer,sprache - HAVING ( COUNT(bild) > 1 );"; - if($this->db_query($qry)) - { - while($row = $this->db_fetch_object()) - { - $this->warningmsg .= "Frage Nummer $row->nummer (ID: $row->frage_id) Sprache $row->sprache hat mehrere gleiche Antworten.\n"; - } - } - - if($this->errormsg=='') - return true; - else - return false; - } - - /** - * Holt alle Gebiete aus der DB - * - * @return true wenn ok, false wenn Fehler - */ - public function getAll() - { - $qry = 'SELECT * FROM testtool.tbl_gebiet ORDER BY bezeichnung'; - - if($this->db_query($qry)) - { - while($row = $this->db_fetch_object()) - { - $obj = new gebiet(); - - $obj->gebiet_id = $row->gebiet_id; - $obj->kurzbz = $row->kurzbz; - $obj->bezeichnung = $row->bezeichnung; - $obj->beschreibung = $row->beschreibung; - $obj->zeit = $row->zeit; - $obj->multipleresponse = $this->db_parse_bool($row->multipleresponse); - $obj->kategorien = $this->db_parse_bool($row->kategorien); - $obj->maxfragen = $row->maxfragen; - $obj->zufallfrage = $this->db_parse_bool($row->zufallfrage); - $obj->zufallvorschlag = $this->db_parse_bool($row->zufallvorschlag); - $obj->levelgleichverteilung = $this->db_parse_bool($row->levelgleichverteilung); - $obj->maxpunkte = $row->maxpunkte; - $obj->level_start = $row->level_start; - $obj->level_sprung_ab = $row->level_sprung_ab; - $obj->level_sprung_auf = $row->level_sprung_auf; - $obj->insertamum = $row->insertamum; - $obj->insertvon = $row->insertvon; - $obj->updateamum = $row->updateamum; - $obj->updatevon = $row->updatevon; - $obj->antwortenprozeile = $row->antwortenprozeile; - - $this->result[] = $obj; - } - - return true; - } - else - { - $this->errormsg = 'Fehler in Fkt getAll()'; - return false; - } - } - - /** - * Berechnet die maxpunkte fuer das Gebiet - * - * @param $gebiet_id - */ - public function berechneMaximalpunkte($gebiet_id) - { - if(!$this->load($gebiet_id)) - return false; - - if(!$this->levelgleichverteilung && ($this->level_start=='' || $this->level_start==0)) - { - $qry = "SELECT sum(punkte) as max - FROM testtool.tbl_vorschlag JOIN testtool.tbl_frage USING(frage_id) - WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND punkte>0 AND NOT demo"; - if($this->maxfragen!='' && $this->maxfragen>0) - $qry.=" LIMIT $this->maxfragen"; - } - elseif($this->levelgleichverteilung && !$this->multipleresponse) - { - //Levelgleichverteilung mit singleresponse - $qry = "SELECT sum(punkteprolevel) as max FROM - ( - SELECT round((anz::decimal/fragengesamt::decimal)*$this->maxfragen*punkte) as punkteprolevel - FROM - ( - SELECT - level, punkte, count(*) as anz, - (SELECT count(*) FROM testtool.tbl_frage - WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER).") as fragengesamt - FROM - testtool.tbl_frage - JOIN testtool.tbl_vorschlag USING(frage_id) - WHERE - gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." - AND NOT demo - GROUP BY level, punkte - ) a - ) b"; - } - elseif($this->levelgleichverteilung && $this->multipleresponse) - { - //Levelgleichverteilung mit multipleresponse - $qry = "SELECT sum(punkteprolevel) as max FROM - ( - SELECT round((anz::decimal/fragengesamt::decimal)*$this->maxfragen*punkte) as punkteprolevel - FROM - ( - SELECT - level, punkte, count(*) as anz, - (SELECT count(*) FROM testtool.tbl_frage - WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER).") as fragengesamt - FROM - testtool.tbl_frage - JOIN testtool.tbl_vorschlag USING(frage_id) - WHERE - gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." - AND NOT demo - GROUP BY level, punkte - ) a - ) b"; - } - elseif($this->level_start!='') - { - //Maximalpunkte fuer geleveltes Gebiet ermitteln - - //Punkte pro Level holen - $qry = " - SELECT level, punkte - FROM - ( - SELECT level, frage_id, sum(punkte) as punkte - FROM testtool.tbl_frage JOIN testtool.tbl_vorschlag USING(frage_id) - WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND punkte>0 AND level>=".$this->db_add_param($this->level_start)." AND NOT demo - GROUP BY level, frage_id - ) as a - GROUP by level, punkte ORDER BY level"; - - if($this->db_query($qry)) - { - $maxfragen = $this->maxfragen; - $maxpunkte = 0; - $lastpunkte=0; - //Punkte mit der Anzahl der Mindestfragen fuer dieses Level multiplizieren - while($row = $this->db_fetch_object()) - { - if($maxfragen>0) - { - $maxpunkte += $row->punkte*$this->level_sprung_auf; - $lastpunkte = $row->punkte; - $maxfragen -=$this->level_sprung_auf; - } - } - // zuletzt die verbleibenden Fragen mit der Punkteanzahl der letzten (schwersten) Fragen multiplizieren - $maxpunkte += $lastpunkte*$maxfragen; - return $maxpunkte; - } - } - - if($this->db_query($qry)) - { - if($row = $this->db_fetch_object()) - { - return $row->max; - } - else - { - $this->errormsg = 'Fehler beim Ermitteln der Maximalpunkte'; - return false; - } - } - else - { - $this->errormsg = 'Fehler beim Ermitteln der Maximalpunkte'; - return false; - } - } - - /** - * Prueft ob das Gebiet bereits gestartet wurde. Wahlweise pruefling_id oder prestudent_id - * - * @param $pruefling_id Wahlweise pruefling_id oder - * @param $prestudent_id prestudent_id des Prueflings. - * @param $gebiet_id Gebiet_id des Gebiets, dessen Start gefprueft werden soll - * @return true wenn das Gebiet bereits gestartet wurde, false wenn nicht. - */ - public function isGestartet($gebiet_id, $pruefling_id=null, $prestudent_id=null) - { - $this->errormsg=''; - - if(!is_numeric($gebiet_id) || $gebiet_id=='') - { - $this->errormsg = 'Gebiet_id muss eine gueltige Zahl sein'; - return false; - } - if(!is_null($pruefling_id) && (!is_numeric($pruefling_id) || $pruefling_id=='')) - { - $this->errormsg = 'Pruefling_id muss eine gueltige Zahl sein'; - return false; - } - if(!is_null($prestudent_id) && (!is_numeric($prestudent_id) || $prestudent_id=='')) - { - $this->errormsg = 'Prestudent_id muss eine gueltige Zahl sein'; - return false; - } - - $qry = ' SELECT - begintime - FROM - testtool.tbl_pruefling_frage - JOIN - testtool.tbl_pruefling USING (pruefling_id) - JOIN - testtool.tbl_frage USING (frage_id) - WHERE '; - if (!is_null($pruefling_id)) - $qry.=' pruefling_id='.$this->db_add_param($pruefling_id, FHC_INTEGER); - else - $qry.=' prestudent_id='.$this->db_add_param($prestudent_id, FHC_INTEGER); - - $qry.=' AND - gebiet_id='.$this->db_add_param($gebiet_id, FHC_INTEGER).' - AND - begintime IS NOT NULL'; - - if($result = $this->db_query($qry)) - { - if($this->db_fetch_object($result)) - return true; - else - { - return false; - } - } - else - { - $this->errormsg = 'Fehler bei der Abfrage aufgetreten'; - return false; - } - } - - /** - * Laedt die Ablaufe die zu einem Gebiet zugeordnet sind - * @param $gebiet_id - * @return boolean true wenn ok, false im Fehlerfall - */ - public function loadAblaufGebiet($gebiet_id) - { - $qry = "SELECT * FROM testtool.tbl_ablauf WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); - if($result = $this->db_query($qry)) - { - while($row = $this->db_fetch_object($result)) - { - $obj = new stdClass(); - $obj->ablauf_id = $row->ablauf_id; - $obj->studiengang_kz = $row->studiengang_kz; - $obj->gebiet_id = $row->gebiet_id; - $obj->reihung = $row->reihung; - $obj->gewicht = $row->gewicht; - $obj->semester = $row->semester; - $obj->ablauf_vorgaben_id = $row->ablauf_vorgaben_id; - $obj->insertamum = $row->insertamum; - $obj->insertvon = $row->insertvon; - $obj->updateamum = $row->updateamum; - $obj->updatevon = $row->updatevon; - - $this->result[] = $obj; - } - return false; - } - } - - /** - * Loescht ein Gebiet und den zugeordneten Ablauf - * @param $gebiet_id - * @return boolean true wenn ok, false im Fehlerfall - */ - public function delete($gebiet_id) - { - $qry = "SELECT * FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); - - if($result = $this->db_query($qry)) - { - if($this->db_num_rows($result)>0) - { - $this->errormsg = 'Bitte entfernen Sie zuerst alle Fragen aus dem Gebiet'; - return false; - } - } - - $qry = " - DELETE FROM testtool.tbl_ablauf WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." - DELETE FROM testtool.tbl_gebiet WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); - - if($this->db_query($qry)) - { - return true; - } - else - { - $this->errormsg = 'Fehler beim Loeschen des Gebiets'; - return false; - } - } - - /** - * Loescht einen Ablauf - * @param $ablauf_id - * @return boolean true wenn ok, false im Fehlerfall - */ - public function deleteAblaufZuordnung($ablauf_id) - { - $qry = "DELETE FROM testtool.tbl_ablauf WHERE ablauf_id=".$this->db_add_param($ablauf_id, FHC_INTEGER); - - if($this->db_query($qry)) - { - return true; - } - else - { - $this->errormsg = 'Fehler beim Entfernen des Ablaufs'; - return false; - } - } - - /** - * Laedt alle AblaufVorabe Eintraege - * @return boolean true wenn ok, false im Fehlerfall - */ - public function getAblaufVorgaben() - { - $qry = "SELECT * FROM testtool.tbl_ablauf_vorgaben ORDER BY studiengang_kz"; - - if($result = $this->db_query($qry)) - { - while($row = $this->db_fetch_object($result)) - { - $obj = new stdClass(); - - $obj->ablauf_vorgaben_id = $row->ablauf_vorgaben_id; - $obj->studiengang_kz = $row->studiengang_kz; - $obj->sprache = $row->sprache; - $obj->sprachwahl = $this->db_parse_bool($row->sprachwahl); - $obj->content_id = $row->content_id; - - $this->result[] = $obj; - } - return true; - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Speichert den Ablauf - */ - public function saveAblauf() - { - if($this->new) - { - $qry = "INSERT INTO testtool.tbl_ablauf (studiengang_kz, gebiet_id, reihung,gewicht,semester,ablauf_vorgaben_id, insertamum, insertvon) VALUES(". - $this->db_add_param($this->studiengang_kz, FHC_INTEGER).','. - $this->db_add_param($this->gebiet_id, FHC_INTEGER).','. - $this->db_add_param($this->reihung, FHC_INTEGER).','. - $this->db_add_param($this->gewicht, FHC_INTEGER).','. - $this->db_add_param($this->semester, FHC_INTEGER).','. - $this->db_add_param($this->ablauf_vorgaben_id, FHC_INTEGER).','. - $this->db_add_param($this->insertamum).','. - $this->db_add_param($this->insertvon).');'; - } - else - { - $this->errormsg='not implemented'; - return false; - } - - if($this->db_query($qry)) - { - return true; - } - else - { - $this->errormsg = 'Fehler beim Speichern der Daten'; - return true; - } - } - - /** - * Prueft, ob das Gebiet zumindest eine Frage oder einen Vorschlag im MathML Format hat. - * @param $gebiet_id - * return true, wenn Gebiet eine/n Frage/Vorschlag im MathML Format enthält. - */ - public function hasMathML($gebiet_id) - { - if (is_numeric($gebiet_id)) - { - $qry = ' - WITH - fragen AS ( - SELECT DISTINCT - frage_id - FROM - testtool.tbl_frage - JOIN - testtool.tbl_gebiet USING (gebiet_id) - WHERE - tbl_gebiet.gebiet_id = '. $this->db_add_param($gebiet_id, FHC_INTEGER). ' - ), - vorschlaege AS ( - SELECT DISTINCT - vorschlag_id - FROM - testtool.tbl_vorschlag - JOIN - fragen USING (frage_id) - ) - - SELECT - 1 - FROM - testtool.tbl_frage_sprache - JOIN - fragen USING (frage_id) - WHERE - SUBSTRING(text, \'MathML\') IS NOT NULL - - UNION - - SELECT - 1 - FROM - testtool.tbl_vorschlag_sprache - JOIN - vorschlaege USING (vorschlag_id) - WHERE - SUBSTRING(text, \'MathML\') IS NOT NULL - '; - - if($result = $this->db_query($qry)) - { - return ($this->db_num_rows($result) > 0); - } - } - else - { - $this->errormsg = 'Eine numerische gebiet_id muss übergeben werden.'; - return false; - } - } -} -?> +, + * Andreas Oesterreicher , + * Rudolf Hangl and + * Gerald Simane-Sequens + */ +/** + * Klasse fuer die Gebiete des Testtools (Reihungstesttool) + * + */ +require_once(dirname(__FILE__).'/basis_db.class.php'); + +class gebiet extends basis_db +{ + //Tabellenspalten + public $gebiet_id; + public $kurzbz; + public $bezeichnung; + public $beschreibung; + public $zeit; + public $multipleresponse; + public $kategorien; + public $maxfragen; + public $zufallfrage; + public $zufallvorschlag; + public $level_start; + public $level_sprung_auf; + public $level_sprung_ab; + public $levelgleichverteilung; + public $maxpunkte; + public $offsetpunkte; + public $insertamum; + public $insertvon; + public $updateamum; + public $updatevon; + + // ErgebnisArray + public $result=array(); + public $new; + + /** + * Konstruktor - Laedt optional ein Gebiet + * @param $gebiet_id Gebiet das geladen werden soll (default=null) + */ + public function __construct($gebiet_id=null) + { + parent::__construct(); + + if(!is_null($gebiet_id)) + $this->load($gebiet_id); + } + + /** + * Laedt Gebiet mit der uebergebenen ID + * @param $gebiet_id ID des Gebiets das geladen werden soll + * @return true wenn ok, sonst false + */ + public function load($gebiet_id) + { + $sprache = new sprache(); + $bezeichnung_mehrsprachig = $sprache->getSprachQuery('bezeichnung_mehrsprachig'); + $qry = "SELECT *,$bezeichnung_mehrsprachig FROM testtool.tbl_gebiet WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); + + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + $this->gebiet_id = $row->gebiet_id; + $this->kurzbz = $row->kurzbz; + $this->bezeichnung = $row->bezeichnung; + $this->bezeichnung_mehrsprachig = $sprache->parseSprachResult('bezeichnung_mehrsprachig', $row); + $this->beschreibung = $row->beschreibung; + $this->zeit = $row->zeit; + $this->multipleresponse = $this->db_parse_bool($row->multipleresponse); + $this->kategorien = $this->db_parse_bool($row->kategorien); + $this->maxfragen = $row->maxfragen; + $this->zufallfrage = $this->db_parse_bool($row->zufallfrage); + $this->zufallvorschlag = $this->db_parse_bool($row->zufallvorschlag); + $this->level_start = $row->level_start; + $this->level_sprung_auf = $row->level_sprung_auf; + $this->level_sprung_ab = $row->level_sprung_ab; + $this->levelgleichverteilung = $this->db_parse_bool($row->levelgleichverteilung); + $this->maxpunkte = $row->maxpunkte; + $this->offsetpunkte = $row->offsetpunkte; + $this->insertamum = $row->insertamum; + $this->insertvon = $row->insertvon; + $this->updateamum = $row->updateamum; + $this->updatevon = $row->updatevon; + $this->antwortenprozeile = $row->antwortenprozeile; + + return true; + } + else + { + $this->errormsg = "Gebiet nicht gefunden"; + return false; + } + } + else + { + $this->errormsg = "Fehler beim Laden des Gebiets"; + return false; + } + } + + /** + * Prueft die Variablen vor dem Speichern + * auf Gueltigkeit. + * @return true wenn ok, false im Fehlerfall + */ + private function validate() + { + if(mb_strlen($this->kurzbz)>10) + { + $this->errormsg = 'Kurzbz darf nicht laenger als 10 Zeichen sein'; + return false; + } + if(mb_strlen($this->bezeichnung)>50) + { + $this->errormsg = 'Bezeichnung darf nicht laenger als 50 Zeichen sein'; + return false; + } + if(!is_bool($this->multipleresponse)) + { + $this->errormsg = 'Multipleresponse muss ein boolscher Wert sein'; + return false; + } + if(!is_bool($this->kategorien)) + { + $this->errormsg = 'Kategorien muss ein boolscher Wert sein'; + return false; + } + if(!is_numeric($this->maxfragen) && $this->maxfragen!='') + { + $this->errormsg = 'maxfragen muss eine gueltige Zahl sein'; + return false; + } + if(!is_bool($this->zufallfrage)) + { + $this->errormsg = 'Zufallfrage muss ein boolscher Wert sein'; + return false; + } + if(!is_bool($this->zufallvorschlag)) + { + $this->errormsg = 'Zufallvorschlag muss ein boolscher Wert sein'; + return false; + } + if(!is_bool($this->levelgleichverteilung) && !is_null($this->levelgleichverteilung)) + { + $this->errormsg = 'Levelgleichverteilung ist ungueltig'; + return false; + } + if(!is_numeric($this->maxpunkte) && $this->maxpunkte!='') + { + $this->errormsg = 'Maxpunkte muss eine gueltige Zahl sein'; + return false; + } + if(!is_numeric($this->antwortenprozeile) || $this->antwortenprozeile<=0) + { + $this->errormsg = 'AntortenProZeile muss eine gueltige Zahl und groesser als 0 sein'; + } + + return true; + } + + /** + * Speichert das Gebiet in die Datenbank + * Wenn $new auf true gesetzt ist wird ein neuer Datensatz angelegt + * ansonsten der Datensatz aktualisiert + * @return true wenn erfolgreich, false im Fehlerfall + */ + public function save($new=null) + { + if(is_null($new)) + $new = $this->new; + + //Variablen auf Gueltigkeit pruefen + if(!$this->validate()) + return false; + + if($new) + { + $qry = 'BEGIN;INSERT INTO testtool.tbl_gebiet (kurzbz, bezeichnung, beschreibung, zeit, multipleresponse, + kategorien, maxfragen, zufallfrage, zufallvorschlag, level_start, level_sprung_auf, level_sprung_ab, + levelgleichverteilung, maxpunkte, offsetpunkte, antwortenprozeile, '; + + foreach($this->bezeichnung_mehrsprachig as $key=>$value) + { + $idx = sprache::$index_arr[$key]; + $qry.=" bezeichnung_mehrsprachig[$idx],"; + } + + $qry.='insertamum, insertvon , updateamum, updatevon) VALUES('. + + $this->db_add_param($this->kurzbz).','. + $this->db_add_param($this->bezeichnung).','. + $this->db_add_param($this->beschreibung).','. + $this->db_add_param($this->zeit).','. + $this->db_add_param($this->multipleresponse, FHC_BOOLEAN).','. + $this->db_add_param($this->kategorien, FHC_BOOLEAN).','. + $this->db_add_param($this->maxfragen).','. + $this->db_add_param($this->zufallfrage, FHC_BOOLEAN).','. + $this->db_add_param($this->zufallvorschlag, FHC_BOOLEAN).','. + $this->db_add_param($this->level_start).','. + $this->db_add_param($this->level_sprung_auf).','. + $this->db_add_param($this->level_sprung_ab).','. + $this->db_add_param($this->levelgleichverteilung, FHC_BOOLEAN).','. + $this->db_add_param($this->maxpunkte).','. + $this->db_add_param($this->offsetpunkte).','. + $this->db_add_param($this->antwortenprozeile).','; + foreach($this->bezeichnung_mehrsprachig as $key=>$value) + $qry.=$this->db_add_param($value).','; + + $qry .= $this->db_add_param($this->insertamum).','. + $this->db_add_param($this->insertvon). + ',null, null);'; + } + else + { + $qry = 'UPDATE testtool.tbl_gebiet SET'. + ' kurzbz='.$this->db_add_param($this->kurzbz).','. + ' bezeichnung='.$this->db_add_param($this->bezeichnung).','. + ' beschreibung='.$this->db_add_param($this->beschreibung).','. + ' zeit='.$this->db_add_param($this->zeit).','. + ' multipleresponse='.$this->db_add_param($this->multipleresponse, FHC_BOOLEAN).','. + ' kategorien='.$this->db_add_param($this->kategorien, FHC_BOOLEAN).','. + ' maxfragen='.$this->db_add_param($this->maxfragen).','. + ' zufallfrage='.$this->db_add_param($this->zufallfrage, FHC_BOOLEAN).','. + ' zufallvorschlag='.$this->db_add_param($this->zufallvorschlag, FHC_BOOLEAN).','. + ' level_start='.$this->db_add_param($this->level_start).','. + ' level_sprung_auf='.$this->db_add_param($this->level_sprung_auf).','. + ' level_sprung_ab='.$this->db_add_param($this->level_sprung_ab).','. + ' levelgleichverteilung='.$this->db_add_param($this->levelgleichverteilung, FHC_BOOLEAN).','. + ' maxpunkte='.$this->db_add_param($this->maxpunkte).','. + ' offsetpunkte='.$this->db_add_param($this->offsetpunkte).','. + ' antwortenprozeile='.$this->db_add_param($this->antwortenprozeile).','. + ' updateamum='.$this->db_add_param($this->updateamum).','. + ' updatevon='.$this->db_add_param($this->updatevon).','; + foreach($this->bezeichnung_mehrsprachig as $key=>$value) + { + $idx = sprache::$index_arr[$key]; + $qry .= " bezeichnung_mehrsprachig[$idx]=".$this->db_add_param($value).","; + } + $qry = mb_substr($qry,0,-1); + $qry .= ' WHERE gebiet_id='.$this->db_add_param($this->gebiet_id, FHC_INTEGER, false).';'; + } + + if($this->db_query($qry)) + { + //aktuelle ID aus der Sequence holen + if($new) + { + $qry="SELECT currval('testtool.tbl_gebiet_gebiet_id_seq') as id;"; + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + $this->gebiet_id = $row->id; + $this->db_query('COMMIT'); + return true; + } + else + { + $this->errormsg = 'Fehler beim Lesen der Sequence'; + $this->db_query('ROLLBACK;'); + return false; + } + } + else + { + $this->errormsg = 'Fehler beim Lesen der Sequence'; + $this->db_query('ROLLBACK'); + return false; + } + } + else + return true; + } + else + { + $this->errormsg = 'Fehler beim Speichern der Frage'; + return false; + } + } + + /** + * prueft das Gebiet auf Gueltigkeit + * (diverse Plausichecks) + * + * @param $gebiet_id + */ + public function check_gebiet($gebiet_id) + { + $this->errormsg = ''; + $this->warningmsg = ''; + $this->load($gebiet_id); + + //wenn levels verwendet werden muss maxfragen gesetzt sein + if($this->level_start!='' && $this->maxfragen=='') + { + $this->errormsg .= "Wenn Levels verwendet werden, muss die maximale Fragenanzahl gesetzt sein.\n"; + } + + //Levelgleichverteilung gibt es nur bei nicht geleveltem ablauf + if($this->level_start!='' && $this->levelgleichverteilung) + { + $this->errormsg .= "Levelgleichverteilung ist nur dann erlaubt, wenn der Ablauf nicht gelevelt ist.\n"; + } + + //Von jedem level muessen mindestens maxfragen vorhanden sein wenn levels aktiv ist + if($this->level_start!='') + { + $qry = "SELECT count(*) as anzahl, level FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER, false)." GROUP BY level"; + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + if($row->anzahl<$this->maxfragen) + { + $this->errormsg .= "Es gibt nur $row->anzahl Fragen fuer das Level $row->level. Es muessen aber mindestens $this->maxfragen angelegt werden.\n"; + } + } + } + } + + //Pruefen ob jede Fragen mindestens 2 Vorschlaege hat + $qry = "SELECT frage_id, nummer FROM testtool.tbl_frage + WHERE (SELECT count(*) as anzahl FROM testtool.tbl_vorschlag WHERE frage_id=tbl_frage.frage_id)<2 + AND gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND NOT demo;"; + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + $this->errormsg .= "Frage Nummer $row->nummer (ID: $row->frage_id) hat weniger als 2 Vorschlaege.\n"; + } + } + + //Wenn Levels verwendet werden, muessen mindestens 2 Verschiedene Level vorhanden sein + if($this->level_start!='') + { + $qry = "SELECT level FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND level is not null GROUP by level"; + if($this->db_query($qry)) + { + if($this->db_num_rows()<2) + { + $this->errormsg .= "Wenn Levels verwendet werden, muessen mindestens 2 verschiedene Level vorhanden sein.\n"; + } + } + } + + // Wenn Levelgleichverteilung true ist, muss maxfragen mindestens so gross wie die Anzahl der level sein + if($this->levelgleichverteilung) + { + if($this->maxfragen!='' && $this->maxfragen!=0) + { + $qry = "SELECT count(*) as anzahl FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND not demo AND level is not null GROUP BY level"; + if($this->db_query($qry)) + { + if($this->db_num_rows() > $this->maxfragen) + { + $this->errormsg .= "Wenn Levelgleichverteilung gesetzt ist, muss maxfragen groesser als die Anzahl der verwendeten Levels sein\n"; + } + } + } + } + + // Wenn zufallsfrage=true und level_start!='' oder levelgleichverteilung + // dann darf die punkteanzahl pro level/Frage sich nicht unterscheiden + if($this->zufallfrage && ($this->level_start!='' || $this->levelgleichverteilung)) + { + $qry = "SELECT * FROM ( + SELECT level, count(*) as anzahl FROM ( + SELECT level, punkte, count(*) as anzahl FROM ( + SELECT level, sum(punkte) as punkte + FROM testtool.tbl_frage JOIN testtool.tbl_vorschlag USING(frage_id) + WHERE punkte>0 AND not demo AND gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." + GROUP BY frage_id, level) as a + GROUP BY level, punkte ) as b + GROUP BY level) as c + WHERE c.anzahl>1"; + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + $this->errormsg .= "Pro Level/Frage darf die positive Punkteanzahl nicht unterschiedlich sein wenn Zufallsfragen und Levels/Levelgleichverteilung verwendet wird. (Unterschiede in Level $row->level)\n"; + } + } + } + + // kein Multipleresponse bei gelevelten Gebieten + if($this->level_start!='' && $this->level_start!=0 && $this->multipleresponse) + { + $this->errormsg .= "Bei gelevelten Gebieten ist Multipleresponse nicht erlaubt\n"; + } + + // maxpunkte muss eingetragen sein + if($this->maxpunkte=='' || $this->maxpunkte==0) + { + $this->errormsg = "Es wurden keine Maximalpunkte fuer dieses Gebiet eingetragen\n"; + } + + // Pruefung, ob eine Frage mehrere gleiche Antworten oder gleiche Bilder hat + $qry = "SELECT text AS antwort, sprache, frage_id, tbl_frage.nummer, COUNT(text) AS Anz + FROM testtool.tbl_vorschlag_sprache + JOIN testtool.tbl_vorschlag USING (vorschlag_id) + JOIN testtool.tbl_frage USING (frage_id) + WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." + AND (bild IS NULL AND audio IS NULL) + GROUP BY antwort,frage_id,tbl_frage.nummer,sprache + HAVING ( COUNT(text) > 1 ) + + UNION + + SELECT bild AS antwort, sprache, frage_id, tbl_frage.nummer, COUNT(bild) AS Anz + FROM testtool.tbl_vorschlag_sprache + JOIN testtool.tbl_vorschlag USING (vorschlag_id) + JOIN testtool.tbl_frage USING (frage_id) + WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." + AND ((text IS NULL OR text='' OR text=' ') AND audio IS NULL) + GROUP BY antwort,frage_id,tbl_frage.nummer,sprache + HAVING ( COUNT(bild) > 1 );"; + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + $this->warningmsg .= "Frage Nummer $row->nummer (ID: $row->frage_id) Sprache $row->sprache hat mehrere gleiche Antworten.\n"; + } + } + + if($this->errormsg=='') + return true; + else + return false; + } + + /** + * Holt alle Gebiete aus der DB + * + * @return true wenn ok, false wenn Fehler + */ + public function getAll() + { + $qry = 'SELECT * FROM testtool.tbl_gebiet ORDER BY bezeichnung'; + + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + $obj = new gebiet(); + + $obj->gebiet_id = $row->gebiet_id; + $obj->kurzbz = $row->kurzbz; + $obj->bezeichnung = $row->bezeichnung; + $obj->beschreibung = $row->beschreibung; + $obj->zeit = $row->zeit; + $obj->multipleresponse = $this->db_parse_bool($row->multipleresponse); + $obj->kategorien = $this->db_parse_bool($row->kategorien); + $obj->maxfragen = $row->maxfragen; + $obj->zufallfrage = $this->db_parse_bool($row->zufallfrage); + $obj->zufallvorschlag = $this->db_parse_bool($row->zufallvorschlag); + $obj->levelgleichverteilung = $this->db_parse_bool($row->levelgleichverteilung); + $obj->maxpunkte = $row->maxpunkte; + $obj->offsetpunkte = $row->offsetpunkte; + $obj->level_start = $row->level_start; + $obj->level_sprung_ab = $row->level_sprung_ab; + $obj->level_sprung_auf = $row->level_sprung_auf; + $obj->insertamum = $row->insertamum; + $obj->insertvon = $row->insertvon; + $obj->updateamum = $row->updateamum; + $obj->updatevon = $row->updatevon; + $obj->antwortenprozeile = $row->antwortenprozeile; + + $this->result[] = $obj; + } + + return true; + } + else + { + $this->errormsg = 'Fehler in Fkt getAll()'; + return false; + } + } + + /** + * Berechnet die maxpunkte fuer das Gebiet + * + * @param $gebiet_id + */ + public function berechneMaximalpunkte($gebiet_id) + { + if(!$this->load($gebiet_id)) + return false; + + if(!$this->levelgleichverteilung && ($this->level_start=='' || $this->level_start==0)) + { + $qry = "SELECT sum(punkte) as max + FROM testtool.tbl_vorschlag JOIN testtool.tbl_frage USING(frage_id) + WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND punkte>0 AND NOT demo"; + if($this->maxfragen!='' && $this->maxfragen>0) + $qry.=" LIMIT $this->maxfragen"; + } + elseif($this->levelgleichverteilung && !$this->multipleresponse) + { + //Levelgleichverteilung mit singleresponse + $qry = "SELECT sum(punkteprolevel) as max FROM + ( + SELECT round((anz::decimal/fragengesamt::decimal)*$this->maxfragen*punkte) as punkteprolevel + FROM + ( + SELECT + level, punkte, count(*) as anz, + (SELECT count(*) FROM testtool.tbl_frage + WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER).") as fragengesamt + FROM + testtool.tbl_frage + JOIN testtool.tbl_vorschlag USING(frage_id) + WHERE + gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." + AND NOT demo + GROUP BY level, punkte + ) a + ) b"; + } + elseif($this->levelgleichverteilung && $this->multipleresponse) + { + //Levelgleichverteilung mit multipleresponse + $qry = "SELECT sum(punkteprolevel) as max FROM + ( + SELECT round((anz::decimal/fragengesamt::decimal)*$this->maxfragen*punkte) as punkteprolevel + FROM + ( + SELECT + level, punkte, count(*) as anz, + (SELECT count(*) FROM testtool.tbl_frage + WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER).") as fragengesamt + FROM + testtool.tbl_frage + JOIN testtool.tbl_vorschlag USING(frage_id) + WHERE + gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." + AND NOT demo + GROUP BY level, punkte + ) a + ) b"; + } + elseif($this->level_start!='') + { + //Maximalpunkte fuer geleveltes Gebiet ermitteln + + //Punkte pro Level holen + $qry = " + SELECT level, punkte + FROM + ( + SELECT level, frage_id, sum(punkte) as punkte + FROM testtool.tbl_frage JOIN testtool.tbl_vorschlag USING(frage_id) + WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." AND punkte>0 AND level>=".$this->db_add_param($this->level_start)." AND NOT demo + GROUP BY level, frage_id + ) as a + GROUP by level, punkte ORDER BY level"; + + if($this->db_query($qry)) + { + $maxfragen = $this->maxfragen; + $maxpunkte = 0; + $lastpunkte=0; + //Punkte mit der Anzahl der Mindestfragen fuer dieses Level multiplizieren + while($row = $this->db_fetch_object()) + { + if($maxfragen>0) + { + $maxpunkte += $row->punkte*$this->level_sprung_auf; + $lastpunkte = $row->punkte; + $maxfragen -=$this->level_sprung_auf; + } + } + // zuletzt die verbleibenden Fragen mit der Punkteanzahl der letzten (schwersten) Fragen multiplizieren + $maxpunkte += $lastpunkte*$maxfragen; + return $maxpunkte; + } + } + + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + return $row->max; + } + else + { + $this->errormsg = 'Fehler beim Ermitteln der Maximalpunkte'; + return false; + } + } + else + { + $this->errormsg = 'Fehler beim Ermitteln der Maximalpunkte'; + return false; + } + } + + /** + * Prueft ob das Gebiet bereits gestartet wurde. Wahlweise pruefling_id oder prestudent_id + * + * @param $pruefling_id Wahlweise pruefling_id oder + * @param $prestudent_id prestudent_id des Prueflings. + * @param $gebiet_id Gebiet_id des Gebiets, dessen Start gefprueft werden soll + * @return true wenn das Gebiet bereits gestartet wurde, false wenn nicht. + */ + public function isGestartet($gebiet_id, $pruefling_id=null, $prestudent_id=null) + { + $this->errormsg=''; + + if(!is_numeric($gebiet_id) || $gebiet_id=='') + { + $this->errormsg = 'Gebiet_id muss eine gueltige Zahl sein'; + return false; + } + if(!is_null($pruefling_id) && (!is_numeric($pruefling_id) || $pruefling_id=='')) + { + $this->errormsg = 'Pruefling_id muss eine gueltige Zahl sein'; + return false; + } + if(!is_null($prestudent_id) && (!is_numeric($prestudent_id) || $prestudent_id=='')) + { + $this->errormsg = 'Prestudent_id muss eine gueltige Zahl sein'; + return false; + } + + $qry = ' SELECT + begintime + FROM + testtool.tbl_pruefling_frage + JOIN + testtool.tbl_pruefling USING (pruefling_id) + JOIN + testtool.tbl_frage USING (frage_id) + WHERE '; + if (!is_null($pruefling_id)) + $qry.=' pruefling_id='.$this->db_add_param($pruefling_id, FHC_INTEGER); + else + $qry.=' prestudent_id='.$this->db_add_param($prestudent_id, FHC_INTEGER); + + $qry.=' AND + gebiet_id='.$this->db_add_param($gebiet_id, FHC_INTEGER).' + AND + begintime IS NOT NULL'; + + if($result = $this->db_query($qry)) + { + if($this->db_fetch_object($result)) + return true; + else + { + return false; + } + } + else + { + $this->errormsg = 'Fehler bei der Abfrage aufgetreten'; + return false; + } + } + + /** + * Laedt die Ablaufe die zu einem Gebiet zugeordnet sind + * @param $gebiet_id + * @return boolean true wenn ok, false im Fehlerfall + */ + public function loadAblaufGebiet($gebiet_id) + { + $qry = "SELECT * FROM testtool.tbl_ablauf WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); + if($result = $this->db_query($qry)) + { + while($row = $this->db_fetch_object($result)) + { + $obj = new stdClass(); + $obj->ablauf_id = $row->ablauf_id; + $obj->studiengang_kz = $row->studiengang_kz; + $obj->gebiet_id = $row->gebiet_id; + $obj->reihung = $row->reihung; + $obj->gewicht = $row->gewicht; + $obj->semester = $row->semester; + $obj->ablauf_vorgaben_id = $row->ablauf_vorgaben_id; + $obj->insertamum = $row->insertamum; + $obj->insertvon = $row->insertvon; + $obj->updateamum = $row->updateamum; + $obj->updatevon = $row->updatevon; + + $this->result[] = $obj; + } + return false; + } + } + + /** + * Loescht ein Gebiet und den zugeordneten Ablauf + * @param $gebiet_id + * @return boolean true wenn ok, false im Fehlerfall + */ + public function delete($gebiet_id) + { + $qry = "SELECT * FROM testtool.tbl_frage WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); + + if($result = $this->db_query($qry)) + { + if($this->db_num_rows($result)>0) + { + $this->errormsg = 'Bitte entfernen Sie zuerst alle Fragen aus dem Gebiet'; + return false; + } + } + + $qry = " + DELETE FROM testtool.tbl_ablauf WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER)." + DELETE FROM testtool.tbl_gebiet WHERE gebiet_id=".$this->db_add_param($gebiet_id, FHC_INTEGER); + + if($this->db_query($qry)) + { + return true; + } + else + { + $this->errormsg = 'Fehler beim Loeschen des Gebiets'; + return false; + } + } + + /** + * Loescht einen Ablauf + * @param $ablauf_id + * @return boolean true wenn ok, false im Fehlerfall + */ + public function deleteAblaufZuordnung($ablauf_id) + { + $qry = "DELETE FROM testtool.tbl_ablauf WHERE ablauf_id=".$this->db_add_param($ablauf_id, FHC_INTEGER); + + if($this->db_query($qry)) + { + return true; + } + else + { + $this->errormsg = 'Fehler beim Entfernen des Ablaufs'; + return false; + } + } + + /** + * Laedt alle AblaufVorabe Eintraege + * @return boolean true wenn ok, false im Fehlerfall + */ + public function getAblaufVorgaben() + { + $qry = "SELECT * FROM testtool.tbl_ablauf_vorgaben ORDER BY studiengang_kz"; + + if($result = $this->db_query($qry)) + { + while($row = $this->db_fetch_object($result)) + { + $obj = new stdClass(); + + $obj->ablauf_vorgaben_id = $row->ablauf_vorgaben_id; + $obj->studiengang_kz = $row->studiengang_kz; + $obj->sprache = $row->sprache; + $obj->sprachwahl = $this->db_parse_bool($row->sprachwahl); + $obj->content_id = $row->content_id; + + $this->result[] = $obj; + } + return true; + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Speichert den Ablauf + */ + public function saveAblauf() + { + if($this->new) + { + $qry = "INSERT INTO testtool.tbl_ablauf (studiengang_kz, gebiet_id, reihung,gewicht,semester,ablauf_vorgaben_id, insertamum, insertvon) VALUES(". + $this->db_add_param($this->studiengang_kz, FHC_INTEGER).','. + $this->db_add_param($this->gebiet_id, FHC_INTEGER).','. + $this->db_add_param($this->reihung, FHC_INTEGER).','. + $this->db_add_param($this->gewicht, FHC_INTEGER).','. + $this->db_add_param($this->semester, FHC_INTEGER).','. + $this->db_add_param($this->ablauf_vorgaben_id, FHC_INTEGER).','. + $this->db_add_param($this->insertamum).','. + $this->db_add_param($this->insertvon).');'; + } + else + { + $this->errormsg='not implemented'; + return false; + } + + if($this->db_query($qry)) + { + return true; + } + else + { + $this->errormsg = 'Fehler beim Speichern der Daten'; + return true; + } + } + + /** + * Prueft, ob das Gebiet zumindest eine Frage oder einen Vorschlag im MathML Format hat. + * @param $gebiet_id + * return true, wenn Gebiet eine/n Frage/Vorschlag im MathML Format enthält. + */ + public function hasMathML($gebiet_id) + { + if (is_numeric($gebiet_id)) + { + $qry = ' + WITH + fragen AS ( + SELECT DISTINCT + frage_id + FROM + testtool.tbl_frage + JOIN + testtool.tbl_gebiet USING (gebiet_id) + WHERE + tbl_gebiet.gebiet_id = '. $this->db_add_param($gebiet_id, FHC_INTEGER). ' + ), + vorschlaege AS ( + SELECT DISTINCT + vorschlag_id + FROM + testtool.tbl_vorschlag + JOIN + fragen USING (frage_id) + ) + + SELECT + 1 + FROM + testtool.tbl_frage_sprache + JOIN + fragen USING (frage_id) + WHERE + SUBSTRING(text, \'MathML\') IS NOT NULL + + UNION + + SELECT + 1 + FROM + testtool.tbl_vorschlag_sprache + JOIN + vorschlaege USING (vorschlag_id) + WHERE + SUBSTRING(text, \'MathML\') IS NOT NULL + '; + + if($result = $this->db_query($qry)) + { + return ($this->db_num_rows($result) > 0); + } + } + else + { + $this->errormsg = 'Eine numerische gebiet_id muss übergeben werden.'; + return false; + } + } +} +?> diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index f73517090..2265c838b 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -3449,6 +3449,18 @@ if(!$result = @$db->db_query("SELECT 1 FROM fue.tbl_projekttyp LIMIT 1")) echo '
fue.tbl_projekttyp hinzugefuegt.'; } +// Add column offset to testtool.tbl_gebiet +if(!$result = @$db->db_query("SELECT offsetpunkte FROM testtool.tbl_gebiet LIMIT 1")) +{ + $qry = "ALTER TABLE testtool.tbl_gebiet ADD COLUMN offsetpunkte smallint"; + + if(!$db->db_query($qry)) + echo 'testtool.tbl_gebiet: '.$db->db_last_error().'
'; + else + echo '
testtool.tbl_gebiet: Spalte offsetpunkte hinzugefuegt'; +} + + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -3689,7 +3701,7 @@ $tabellen=array( "testtool.tbl_ablauf_vorgaben" => array("ablauf_vorgaben_id","studiengang_kz","sprache","sprachwahl","content_id","insertamum","insertvon","updateamum", "updatevon"), "testtool.tbl_antwort" => array("antwort_id","pruefling_id","vorschlag_id"), "testtool.tbl_frage" => array("frage_id","kategorie_kurzbz","gebiet_id","level","nummer","demo","insertamum","insertvon","updateamum","updatevon","aktiv"), - "testtool.tbl_gebiet" => array("gebiet_id","kurzbz","bezeichnung","beschreibung","zeit","multipleresponse","kategorien","maxfragen","zufallfrage","zufallvorschlag","levelgleichverteilung","maxpunkte","insertamum", "insertvon", "updateamum", "updatevon", "level_start","level_sprung_auf","level_sprung_ab","antwortenprozeile","bezeichnung_mehrsprachig"), + "testtool.tbl_gebiet" => array("gebiet_id","kurzbz","bezeichnung","beschreibung","zeit","multipleresponse","kategorien","maxfragen","zufallfrage","zufallvorschlag","levelgleichverteilung","maxpunkte","insertamum", "insertvon", "updateamum", "updatevon", "level_start","level_sprung_auf","level_sprung_ab","antwortenprozeile","bezeichnung_mehrsprachig", "offsetpunkte"), "testtool.tbl_kategorie" => array("kategorie_kurzbz","gebiet_id"), "testtool.tbl_kriterien" => array("gebiet_id","kategorie_kurzbz","punkte","typ"), "testtool.tbl_pruefling" => array("pruefling_id","prestudent_id","studiengang_kz","idnachweis","registriert","semester"), diff --git a/vilesci/stammdaten/auswertung_fhtw.php b/vilesci/stammdaten/auswertung_fhtw.php index 051b8f6d9..a18446f8b 100644 --- a/vilesci/stammdaten/auswertung_fhtw.php +++ b/vilesci/stammdaten/auswertung_fhtw.php @@ -1035,7 +1035,7 @@ function getMailEmpfaenger($studiengang_kz, $studienplan_id = null, $orgform_kur return false; } -$ergebnis = ''; +$ergebnis = array(); $gebiet = array(); $kategorie = array(); $erg_kat = array(); @@ -1222,6 +1222,7 @@ if (isset($_REQUEST['reihungstest'])) tbl_studiengang.bezeichnung AS stg_bez, tbl_studienplan.orgform_kurzbz, tbl_gebiet.maxpunkte, + tbl_gebiet.offsetpunkte, tbl_prestudentstatus.ausbildungssemester, tbl_ablauf.gewicht, tbl_ort.planbezeichnung AS raum, @@ -1313,6 +1314,7 @@ if (isset($_REQUEST['reihungstest'])) AND studiensemester_kurzbz = rt.studiensemester_kurzbz ORDER BY registriert DESC LIMIT 1 ) + ORDER BY registriert DESC LIMIT 1 ) AND testtool.tbl_frage.gebiet_id = tbl_gebiet.gebiet_id ) @@ -1404,7 +1406,7 @@ if (isset($_REQUEST['reihungstest'])) $query .= " ORDER BY nachname, vorname, person_id - ";//var_dump($query); + ";/*print_r($query);*/ if (!($result = $db->db_query($query))) { die($db->db_last_error()); @@ -1448,7 +1450,7 @@ if (isset($_REQUEST['reihungstest'])) $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->name = $row->gebiet; $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->punkte = (($row->punkte >= $row->maxpunkte) ? $row->maxpunkte : $row->punkte); - if ($row->punkte == 0 && $row->punkte != '') + /*if ($row->punkte == 0 && $row->punkte != '') { $prozent = '0'; } @@ -1459,7 +1461,7 @@ if (isset($_REQUEST['reihungstest'])) else { $prozent = ($row->punkte / $row->maxpunkte) * 100; - } + }*/ if ($row->punkte >= $row->maxpunkte) { @@ -1470,9 +1472,24 @@ if (isset($_REQUEST['reihungstest'])) $punkte = $row->punkte; } - $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->prozent = $prozent; + $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->prozent = null; $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->punkte = $punkte; + // Punkte berechnen + if (isset($punkte)) + { + if ($row->punkte >= $row->maxpunkte) + $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->prozent = 100; + else + { + //offset zur Vermeidung negativer Prozentzahlen + $punkte_positiv = $punkte + $row->offsetpunkte; + $maxpunkte_positiv = $row->maxpunkte + $row->offsetpunkte; + //Formel: Summe(Punkte/Max Punkte * Gewicht) + $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->prozent = $maxpunkte_positiv > 0 ? $punkte_positiv / $maxpunkte_positiv * $row->gewicht * 100 : null; + } + } + // Bei Auswertungen ohne rt_id kann es vorkommen, dass Datensätze Doppelt sind // Bei der Summe darf ein Gebiet jedenfalls nur einmal summiert werden @@ -1480,14 +1497,14 @@ if (isset($_REQUEST['reihungstest'])) { $gebiete_arr[$row->prestudent_id][] = $row->gebiet_id; - // Gesamtpunkte mit Physik + // Gesamtpunkte if (isset($ergebnis[$row->prestudent_id]->gesamt)) { - $ergebnis[$row->prestudent_id]->gesamt += $prozent * $row->gewicht; + $ergebnis[$row->prestudent_id]->gesamt += $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->prozent; } else { - $ergebnis[$row->prestudent_id]->gesamt = $prozent * $row->gewicht; + $ergebnis[$row->prestudent_id]->gesamt = $ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id]->prozent; } if (isset($ergebnis[$row->prestudent_id]->gesamtpunkte)) @@ -1499,8 +1516,20 @@ if (isset($_REQUEST['reihungstest'])) $ergebnis[$row->prestudent_id]->gesamtpunkte = $punkte; } + if (isset($row->punkte)) + { + if (isset($ergebnis[$row->prestudent_id]->gesamtgewicht)) + { + $ergebnis[$row->prestudent_id]->gesamtgewicht += $row->gewicht; + } + else + { + $ergebnis[$row->prestudent_id]->gesamtgewicht = $row->gewicht; + } + } + // Gesamtpunkte ohne Physik - if ($row->gebiet_id != 10) +/* if ($row->gebiet_id != 10) { if (isset($ergebnis[$row->prestudent_id]->gesamt_ohne_physik)) { @@ -1519,10 +1548,17 @@ if (isset($_REQUEST['reihungstest'])) { $ergebnis[$row->prestudent_id]->gesamtpunkte_ohne_physik = $punkte; } - } + }*/ } } + foreach ($ergebnis as $prestudentid => $erg) + { + //Berechnen Gesamtpunkte nach Formel: Summe(Punkte/Max Punkte * Gewicht)/Summe(Gewichte) * 100 + if (isset($erg->gesamtgewicht) && $erg->gesamtgewicht > 0) + $erg->gesamt /= $erg->gesamtgewicht; + } + $ergb = $ergebnis; } @@ -1567,7 +1603,7 @@ if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'xls') // Eigener TItel bei Bachelor-Studiengängen if (isset($studiengangObj) && $studiengangObj->typ == 'b') { - $worksheet =& $workbook->addWorksheet("Auswertung MIT Physik " . ($titel_studiengang ? $stg_arr[$_REQUEST['studiengang']] : '') . ($titel_semester ? ' ' . $semester . '.Semester' : '')); + $worksheet =& $workbook->addWorksheet("Auswertung " . ($titel_studiengang ? $stg_arr[$_REQUEST['studiengang']] : '') . ($titel_semester ? ' ' . $semester . '.Semester' : '')); } else { @@ -1756,7 +1792,7 @@ if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'xls') } // Worksheet ohne Physik nur für Bachelor-Studiengänge - if (isset($studiengangObj) && $studiengangObj->typ == 'b') + /*if (isset($studiengangObj) && $studiengangObj->typ == 'b') { $worksheetOhnePhsyik =& $workbook->addWorksheet("Auswertung OHNE Physik " . ($titel_studiengang ? $stg_arr[$_REQUEST['studiengang']] : '') . ($titel_semester ? ' ' . $semester . '.Semester' : '')); $worksheetOhnePhsyik->setInputEncoding('utf-8'); @@ -1912,7 +1948,7 @@ if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'xls') { $worksheetOhnePhsyik->setColumn($i, $i, $breite); } - } + }*/ if (isset($erg_kat) && count($erg_kat) > 0) { @@ -2263,7 +2299,7 @@ else } else { - $("#row_"+prestudent_id).find("td.punkte, td.col_gesamtpunkte_ohne_physik").each (function() + $("#row_"+prestudent_id).find("td.punkte, td.col_gesamtpunkte").each (function() { $(this).html(""); }); @@ -2434,7 +2470,7 @@ else function checkAllWithResult() { // Schleife ueber die einzelnen Elemente - $(".col_gesamtpunkte_ohne_physik").each(function() + $(".col_gesamtpunkte").each(function() { if ($(this).text().trim() !== "") { @@ -2469,20 +2505,10 @@ else { $("input.prestudentCheckbox:checked").each(function() { - if ($("#uebertragenOptionPhysik:checked").length === 1) - { - prestudentPunkteArr.push({ - prestudent_id: $(this).attr("name"), - ergebnis: $(this).parents("tr").find(".erg_gesamt_mit_physik").text() - }); - } - else - { - prestudentPunkteArr.push({ - prestudent_id: $(this).attr("name"), - ergebnis: $(this).parents("tr").find(".erg_gesamt_ohne_physik").text() - }); - } + prestudentPunkteArr.push({ + prestudent_id: $(this).attr("name"), + ergebnis: $(this).parents("tr").find(".erg_gesamt").text() + }); }); $(".loaderIcon").show(); @@ -2814,9 +2840,6 @@ else echo '