mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 06:54:04 +00:00
check for schlagwoerter length in zusatzdaten frontend/backend - likely the cause of finished projects with missing data
This commit is contained in:
@@ -22,6 +22,10 @@ use CI3_Events as Events;
|
||||
|
||||
class Abgabe extends FHCAPI_Controller
|
||||
{
|
||||
// col limits of lehre.tbl_projektarbeit, exceeding them aborts the zusatzdaten update and lead to unpublishable enduploads
|
||||
const MAX_LEN_SCHLAGWOERTER = 150; // varchar(150)
|
||||
const MAX_LEN_ABSTRACT = 5000; // text, capped to match the ui counter
|
||||
const MAX_SEITENANZAHL = 32767; // smallint
|
||||
|
||||
/**
|
||||
* Object initialization
|
||||
@@ -326,6 +330,10 @@ class Abgabe extends FHCAPI_Controller
|
||||
// block uploads for quality gate termine that are already graded
|
||||
$this->checkPaabgabeForGradedStatus($paabgabe_id);
|
||||
|
||||
// the posted typ is client state only - verify it against the row so a stale ui cannot push an
|
||||
// endabgabe through here, which would mark the abgabe without ever writing the zusatzdaten
|
||||
$this->checkPaabgabeTypForZwischenabgabe($paabgabe_id, $paabgabetyp_kurzbz);
|
||||
|
||||
// load the $student_uid by $projektarbeit_id so we dont need any post params
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$res = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id);
|
||||
@@ -403,8 +411,10 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$this->checkZusatzdatenLengths($schlagwoerter, $schlagwoerter_en, $abstract, $abstract_en, $seitenanzahl);
|
||||
|
||||
$this->checkPaabgabeDeadline($paabgabe_id);
|
||||
|
||||
|
||||
$this->checkProjektarbeitForFinishedStatus($projektarbeit_id);
|
||||
|
||||
// load the $student_uid by $projektarbeit_id so we dont need any post params
|
||||
@@ -453,17 +463,25 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->checkAbgabeSignatur($paabgabe, $projektarbeit->student_uid);
|
||||
$signaturstatus = $paabgabe->signatur;
|
||||
|
||||
// update projektarbeit cols with zusatzdaten AND abgabedatum!
|
||||
$this->ProjektarbeitModel->update($projektarbeit->projektarbeit_id, array(
|
||||
'sprache' => $sprache,
|
||||
'seitenanzahl' => $seitenanzahl,
|
||||
'abgabedatum' => date('Y-m-d'),
|
||||
'schlagwoerter_en' => $schlagwoerter_en,
|
||||
'schlagwoerter' => $schlagwoerter,
|
||||
'abstract' => $abstract,
|
||||
'abstract_en' => $abstract_en
|
||||
));
|
||||
// update projektarbeit cols with zusatzdaten AND abgabedatum!
|
||||
$updateRes = $this->ProjektarbeitModel->update($projektarbeit->projektarbeit_id, array(
|
||||
'sprache' => $sprache,
|
||||
'seitenanzahl' => $seitenanzahl,
|
||||
'abgabedatum' => date('Y-m-d'),
|
||||
'schlagwoerter_en' => $schlagwoerter_en,
|
||||
'schlagwoerter' => $schlagwoerter,
|
||||
'abstract' => $abstract,
|
||||
'abstract_en' => $abstract_en
|
||||
));
|
||||
|
||||
// abort before marking the abgabe - a failed update used to leave the projektarbeit without
|
||||
// abgabedatum and zusatzdaten while the endupload counted as done, blocking the publication
|
||||
if(isError($updateRes)) {
|
||||
$this->logLib->logInfoDB(array('endupload projektarbeit update failed', getError($updateRes),
|
||||
$projektarbeit_id, $paabgabe_id, getAuthUID(), getAuthPersonId()));
|
||||
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4enduploadZusatzdatenSpeichernFehlgeschlagen'), 'general');
|
||||
}
|
||||
|
||||
// update paabgabe datum
|
||||
$res = $this->PaabgabeModel->update($paabgabe_id, array(
|
||||
@@ -1070,6 +1088,22 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
// a termin with an upload or a note must keep its typ and datum.
|
||||
// the table only hides those rows client side, so a student upload
|
||||
// after the table was loaded would otherwise still let a zwischenabgabe be retyped to 'end'
|
||||
$existingPaabgabe = $paabgabeArr[0];
|
||||
|
||||
if($existingPaabgabe->note !== null || $existingPaabgabe->abgabedatum !== null) {
|
||||
if(isset($updateFields['paabgabetyp_kurzbz'])
|
||||
&& $updateFields['paabgabetyp_kurzbz'] !== $existingPaabgabe->paabgabetyp_kurzbz) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4abgabetypAendernNichtErlaubt'));
|
||||
}
|
||||
|
||||
if(isset($updateFields['datum']) && $updateFields['datum'] !== $existingPaabgabe->datum) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4datumAendernNichtErlaubt'));
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->PaabgabeModel->update(
|
||||
$paabgabe_id,
|
||||
array_merge($updateFields, [
|
||||
@@ -1583,7 +1617,9 @@ class Abgabe extends FHCAPI_Controller
|
||||
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
|
||||
$this->checkZusatzdatenLengths($schlagwoerter, $schlagwoerter_en, $abstract, $abstract_en, $seitenanzahl);
|
||||
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
|
||||
|
||||
@@ -1618,7 +1654,7 @@ class Abgabe extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
// update projektarbeit cols with zusatzdaten only
|
||||
$this->ProjektarbeitModel->update($projektarbeit_id, array(
|
||||
$updateRes = $this->ProjektarbeitModel->update($projektarbeit_id, array(
|
||||
'sprache' => $sprache,
|
||||
'seitenanzahl' => $seitenanzahl,
|
||||
'schlagwoerter_en' => $schlagwoerter_en,
|
||||
@@ -1627,6 +1663,9 @@ class Abgabe extends FHCAPI_Controller
|
||||
'abstract_en' => $abstract_en
|
||||
));
|
||||
|
||||
// dont report success on a failed update, otherwise a repair attempt silently changes nothing
|
||||
$this->getDataOrTerminateWithError($updateRes, 'general');
|
||||
|
||||
$this->logLib->logInfoDB(array('zusatzdatenEditMitarbeiter', array(
|
||||
'updatevon' => getAuthUID(),
|
||||
'updateamum' => date('Y-m-d H:i:s')
|
||||
@@ -2009,16 +2048,48 @@ class Abgabe extends FHCAPI_Controller
|
||||
|
||||
$data = getData($res)[0];
|
||||
if($data->note !== NULL) {
|
||||
// hardcode this error msg cause phrasen arent always being updated
|
||||
$message = $this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv3');
|
||||
if(strpos($message, "<<") === 0) { // phrase could not be loaded
|
||||
$this->terminateWithError('Die Projektarbeit wurde bereits benotet, Sie dürfen deshalb keine weiteren Termine anlegen oder bearbeiten.', 'general');
|
||||
} else {
|
||||
$this->terminateWithError($message);
|
||||
}
|
||||
$this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv3'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// validates the zusatzdaten against the column limits of lehre.tbl_projektarbeit.
|
||||
private function checkZusatzdatenLengths($schlagwoerter, $schlagwoerter_en, $abstract, $abstract_en, $seitenanzahl) {
|
||||
if(mb_strlen((string)$schlagwoerter) > self::MAX_LEN_SCHLAGWOERTER
|
||||
|| mb_strlen((string)$schlagwoerter_en) > self::MAX_LEN_SCHLAGWOERTER) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4schlagwoerterZuLang', array(self::MAX_LEN_SCHLAGWOERTER)), 'general');
|
||||
}
|
||||
|
||||
if(mb_strlen((string)$abstract) > self::MAX_LEN_ABSTRACT
|
||||
|| mb_strlen((string)$abstract_en) > self::MAX_LEN_ABSTRACT) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4abstractZuLang', array(self::MAX_LEN_ABSTRACT)), 'general');
|
||||
}
|
||||
|
||||
if(!is_numeric($seitenanzahl) || (int)$seitenanzahl < 1 || (int)$seitenanzahl > self::MAX_SEITENANZAHL) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4seitenanzahlUngueltig', array(self::MAX_SEITENANZAHL)), 'general');
|
||||
}
|
||||
}
|
||||
|
||||
// zwischenabgabe uploads must never touch an endabgabe termin, to avoid empty zusatzdaten
|
||||
private function checkPaabgabeTypForZwischenabgabe($paabgabe_id, $posted_paabgabetyp_kurzbz) {
|
||||
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
|
||||
$res = $this->PaabgabeModel->load($paabgabe_id);
|
||||
|
||||
if(isError($res) || !hasData($res)) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4projektabgabeNichtGefunden'), 'general');
|
||||
}
|
||||
|
||||
$paabgabe = getData($res)[0];
|
||||
|
||||
if($paabgabe->paabgabetyp_kurzbz === 'end') {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4enduploadUeberZwischenabgabeNichtErlaubt'), 'general');
|
||||
}
|
||||
|
||||
// typ changed between page load and upload -> the client would use the wrong upload path
|
||||
if($paabgabe->paabgabetyp_kurzbz !== $posted_paabgabetyp_kurzbz) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4abgabeterminGeaendertNeuLaden'), 'general');
|
||||
}
|
||||
}
|
||||
|
||||
private function checkPaabgabeForGradedStatus($paabgabe_id) {
|
||||
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
|
||||
$res = $this->PaabgabeModel->load($paabgabe_id);
|
||||
@@ -2029,13 +2100,7 @@ class Abgabe extends FHCAPI_Controller
|
||||
|
||||
$paabgabe = getData($res)[0];
|
||||
if($paabgabe->note !== NULL) {
|
||||
// hardcode a fallback cause phrasen arent reliable
|
||||
$message = $this->p->t('abgabetool', 'c4studentAbgabeNotAllowedRegularv3');
|
||||
if(strpos($message, "<<") === 0) { // phrase could not be loaded
|
||||
$this->terminateWithError('Uploads sind für bereits benotete Quality Gates gesperrt. Sollten Sie trotzdem etwas hochladen wollen, wenden Sie sich bitte an Ihre Studiengangsassistenz.', 'general');
|
||||
} else {
|
||||
$this->terminateWithError($message);
|
||||
}
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4studentAbgabeNotAllowedRegularv3'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -442,7 +442,12 @@ export const AbgabeMitarbeiterDetail = {
|
||||
return true
|
||||
},
|
||||
allowedToSaveZusatzdaten() {
|
||||
return this.form.schlagwoerter.length > 0 && this.form.schlagwoerter_en.length > 0 && this.form.abstract.length > 0 && this.form.abstract_en.length > 0 && this.form.seitenanzahl > 0
|
||||
// upper bounds mirror the column limits of lehre.tbl_projektarbeit, see Abgabe.php
|
||||
return this.form.schlagwoerter.length > 0 && this.form.schlagwoerter.length <= 150
|
||||
&& this.form.schlagwoerter_en.length > 0 && this.form.schlagwoerter_en.length <= 150
|
||||
&& this.form.abstract.length > 0 && this.form.abstract.length <= 5000
|
||||
&& this.form.abstract_en.length > 0 && this.form.abstract_en.length <= 5000
|
||||
&& this.form.seitenanzahl > 0 && this.form.seitenanzahl <= 32767
|
||||
},
|
||||
getAllowedAbgabeTypeOptions() {
|
||||
if(this.assistenzMode) {
|
||||
@@ -1003,14 +1008,16 @@ export const AbgabeMitarbeiterDetail = {
|
||||
<div class="row mb-3 align-items-start">
|
||||
<div class="row">{{$capitalize( $p.t('abgabetool/c4schlagwoerterGer') )}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.schlagwoerter" class="w-100"></Textarea>
|
||||
<Textarea v-model="form.schlagwoerter" maxlength="150" class="w-100"></Textarea>
|
||||
<p>{{ form.schlagwoerter?.length ? form.schlagwoerter.length : 0 }} / 150 characters</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row mb-3 align-items-start">
|
||||
<div class="row">{{$capitalize( $p.t('abgabetool/c4schlagwoerterEng') )}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.schlagwoerter_en" class="w-100"></Textarea>
|
||||
<Textarea v-model="form.schlagwoerter_en" maxlength="150" class="w-100"></Textarea>
|
||||
<p>{{ form.schlagwoerter_en?.length ? form.schlagwoerter_en.length : 0 }} / 150 characters</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1035,7 +1042,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
<div class="row">
|
||||
<InputNumber
|
||||
v-model="form.seitenanzahl"
|
||||
inputId="seitenanzahlInput" :min="1" :max="100000">
|
||||
inputId="seitenanzahlInput" :min="1" :max="32767">
|
||||
</InputNumber>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -258,7 +258,9 @@ export const AbgabeStudentDetail = {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(termin.bezeichnung?.paabgabetyp_kurzbz === 'end') {
|
||||
// use the field from the backend, not the client side mapped bezeichnung object - a failed
|
||||
// lookup there would silently route an endupload through the zwischenabgabe endpoint
|
||||
if(termin.paabgabetyp_kurzbz === 'end') {
|
||||
this.enduploadTermin = termin
|
||||
this.$refs.modalContainerEnduploadZusatzdaten.show()
|
||||
} else {
|
||||
@@ -365,7 +367,12 @@ export const AbgabeStudentDetail = {
|
||||
return this.$capitalize(this.$p.t('abgabetool/c4eidesstattlicheErklaerung'))
|
||||
},
|
||||
allowedToSaveZusatzdaten() {
|
||||
return this.form.schlagwoerter.length > 0 && this.form.schlagwoerter_en.length > 0 && this.form.abstract.length > 0 && this.form.abstract_en.length > 0 && this.form.seitenanzahl > 0
|
||||
// upper bounds mirror the column limits of lehre.tbl_projektarbeit, see Abgabe.php
|
||||
return this.form.schlagwoerter.length > 0 && this.form.schlagwoerter.length <= 150
|
||||
&& this.form.schlagwoerter_en.length > 0 && this.form.schlagwoerter_en.length <= 150
|
||||
&& this.form.abstract.length > 0 && this.form.abstract.length <= 5000
|
||||
&& this.form.abstract_en.length > 0 && this.form.abstract_en.length <= 5000
|
||||
&& this.form.seitenanzahl > 0 && this.form.seitenanzahl <= 32767
|
||||
},
|
||||
getAllowedToSendEndupload() {
|
||||
return this.eidAkzeptiert && this.allowedToSaveZusatzdaten
|
||||
@@ -733,14 +740,16 @@ export const AbgabeStudentDetail = {
|
||||
<div class="row mb-3 align-items-start">
|
||||
<div class="row">{{$capitalize( $p.t('abgabetool/c4schlagwoerterGer') )}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.schlagwoerter" class="w-100"></Textarea>
|
||||
<Textarea v-model="form.schlagwoerter" maxlength="150" class="w-100"></Textarea>
|
||||
<p>{{ form.schlagwoerter?.length ? form.schlagwoerter.length : 0 }} / 150 characters</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row mb-3 align-items-start">
|
||||
<div class="row">{{$capitalize( $p.t('abgabetool/c4schlagwoerterEng') )}}</div>
|
||||
<div class="row">
|
||||
<Textarea v-model="form.schlagwoerter_en" class="w-100"></Textarea>
|
||||
<Textarea v-model="form.schlagwoerter_en" maxlength="150" class="w-100"></Textarea>
|
||||
<p>{{ form.schlagwoerter_en?.length ? form.schlagwoerter_en.length : 0 }} / 150 characters</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -765,7 +774,7 @@ export const AbgabeStudentDetail = {
|
||||
<div class="row">
|
||||
<InputNumber
|
||||
v-model="form.seitenanzahl"
|
||||
inputId="seitenanzahlInput" :min="1" :max="100000">
|
||||
inputId="seitenanzahlInput" :min="1" :max="32767">
|
||||
</InputNumber>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -48056,6 +48056,126 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4schlagwoerterZuLang',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Die Schlagwörter dürfen maximal {0} Zeichen lang sein.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Keywords may not exceed {0} characters.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4abstractZuLang',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Der Abstract darf maximal {0} Zeichen lang sein.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'The abstract may not exceed {0} characters.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4seitenanzahlUngueltig',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Die Seitenanzahl muss zwischen 1 und {0} liegen.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'The number of pages must be between 1 and {0}.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4enduploadZusatzdatenSpeichernFehlgeschlagen',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Die Zusatzdaten konnten nicht gespeichert werden, der Upload wurde daher nicht abgeschlossen. Bitte wenden Sie sich an Ihre Studiengangsassistenz.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'The additional data could not be saved, therefore the upload was not completed. Please contact your degree programme assistant.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4enduploadUeberZwischenabgabeNichtErlaubt',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Dieser Termin ist eine Endabgabe und kann nur über den Endupload inklusive Zusatzdaten hochgeladen werden. Bitte laden Sie die Seite neu.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'This deadline is a final submission and can only be uploaded via the final upload including the additional data. Please reload the page.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4abgabeterminGeaendertNeuLaden',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Der Abgabetermin wurde zwischenzeitlich geändert. Bitte laden Sie die Seite neu.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'The submission deadline has been changed in the meantime. Please reload the page.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
// ABGABETOOL PHRASEN END
|
||||
array(
|
||||
'app' => 'core',
|
||||
|
||||
Reference in New Issue
Block a user