diff --git a/application/controllers/Documents.php b/application/controllers/Documents.php
new file mode 100644
index 000000000..47aae7ed1
--- /dev/null
+++ b/application/controllers/Documents.php
@@ -0,0 +1,294 @@
+.
+ */
+
+if (! defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+ * This controller handles output and access to documents.
+ * It creates a XML file, transforms it with the XSL-FO Vorlage from the
+ * database and generates a PDF file with unoconv or docsbox.
+ * This file is then outputted as download.
+ *
+ * It is the CodeIgniter version of content/pdfExport.php when not using the
+ * get paremeters: "archivdokument" and "archive".
+ * Use exportSigned() instead of providing the "sign" get parameter and
+ * export() otherwise.
+ */
+class Documents extends Auth_Controller
+{
+ public function __construct()
+ {
+ parent::__construct([
+ 'export' => self::PERM_LOGGED,
+ 'exportSigned' => self::PERM_LOGGED
+ ]);
+
+ // Load Phrases
+ $this->loadPhrases([
+ 'stv'
+ ]);
+ }
+
+ /**
+ * Download a not signed document.
+ *
+ * @param string $xml
+ * @param string $xsl
+ *
+ * @return void
+ */
+ public function export($xml, $xsl)
+ {
+ return $this->_export($xml, $xsl);
+ }
+
+ /**
+ * Download a signed document.
+ *
+ * @param string $xml
+ * @param string $xsl
+ *
+ * @return void
+ */
+ public function exportSigned($xml, $xsl)
+ {
+ return $this->_export($xml, $xsl, getAuthUID());
+ }
+
+ /**
+ * Helper function for export() and exportSigned()
+ *
+ * @param string $xml
+ * @param string $xsl
+ * @param string $sign_user (optional)
+ *
+ * @return void
+ */
+ protected function _export($xml, $xsl, $sign_user = null)
+ {
+ $xsl_oe_kurzbz = null;
+ $version = $this->input->post_get('version') ?: null;
+
+ // Get the OE or STG of the document
+ $xsl_oe_kurzbz = $this->input->post_get('xsl_oe_kurzbz')
+ ?: $this->input->post_get('xsl_stg_kz')
+ ?: $this->input->post_get('stg_kz');
+ if (is_null($xsl_oe_kurzbz)) {
+ $uid = $this->input->post_get('uid');
+ if ($uid) {
+ $uid = current(explode(';', $uid));
+ $this->load->model('crm/Student_model', 'StudentModel');
+ $result = $this->StudentModel->load([$uid]);
+ if (!isError($result) && hasData($result))
+ $xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
+ }
+ }
+ if (is_null($xsl_oe_kurzbz)) {
+ $prestudent_id = $this->input->post_get('prestudent_id');
+ if ($prestudent_id) {
+ $prestudent_id = current(explode(';', $prestudent_id));
+ $this->load->model('crm/Prestudent_model', 'PrestudentModel');
+ $result = $this->PrestudentModel->load($prestudent_id);
+ if (!isError($result) && hasData($result))
+ $xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
+ }
+ }
+ if (is_null($xsl_oe_kurzbz))
+ $xsl_oe_kurzbz = 0;
+
+ // Access rights
+ if ($xsl == 'AccountInfo') {
+ $this->load->model('resource/Mitarbeiter_model', 'MitarbeiterModel');
+ $this->load->model('crm/Student_model', 'StudentModel');
+ $uids = $this->input->post_get('uid');
+ if ($uids) {
+ $uids = explode(';', $uids);
+ foreach ($uids as $uid) {
+ $result = $this->MitarbeiterModel->load($uid);
+ if (!isError($result) && hasData($result)) {
+ if (!$this->permissionlib->isBerechtigt('admin', 'suid', 0)
+ && !$this->permissionlib->isBerechtigt('mitarbeiter', 'suid', 0))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'mitarbeiter:rw']]);
+ } else {
+ $result = $this->StudentModel->load([$uid]);
+ if (!isError($result) && hasData($result)) {
+ $student = current(getData($result));
+ if (!$this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz)
+ && !$this->permissionlib->isBerechtigt('admin', 'suid', 0)
+ && !$this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz)
+ && !$this->permissionlib->isBerechtigt('assistenz', 'suid', 0)
+ && !$this->permissionlib->isBerechtigt('support', 'suid', 0))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw', 'support:rw']]);
+ }
+ }
+ }
+ }
+ } else {
+ $this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
+
+ $result = $this->VorlagestudiengangModel->getCurrent($xsl, $xsl_oe_kurzbz, $version);
+ if (isError($result))
+ return show_error(getError($result));
+ if (!hasData($result))
+ return show_404();
+
+ $access_rights = current(getData($result))->berechtigung;
+ if (!$access_rights)
+ return show_404();
+ $allowed = false;
+ foreach ($access_rights as $access_right) {
+ if ($this->permissionlib->isBerechtigt($access_right)) {
+ $allowed = true;
+ break;
+ }
+ }
+ if (!$allowed)
+ return $this->_outputAuthError([$this->router->method => $access_rights]);
+ }
+
+ // Output format
+ $outputformat = $this->input->post_get('output') ?: 'pdf';
+ if ($outputformat != 'pdf'
+ // An der FHTW darf das Studienblatt und das Prüfungsprotokoll auch in anderen Formaten exportiert werden
+ && !(CAMPUS_NAME == 'FH Technikum Wien'
+ && ($xsl == 'Studienblatt'
+ || $xsl == 'StudienblattEng'
+ || $xsl == 'PrProtBA'
+ || $xsl == 'PrProtBAEng'
+ || $xsl == 'PrProtMA'
+ || $xsl == 'PrProtMAEng'
+ )
+ )
+ && !$this->permissionlib->isBerechtigt('system/change_outputformat', null, $xsl_oe_kurzbz)
+ ) {
+ $outputformat = 'pdf';
+ }
+
+ // XML Params
+ $params = 'xmlformat=xml';
+ foreach ([
+ 'uid',
+ 'stg_kz',
+ 'person_id',
+ 'id',
+ 'prestudent_id',
+ 'buchungsnummern',
+ 'ss',
+ 'abschlusspruefung_id',
+ 'typ',
+ 'all',
+ 'preoutgoing_id',
+ 'lvid',
+ 'projekt_kurzbz',
+ 'von',
+ 'bis',
+ 'stundevon',
+ 'stundebis',
+ 'sem',
+ 'lehreinheit',
+ 'mitarbeiter_uid',
+ 'studienordnung_id',
+ 'fixangestellt',
+ 'standort',
+ 'abrechnungsmonat',
+ 'form',
+ 'projektarbeit_id',
+ 'betreuerart_kurzbz',
+ 'studiensemester_kurzbz'
+ ] as $key) {
+ $value = $this->input->post_get($key);
+ if ($value !== null)
+ $params .= '&' . $key . '=' . urlencode($value);
+ }
+ $value = $this->input->post_get('vertrag_id');
+ if ($value !== null) {
+ foreach ($value as $id)
+ $params .= '&vertrag_id[]=' . urlencode($id);
+ }
+
+ $this->load->library('DocumentExportLib');
+ $this->load->model('system/Vorlage_model', 'VorlageModel');
+
+ $result = $this->VorlageModel->load($xsl);
+ if (isError($result))
+ return show_error(getError($result));
+ if (!hasData($result))
+ show_404();
+
+ $vorlage = current(getData($result));
+ if ($sign_user && !$vorlage->signierbar)
+ return show_error($this->p->t("stv", "grades_error_sign"));
+
+
+ // Filename
+ $filename = ($vorlage->bezeichnung ?: $vorlage->vorlage_kurzbz);
+ switch ($xsl) {
+ case 'LV_Informationen':
+ $this->load->model('organisation/Studiengang_model', 'StudiengangModel');
+ $result = $this->StudiengangModel->load($this->input->post_get('stg_kz'));
+ if (!isError($result) && hasData($result))
+ $filename .= '_' . sanitizeProblemChars(current(getData($result))->kurzbzlang);
+
+ $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
+ $result = $this->StudiensemesterModel->load($this->input->post_get('ss'));
+ if (!isError($result) && hasData($result))
+ $filename .= '_' . sanitizeProblemChars(current(getData($result))->studiensemester_kurzbz);
+ break;
+ case 'Honorarvertrag':
+ $uid = str_replace(';', '', $this->input->post_get('uid') ?: '');
+ $this->load->model('person/Benutzer_model', 'BenutzerModel');
+ $this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT');
+ $result = $this->BenutzerModel->load([$uid]);
+ if (!isError($result) && hasData($result)) {
+ $user = current(getData($result));
+ $filename .= '_' . sanitizeProblemChars($user->nachname) . '_' . sanitizeProblemChars($user->vorname);
+ }
+ break;
+ case 'Studienordnung':
+ $filename = 'Studienordnung-Studienplan-';
+
+ $this->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
+ $result = $this->StudienordnungModel->load($this->input->post_get('studienordnung_id'));
+ if (!isError($result) && hasData($result)) {
+ $so = current(getData($result));
+ $filename .= sprintf("%'.04d", $so->studiengang_kz) . '-' . $so->studiengangkurzbzlang;
+ }
+ break;
+ default:
+ $uid = str_replace(';', '', $this->input->post_get('uid') ?: '');
+ $this->load->model('person/Benutzer_model', 'BenutzerModel');
+ $this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT');
+ $result = $this->BenutzerModel->load([$uid]);
+ if (!isError($result) && hasData($result)) {
+ $user = current(getData($result));
+ $filename .= '_' . sanitizeProblemChars($user->nachname);
+ }
+ break;
+ }
+
+ // XML Data
+ $result = $this->documentexportlib->getDataURL($xml, $params);
+ if (isError($result))
+ return show_error(getError($result));
+
+ $data = getData($result);
+
+ // Output
+ $this->documentexportlib->showContent($filename, $vorlage, $data, $xsl_oe_kurzbz, $version, $outputformat, $sign_user);
+ }
+}
diff --git a/application/controllers/api/frontend/v1/Documents.php b/application/controllers/api/frontend/v1/Documents.php
new file mode 100644
index 000000000..60010e14d
--- /dev/null
+++ b/application/controllers/api/frontend/v1/Documents.php
@@ -0,0 +1,422 @@
+.
+ */
+
+if (! defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+ * This controller operates between (interface) the JS (GUI) and the back-end
+ * Provides data to the ajax get calls about documents
+ * Listens to ajax post calls to change the documents data
+ * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
+ *
+ * This controller handles output and access to documents.
+ * It checks permissions to render documents in an alternative format
+ * or it creates a XML file, transforms it with the XSL-FO Vorlage from the
+ * database and generates a PDF file with unoconv or docsbox.
+ * This file is then archivated in the database.
+ *
+ * The last part is the CodeIgniter version of content/pdfExport.php when not
+ * using the get paremeter: "archivdokument" but using the get parameter:
+ * "archive".
+ * Use archiveSigned() instead of providing the "sign" get parameter and
+ * archive() otherwise.
+ */
+class Documents extends FHCAPI_Controller
+{
+ public function __construct()
+ {
+ parent::__construct([
+ 'permissionAlternativeFormat' => self::PERM_LOGGED,
+ 'archive' => ['admin:rw', 'assistenz:rw'],
+ 'archiveSigned' => ['admin:rw', 'assistenz:rw']
+ ]);
+
+ // Load Phrases
+ $this->loadPhrases([
+ 'stv'
+ ]);
+ }
+
+ /**
+ * Checks if the current user has permission to render documents in an
+ * alternative format.
+ *
+ * @param string $oe_kurzbz Or studiengang_kz
+ *
+ * @return void
+ */
+ public function permissionAlternativeFormat($oe_kurzbz)
+ {
+ $this->terminateWithSuccess($this->permissionlib->isBerechtigt('system/change_outputformat', null, $oe_kurzbz));
+ }
+
+ /**
+ * Download a not signed document.
+ *
+ * @param string $xml (optional)
+ * @param string $xsl (optional)
+ *
+ * @return void
+ */
+ public function archive($xml = null, $xsl = null)
+ {
+ return $this->_archive($xml, $xsl);
+ }
+
+ /**
+ * Download a signed document.
+ *
+ * @param string $xml (optional)
+ * @param string $xsl (optional)
+ *
+ * @return void
+ */
+ public function archiveSigned($xml = null, $xsl = null)
+ {
+ return $this->_archive($xml, $xsl, getAuthUID());
+ }
+
+ /**
+ * Helper function for archive() and archiveSigned()
+ *
+ * @param string $xml
+ * @param string $xsl
+ * @param string $sign_user (optional)
+ *
+ * @return void
+ */
+ public function _archive($xml, $xsl, $sign_user = null)
+ {
+ if (!$xml || !$xsl) {
+ $this->load->library('form_validation');
+ if (!$xml) {
+ $xml = $this->input->post_get('xml');
+ $this->form_validation->set_rules('xml', 'xml', 'required');
+ }
+ if (!$xsl) {
+ $xsl = $this->input->post_get('xsl');
+ $this->form_validation->set_rules('xsl', 'xsl', 'required');
+ }
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+ }
+
+ $xsl_oe_kurzbz = null;
+ $version = $this->input->post_get('version') ?: null;
+
+ // Get the OE or STG of the document
+ $xsl_oe_kurzbz = $this->input->post_get('xsl_oe_kurzbz')
+ ?: $this->input->post_get('xsl_stg_kz')
+ ?: $this->input->post_get('stg_kz');
+ if (is_null($xsl_oe_kurzbz)) {
+ $uid = $this->input->post_get('uid');
+ if ($uid) {
+ $uid = current(explode(';', $uid));
+ $this->load->model('crm/Student_model', 'StudentModel');
+ $result = $this->StudentModel->load([$uid]);
+ if (!isError($result) && hasData($result))
+ $xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
+ }
+ }
+ if (is_null($xsl_oe_kurzbz)) {
+ $prestudent_id = $this->input->post_get('prestudent_id');
+ if ($prestudent_id) {
+ $prestudent_id = current(explode(';', $prestudent_id));
+ $this->load->model('crm/Prestudent_model', 'PrestudentModel');
+ $result = $this->PrestudentModel->load($prestudent_id);
+ if (!isError($result) && hasData($result))
+ $xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
+ }
+ }
+ if (is_null($xsl_oe_kurzbz))
+ $xsl_oe_kurzbz = 0;
+
+ // Vorlage
+ $this->load->model('system/Vorlage_model', 'VorlageModel');
+
+ $result = $this->VorlageModel->load($xsl);
+ $vorlage = current($this->getDataOrTerminateWithError($result));
+ if (!$vorlage)
+ show_404();
+
+ // Akte Data
+ $akteData = [
+ 'dokument_kurzbz' => $vorlage->dokument_kurzbz ?: 'Zeugnis',
+ 'mimetype' => 'application/pdf',
+ 'erstelltam' => date('Y-m-d'),
+ 'gedruckt' => true,
+ 'insertamum' => date('c'),
+ 'insertvon' => getAuthUID(),
+ 'uid' => $this->input->post_get('uid') ?: '',
+ 'archiv' => true,
+ 'signiert' => !!$sign_user,
+ 'stud_selfservice' => $vorlage->stud_selfservice
+ ];
+ $studiengang_kz = null;
+ if ($akteData['uid']) {
+ $this->load->model('crm/Student_model', 'StudentModel');
+ $this->StudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
+ $result = $this->StudentModel->load([$akteData['uid']]);
+ $student = current($this->getDataOrTerminateWithError($result));
+
+ $ss = $this->input->post_get('ss');
+
+ if ($ss !== null) {
+ $this->load->model('crm/prestudentstatus_model', 'PrestudentstatusModel');
+ $result = $this->PrestudentstatusModel->getLastStatus($student->prestudent_id, $ss);
+ $status = current($this->getDataOrTerminateWithError($result));
+ if (!$status)
+ $this->terminateWithError($this->p->t("stv", "grades_error_prestudentstatus"));
+ $semester = $status->ausbildungssemester;
+
+ $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
+ $this->StudentlehrverbandModel->addJoin('public.tbl_benutzer', 'uid = student_uid');
+ $this->StudentlehrverbandModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
+ $result = $this->StudentlehrverbandModel->load([
+ 'studiensemester_kurzbz' => $ss,
+ 'student_uid' => $akteData['uid']
+ ]);
+ $res = current($this->getDataOrTerminateWithError($result));
+
+ $studiengang_kz = $res->studiengang_kz;
+ $akteData['person_id'] = $res->person_id;
+ switch ($xsl) {
+ case 'Ausbildungsver':
+ case 'AusbVerEng':
+ $akteData['titel'] = mb_substr($xsl .
+ "_" .
+ strtoupper($res->typ) .
+ strtoupper($res->kurzbz) .
+ "_" .
+ $semester .
+ "_" .
+ $ss, 0, 64);
+ $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
+ break;
+ case 'LVZeugnisEng':
+ case 'LVZeugnis':
+ case 'Zertifikat':
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+ $result = $this->LehrveranstaltungModel->load($this->input->post_get('lvid'));
+ $lv = current($this->getDataOrTerminateWithError($result));
+ $akteData['dokument_kurzbz'] = $xsl;
+ $akteData['titel'] = mb_substr($xsl .
+ "_" .
+ strtoupper($res->typ) .
+ strtoupper($res->kurzbz) .
+ "_" .
+ $semester .
+ '_' .
+ $ss .
+ '_' .
+ str_replace(' ', '_', $lv->bezeichnung), 0, 60);
+ $akteData['bezeichnung'] = mb_substr($xsl .
+ " " .
+ strtoupper($res->typ) .
+ strtoupper($res->kurzbz) .
+ " " .
+ $semester .
+ ". Semester" .
+ ' ' .
+ $ss .
+ ' ' .
+ $lv->bezeichnung, 0, 64);
+ break;
+ case 'SZeugnis':
+ $akteData['titel'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
+ $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
+ break;
+ default:
+ $akteData['titel'] = mb_substr($xsl .
+ "_" .
+ strtoupper($res->typ) .
+ strtoupper($res->kurzbz) .
+ "_" .
+ $semester .
+ "_" .
+ $ss, 0, 64);
+ $akteData['bezeichnung'] = mb_substr($xsl .
+ " " .
+ strtoupper($res->typ) .
+ strtoupper($res->kurzbz) .
+ " " .
+ $semester .
+ ". Semester" .
+ ' ' .
+ $ss, 0, 64);
+ break;
+ }
+ } else {
+ $studiengang_kz = $student->studiengang_kz;
+ $akteData['person_id'] = $student->person_id;
+ $akteData['titel'] = $vorlage->bezeichnung . '_' . $student->kuerzel;
+ $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
+ }
+ } else {
+ $prestudent_id = $this->input->post_get('prestudent_id');
+ if ($prestudent_id) {
+ $this->load->model('crm/prestudent_model', 'PrestudentModel');
+ $this->PrestudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
+ $result = $this->PrestudentModel->load($prestudent_id);
+ $prestudent = current($this->getDataOrTerminateWithError($result));
+
+ $studiengang_kz = $prestudent->studiengang_kz;
+ $akteData['person_id'] = $prestudent->person_id;
+ $akteData['titel'] = mb_substr($xsl . "_" . $prestudent->kuerzel, 0, 64);
+ $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $prestudent->kuerzel, 0, 64);
+ }
+ }
+
+ // Access rights
+ if (!$this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz)
+ && !$this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
+ if ($xsl == 'AccountInfo') {
+ $this->load->model('resource/Mitarbeiter_model', 'MitarbeiterModel');
+ $this->load->model('crm/Student_model', 'StudentModel');
+ $uids = $this->input->post_get('uid');
+ if ($uids) {
+ $uids = explode(';', $uids);
+ foreach ($uids as $uid) {
+ $result = $this->MitarbeiterModel->load($uid);
+ if (!isError($result) && hasData($result)) {
+ if (!$this->permissionlib->isBerechtigt('admin', 'suid', 0)
+ && !$this->permissionlib->isBerechtigt('mitarbeiter', 'suid', 0))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'mitarbeiter:rw']]);
+ } else {
+ $result = $this->StudentModel->load([$uid]);
+ if (!isError($result) && hasData($result)) {
+ $student = current(getData($result));
+ if (!$this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz)
+ && !$this->permissionlib->isBerechtigt('admin', 'suid', 0)
+ && !$this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz)
+ && !$this->permissionlib->isBerechtigt('assistenz', 'suid', 0)
+ && !$this->permissionlib->isBerechtigt('support', 'suid', 0))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw', 'support:rw']]);
+ }
+ }
+ }
+ }
+ } else {
+ $this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
+
+ $result = $this->VorlagestudiengangModel->getCurrent($xsl, $xsl_oe_kurzbz, $version);
+ $access_rights = current($this->getDataOrTerminateWithError($result));
+ if (!$access_rights || !$access_rights->berechtigung)
+ return show_404();
+
+ $allowed = false;
+ foreach ($access_rights->berechtigung as $access_right) {
+ if ($this->permissionlib->isBerechtigt($access_right)) {
+ $allowed = true;
+ break;
+ }
+ }
+ if (!$allowed)
+ return $this->_outputAuthError([$this->router->method => $access_rights]);
+ }
+
+ // Output format
+ $outputformat = $this->input->post_get('output') ?: 'pdf';
+ if ($outputformat != 'pdf'
+ // An der FHTW darf das Studienblatt und das Prüfungsprotokoll auch in anderen Formaten exportiert werden
+ && !(CAMPUS_NAME == 'FH Technikum Wien'
+ && ($xsl == 'Studienblatt'
+ || $xsl == 'StudienblattEng'
+ || $xsl == 'PrProtBA'
+ || $xsl == 'PrProtBAEng'
+ || $xsl == 'PrProtMA'
+ || $xsl == 'PrProtMAEng'
+ )
+ )
+ && !$this->permissionlib->isBerechtigt('system/change_outputformat', null, $xsl_oe_kurzbz)
+ ) {
+ $outputformat = 'pdf';
+ }
+
+ // XML Params
+ $params = 'xmlformat=xml';
+ foreach ([
+ 'uid',
+ 'stg_kz',
+ 'person_id',
+ 'id',
+ 'prestudent_id',
+ 'buchungsnummern',
+ 'ss',
+ 'abschlusspruefung_id',
+ 'typ',
+ 'all',
+ 'preoutgoing_id',
+ 'lvid',
+ 'projekt_kurzbz',
+ 'von',
+ 'bis',
+ 'stundevon',
+ 'stundebis',
+ 'sem',
+ 'lehreinheit',
+ 'mitarbeiter_uid',
+ 'studienordnung_id',
+ 'fixangestellt',
+ 'standort',
+ 'abrechnungsmonat',
+ 'form',
+ 'projektarbeit_id',
+ 'betreuerart_kurzbz',
+ 'studiensemester_kurzbz'
+ ] as $key) {
+ $value = $this->input->post_get($key);
+ if ($value !== null)
+ $params .= '&' . $key . '=' . urlencode($value);
+ }
+ $value = $this->input->post_get('vertrag_id');
+ if ($value !== null) {
+ foreach ($value as $id)
+ $params .= '&vertrag_id[]=' . urlencode($id);
+ }
+
+ if (!$vorlage->archivierbar)
+ $this->terminateWithError($this->p->t("stv", "grades_error_archive"));
+
+ if ($sign_user && !$vorlage->signierbar)
+ $this->terminateWithError($this->p->t("stv", "grades_error_sign"));
+
+
+ $this->load->library('DocumentExportLib');
+
+ // XML Data
+ $result = $this->documentexportlib->getDataURL($xml, $params);
+ $data = $this->getDataOrTerminateWithError($result);
+ $this->documentexportlib->addArchiveToData($data);
+
+ // Output
+ $result = $this->documentexportlib->getContent($vorlage, $data, $xsl_oe_kurzbz, $version, $outputformat, $sign_user);
+
+ $content = $this->getDataOrTerminateWithError($result);
+ $akteData['titel'] .= '.pdf';
+ $akteData['inhalt'] = base64_encode($content);
+
+ $this->load->model('crm/Akte_model', 'AkteModel');
+ $result = $this->AkteModel->insert($akteData);
+ $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess(true);
+ }
+}
diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php
index 9010bcc0b..c3aeda49d 100644
--- a/application/controllers/api/frontend/v1/stv/Config.php
+++ b/application/controllers/api/frontend/v1/stv/Config.php
@@ -99,12 +99,19 @@ class Config extends FHCAPI_Controller
'title' => $this->p->t('stv', 'tab_resources'),
'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js'
];
- /* TODO(chris): Ausgeblendet für Testing
$result['grades'] = [
'title' => $this->p->t('stv', 'tab_grades'),
- 'component' => './Stv/Studentenverwaltung/Details/Noten.js'
+ 'component' => './Stv/Studentenverwaltung/Details/Noten.js',
+ 'showOnlyWithUid' => true,
+ 'config' => [
+ 'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE,
+ 'edit' => 'both', // Possible values: both|header|inline
+ 'delete' => 'both', // Possible values: both|header|inline
+ 'documents' => 'both', // Possible values: both|header|inline
+ 'documentslist' => $this->gradesDocumentsList()
+ ]
];
- */
+
$result['exam'] = [
'title' => $this->p->t('stv', 'tab_exam'),
'component' => './Stv/Studentenverwaltung/Details/Pruefung.js'
@@ -254,4 +261,186 @@ class Config extends FHCAPI_Controller
]
] + $this->kontoColumns();
}
+
+ /**
+ * Helper function to generate the default documentslist config for the
+ * grades tab.
+ *
+ * The resulting array consists of elements which are associative arrays
+ * that can have the following entries:
+ * title (required) on the first level this can be HTML code.
+ * permissioncheck (optional) an URL to an FHCAPI endpoint which returns
+ * true or false.
+ * link (optional) an URL that will be called if "action" and
+ * "children" are not defined.
+ * action (optional) an associative array that describes an
+ * POST action that will be called if "children" is
+ * not defined.
+ * It can have the following entries:
+ * - url (required) an URL to an FHCAPI endpoint.
+ * - post (optional) an associative array with the POST data to
+ * be sent.
+ * - response (optional) a string that will be displayed on success.
+ * children (optional) an array of child elements
+ *
+ * All strings that start with { and end with } in the URLs and the
+ * actions post parameter will be replaced with the corresponding
+ * attribute of the current dataset (e.G: {uid} will be replaced with the
+ * uid of the current dataset)
+ *
+ * @return array
+ */
+ protected function gradesDocumentsList()
+ {
+ $permissioncheck = site_url("api/frontend/v1/documents/permissionAlternativeFormat/{studiengang_kz}");
+
+ $title_ger = $this->p->t("global", "deutsch");
+ $title_eng = $this->p->t("global", "englisch");
+ $title_ff = $this->p->t("stv", "document_certificate");
+ $title_lv = $this->p->t("stv", "document_coursecertificate");
+
+ $link_ff = "documents/export/" .
+ "zertifikat.rdf.php/" .
+ "Zertifikat" .
+ "?stg_kz={studiengang_kz_lv}" .
+ "&uid={uid}" .
+ "&ss={studiensemester_kurzbz}" .
+ "&lvid={lehrveranstaltung_id}";
+ $link_lv_ger = "documents/export/" .
+ "lehrveranstaltungszeugnis.rdf.php/" .
+ "LVZeugnis" .
+ "?stg_kz={studiengang_kz}" .
+ "&uid={uid}" .
+ "&ss={studiensemester_kurzbz}" .
+ "&lvid={lehrveranstaltung_id}";
+ $link_lv_eng = "documents/export/" .
+ "lehrveranstaltungszeugnis.rdf.php/" .
+ "LVZeugnisEng" .
+ "?stg_kz={studiengang_kz}" .
+ "&uid={uid}" .
+ "&ss={studiensemester_kurzbz}" .
+ "&lvid={lehrveranstaltung_id}";
+
+ $archive_url = "api/frontend/v1/documents/archiveSigned";
+ $archive_response = $this->p->t("stv", "document_signed_and_archived");
+ $archive_post_ff = [
+ "xml" => "zertifikat.rdf.php",
+ "xsl" => "Zertifikat",
+ "stg_kz" => "{studiengang_kz_lv}",
+ "uid" => "{uid}",
+ "ss" => "{studiensemester_kurzbz}",
+ "lvid" => "{lehrveranstaltung_id}"
+ ];
+ $archive_post_lv_ger = [
+ "xml" => "lehrveranstaltungszeugnis.rdf.php",
+ "xsl" => "LVZeugnis",
+ "stg_kz" => "{studiengang_kz}",
+ "uid" => "{uid}",
+ "ss" => "{studiensemester_kurzbz}",
+ "lvid" => "{lehrveranstaltung_id}"
+ ];
+ $archive_post_lv_eng = [
+ "xml" => "lehrveranstaltungszeugnis.rdf.php",
+ "xsl" => "LVZeugnisEng",
+ "stg_kz" => "{studiengang_kz}",
+ "uid" => "{uid}",
+ "ss" => "{studiensemester_kurzbz}",
+ "lvid" => "{lehrveranstaltung_id}"
+ ];
+
+ $list = [
+ [
+ 'title' => '',
+ 'children' => [
+ [
+ 'title' => $title_ff,
+ 'link' => site_url($link_ff)
+ ],
+ [
+ 'title' => $title_lv,
+ 'children' => [
+ [
+ 'title' => $title_ger,
+ 'link' => site_url($link_lv_ger),
+ 'children' => [
+ [
+ 'title' => 'PDF',
+ 'permissioncheck' => $permissioncheck,
+ 'link' => site_url($link_lv_ger)
+ ],
+ [
+ 'title' => 'DOC',
+ 'permissioncheck' => $permissioncheck,
+ 'link' => site_url($link_lv_ger . "&output=doc")
+ ],
+ [
+ 'title' => 'ODT',
+ 'permissioncheck' => $permissioncheck,
+ 'link' => site_url($link_lv_ger . "&output=odt")
+ ]
+ ]
+ ],
+ [
+ 'title' => $title_eng,
+ 'link' => site_url($link_lv_eng),
+ 'children' => [
+ [
+ 'title' => 'PDF',
+ 'permissioncheck' => $permissioncheck,
+ 'link' => site_url($link_lv_eng)
+ ],
+ [
+ 'title' => 'DOC',
+ 'permissioncheck' => $permissioncheck,
+ 'link' => site_url($link_lv_eng . "&output=doc")
+ ],
+ [
+ 'title' => 'ODT',
+ 'permissioncheck' => $permissioncheck,
+ 'link' => site_url($link_lv_eng . "&output=odt")
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ],
+ [
+ 'title' => '',
+ 'children' => [
+ [
+ 'title' => $title_ff,
+ 'action' => [
+ 'url' => site_url($archive_url),
+ 'post' => $archive_post_ff,
+ 'response' => $archive_response
+ ]
+ ],
+ [
+ 'title' => $title_lv,
+ 'children' => [
+ [
+ 'title' => $title_ger,
+ 'action' => [
+ 'url' => site_url($archive_url),
+ 'post' => $archive_post_lv_ger,
+ 'response' => $archive_response
+ ]
+ ],
+ [
+ 'title' => $title_eng,
+ 'action' => [
+ 'url' => site_url($archive_url),
+ 'post' => $archive_post_lv_eng,
+ 'response' => $archive_response
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ return $list;
+ }
}
diff --git a/application/controllers/api/frontend/v1/stv/Grades.php b/application/controllers/api/frontend/v1/stv/Grades.php
new file mode 100644
index 000000000..61d797495
--- /dev/null
+++ b/application/controllers/api/frontend/v1/stv/Grades.php
@@ -0,0 +1,685 @@
+.
+ */
+
+if (! defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+ * This controller operates between (interface) the JS (GUI) and the back-end
+ * Provides data to the ajax get calls about grades
+ * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
+ */
+class Grades extends FHCAPI_Controller
+{
+ public function __construct()
+ {
+ parent::__construct([
+ 'list' => 'student/noten:r',
+ 'getCertificate' => 'student/noten:r',
+ 'getTeacherProposal' => 'student/noten:r',
+ 'getRepeaterGrades' => 'student/noten:r',
+ 'updateCertificate' => ['admin:w', 'assistenz:w'],
+ 'deleteCertificate' => ['admin:w', 'assistenz:w'],
+ 'copyTeacherProposalToCertificate' => 'student/noten:w',
+ 'copyRepeaterGradeToCertificate' => 'student/noten:w',
+ 'getGradeFromPoints' => 'student/noten:r'
+ ]);
+
+ // Load Libraries
+ $this->load->library('VariableLib', ['uid' => getAuthUID()]);
+
+ // Load Phrases
+ $this->loadPhrases([
+ 'stv',
+ 'person',
+ 'lehre'
+ ]);
+ }
+
+ /**
+ * List all possible grades
+ * (Entries in lehre.tbl_note)
+ *
+ * @return void
+ */
+ public function list()
+ {
+ $this->load->model('codex/Note_model', 'NoteModel');
+
+ $this->NoteModel->addOrder('note');
+
+ $result = $this->NoteModel->load();
+
+ $grades = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($grades);
+ }
+
+ /**
+ * List grades for the certificate of a prestudent.
+ * (Entries in lehre.tbl_zeugnisnote)
+ *
+ * @param string $prestudent_id
+ * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded.
+ *
+ * @return void
+ */
+ public function getCertificate($prestudent_id, $all = null)
+ {
+ $this->load->model('crm/Student_model', 'StudentModel');
+ $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
+
+ $result = $this->StudentModel->loadWhere([
+ 'prestudent_id' => $prestudent_id
+ ]);
+
+ $student = $this->getDataOrTerminateWithError($result);
+ if (!$student)
+ $this->terminateWithSuccess([]);
+
+
+ $student_uid = current($student)->student_uid;
+
+ $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null;
+
+
+ $result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz);
+
+ $grades = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($grades);
+ }
+
+ /**
+ * List grades of a prestudent that teachers gave.
+ * (Entries in campus.tbl_lvgesamtnote)
+ *
+ * @param string $prestudent_id
+ * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded.
+ *
+ * @return void
+ */
+ public function getTeacherProposal($prestudent_id, $all = null)
+ {
+ $this->load->model('crm/Student_model', 'StudentModel');
+ $this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
+
+ $result = $this->StudentModel->loadWhere([
+ 'prestudent_id' => $prestudent_id
+ ]);
+
+ $student = $this->getDataOrTerminateWithError($result);
+ if (!$student)
+ $this->terminateWithSuccess([]);
+
+
+ $student_uid = current($student)->student_uid;
+
+ $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null;
+
+
+ $result = $this->LvgesamtnoteModel->getLvGesamtNoten(null, $student_uid, $studiensemester_kurzbz);
+
+ $grades = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($grades);
+ }
+
+ /**
+ * List grades of a prestudent that an assistant marked as already done
+ * or as not allowed because of the repeating of a semester.
+ *
+ * @param string $prestudent_id
+ * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded.
+ *
+ * @return void
+ */
+ public function getRepeaterGrades($prestudent_id, $all = null)
+ {
+ $this->load->library('AntragLib');
+
+ $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : false;
+
+
+ $result = $this->antraglib->getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz);
+
+ $grades = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($grades);
+ }
+
+ /**
+ * Update or Insert a grade for the certificate of a prestudent.
+ * (Entry in lehre.tbl_zeugnisnote)
+ *
+ * @return void
+ */
+ public function updateCertificate()
+ {
+ $this->load->library('form_validation');
+
+ $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
+ $this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required");
+ $this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required");
+ $this->form_validation->set_rules('note', $this->p->t('lehre', 'note'), 'required|numeric');
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+
+
+ $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
+ $student_uid = $this->input->post('student_uid');
+ $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
+ $note = $this->input->post('note');
+ $authUID = getAuthUID();
+ $now = date('c');
+
+ // NOTE(chris): Stg Permissions
+ if (!$this->hasPermissionUpdate($lehrveranstaltung_id, $student_uid))
+ return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]);
+
+ $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
+
+ $result = $this->ZeugnisnoteModel->load([
+ 'studiensemester_kurzbz' => $studiensemester_kurzbz,
+ 'student_uid' => $student_uid,
+ 'lehrveranstaltung_id' => $lehrveranstaltung_id
+ ]);
+ $current = $this->getDataOrTerminateWithError($result);
+
+ if ($current) {
+ $result = $this->ZeugnisnoteModel->update([
+ 'studiensemester_kurzbz' => $studiensemester_kurzbz,
+ 'student_uid' => $student_uid,
+ 'lehrveranstaltung_id' => $lehrveranstaltung_id
+ ], [
+ 'note' => $note,
+ 'benotungsdatum' => $now,
+ 'updateamum' => $now,
+ 'updatevon' => $authUID
+ ]);
+ } else {
+ $result = $this->ZeugnisnoteModel->insert([
+ 'studiensemester_kurzbz' => $studiensemester_kurzbz,
+ 'student_uid' => $student_uid,
+ 'lehrveranstaltung_id' => $lehrveranstaltung_id,
+ 'note' => $note,
+ 'benotungsdatum' => $now,
+ 'insertamum' => $now,
+ 'insertvon' => $authUID
+ ]);
+ }
+ $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess(true);
+ }
+
+ /**
+ * Delete a grade from the certificate of a prestudent.
+ * (Entry in lehre.tbl_zeugnisnote)
+ *
+ * @return void
+ */
+ public function deleteCertificate()
+ {
+ $this->load->library('form_validation');
+
+ $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
+ $this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required");
+ $this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required");
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+
+
+ $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
+ $student_uid = $this->input->post('student_uid');
+ $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
+
+ // NOTE(chris): Stg Permissions
+ if (!$this->hasPermissionDelete($lehrveranstaltung_id, $student_uid))
+ return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]);
+
+ $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
+
+ $result = $this->ZeugnisnoteModel->delete([
+ 'studiensemester_kurzbz' => $studiensemester_kurzbz,
+ 'student_uid' => $student_uid,
+ 'lehrveranstaltung_id' => $lehrveranstaltung_id
+ ]);
+ $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess(true);
+ }
+
+ /**
+ * Copy a grade that teachers gave to the certificate of a prestudent.
+ * (Entry in campus.tbl_lvgesamtnote to an entry in lehre.tbl_zeugnisnote)
+ *
+ * @return void
+ */
+ public function copyTeacherProposalToCertificate()
+ {
+ $this->load->library('form_validation');
+
+ $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
+ $this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required");
+ $this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required");
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+
+ $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
+ $student_uid = $this->input->post('student_uid');
+ $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
+ $authUID = getAuthUID();
+
+ // NOTE(chris): Stg Permissions
+ if (!$this->hasPermissionCopy($lehrveranstaltung_id, $student_uid))
+ return $this->_outputAuthError([$this->router->method => 'student/noten']);
+
+ $this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
+
+ $result = $this->LvgesamtnoteModel->load([
+ 'student_uid' => $student_uid,
+ 'studiensemester_kurzbz' => $studiensemester_kurzbz,
+ 'lehrveranstaltung_id' => $lehrveranstaltung_id
+ ]);
+ $teacherGrade = $this->getDataOrTerminateWithError($result);
+
+ if (!$teacherGrade)
+ show_404();
+
+ $teacherGrade = current($teacherGrade);
+
+ $data = [
+ 'note' => $teacherGrade->note,
+ 'punkte' => $teacherGrade->punkte,
+ 'uebernahmedatum' => date('c'),
+ 'benotungsdatum' => $teacherGrade->benotungsdatum,
+ 'bemerkung' => $teacherGrade->bemerkung
+ ];
+
+ $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
+
+ $this->ZeugnisnoteModel->addJoin('lehre.tbl_note n', 'note');
+ $result = $this->ZeugnisnoteModel->load([
+ 'studiensemester_kurzbz' => $studiensemester_kurzbz,
+ 'student_uid' => $student_uid,
+ 'lehrveranstaltung_id' => $lehrveranstaltung_id
+ ]);
+ $certificateGrade = $this->getDataOrTerminateWithError($result);
+
+ if ($certificateGrade) {
+ $certificateGrade = current($certificateGrade);
+
+ if (!$certificateGrade->lkt_ueberschreibbar)
+ $this->terminateWithError($this->p->t("stv", "grades_error_overwrite"));
+
+ // NOTE(chris): update
+ $data['updateamum'] = $data['uebernahmedatum'];
+ $data['updatevon'] = $authUID;
+
+ $this->ZeugnisnoteModel->update([
+ 'studiensemester_kurzbz' => $studiensemester_kurzbz,
+ 'student_uid' => $student_uid,
+ 'lehrveranstaltung_id' => $lehrveranstaltung_id
+ ], $data);
+ } else {
+ // NOTE(chris): insert
+ $data['insertamum'] = $data['uebernahmedatum'];
+ $data['insertvon'] = $authUID;
+ $data['lehrveranstaltung_id'] = $lehrveranstaltung_id;
+ $data['student_uid'] = $student_uid;
+ $data['studiensemester_kurzbz'] = $studiensemester_kurzbz;
+
+ $this->ZeugnisnoteModel->insert($data);
+
+ if (defined('FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN')
+ && FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN) {
+ $result = $this->addTestsForGrade(
+ $studiensemester_kurzbz,
+ $student_uid,
+ $lehrveranstaltung_id,
+ $teacherGrade->note,
+ $teacherGrade->punkte
+ );
+ $this->getDataOrTerminateWithError($result);
+ }
+ }
+
+
+ $this->terminateWithSuccess(true);
+ }
+
+ /**
+ * Copy a grade that was marked by an assistant as already done or not
+ * allowed because of the repeating of a semester to the certificate of a
+ * prestudent.
+ *
+ * @return void
+ */
+ public function copyRepeaterGradeToCertificate()
+ {
+ $this->load->library('form_validation');
+
+ $this->form_validation->set_rules("studierendenantrag_lehrveranstaltung_id", "studierendenantrag_lehrveranstaltung_id", "required|integer");
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+
+ $id = $this->input->post('studierendenantrag_lehrveranstaltung_id');
+ $authUID = getAuthUID();
+
+ $this->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel');
+
+ $this->StudierendenantraglehrveranstaltungModel->addSelect("tbl_studierendenantrag_lehrveranstaltung.*");
+ $this->StudierendenantraglehrveranstaltungModel->addSelect("student_uid");
+ $this->StudierendenantraglehrveranstaltungModel->addJoin("campus.tbl_studierendenantrag", "studierendenantrag_id");
+ $this->StudierendenantraglehrveranstaltungModel->addJoin("public.tbl_student", "prestudent_id", "LEFT");
+
+ $result = $this->StudierendenantraglehrveranstaltungModel->load($id);
+ $repeaterGrade = $this->getDataOrTerminateWithError($result);
+
+ if (!$repeaterGrade)
+ show_404();
+
+ $repeaterGrade = current($repeaterGrade);
+
+ // NOTE(chris): Stg Permissions
+ if (!$this->hasPermissionCopy($repeaterGrade->lehrveranstaltung_id, $repeaterGrade->student_uid))
+ return $this->_outputAuthError([$this->router->method => 'student/noten']);
+
+ $data = [
+ 'note' => $repeaterGrade->note,
+ 'uebernahmedatum' => date('c'),
+ 'benotungsdatum' => $repeaterGrade->insertamum,
+ 'bemerkung' => $repeaterGrade->anmerkung
+ ];
+
+ $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
+
+ $result = $this->ZeugnisnoteModel->load([
+ $repeaterGrade->studiensemester_kurzbz,
+ $repeaterGrade->student_uid,
+ $repeaterGrade->lehrveranstaltung_id
+ ]);
+ $certificateGrade = $this->getDataOrTerminateWithError($result);
+
+ if ($certificateGrade) {
+ // NOTE(chris): update
+ $data['updateamum'] = $data['uebernahmedatum'];
+ $data['updatevon'] = $authUID;
+
+ $this->ZeugnisnoteModel->update([
+ $repeaterGrade->studiensemester_kurzbz,
+ $repeaterGrade->student_uid,
+ $repeaterGrade->lehrveranstaltung_id
+ ], $data);
+ } else {
+ // NOTE(chris): insert
+ $data['insertamum'] = $data['uebernahmedatum'];
+ $data['insertvon'] = $authUID;
+ $data['lehrveranstaltung_id'] = $repeaterGrade->lehrveranstaltung_id;
+ $data['student_uid'] = $repeaterGrade->student_uid;
+ $data['studiensemester_kurzbz'] = $repeaterGrade->studiensemester_kurzbz;
+
+ $this->ZeugnisnoteModel->insert($data);
+ }
+
+
+ $this->terminateWithSuccess(true);
+ }
+
+ /**
+ * Loads the grade from the points using the gradingkey
+ *
+ * @return void
+ */
+ public function getGradeFromPoints()
+ {
+ $this->load->library('form_validation');
+
+ $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
+ $this->form_validation->set_rules("points", $this->p->t("stv", "grades_points"), "required|numeric");
+
+ if (!$this->form_validation->run())
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+
+ $this->load->model('education/Notenschluesselaufteilung_model', 'NotenschluesselaufteilungModel');
+
+ $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
+
+ $result = $this->NotenschluesselaufteilungModel->getNote(
+ $this->input->post('points'),
+ $this->input->post('lehrveranstaltung_id'),
+ $studiensemester_kurzbz
+ );
+
+ $note = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($note);
+ }
+
+ /**
+ * Helper function that adds tests for a student
+ * (Entries in lehre.tbl_pruefung)
+ *
+ * @param string $studiensemester_kurzbz
+ * @param string $student_uid
+ * @param integer $lehrveranstaltung_id
+ * @param integer $note
+ * @param numeric $punkte
+ *
+ * @return stdClass
+ */
+ protected function addTestsForGrade($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id, $note, $punkte)
+ {
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+
+ // Get Lehreinheit
+ $result = $this->LehrveranstaltungModel->getLeByStudent($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id);
+
+ if (isError($result))
+ return $result;
+ if (!hasData($result))
+ return error($this->p->t("stv", "grades_error_lehreinheit_id"));
+ $le = current(getData($result));
+
+ // Prepare
+ $this->load->model('education/LePruefung_model', 'LePruefungModel');
+ $data = [
+ "student_uid" => $student_uid,
+ "lehreinheit_id" => $le->lehreinheit_id,
+ "datum" => date('Y-m-d'),
+ "pruefungstyp_kurzbz" => "Termin1",
+ "note" => $note
+ ];
+
+ if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE)
+ $data["punkte"] = $punkte;
+
+ // Get Anwesenheit
+ $this->load->model('education/Anwesenheit_model', 'AnwesenheitModel');
+ $result = $this->AnwesenheitModel->loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id);
+ if (isError($result))
+ return $result;
+ $anwesenheit = getData($result);
+
+ if ($anwesenheit && (float)current($anwesenheit)->prozent < FAS_ANWESENHEIT_ROT) {
+ // Get Anwesenheitsbefreiung
+ $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
+ $result = $this->BenutzerfunktionModel->getBenutzerFunktionByUidInStdsem($student_uid, $studiensemester_kurzbz, 'awbefreit');
+
+ if (isError($result))
+ return $result;
+
+ $anwesenheitsbefreit = hasData($result);
+
+ // Wenn nicht Anwesenheitsbefreit und Anwesenheit unter einem bestimmten Prozentsatz fällt dann wird ein Pruefungsantritt abgezogen
+ if (!$anwesenheitsbefreit) {
+ $data2 = $data;
+ $data2["note"] = 7;
+ if (isset($data2["punkte"]))
+ unset($data2["punkte"]);
+
+ $result = $this->LePruefungModel->insert($data2);
+
+ if (isError($result))
+ return $result;
+
+ $data["pruefungstyp_kurzbz"] = "Termin2";
+ }
+ }
+
+ return $this->LePruefungModel->insert($data);
+ }
+
+ /**
+ * Helper function to check permissions for updateCertificate()
+ *
+ * @param integer $lehrveranstaltung_id
+ * @param string $student_uid
+ *
+ * @return boolean
+ */
+ protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid)
+ {
+ if ($lehrveranstaltung_id === null || $student_uid === null)
+ return true;
+
+ $this->load->model('crm/Student_model', 'StudentModel');
+
+ $result = $this->StudentModel->load([$student_uid]);
+ if (isError($result) || !hasData($result))
+ return false;
+
+ $student = current(getData($result));
+
+ if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
+ return true;
+ if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
+ return true;
+
+ $this->load->model('organisation/Studienplan_model', 'StudienplanModel');
+
+ $result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id);
+ if (isError($result))
+ return false;
+
+ $oes = getData($result) ?: [];
+
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+
+ $result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id);
+ if (isError($result))
+ return false;
+
+ if (hasData($result))
+ $oes[] = current(getData($result));
+
+ foreach ($oes as $oe) {
+ if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
+ return true;
+ if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Helper function to check permissions for deleteCertificate()
+ *
+ * @param integer $lehrveranstaltung_id
+ * @param string $student_uid
+ *
+ * @return boolean
+ */
+ protected function hasPermissionDelete($lehrveranstaltung_id, $student_uid)
+ {
+ if ($lehrveranstaltung_id === null || $student_uid === null)
+ return true;
+
+ $this->load->model('crm/Student_model', 'StudentModel');
+
+ $result = $this->StudentModel->load([$student_uid]);
+ if (isError($result) || !hasData($result))
+ return false;
+
+ $student = current(getData($result));
+
+ if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
+ return true;
+ if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
+ return true;
+
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+
+ $result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
+ if (isError($result) || !hasData($result))
+ return false;
+
+ $oe = current(getData($result));
+
+ if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
+ return true;
+ if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Helper function to check permissions for
+ * copyTeacherProposalToCertificate() and copyRepeaterGradeToCertificate()
+ *
+ * @param integer $lehrveranstaltung_id
+ * @param string $student_uid
+ *
+ * @return boolean
+ */
+ protected function hasPermissionCopy($lehrveranstaltung_id, $student_uid)
+ {
+ if ($lehrveranstaltung_id === null || $student_uid === null)
+ return true;
+
+ $this->load->model('crm/Student_model', 'StudentModel');
+
+ $result = $this->StudentModel->load([$student_uid]);
+ if (isError($result) || !hasData($result))
+ return false;
+
+ $student = current(getData($result));
+
+ if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $student->studiengang_kz))
+ return true;
+
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+
+ $result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
+ if (isError($result) || !hasData($result))
+ return false;
+
+ $oe = current(getData($result));
+
+ if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $oe->oe_kurzbz))
+ return true;
+
+ return false;
+ }
+}
diff --git a/application/controllers/components/stv/Noten.php b/application/controllers/components/stv/Noten.php
deleted file mode 100644
index fb61de065..000000000
--- a/application/controllers/components/stv/Noten.php
+++ /dev/null
@@ -1,168 +0,0 @@
- 'student/noten:r',
- 'getZeugnis' => 'student/noten:r',
- 'update' => ['admin:w', 'assistenz:w']
- ]);
-
- // Load Libraries
- $this->load->library('VariableLib', ['uid' => getAuthUID()]);
- }
-
- public function get()
- {
- $this->load->model('codex/Note_model', 'NoteModel');
-
- $result = $this->NoteModel->addOrder('note');
-
- $result = $this->NoteModel->load();
- if (isError($result)) {
- $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
- }
-
- return $this->outputJson($result);
- }
-
- public function getZeugnis($prestudent_id, $all = null)
- {
- $this->load->model('crm/Student_model', 'StudentModel');
- $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
-
- $result = $this->StudentModel->loadWhere([
- 'prestudent_id' => $prestudent_id
- ]);
- if (isError($result)) {
- $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
- return $this->outputJson($result);
- }
- if (!hasData($result))
- return $this->outputJsonSuccess(null);
-
- $student_uid = current(getData($result))->student_uid;
-
- $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null;
-
- $result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz);
- if (isError($result)) {
- $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
- }
-
- return $this->outputJson($result);
- }
-
- public function update()
- {
- $this->load->model('crm/Student_model', 'StudentModel');
- $this->load->model('organisation/Studienplan_model', 'StudienplanModel');
- $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
- $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
-
- $this->load->library('form_validation');
-
- $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
-
- if (empty($_POST) || !is_array(current($_POST))) {
- $result = $this->hasPermissionUpdate($this->input->post('lehrveranstaltung_id'), $this->input->post('student_uid'));
- if (isError($result)) {
- $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
- return $this->outputJson($result);
- }
-
- $this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrverantaltung ID', 'required|numeric');
- $this->form_validation->set_rules('student_uid', 'Student UID', 'required');
- $this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester Kurzbezeichnung', 'required');
- $this->form_validation->set_rules('note', 'Note', 'required|numeric');
- $post = [$_POST];
- } else {
- foreach ($_POST as $i => $data) {
- $lvid = isset($data['lehrveranstaltung_id']) ? $data['lehrveranstaltung_id'] : null;
- $uid = isset($data['student_uid']) ? $data['student_uid'] : null;
- $result = $this->hasPermissionUpdate($lvid, $uid);
- if (isError($result)) {
- $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
- return $this->outputJson($result);
- }
-
- $this->form_validation->set_rules($i . '[lehrveranstaltung_id]', '#' . $i . ' Lehrverantaltung ID', 'required|numeric');
- $this->form_validation->set_rules($i . '[student_uid]', '#' . $i . ' Student UID', 'required');
- $this->form_validation->set_rules($i . '[studiensemester_kurzbz]', '#' . $i . ' Studiensemester Kurzbezeichnung', 'required');
- $this->form_validation->set_rules($i . '[note]', '#' . $i . ' Note', 'required|numeric');
- }
- $post = $_POST;
- }
- if ($this->form_validation->run() == false) {
- $this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
- return $this->outputJsonError($this->form_validation->error_array());
- }
-
- $final_result = success();
- $this->ZeugnisnoteModel->db->trans_start();
-
- foreach ($post as $i => $data) {
- $note = $data['note'];
- unset($data['note']);
- $result = $this->ZeugnisnoteModel->update($data, [
- 'note' => $note,
- 'benotungsdatum' => date('c'),
- 'updateamum' => date('c'),
- 'updatevon' => getAuthUID()
- ]);
- if (isError($result)) {
- $final_result = $result;
- break;
- }
- }
-
- $this->ZeugnisnoteModel->db->trans_complete();
-
- if (isError($final_result)) {
- $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
- }
-
- $this->outputJson($final_result);
- }
-
- protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid)
- {
- // TODO(chris): error phrases!
- if ($lehrveranstaltung_id === null || $student_uid === null)
- return success();
- $result = $this->StudentModel->load([$student_uid]);
- if (isError($result))
- return $result;
- if (!hasData($result))
- return error('Fehler beim Ermitteln des Studenten');
- $student = current(getData($result));
-
- if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
- return success();
- if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
- return success();
-
- $result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id);
- if (isError($result))
- return $result;
- $oes = getData($result) ?: [];
- $result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id);
- if (isError($result))
- return $result;
- if (hasData($result))
- $oes[] = current(getData($result));
-
- foreach ($oes as $oe) {
- if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
- return success();
- if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
- return success();
- }
-
- return error('Forbidden');
- }
-}
diff --git a/application/libraries/DocumentExportLib.php b/application/libraries/DocumentExportLib.php
new file mode 100644
index 000000000..595ac461a
--- /dev/null
+++ b/application/libraries/DocumentExportLib.php
@@ -0,0 +1,714 @@
+vorlage_kurzbz, $oe_kurzbz, $version);
+ * $doc->setFilename($filename);
+ * $doc->addDataXML($data);
+ * $doc->addImage($imagepath, $imagename, $imagecontenttype);
+ * $doc->create($outputformat);
+ * $doc->output(true);
+ * $doc->close();
+ *
+ * New:
+ * $xml_data = $this->documentexportlib->getDataXML($data);
+ * $images = [[
+ * 'path' => $imagepath,
+ * 'name' => $imagename,
+ * 'contenttype' => $imagecontenttype
+ * ]];
+ * $this->documentexportlib->showContent(
+ * $filename,
+ * $vorlage,
+ * $xml_data,
+ * $oe_kurzbz,
+ * $version,
+ * $outputformat,
+ * null,
+ * null,
+ * $images
+ * );
+ */
+class DocumentExportLib
+{
+ private $unoconv_version;
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ // Gets CI instance
+ $this->ci =& get_instance();
+
+ // Load Phrases
+ $this->ci->load->library('PhrasesLib', ['document_export', null], 'documentExportPhrases');
+
+ // Which document converter has to be used
+ if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true)
+ {
+ // Use docsbox!!
+ }
+ else
+ {
+ exec('unoconv --version', $ret_arr);
+
+ if(isset($ret_arr[0]))
+ {
+ $hlp = explode(' ', $ret_arr[0]);
+ if(isset($hlp[1]))
+ {
+ $this->unoconv_version = $hlp[1];
+ }
+ else
+ show_error($this->ci->documentExportPhrases->t("document_export", "error_unoconv_version"));
+ }
+ else
+ show_error($this->ci->documentExportPhrases->t("document_export", "error_unoconv"));
+ }
+ }
+
+ /**
+ * Laedt die XML Daten fuer die XSL Transformation anhand eines Arrays
+ *
+ * @param array $data Array mit Daten
+ * @param string $root Bezeichnung des Root Nodes
+ *
+ * @return DOMDocument
+ */
+ public function getDataArray($data, $root)
+ {
+ $xml_data = new DOMDocument();
+ $xml_data->loadXML($this->convertArrayToXML($data, $root));
+ return $xml_data;
+ }
+
+ /**
+ * XML Daten fuer die XSL Transformation
+ *
+ * @param string $xml
+ *
+ * @return DOMDocument
+ */
+ public function getDataXML($xml)
+ {
+ $xml_data = new DOMDocument();
+ $xml_data->loadXML($xml);
+ return $xml_data;
+ }
+
+ /**
+ * URL zu XML Datei die fuer XSLTransformation verwendet werden soll
+ *
+ * @param string $xml URL to XML
+ * @param string $params GET parameter
+ *
+ * @return stdClass
+ */
+ public function getDataURL($xml, $params)
+ {
+ $xml_found = false;
+
+ $aktive_addons = array_filter(array_map('trim', explode(";", ACTIVE_ADDONS)));
+ foreach($aktive_addons as $addon) {
+ $xmlfile = DOC_ROOT . 'addons/' . $addon . '/rdf/' . $xml;
+ if (file_exists($xmlfile)) {
+ $xml_found = true;
+ $xml_url = XML_ROOT . '../addons/' . $addon . '/rdf/' . $xml . '?' . $params;
+ break;
+ }
+ }
+ if (!$xml_found)
+ $xml_url = XML_ROOT . $xml . '?' . $params;
+
+
+ // Load the XML source
+ $xml_data = new DOMDocument;
+
+ if (!$xml_data->load($xml_url))
+ return error($this->ci->documentExportPhrases->t("document_export", "error_xml_load", [
+ "url" => $xml_url,
+ "xml" => $xml,
+ "params" => $params
+ ]));
+
+ return success($xml_data);
+ }
+
+ /**
+ * Adds a XML Tag for signatur to the document
+ *
+ * @param DomDocument $xml_data
+ *
+ * @return void
+ */
+ protected function addSignToData($xml_data)
+ {
+ $signblock = $xml_data->createElement("signed", "true");
+ $xml_data->documentElement->appendChild($signblock);
+ }
+
+ /**
+ * Adds a XML Tag for archive to the document
+ *
+ * @param DomDocument $xml_data
+ *
+ * @return void
+ */
+ public function addArchiveToData($xml_data)
+ {
+ $archiv = $xml_data->createElement("archivierbar", "true");
+ $xml_data->documentElement->appendChild($archiv);
+ }
+
+ /**
+ * Get the contents of a Document
+ *
+ * @param stdClass $vorlage A db entry from tbl_vorlage
+ * @param DomDocument $xml_data
+ * @param string $oe_kurzbz
+ * @param integer|null $version (optional)
+ * @param string $outputformat (optional)
+ * @param string $sign_user (optional) Must be a valid uid
+ * @param string $sign_profile (optional) Signatureprofile for signing
+ * @param array $images (optional) Each element should have a property path, name & contenttype which are all strings
+ *
+ * @return stdClass
+ */
+ public function getContent(
+ $vorlage,
+ $xml_data,
+ $oe_kurzbz,
+ $version = null,
+ $outputformat = null,
+ $sign_user = null,
+ $sign_profile = null,
+ $images = []
+ ) {
+ $source_folder = getcwd();
+ $temp_folder = sys_get_temp_dir() . '/fhcunoconv-' . uniqid();
+
+ $outputformat = $this->getDefaultOutputFormat($outputformat, $vorlage->mimetype);
+
+ $result = $this->createAndSignContent(
+ $temp_folder,
+ $outputformat,
+ $vorlage,
+ $oe_kurzbz,
+ $version,
+ $xml_data,
+ $images,
+ $sign_user,
+ $sign_profile
+ );
+ if (isError($result)) {
+ $this->close($temp_folder, $source_folder);
+ return $result;
+ }
+ $temp_filename = getData($result);
+
+ $fsize = filesize($temp_filename);
+ $handle = fopen($temp_filename, 'r');
+ if (!$handle)
+ return error($this->ci->documentExportPhrases->t("document_export", "error_file_load"));
+ $result = fread($handle, $fsize);
+ fclose($handle);
+
+ $this->close($temp_folder, $source_folder);
+
+ return success($result);
+ }
+
+ /**
+ * Sets the headers and displays the Document.
+ * On failure the exit() function will be called
+ *
+ * @param string $filename
+ * @param stdClass $vorlage A db entry from tbl_vorlage
+ * @param DomDocument $xml_data
+ * @param string $oe_kurzbz
+ * @param integer|null $version (optional)
+ * @param string $outputformat (optional)
+ * @param string $sign_user (optional) Must be a valid uid
+ * @param string $sign_profile (optional) Signatureprofile for signing
+ * @param array $images (optional) Each element should have a property path, name & contenttype which are all strings
+ *
+ * @return void
+ */
+ public function showContent(
+ $filename,
+ $vorlage,
+ $xml_data,
+ $oe_kurzbz,
+ $version = null,
+ $outputformat = null,
+ $sign_user = null,
+ $sign_profile = null,
+ $images = []
+ ) {
+ $source_folder = getcwd();
+ $temp_folder = sys_get_temp_dir() . '/fhcunoconv-' . uniqid();
+
+ $outputformat = $this->getDefaultOutputFormat($outputformat, $vorlage->mimetype);
+
+ $result = $this->createAndSignContent(
+ $temp_folder,
+ $outputformat,
+ $vorlage,
+ $oe_kurzbz,
+ $version,
+ $xml_data,
+ $images,
+ $sign_user,
+ $sign_profile
+ );
+ if (isError($result)) {
+ $this->close($temp_folder, $source_folder);
+ exit(getError($result));
+ }
+ $temp_filename = getData($result);
+
+ $fsize = filesize($temp_filename);
+ $handle = fopen($temp_filename, 'r');
+ if (!$handle) {
+ $this->close($temp_folder, $source_folder);
+ exit($this->ci->documentExportPhrases->t("document_export", "error_file_load"));
+ }
+
+ if (headers_sent()) {
+ $this->close($temp_folder, $source_folder);
+ exit($this->ci->documentExportPhrases->t("document_export", "error_headers"));
+ }
+
+ switch ($outputformat) {
+ case 'pdf':
+ header('Content-type: application/pdf');
+ header('Content-Disposition: attachment; filename="' . $filename . '.pdf"');
+ header('Content-Length: ' . $fsize);
+ break;
+
+ case 'doc':
+ header('Content-type: application/vnd.ms-word');
+ header('Content-Disposition: attachment; filename="' . $filename . '.doc"');
+ header('Content-Length: ' . $fsize);
+ break;
+
+ case 'odt':
+ header('Content-type: application/vnd.oasis.opendocument.text');
+ header('Content-Disposition: attachment; filename="' . $filename . '.odt"');
+ header('Content-Length: ' . $fsize);
+ break;
+ default:
+ $this->close($temp_folder, $source_folder);
+ exit($this->ci->documentExportPhrases->t("document_export", "error_outputformat_missing"));
+ }
+
+ while (!feof($handle)) {
+ echo fread($handle, 8192);
+ }
+ fclose($handle);
+
+ $this->close($temp_folder, $source_folder);
+ }
+
+ /**
+ * Helper function for getContent and showContent.
+ * Creates the temp folder and calls create and sign functions.
+ *
+ * @param string $temp_folder
+ * @param string $outputformat
+ * @param stdClass $vorlage
+ * @param string $oe_kurzbz
+ * @param integer $version
+ * @param DomDocument $xml_data
+ * @param array $images Each element should have a property path, name and contenttype which are all strings
+ * @param string $sign_user Must be a valid uid
+ * @param string $sign_profile Signatureprofile for signing
+ *
+ * @return stdClass
+ */
+ protected function createAndSignContent(
+ $temp_folder,
+ $outputformat,
+ $vorlage,
+ $oe_kurzbz,
+ $version,
+ $xml_data,
+ $images,
+ $sign_user,
+ $sign_profile
+ ) {
+ mkdir($temp_folder);
+ chdir($temp_folder);
+
+ $this->ci->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
+
+ $result = $this->ci->VorlagestudiengangModel->getCurrent($vorlage->vorlage_kurzbz, $oe_kurzbz, $version);
+ if (isError($result))
+ return $result;
+ if (!hasData($result))
+ return error($this->ci->documentExportPhrases->t("document_export", "error_template_missing"));
+ $vorlage_stg = current(getData($result));
+ foreach ($vorlage_stg as $k => $v)
+ $vorlage->$k = $v;
+
+ $result = $this->create($temp_folder, $outputformat, $vorlage, $xml_data, $images);
+ if (isError($result))
+ return $result;
+
+ $temp_filename = getData($result);
+
+ if ($sign_user) {
+ $this->addSignToData($xml_data);
+
+ $result = $this->sign($temp_folder, $temp_filename, $outputformat, $sign_user, $sign_profile);
+ if (isError($result))
+ return $result;
+
+ $temp_filename = getData($result);
+ }
+
+ return success($temp_filename);
+ }
+
+ /**
+ * Helper function for createAndSignContent.
+ * Creates the files in the temp folder.
+ *
+ * @param string $temp_folder
+ * @param string $outputformat
+ * @param stdClass $vorlage
+ * @param DomDocument $xml_data
+ * @param array $images Each element should have a property path, name and contenttype which are all strings
+ *
+ * @return stdClass
+ */
+ protected function create($temp_folder, $outputformat, $vorlage, $xml_data, $images)
+ {
+ $content_xsl = new DOMDocument();
+ if (!$content_xsl->loadXML($vorlage->text))
+ return error($this->ci->documentExportPhrases->t("document_export", "error_xsl_load"));
+
+ $proc = new XSLTProcessor();
+ $proc->importStyleSheet($content_xsl);
+
+ $contentbuffer = $proc->transformToXml($xml_data);
+
+ file_put_contents($temp_folder . '/content.xml', $contentbuffer);
+
+ if ($xml_data->firstChild->tagName == 'error')
+ return error($xml_data->firstChild->textContent);
+
+ // styles.xml erstellen
+ if ($vorlage->style) {
+ $styles_xsl = new DOMDocument();
+ if (!$styles_xsl->loadXML($vorlage->style))
+ return error($this->ci->documentExportPhrases->t("document_export", "error_styles_load"));
+ $style_proc = new XSLTProcessor();
+ $style_proc->importStyleSheet($styles_xsl);
+
+ $stylesbuffer = $style_proc->transformToXml($xml_data);
+
+ file_put_contents($temp_folder . '/styles.xml', $stylesbuffer);
+ }
+
+ // Template holen
+ $vorlage_found = false;
+ $vorlage_filename = $vorlage->vorlage_kurzbz . ($vorlage->mimetype == 'application/vnd.oasis.opendocument.spreadsheet' ? '.ods' : '.odt');
+
+ $aktive_addons = array_filter(array_map('trim', explode(";", ACTIVE_ADDONS)));
+ foreach($aktive_addons as $addon) {
+ $zipfile = DOC_ROOT . 'addons/' . $addon . '/system/vorlage_zip/' . $vorlage_filename;
+
+ if (file_exists($zipfile)) {
+ $vorlage_found = true;
+ break;
+ }
+ }
+ if (!$vorlage_found)
+ $zipfile = DOC_ROOT . 'system/vorlage_zip/' . $vorlage_filename;
+
+ $tempname_zip = $temp_folder . '/out.zip';
+
+ if (!copy($zipfile, $tempname_zip))
+ return error($this->ci->documentExportPhrases->t("document_export", "error_file_copy"));
+
+ exec("zip $tempname_zip content.xml");
+ if (!is_null($styles_xsl))
+ exec("zip $tempname_zip styles.xml");
+
+ // bilder hinzufuegen
+ if (count($images) > 0)
+ {
+ // Unterordner fuer die Bilder erstellen
+ mkdir('Pictures');
+
+ // Manifest Datei holen
+ exec('unzip ' . $tempname_zip . ' META-INF/manifest.xml');
+
+ // Bild zur Manifest Datei hinzufuegen
+ $manifest = file_get_contents('META-INF/manifest.xml');
+
+ $manifest_xml = new DOMDocument;
+ if (!$manifest_xml->loadXML($manifest))
+ return error($this->ci->documentExportPhrases->t("document_export", "error_manifest"));
+
+ //root-node holen
+ $root = $manifest_xml->getElementsByTagName('manifest')->item(0);
+
+ foreach ($images as $bild) {
+ copy($bild['path'], 'Pictures/' . $bild['name']);
+
+ //Neues Element unterhalb des Root Nodes anlegen
+ $node = $manifest_xml->createElement("manifest:file-entry");
+ $node->setAttribute("manifest:full-path", 'Pictures/' . $bild['name']);
+ $node->setAttribute("manifest:media-type", $bild['contenttype']);
+ $root->appendChild($node);
+ }
+
+ $out = $manifest_xml->saveXML();
+
+ //geaenderte Manifest Datei speichern und wieder ins Zip packen
+ file_put_contents('META-INF/manifest.xml', $out);
+ exec('zip ' . $tempname_zip . ' META-INF/*');
+
+ // Bilder zum ZIP-File hinzufuegen
+ exec('zip ' . $tempname_zip . ' Pictures/*');
+ }
+
+ clearstatcache();
+
+ switch ($outputformat) {
+ case 'pdf':
+ case 'doc':
+ $ret = 0;
+ $temp_filename = $temp_folder . '/out.' . $outputformat;
+
+ if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) {
+ // Use docsbox
+
+ $this->ci->load->library("DocsboxLib");
+
+ $docboxlib = get_class($this->ci->docboxlib);
+
+ $ret = $docboxlib::convert($tempname_zip, $temp_filename, $outputformat);
+ } else {
+ // Use unoconv
+
+ // Unoconv Version 0.6 hat eine Bug wodurch die Berechtigungen des PDF/Doc nicht korrekt gesetzt
+ // werden. Deshalb wird dies hier speziell behandelt.
+ // Die 2. Variante hat den Vorteil dass hier eine bessere Fehlerbehandlung moeglich ist
+ if ($this->unoconv_version == '0.6')
+ $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $outputformat . ' %2$s > %1$s';
+ else
+ $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $outputformat . ' --output %s %s 2>&1';
+
+ $command = sprintf($command, $temp_filename, $tempname_zip);
+
+ exec($command, $out, $ret);
+ }
+
+ if ($ret)
+ return error($this->ci->documentExportPhrases->t("document_export", "error_conv_timeout"));
+ break;
+ case 'odt':
+ default:
+ $temp_filename = $tempname_zip;
+ }
+
+ return success($temp_filename);
+ }
+
+ /**
+ * Helper function for createAndSignContent.
+ * Signs the main file in the temp folder.
+ *
+ * @param string $temp_folder
+ * @param string $temp_filename
+ * @param string $outputformat
+ * @param string $user Must be a valid uid
+ * @param string $profile Signatureprofile for signing
+ *
+ * @return stdClass
+ */
+ protected function sign($temp_folder, $temp_filename, $outputformat, $user, $profile)
+ {
+ if ($outputformat != 'pdf')
+ return error($this->ci->documentExportPhrases->t("document_export", "error_sign_pdf"));
+
+ // Load the File
+ $file_data = file_get_contents($temp_filename);
+
+ $data = new stdClass();
+ $data->document = base64_encode($file_data);
+
+ // Signatur Profil
+ if (!is_null($profile))
+ $data->profile = $profile;
+ else
+ $data->profile = SIGNATUR_DEFAULT_PROFILE;
+
+ // Username des Endusers der die Signatur angefordert hat
+ $data->user = $user;
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_URL, SIGNATUR_URL . '/' . SIGNATUR_SIGN_API);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7);
+ curl_setopt($ch, CURLOPT_USERAGENT, "FH-Complete");
+
+ // SSL Zertifikatsprüfung deaktivieren
+ // Besser ist es das Zertifikat am Server zu installieren!
+ //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+
+ $data_string = json_encode($data, JSON_FORCE_OBJECT);
+
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, [
+ 'Content-Type: application/json',
+ 'Content-Length:' . mb_strlen($data_string),
+ 'Authorization: Basic ' . base64_encode(SIGNATUR_USER . ":" . SIGNATUR_PASSWORD)
+ ]);
+
+ $result = curl_exec($ch);
+ if (curl_errno($ch)) {
+ curl_close($ch);
+ return error($this->ci->documentExportPhrases->t("document_export", "error_sign_timeout"));
+ }
+ curl_close($ch);
+ $resultdata = json_decode($result);
+
+ // If it is success
+ if (isset($resultdata->error) && $resultdata->error == 0) {
+ $signed_filename = $temp_folder . '/signed.pdf';
+ file_put_contents($signed_filename, base64_decode($resultdata->retval));
+ return success($signed_filename);
+ }
+
+ // otherwise if it is an error
+ return error($resultdata->retval ?? $this->ci->documentExportPhrases->t("global", "unknown_error", ["error" => $result]));
+ }
+
+ /**
+ * Deletes all files in the $temp_folder and changes back to the source_folder
+ *
+ * @param string $temp_folder
+ * @param string $source_folder
+ *
+ * @return void
+ */
+ protected function close($temp_folder, $source_folder)
+ {
+ $files = glob($temp_folder . '/*'); // get all file names
+ foreach ($files as $file)
+ if (is_file($file))
+ unlink($file);
+
+ chdir($source_folder);
+ rmdir($temp_folder);
+ }
+
+ /**
+ * Convert an array to XML
+ *
+ * @param array $data
+ * @param string $root
+ * @param SimpleXMLElement $xml_data
+ *
+ * @return string|boolean
+ */
+ private function convertArrayToXML($data, $root = null, $xml_data = null)
+ {
+ $_xml_data = $xml_data;
+ if ($_xml_data === null)
+ $_xml_data = new SimpleXMLElement($root !== null ? '<' . $root . ' />' : '