, */ /** * Datenverbund Services * Anbindung für Datenverbund des Bundesrechenzetrums zur * Abfrage und Vergabe von Matrikelnummern */ require_once(dirname(__FILE__).'/basis_db.class.php'); class dvb { const DVB_URL_WEBSERVICE_OAUTH = 'https://stubei-q.portal.at/dvb/oauth/token'; const DVB_URL_WEBSERVICE_SVNR = 'https://stubei-q.portal.at/rws/0.1/simpleStudentBySozialVersicherungsnummer.xml'; const DVB_URL_WEBSERVICE_ERSATZKZ = 'https://stubei-q.portal.at/rws/0.1/simpleStudentByErsatzKennzeichen.xml'; const DVB_URL_WEBSERVICE_RESERVIERUNG = 'https://stubei-q.portal.at/dvb/matrikelnummern/1.0/reservierung.xml'; const DVB_URL_WEBSERVICE_MELDUNG = 'https://stubei-q.portal.at/dvb/matrikelnummern/1.0/meldung.xml'; public $authentication; private $username; private $password; private $debug; public $debug_output = ''; /** * Constructor * @param string $username Username fuer OAuth2 Login. * @param string $password Passwort fuer OAuth2 Login. * @param bool $debug Enables/Disables Debugging. */ public function __construct($username, $password, $debug = false) { $this->username = $username; $this->password = $password; $this->debug = $debug; } /** * Performs a OAuth2 Authentication and returns the OAuth Bearer Token * @return boolean true wenn erfolgreich, false im Fehlerfall */ public function authenticate() { $this->debug('Request new OAuth Token'); $curl = curl_init(); $url = self::DVB_URL_WEBSERVICE_OAUTH; $url .= '?grant_type=client_credentials'; curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $headers = array( 'Accept: application/json', 'Content-Type: application/x-www-form-urlencoded', 'Authorization: Basic '.base64_encode($this->username.":".$this->password), 'User-Agent: FHComplete', 'Connection: Keep-Alive', 'Expect:', 'Content-Length: 0' ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $this->debug('Sending Request to '.$url); $json_response = curl_exec($curl); $curl_info = curl_getinfo($curl); curl_close($curl); $this->debug('Response: '.$curl_info['http_code']); if ($curl_info['http_code'] == '200') { /* Example Response: { "access_token": "d9c60404-1530-4b05-bb8e-0a0b0f321726", "token_type": "bearer", "expires_in": 41087, "scope": "read write ROLE_bildungseinrichtung ROLE_bildungseinrichtung_A" } */ $this->authentication = json_decode($json_response); // Calculate Expire Date $ttl = new DateTime(); $ttl->add(new DateInterval('PT'.$this->authentication->expires_in.'S')); $this->authentication->DateTimeExpires = $ttl; $this->debug('Access_token:'.$this->authentication->access_token); $this->debug('Scope:'.$this->authentication->scope); return true; } else { $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$json_response; return false; } } /** * Checks if the Token is Expired * @return boolean true if expired, false if valid. */ private function tokenIsExpired() { if (!isset($this->authentication)) return true; $dtnow = new DateTime(); if ($this->authentication->DateTimeExpires < $dtnow) { return true; } else return false; } /** * Get Matrikelnummer by Social Security Number * @param string $svnr Social Security Number. * @return Matrikelnummer or false on error. */ public function getMatrikelnrBySVNR($svnr) { if ($this->tokenIsExpired()) { $this->authenticate(); } $this->debug('getMatirkelnrBySVNR'); $curl = curl_init(); $url = self::DVB_URL_WEBSERVICE_SVNR; $url .= '?sozialVersicherungsNummer='.curl_escape($curl, $svnr); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $headers = array( 'Accept: application/json', 'Authorization: Bearer '.$this->authentication->access_token, 'User-Agent: FHComplete', 'Connection: Keep-Alive', 'Expect:', 'Content-Length: 0' ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $this->debug('Sending Request to '.$url); $response = curl_exec($curl); $curl_info = curl_getinfo($curl); curl_close($curl); $this->debug('Response '.$curl_info['http_code']); if ($curl_info['http_code'] == '200') { /* Example Response: 12345678 Max Mustermann M 1999-02-19 A */ $dom = new DOMDocument(); $dom->loadXML($response); $namespace = 'http://www.brz.gv.at/datenverbund-unis'; $domnodes_matrikelnummer = $dom->getElementsByTagNameNS($namespace, 'matrikelNummer'); foreach ($domnodes_matrikelnummer as $row) { // Found return $row->textContent; } $this->errormsg = ''; return false; } else { $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; return false; } } /** * Get Matrikelnummer by Ersatzkennzeichen * @param string $ersatzkennzeichen Ersatzkennzeichen to search for. * @return Matrikelnummer or false */ public function getMatrikelnrByErsatzkennzeichen($ersatzkennzeichen) { if ($this->tokenIsExpired()) { $this->authenticate(); } $this->debug('getMatrikelnrByErsatzkennzeichen'); $curl = curl_init(); $url = self::DVB_URL_WEBSERVICE_ERSATZKZ; $url .= '?ersatzKennzeichen='.curl_escape($curl, $ersatzkennzeichen); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $headers = array( 'Accept: application/json', 'Authorization: Bearer '.$this->authentication->access_token, 'User-Agent: FHComplete', 'Connection: Keep-Alive', 'Expect:', 'Content-Length: 0' ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $this->debug('Sending Request to '.$url); $xml_response = curl_exec($curl); $curl_info = curl_getinfo($curl); curl_close($curl); $this->debug('Response: '.$curl_info['http_code']); if ($curl_info['http_code'] == '200') { /* Example Response Success A 12345678 2017S ABCD201093 Bc. Max Mustermann W 1993-06-26 TCH A 1030 Wien Obere Bahngasse 20/12 A 1030 Wien Obere Bahngasse 20/12 12345678 Max Mustermann W 1993-06-26 TCH */ /* 200 - No Entry found */ /* 401 Error Code Token Expired { "error": "invalid_token", "error_description": "Access token expired: 64a58ef3-1a70-46e9-b44f-35cc5051ae8e" } */ /* 400 Bad Request 318e1bc5-279d-43c4-af47-5e6df2ff5279 ZD00001 Z Der Server konnte die Anfrage nicht vearbeiten. Required String parameter 'ersatzKennzeichen' is not present */ $dom = new DOMDocument(); $dom->loadXML($xml_response); $namespace = 'http://www.brz.gv.at/datenverbund-unis'; $domnodes_matrikelnummer = $dom->getElementsByTagNameNS($namespace, 'matrikelNummer'); foreach ($domnodes_matrikelnummer as $row) { // Found return $row->textContent; } } else { $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$xml_response; return false; } } /** * List of already Reserved Matrikelnummern * @param string $bildungseinrichtung Shortname of Institution. * @param string $studienjahr Year of Reservation. * @return array with reserved Matrikelnr. or false on failure. */ public function getReservations($bildungseinrichtung, $studienjahr) { $this->debug('getReservations'); $uuid = $this->getUUID(); if ($this->tokenIsExpired()) { $this->authenticate(); } $curl = curl_init(); $url = self::DVB_URL_WEBSERVICE_RESERVIERUNG; $url .= '?uuid='.curl_escape($curl, $uuid); $url .= '&be='.curl_escape($curl, $bildungseinrichtung); $url .= '&sj='.curl_escape($curl, $studienjahr); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $headers = array( 'Accept: application/xml', 'Authorization: Bearer '.$this->authentication->access_token, 'User-Agent: FHComplete', 'Connection: Keep-Alive', 'Expect:', 'Content-Length: 0' ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $this->debug('Request URL:'.$url); $response = curl_exec($curl); $curl_info = curl_getinfo($curl); curl_close($curl); $this->debug('Response: '.$curl_info['http_code']); /* 200 ok 793d44fa-5646-42b1-b0cb-f2f121b2f14f 12345678 23456789 */ if ($curl_info['http_code'] == '200') { $dom = new DOMDocument(); $dom->loadXML($response); $domnodes_matrikelnummer = $dom->getElementsByTagName('matrikelnummer'); $reservations = array(); foreach ($domnodes_matrikelnummer as $row) { $reservations[] = $row->textContent; } return $reservations; } else { $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; return false; } } /** * Request a new Matrikelnummer * @param string $bildungseinrichtung Shortname of Institution. * @param string $studienjahr Year of issuing. * @param int $anzahl Number of Requested Numbers. * @return array list of matrikelnr or false on failure. */ public function getKontingent($bildungseinrichtung, $studienjahr, $anzahl = 1) { $this->debug('getKontingent'); $uuid = $this->getUUID(); if ($this->tokenIsExpired()) { $this->authenticate(); } $data = ' '.$uuid.' '.$anzahl.' '.$bildungseinrichtung.' '.$studienjahr.' '; $curl = curl_init(); $url = self::DVB_URL_WEBSERVICE_RESERVIERUNG; curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); $headers = array( 'Accept: application/xml', 'Content-Type: application/xml', 'Authorization: Bearer '.$this->authentication->access_token, 'User-Agent: FHComplete', 'Connection: Keep-Alive', 'Expect:' ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $this->debug('Request URL:'.$url); $this->debug('Request Data:'.$data); $response = curl_exec($curl); $curl_info = curl_getinfo($curl); curl_close($curl); $this->debug('Response: '.$curl_info['http_code']); if ($curl_info['http_code'] == '200') { $dom = new DOMDocument(); $dom->loadXML($response); $domnodes_matrikelnummer = $dom->getElementsByTagName('matrikelnummer'); $kontingent = array(); foreach ($domnodes_matrikelnummer as $row) { $kontingent[] = $row->textContent; } return $kontingent; } else { $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; return false; } } /** * Meldet die Vergabe der Matrikelnummer * @param string $bildungseinrichtung Kennzeichen der Bildungseinrichtung. * @param object $person Objekt mit den Personendaten. * @return booelan true wenn erfolgreich */ public function setMatrikelnummer($bildungseinrichtung, $person) { $this->debug('setMatrikelnummer'); $uuid = $this->getUUID(); if ($this->tokenIsExpired()) { $this->authenticate(); } $data = ' '.$uuid.' '.$bildungseinrichtung.' '.$person->geburtsdatum.' '.$person->geschlecht.' '.$person->matrikelnummer.''; if (isset($person->matura) && $person->matura != '') $data .= ''.$person->matura.''; else $data .= '00000000'; $data .= ''.$person->nachname.''; if (isset($person->plz) && $person->plz != '') $data .= ''.$person->plz.''; $data .= ''.$person->staat.''; if (isset($person->svnr) && $person->svnr != '') $data .= ''.$person->svnr.''; $data .= ''.$person->vorname.''; if (isset($person->writeonerror) && $person->writeonerror === true) $data .= 'J'; $data .= ' '; $curl = curl_init(); $url = self::DVB_URL_WEBSERVICE_MELDUNG; curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); $headers = array( 'Accept: application/xml', 'Content-Type: application/xml', 'Authorization: Bearer '.$this->authentication->access_token, 'User-Agent: FHComplete', 'Connection: Keep-Alive', 'Expect:' ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $this->debug('Request URL:'.$url); $this->debug('Request Data:'.$data); $response = curl_exec($curl); $curl_info = curl_getinfo($curl); curl_close($curl); $this->debug('Response: '.$curl_info['http_code']); $this->debug('Response: '.print_r($response, true)); /* 200 Fehlermeldung b76e84a9-c0bd-494c-97cb-c4ab9cd452c5 ZD01471 90 UNI-Kennzeichen UNI-Kennzeichen fehlt oder ungültig (FHTEST) BRZ FHTEST AG21333 65 Datum allg.Univ.reife kein gültiges Datum oder Format Korrektur Datum allg. Univ.reife oder 000000 angeben, falls nicht anwendbar leer ZD10073 90 Matrikelnummer aus ungültigem Kontingent Korrektur der Matrikelnummer 12345678 */ /* 200 ok 8b239582-6bc5-4193-ac79-2dcf9ec96439 */ if ($curl_info['http_code'] == '200') { $dom = new DOMDocument(); $dom->loadXML($response); $domnodes_fehlerliste = $dom->getElementsByTagName('fehlerliste'); $fehleranzahl = $domnodes_fehlerliste[0]->getAttribute('fehleranzahl'); if ($fehleranzahl === '0') { // Keine Fehler -> Meldung erfolgreich return true; } else { $this->errormsg = 'Es gab '.$fehleranzahl.' Fehler:'; $domnodes_fehler = $dom->getElementsByTagName('fehler'); foreach ($domnodes_fehler as $row) { $datenfeld = $row->getElementsByTagName('datenfeld'); $fehlertext = $row->getElementsByTagName('fehlertext'); $this->errormsg .= ' Datenfeld:'.$datenfeld[0]->textContent; $this->errormsg .= ' Fehlertext:'.$fehlertext[0]->textContent; } return false; } } else { $this->errormsg = 'Request Failed with HTTP Code:'.$curl_info['http_code'].' and Response:'.$response; return false; } } /** * Generiert eine eindeutige UUID * @return uuid */ private function getUUID() { $data = openssl_random_pseudo_bytes(16); $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100 $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10 return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } /** * Erstellt eine Debug Message * @param string $msg Message to log. * @return void */ private function debug($msg) { if ($this->debug) $this->debug_output .= "\n
".date('Y-m-d H:i:s').': '.htmlentities($msg); } }