From 13d05e6b486f3b377854328eddc17a1b3ecc64e0 Mon Sep 17 00:00:00 2001 From: Werner Masik Date: Mon, 20 Jan 2014 09:04:29 +0000 Subject: [PATCH] Studienplatz Serverside API update --- include/appdaten.class.php | 113 +++++++++-- include/benutzer.class.php | 26 +++ include/studienplatz.class.php | 34 +++- system/UnitTests/AppdatenTest.php | 183 ++++++++++++++++++ system/UnitTests/StudienplatzTest.php | 108 +++++++++++ .../studienplatzverwaltungAPITest.php | 158 +++++++++++++++ system/checksystem.php | 6 +- 7 files changed, 604 insertions(+), 24 deletions(-) create mode 100644 system/UnitTests/AppdatenTest.php create mode 100644 system/UnitTests/StudienplatzTest.php create mode 100644 system/UnitTests/addons/studienplatzverwaltung/studienplatzverwaltungAPITest.php diff --git a/include/appdaten.class.php b/include/appdaten.class.php index 35ba1a484..fc5d910f4 100644 --- a/include/appdaten.class.php +++ b/include/appdaten.class.php @@ -21,6 +21,7 @@ * * * Authors: Martin Tatzber */ require_once(dirname(__FILE__).'/basis_db.class.php'); @@ -62,10 +63,12 @@ class appdaten extends basis_db return $this->$name; } + + /** * Laden von Appdaten * @param appdaten_id ID des Datensatzes, der geladen werden soll - * @return true wenn ok, false im Fehlerfall + * @return boolean true wenn ok, false im Fehlerfall */ public function load($appdaten_id) { @@ -81,18 +84,7 @@ class appdaten extends basis_db { if($row = $this->db_fetch_object()) { - $this->appdaten_id=$row->appdaten_id; - $this->uid=$row->uid; - $this->app=$row->app; - $this->appversion=$row->appversion; - $this->version=$row->version; - $this->bezeichnung=$row->bezeichnung; - $this->daten=$row->daten; - $this->freigabe=$this->db_parse_bool($row->freigabe); - $this->insertamum=$row->insertamum; - $this->insertvon=$row->insertvon; - $this->updatenamum=$row->updateamum; - $this->updatevon=$row->updatenvon; + $this->mapRow($this, $row); } } else @@ -104,6 +96,57 @@ class appdaten extends basis_db return true; } + /** + * Laden aller Appdaten sortiert nach Bezeichnung und version + * @param string app name + * @return array mit appdaten + */ + public function getAllByApp($app) + { + $result = array(); + $qry = "SELECT * FROM system.tbl_appdaten ". + "WHERE app=".$this->db_add_param($app, FHC_STRING, false).' '. + "ORDER BY bezeichnung,version"; + + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + $appData = new appdaten(); + $this->mapRow($appData, $row); + $result[] = $appData; + } + } + else + { + $this->errormsg = 'Datensatz konnte nicht geladen werden'; + return false; + } + + return $result; + + } + + /** + * Helper + * @param type $target + * @param type $row + */ + private function mapRow($target,$row) { + $target->appdaten_id=$row->appdaten_id; + $target->uid=$row->uid; + $target->app=$row->app; + $target->appversion=$row->appversion; + $target->version=$row->version; + $target->bezeichnung=$row->bezeichnung; + $target->daten=$row->daten; + $target->freigabe=$this->db_parse_bool($row->freigabe); + $target->insertamum=$row->insertamum; + $target->insertvon=$row->insertvon; + $target->updatenamum=$row->updateamum; + $target->updatevon=$row->updatevon; + } + /** * Prueft die Variablen auf Gueltigkeit * @return true wenn ok, false im Fehlerfall @@ -111,11 +154,12 @@ class appdaten extends basis_db protected function validate() { //Zahlenfelder pruefen + /* version wird beim speichern automatisch gesetzt if(!is_numeric($this->version) && $this->version!=='') { $this->errormsg='version enthaelt ungueltige Zeichen'; return false; - } + }*/ //Gesamtlaenge pruefen if(mb_strlen($this->uid)>32) @@ -152,18 +196,53 @@ class appdaten extends basis_db /** * Speichert den aktuellen Datensatz in die Datenbank + * @param neueVersion boolean default false; wenn gesetzt, dann + * wird Versionsnummer auf aktuelles Maximum+1 gesetzt. (für 'Save As' + * Funktion bzw. zum Anlegen komplett neuer Daten) * @return true wenn ok, false im Fehlerfall */ - public function save() + public function save($neueVersion=false) { //Variablen pruefen if(!$this->validate()) return false; - if($this->new) + if($this->new || $neueVersion) { + + $this->db_query('BEGIN'); + + if ($neueVersion) { + // höchste Versionsnummer holen + $qry = "SELECT max(version) as version ". + "FROM system.tbl_appdaten ". + "WHERE app=".$this->db_add_param($this->app, FHC_STRING, false). + "AND bezeichnung=".$this->db_add_param($this->bezeichnung, FHC_STRING, false); + + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + if ($row->version != null || !is_numeric($this->version)) + { + $this->version = $row->version + 1; + } + else + { + $this->version = 1; + } + } + else + { + $this->db_query('ROLLBACK'); + $this->errormsg = "Fehler beim Auslesen der Version"; + return false; + } + } + } + //Neuen Datensatz einfuegen - $qry='BEGIN;INSERT INTO system.tbl_appdaten (uid, app, appversion, version, + $qry='INSERT INTO system.tbl_appdaten (uid, app, appversion, version, bezeichnung, daten, freigabe, insertamum, insertvon) VALUES ('. $this->db_add_param($this->uid).', '. $this->db_add_param($this->app).', '. diff --git a/include/benutzer.class.php b/include/benutzer.class.php index ba808da7c..59b3e08c1 100644 --- a/include/benutzer.class.php +++ b/include/benutzer.class.php @@ -200,6 +200,32 @@ class benutzer extends person } } + + /** + * Löscht den Benutzer mit der übergebenen uid. Da beim Speichern auch + * eine Person angelegt wird, muss eventuell auch diese gelöscht werden. + * Das kann durch Aufruf der geerbten Methode {@link person::delete()} + * erledigt werden. Damit die Klasse Abwärtskombatibel bleibt, wurde die + * Methode delete() absichtlich nicht überschrieben. + * @param $uid + */ + public function deleteBenutzer($uid) + { + $qry = "DELETE from public.tbl_benutzer where uid = ".$this->db_add_param($uid).";"; + + if($this->db_query($qry)) + { + return true; + } + else + { + $this->errormsg = "Es ist ein Fehler beim Löschen des Benutzers aufgetreten"; + return false; + } + } + + + /** * Prueft ob die UID bereits existiert * @param uid diff --git a/include/studienplatz.class.php b/include/studienplatz.class.php index 066a7b812..d4c9fc92a 100644 --- a/include/studienplatz.class.php +++ b/include/studienplatz.class.php @@ -28,7 +28,7 @@ require_once(dirname(__FILE__).'/basis_db.class.php'); class studienplatz extends basis_db { /** @var $new boolean */ - private $new; + private $new = true; /** @var DB-Result */ private $result; /** @var object */ @@ -50,9 +50,9 @@ class studienplatz extends basis_db /** @var integer */ private $npz; /** @var timestamp */ - private $updateamum; + private $updateamum; /** @var string */ - private $studienplatz_id; + private $updatevon; /** @var timestamp */ private $insertamum; /** @var string */ @@ -70,6 +70,29 @@ class studienplatz extends basis_db $this->load($studienplatz_id); } + public function __set($name,$value) + { + switch ($name) + { + case 'gpz': + case 'npz': + case 'ausbildungssemester': + case 'studienplatz_id': + if (!is_numeric($value)) + throw new Exception("Attribute $name must be numeric!"); + $this->$name=$value; + break; + default: + $this->$name=$value; + } + } + + public function __get($name) + { + return $this->$name; + } + + /** * Laedt einzelnen Studienplatz der ID $studienplatz_id * @param integer $studienplatz_id ID des zu ladenden Studienplatzes @@ -218,11 +241,10 @@ class studienplatz extends basis_db if($this->new) { //Neuen Datensatz einfuegen - $qry='BEGIN;INSERT INTO lehre.tbl_studienplatz (studienplatz_id, '. + $qry='BEGIN;INSERT INTO lehre.tbl_studienplatz ('. 'studiengang_kz, orgform_kurzbz, studiensemester_kurzbz, '. 'ausbildungssemester, gpz, npz, insertamum, insertvon, '. - 'updateamum, updatevon) VALUES('. - $this->db_add_param($this->studienplatz_id, FHC_INTEGER).', '. + 'updateamum, updatevon) VALUES('. $this->db_add_param($this->studiengang_kz, FHC_INTEGER).', '. $this->db_add_param($this->orgform_kurzbz).', '. $this->db_add_param($this->studiensemester_kurzbz).', '. diff --git a/system/UnitTests/AppdatenTest.php b/system/UnitTests/AppdatenTest.php new file mode 100644 index 000000000..30848cc12 --- /dev/null +++ b/system/UnitTests/AppdatenTest.php @@ -0,0 +1,183 @@ + + * + */ +require_once('../../config/system.config.inc.php'); +require_once('../../include/appdaten.class.php'); +require_once('../../include/benutzer.class.php'); + +class AppdatenTest extends PHPUnit_Framework_TestCase +{ + protected $benutzer; + protected $uid = 'unittest'; + + public function setUp() + { + $this->benutzer = new benutzer(); + $this->benutzer->new = true; + $this->benutzer->uid = $this->uid; + $this->benutzer->alias = 'Unit Test Benutzer'; + $this->benutzer->aktiv = true; + $this->benutzer->nachname = 'Unit'; + $this->benutzer->geschlecht = 'm'; + $result = $this->benutzer->save(); + if (!$result) { + echo 'Fehler: '.$this->benutzer->errormsg; + } + $this->assertTrue($result); + } + + public function tearDown() + { + if ($this->benutzer) { + // Benutzer löschen + $this->assertTrue( + $this->benutzer->deleteBenutzer($this->uid)); + // Person löschen + $this->assertTrue( + $this->benutzer->delete($this->benutzer->person_id)); + // benutzer hat On Delete Cascade zu den appdaten!!! + } + } + + public function testCRUD() + { + + $app = 'TestApp'; + $bezeichnung = 'TestDaten'; + $daten = 'Hello World'; + $version = '2'; + $appversion = '1.0'; + $insertvon = 'unittest'; + + // Create + $appdaten = new appdaten(); + $appdaten->uid = $this->benutzer->uid; + $appdaten->app = $app; + $appdaten->appversion = $appversion; // string + $appdaten->version = $version; // integer + $appdaten->bezeichnung = $bezeichnung; + $appdaten->daten = $daten; + $appdaten->freigabe = false; + $appdaten->insertvon = $insertvon; + $appdaten_id = $appdaten->save(); + $this->assertNotEquals($appdaten_id, false); + + // load + $this->assertTrue($appdaten->load($appdaten_id)); + $this->assertEquals($this->benutzer->uid,$appdaten->uid); + $this->assertEquals($appversion,$appdaten->appversion); + $this->assertEquals($version,$appdaten->version); + $this->assertEquals($app,$appdaten->app); + $this->assertEquals($bezeichnung,$appdaten->bezeichnung); + $this->assertEquals($daten,$appdaten->daten); + $this->assertEquals($insertvon,$appdaten->insertvon); + // test delete + cleanup test data + $this->assertNotEquals($appdaten->delete($appdaten_id), false); + + } + + public function testSaveNeueVersion() + { + $app = 'TestApp'; + $bezeichnung = 'TestDaten'; + $daten = 'Hello World'; + $appversion = '1.0'; + $insertvon = 'unittest'; + + // neuen Datensatz anlegen und Version automatisch setzen + $appdaten = new appdaten(); + $appdaten->uid = $this->benutzer->uid; + $appdaten->app = $app; + $appdaten->appversion = $appversion; // string + //$appdaten->version = $version; // integer + $appdaten->bezeichnung = $bezeichnung; + $appdaten->daten = $daten; + $appdaten->freigabe = false; + $appdaten->insertvon = $insertvon; + $appdaten_id1 = $appdaten->save(true); + $this->assertNotEquals($appdaten_id1, false, 'Speichern der Appdaten fehlgeschlagen: '.$appdaten->errormsg); + $this->assertEquals($appdaten->version, 1, 'Version des ersten Datensatzes ist ungleich 1'); + // noch ein Datensatz + $appdaten = new appdaten(); + $appdaten->uid = $this->benutzer->uid; + $appdaten->app = $app; + $appdaten->appversion = $appversion; // string + $appdaten->bezeichnung = $bezeichnung; + $appdaten->daten = $daten; + $appdaten->freigabe = false; + $appdaten->insertvon = $insertvon; + $appdaten_id2 = $appdaten->save(true); + $this->assertNotEquals($appdaten_id2, false); + $this->assertEquals($appdaten->version,2, 'Version des ersten Datensatzes ist ungleich 2'); + // selben Datensatz in neue Version kopieren + $appdaten_id3 = $appdaten->save(true); + $this->assertNotEquals($appdaten_id3, false); + $this->assertEquals($appdaten->version,3, 'Version des kopierten Datensatzes ist ungleich 3'); + // cleanup siehe teardown + + } + + public function testGetGetAllByApp() { + $this->assertNotEquals($this->createAppdaten('2013/14'), false); + $this->assertNotEquals($this->createAppdaten('2013/14'), false); + $this->assertNotEquals($this->createAppdaten('2013/14'), false); + + $this->assertNotEquals($this->createAppdaten('2014/15'), false); + $this->assertNotEquals($this->createAppdaten('2014/15'), false); + + $appdaten = new appdaten(); + $apps = $appdaten->getAllByApp('TestApp1'); + $this->assertTrue(is_array($apps)); + $this->assertEquals(count($apps), 5); + $this->assertEquals($apps[2]->version, 3); + $this->assertEquals($apps[4]->bezeichnung, '2014/15'); + $this->assertEquals($apps[4]->version, 2); + + } + + + + private function createAppdaten($bezeichnung) { + $app = 'TestApp1'; + $daten = 'Hello World'; + $appversion = '1.0'; + $insertvon = 'unittest'; + + // neuen Datensatz anlegen + $appdaten = new appdaten(); + $appdaten->uid = $this->benutzer->uid; + $appdaten->app = $app; + $appdaten->appversion = $appversion; + $appdaten->bezeichnung = $bezeichnung; + $appdaten->daten = $daten; + $appdaten->freigabe = false; + $appdaten->insertvon = $insertvon; + $appdaten->save(true); + return $appdaten; + } + + +} +?> + diff --git a/system/UnitTests/StudienplatzTest.php b/system/UnitTests/StudienplatzTest.php new file mode 100644 index 000000000..d179c541c --- /dev/null +++ b/system/UnitTests/StudienplatzTest.php @@ -0,0 +1,108 @@ + + * + */ +require_once('../../config/system.config.inc.php'); +require_once('../../include/studienplatz.class.php'); +require_once('../../include/benutzer.class.php'); + + +class StudienplatzTest extends PHPUnit_Framework_TestCase +{ + protected $benutzer; + protected $uid = 'unittest'; + + public function setUp() + { + $this->benutzer = new benutzer(); + $this->benutzer->new = true; + $this->benutzer->uid = $this->uid; + $this->benutzer->alias = 'Unit Test Benutzer'; + $this->benutzer->aktiv = true; + $this->benutzer->nachname = 'Unit'; + $this->benutzer->geschlecht = 'm'; + $result = $this->benutzer->save(); + if (!$result) { + echo 'Fehler: '.$this->benutzer->errormsg; + } + $this->assertTrue($result); + + + } + + public function tearDown() + { + if ($this->benutzer) { + // Benutzer löschen + $this->assertTrue( + $this->benutzer->deleteBenutzer($this->uid)); + // Person löschen + $this->assertTrue( + $this->benutzer->delete($this->benutzer->person_id)); + // benutzer hat On Delete Restrict zu den appdaten!!! + } + } + + public function testCRUD() + { + + + $studiengang_kz = '120'; // 120 = dummy + $studiensemester_kurzbz = 'WS2014'; + $orgform_kurzbz = 'BB'; + $ausbildungssemester = 2; + $npz = 123; + $gpz = 234; + $insertvon = 'unittest'; + + // Create + $studienplatz = new studienplatz(); + $studienplatz->studiengang_kz = $studiengang_kz; + $studienplatz->studiensemester_kurzbz = $studiensemester_kurzbz; + $studienplatz->orgform_kurzbz = $orgform_kurzbz; + $studienplatz->ausbildungssemester = $ausbildungssemester; + $studienplatz->npz = $npz; + $studienplatz->gpz = $gpz; + $studienplatz->insertvon = $insertvon; + $studienplatz_id = $studienplatz->save(); + $this->assertNotEquals($studienplatz_id, false); + + // load + $this->assertTrue($studienplatz->loadStudienplatz($studienplatz_id)); + $this->assertEquals($studiensemester_kurzbz,$studienplatz->studiensemester_kurzbz); + $this->assertEquals($orgform_kurzbz,$studienplatz->orgform_kurzbz); + $this->assertEquals($studiengang_kz,$studienplatz->studiengang_kz); + $this->assertEquals($ausbildungssemester,$studienplatz->ausbildungssemester); + $this->assertEquals($npz,$studienplatz->npz); + $this->assertEquals($gpz,$studienplatz->gpz); + + // test delete + cleanup test data + $this->assertNotEquals($studienplatz->delete($studienplatz_id), false); + + } + + + +} +?> + diff --git a/system/UnitTests/addons/studienplatzverwaltung/studienplatzverwaltungAPITest.php b/system/UnitTests/addons/studienplatzverwaltung/studienplatzverwaltungAPITest.php new file mode 100644 index 000000000..9d5ff750e --- /dev/null +++ b/system/UnitTests/addons/studienplatzverwaltung/studienplatzverwaltungAPITest.php @@ -0,0 +1,158 @@ + + * + */ +require_once('../../../../config/system.config.inc.php'); +require_once('../../../../include/appdaten.class.php'); +require_once('../../../../include/benutzer.class.php'); +require_once('../../../../addons/studienplatzverwaltung/vilesci/StudienplatzverwaltungAPI.class.php'); + +class StudienplatzverwaltungAPITest extends PHPUnit_Framework_TestCase +{ + protected $benutzer; + protected $uid = 'unittest'; + + public function setUp() + { + $this->benutzer = new benutzer(); + $this->benutzer->new = true; + $this->benutzer->uid = $this->uid; + $this->benutzer->alias = 'Unit Test Benutzer'; + $this->benutzer->aktiv = true; + $this->benutzer->nachname = 'Unit'; + $this->benutzer->geschlecht = 'm'; + $result = $this->benutzer->save(); + if (!$result) { + echo 'Fehler: '.$this->benutzer->errormsg; + } + $this->assertTrue($result); + } + + public function tearDown() + { + if ($this->benutzer) { + // Benutzer löschen + $this->assertTrue( + $this->benutzer->deleteBenutzer($this->uid)); + // Person löschen + $this->assertTrue( + $this->benutzer->delete($this->benutzer->person_id)); + // benutzer hat On Delete Cascade zu den appdaten!!! + } + } + + public function testGetMetadata() { + $sj = '2013/14'; + $this->assertNotEquals($this->createAppdaten($sj, $this->createDaten($sj)), false); + $this->assertNotEquals($this->createAppdaten($sj, $this->createDaten($sj)), false); + $this->assertNotEquals($this->createAppdaten($sj, $this->createDaten($sj)), false); + $sj = '2014/15'; + $this->assertNotEquals($this->createAppdaten($sj, $this->createDaten($sj)), false); + $this->assertNotEquals($this->createAppdaten($sj, $this->createDaten($sj)), false); + $api = StudienplatzverwaltungAPI::init(); + $metadataJSON = $api->getMetadata(); + $this->assertNotEquals($metadataJSON, false); + $metadata = json_decode($metadataJSON, false); + $this->assertTrue(is_array($metadata)); + $this->assertEquals($metadata[0]->studienjahr,'2013/14'); + $this->assertEquals($metadata[1]->studienjahr,'2014/15'); + } + + private function createDaten($studienjahr) { + $daten = + array( + 'studienjahr' => $studienjahr, + 'zeitraum' => 2, + 'status' => 'Entwurf', + 'notizen' => '', + 'gesamtDaten' => array( + array( + 'stgKz' => '0227', + 'stgArt' => 'Ba', + 'orgForm' => 'VZ', + 'studiengangDaten' => $this->createStgDaten(164, 168, $studienjahr) + ), + array( + 'stgKz' => '0228', + 'stgArt' => 'Ba', + 'orgForm' => 'BB', + 'studiengangDaten' => $this->createStgDaten(60, 65, $studienjahr) + ) + ) + ); + + + return json_encode($daten); + } + + private function createStgDaten($gpzBd, $gpzUv, $sj) { + $jahr = substr($sj,0,4) + 0; + return array( + array('studiensemester' => 'WS'.$jahr++, + 'gpzBd' => $gpzBd, + 'gpzUV' => $gpzUv, + 'npzBd' => $gpzBd, + 'npzUv' => $gpzUv, + 'aufnahme' => true), + array('studiensemester' => 'SS'.$jahr, + 'gpzBd' => $gpzBd, + 'gpzUV' => $gpzUv, + 'npzBd' => $gpzBd, + 'npzUv' => $gpzUv, + 'aufnahme' => true), + array('studiensemester' => 'WS'.$jahr++, + 'gpzBd' => $gpzBd, + 'gpzUV' => $gpzUv, + 'npzBd' => $gpzBd, + 'npzUv' => $gpzUv, + 'aufnahme' => true), + array('studiensemester' => 'SS'.$jahr, + 'gpzBd' => $gpzBd, + 'gpzUV' => $gpzUv, + 'npzBd' => $gpzBd, + 'npzUv' => $gpzUv, + 'aufnahme' => true), + ); + } + + private function createAppdaten($bezeichnung, $gesamtdaten) { + $app = 'Studienplatzverwaltung'; + $appversion = '1.0'; + $insertvon = 'unittest'; + + // neuen Datensatz anlegen + $appdaten = new appdaten(); + $appdaten->uid = $this->benutzer->uid; + $appdaten->app = $app; + $appdaten->appversion = $appversion; + $appdaten->bezeichnung = $bezeichnung; + $appdaten->daten = $gesamtdaten; + $appdaten->freigabe = false; + $appdaten->insertvon = $insertvon; + $appdaten->save(true); + return $appdaten; + } + +} + +?> diff --git a/system/checksystem.php b/system/checksystem.php index a49773f6a..a6cab644e 100644 --- a/system/checksystem.php +++ b/system/checksystem.php @@ -427,7 +427,11 @@ if(!$result = @$db->db_query("SELECT 1 FROM lehre.tbl_studienplatz LIMIT 1;")) orgform_kurzbz varchar(3), ausbildungssemester smallint, gpz integer, - npz integer + npz integer, + insertamum timestamp, + insertvon varchar(32), + updateamum timestamp, + updatevon varchar(32) ); CREATE SEQUENCE lehre.seq_studienplatz_studienplatz_id