/** * Loads all selected submissions as a zip file. * * Called when this component receives an HTTP GET request to * /submissions/exercisesheet/$sheetid/user/$userid. * * @param int $sheetid The id of the sheet of which the submissions should * be zipped. * @param int $userid The id of the user whose submissions should be zipped. * * @author Till Uhlig * @date 2014 */ public function loadSubmissionAsZip($sheetid, $userid) { $result = Request::routeRequest('GET', '/submission/group/user/' . $userid . '/exercisesheet/' . $sheetid . '/selected', $this->app->request->headers->all(), '', $this->_submission, 'submission'); if ($result['status'] >= 200 && $result['status'] <= 299) { $submissions = Submission::decodeSubmission($result['content']); $files = array(); foreach ($submissions as $submission) { $file = $submission->getFile(); $file->setDisplayName($file->getDisplayName()); $files[] = $file; } $result = Request::routeRequest('POST', '/zip/' . $sheetid . '.zip', $this->app->request->headers->all(), File::encodeFile($files), $this->_zip, 'zip'); if ($result['status'] >= 200 && $result['status'] <= 299) { $this->app->response->setBody($result['content']); $this->app->response->setStatus(200); if (isset($result['headers']['Content-Type'])) { $this->app->response->headers->set('Content-Type', $result['headers']['Content-Type']); } if (isset($result['headers']['Content-Disposition'])) { $this->app->response->headers->set('Content-Disposition', $result['headers']['Content-Disposition']); } $this->app->stop(); } } $this->app->response->setBody(''); $this->app->response->setStatus(404); $this->app->stop(); }
public static function getRoutedSql($querys, $sql, $checkSession = true) { $obj = new Query(); $obj->setRequest($sql); $obj->setCheckSession($checkSession); // perform the route process return Request::routeRequest('POST', '/query', array(), Query::encodeQuery($obj), $querys, 'query'); }
/** * Processes a process * * Called when this component receives an HTTP POST request to * /process(/). */ public function postProcess() { $this->app->response->setStatus(201); $header = $this->app->request->headers->all(); $body = $this->app->request->getBody(); $process = Process::decodeProcess($body); // always been an array $arr = true; if (!is_array($process)) { $process = array($process); $arr = false; } // this array contains the indices of the inserted objects $res = array(); foreach ($process as $pro) { $eid = $pro->getExercise()->getId(); // loads the form from database $result = Request::routeRequest('GET', '/form/exercise/' . $eid, $this->app->request->headers->all(), '', $this->_formDb, 'form'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299) { // only one form as result $forms = Form::decodeForm($result['content']); $forms = $forms[0]; $formdata = $pro->getRawSubmission()->getFile(); $timestamp = $formdata->getTimeStamp(); if ($timestamp === null) { $timestamp = time(); } if ($formdata !== null && $forms !== null) { $formdata = Form::decodeForm($formdata->getBody(true)); if (is_array($formdata)) { $formdata = $formdata[0]; } if ($formdata !== null) { // evaluate the formdata $points = 0; $answers = $formdata->getChoices(); $correctAnswers = $forms->getChoices(); $allcorrect = true; if ($forms->getType() == 0) { $parameter = explode(' ', strtolower($pro->getParameter())); if ($parameter === null || count($parameter) === 0 || $parameter[0] === '') { if (DefaultNormalizer::normalizeText($correctAnswers[0]->getText()) != DefaultNormalizer::normalizeText($answers[0]->getText())) { $allcorrect = false; } } elseif (strtolower($parameter[0]) === 'distance1') { $similarity = 0; similar_text(DefaultNormalizer::normalizeText($answers[0]->getText()), DefaultNormalizer::normalizeText($correctAnswers[0]->getText()), $similarity); if (isset($parameter[1])) { if ($similarity < $parameter[1]) { $allcorrect = false; } } else { if ($similarity < 100) { $allcorrect = false; } } } elseif (strtolower($parameter[0]) === 'regularexpression') { $i = 1; $test = $parameter[$i]; while ($i < count($parameter)) { if (@preg_match($test, DefaultNormalizer::normalizeText($answers[0]->getText())) !== false) { break; } $test .= ' ' . $parameter[$i]; $i++; } $match = @preg_match($test, DefaultNormalizer::normalizeText(DefaultNormalizer::normalizeText($answers[0]->getText()))); if ($match === false || $match == false || $test == '') { $allcorrect = false; } } } elseif ($forms->getType() == 1) { foreach ($correctAnswers as $mask) { $foundInStudentsAnswer = false; foreach ($answers as $answer) { if ($answer->getText() === $mask->getChoiceId()) { $foundInStudentsAnswer = true; break; } } if ($mask->getCorrect() === '1' && !$foundInStudentsAnswer) { $allcorrect = false; break; } elseif ($mask->getCorrect() === '0' && $foundInStudentsAnswer) { $allcorrect = false; break; } } } elseif ($forms->getType() == 2) { foreach ($correctAnswers as $mask) { $foundInStudentsAnswer = false; foreach ($answers as $answer) { if ($answer->getText() === $mask->getChoiceId()) { $foundInStudentsAnswer = true; break; } } if ($mask->getCorrect() === '1' && !$foundInStudentsAnswer) { $allcorrect = false; break; } elseif ($mask->getCorrect() === '0' && $foundInStudentsAnswer) { $allcorrect = false; break; } } } if ($allcorrect) { $points = $pro->getExercise()->getMaxPoints(); } // save the marking #region Form to PDF if ($pro->getMarking() === null) { $raw = $pro->getRawSubmission(); $exerciseName = ''; if ($raw !== null) { $exerciseName = $raw->getExerciseName(); } $answer = ""; if ($forms->getType() == 0) { $answer = $formdata->getChoices()[0]->getText(); } if ($forms->getType() == 1) { $answer = $this->ChoiceIdToText($formdata->getChoices()[0]->getText(), $forms->getChoices()); } if ($forms->getType() == 2) { foreach ($formdata->getChoices() as $chosen) { $answer .= $this->ChoiceIdToText($chosen->getText(), $forms->getChoices()) . '<br>'; } } $answer2 = ""; foreach ($forms->getChoices() as $chosen) { if ($chosen->getCorrect() === '1') { $answer2 .= $chosen->getText() . '<br>'; } } $Text = "<h1>AUFGABE {$exerciseName}</h1>" . "<hr>"; if ($forms->getTask() !== null && trim($forms->getTask()) != '') { $Text .= "<p>" . "<h2>Aufgabenstellung:</h2>" . $forms->getTask() . "</p>"; } $Text .= "<p>" . "<h2>Antwort:</h2>" . "<span style=\"color: " . ($points === 0 ? 'red' : 'black') . "\">" . $answer . "</span></p>"; if ($points === 0) { $Text .= "<p>" . "<h2>Lösung:</h2><span style=\"color: green\">" . $answer2 . "</span></p>"; } if ($forms->getSolution() !== null && trim($forms->getSolution()) != '') { $Text .= "<p>" . "<h2>Lösungsbegründung:</h2>" . $forms->getSolution() . "</p>"; } $Text .= "<p style=\"text-align: center;\">" . "<h2><span style=\"color: red\">{$points}P</span></h2>" . "</p>"; $pdf = Pdf::createPdf($Text); //echo Pdf::encodePdf($pdf);return; $result = Request::routeRequest('POST', '/pdf', array(), Pdf::encodePdf($pdf), $this->_pdf, 'pdf'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299) { $pdf = File::decodeFile($result['content']); $pdf->setDisplayName($exerciseName . '.pdf'); $pdf->setTimeStamp($timestamp); $pdf->setBody(null); $submission = $pro->getSubmission(); if ($submission === null) { $submission = $pro->getRawSubmission(); } $studentId = $pro->getRawSubmission() !== null ? $pro->getRawSubmission()->getStudentId() : null; if ($studentId === null) { $studentId = $pro->getSubmission() !== null ? $pro->getSubmission()->getStudentId() : null; } $marking = Marking::createMarking(null, $studentId, null, null, null, null, 3, $points, $submission->getDate() !== null ? $submission->getDate() : time()); if (is_object($submission)) { $marking->setSubmission(clone $submission); } $marking->setFile($pdf); $pro->setMarking($marking); } else { $res[] = null; $this->app->response->setStatus(409); continue; } } #endregion $rawSubmission = $pro->getRawSubmission(); $rawFile = $rawSubmission->getFile(); $rawFile->setBody(Form::encodeForm($formdata), true); $rawSubmission->setFile($rawFile); $rawSubmission->setExerciseId($eid); $pro->setRawSubmission($rawSubmission); $res[] = $pro; continue; } } } $this->app->response->setStatus(409); $res[] = null; } if (!$arr && count($res) == 1) { $this->app->response->setBody(Process::encodeProcess($res[0])); } else { $this->app->response->setBody(Process::encodeProcess($res)); } }
/** * Adds a form. * * Called when this component receives an HTTP POST request to * /form(/). */ public function addForm() { Logger::Log('starts POST AddForm', LogLevel::DEBUG); $header = $this->app->request->headers->all(); $body = $this->app->request->getBody(); $this->app->response->setStatus(201); $forms = Form::decodeForm($body); // always been an array $arr = true; if (!is_array($forms)) { $forms = array($forms); $arr = false; } // this array contains the indices of the inserted objects $res = array(); $choices = array(); foreach ($forms as $key => $form) { $choices[] = $form->getChoices(); $forms[$key]->setChoices(null); } $resForms = array(); foreach ($forms as $form) { $method = 'POST'; $URL = '/form'; if ($form->getFormId() !== null) { $method = 'PUT'; $URL = '/form/' . $form->getFormId(); } $result = Request::routeRequest($method, $URL, array(), Form::encodeForm($form), $this->_form, 'form'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299 && isset($result['content'])) { $newform = Form::decodeForm($result['content']); if ($form->getFormId() === null) { $form->setFormId($newform->getFormId()); } $resForms[] = $form; } else { $f = new Form(); $f->setStatus(409); $resForms[] = $f; } } $forms = $resForms; $i = 0; foreach ($choices as &$choicelist) { foreach ($choicelist as $key2 => $choice) { if ($forms[$i]->getFormId() !== null) { $formId = $forms[$i]->getFormId(); $choicelist[$key2]->setFormId($formId); $method = 'POST'; $URL = '/choice'; if ($choicelist[$key2]->getChoiceId() !== null) { $method = 'PUT'; $URL = '/choice/' . $choice->getChoiceId(); } $result = Request::routeRequest($method, $URL, array(), Choice::encodeChoice($choicelist[$key2]), $this->_choice, 'choice'); if ($result['status'] >= 200 && $result['status'] <= 299) { $newchoice = Choice::decodeChoice($result['content']); if ($choicelist[$key2]->getChoiceId() === null) { $choicelist[$key2]->setChoiceId($newchoice->getChoiceId()); } $choicelist[$key2]->setStatus(201); } else { $choicelist[$key2]->setStatus(409); } } } $forms[$i]->setChoices($choicelist); $i++; } // checks the correctness of the query /*if ( $result['status'] >= 200 && $result['status'] <= 299 && isset($result['content'])){ $newforms = Form::decodeForm($result['content']); if ( !is_array( $newforms ) ) $newforms = array($newforms); $i=0; foreach ($forms as &$form){ if ($form->getFormId() === null) $form->setFormId($newforms[$i]->getFormId()); $i++; } $sendChoices = array(); $i=0; foreach ( $choices as $choicelist ){ foreach ( $choicelist as $choice ){ $choice->setFormId($forms[$i]->getFormId()); $sendChoices[] = $choice; } $i++; } $choices = $sendChoices; $result = Request::routeRequest( 'POST', '/choice', $this->app->request->headers->all( ), Choice::encodeChoice($choices), $this->_choice, 'choice' ); // checks the correctness of the query if ( $result['status'] >= 200 && $result['status'] <= 299 ){ $newchoices = Choice::decodeChoice($result['content']); $choicelist = array(); $i=0; foreach ( $choices as &$choice ){ $choice->setChoiceId($newchoices[$i]->getChoiceId()); if (!isset($choicelist[$choice->getFormId()])) $choicelist[$choice->getFormId()] = array(); $choicelist[$choice->getFormId()][] = $choice; $i++; } foreach ( $forms as &$form ){ $form->setChoices($choicelist[$form->getFormId()]); } $res[] = $forms; } else{ // remove forms on failure foreach ($forms as $form){ $result = Request::routeRequest( 'DELETE', '/form/'.$form->getFormId(), $this->app->request->headers->all( ), '', $this->_form, 'form' ); } $res[] = null; $this->app->response->setStatus( 409 ); } } else { $res[] = null; $this->app->response->setStatus( 409 ); }*/ if ($this->app->response->getStatus() != 201) { Logger::Log('POST AddForms failed', LogLevel::ERROR); } if (!$arr && count($res) == 1) { $this->app->response->setBody(Form::encodeForm($res[0])); } else { $this->app->response->setBody(Form::encodeForm($res)); } }
/** * Adds an exercise. * * Called when this component receives an HTTP POST request to * /exercise(/). * The request body should contain a JSON object representing an array of exercises */ public function addExercise() { $header = $this->app->request->headers->all(); $body = json_decode($this->app->request->getBody(), true); $allright = true; $result = array(); if (isset($body) == true && empty($body) == false) { foreach ($body as $subexercise) { // create exercise in DB $FileTypesArrayTemp = null; if (isset($subexercise['fileTypes'])) { $FileTypesArrayTemp = $subexercise['fileTypes']; unset($subexercise['fileTypes']); } $subexerciseJSON = json_encode($subexercise); $URL = $this->lURL . '/DB/exercise'; $method = 'POST'; if (isset($subexercise['id']) && $subexercise['id'] !== null) { $method = 'PUT'; $URL = $this->lURL . '/DB/exercise/' . $subexercise['id']; } $subexerciseAnswer = Request::custom($method, $URL, $header, $subexerciseJSON); if ($subexerciseAnswer['status'] == 201) { $subexerciseOutput = json_decode($subexerciseAnswer['content'], true); if (isset($subexercise['id'])) { $result[] = $subexercise; $subexerciseOutput = $subexercise; } else { $result[] = Exercise::decodeExercise($subexerciseAnswer['content']); } if (isset($subexerciseOutput['id'])) { $linkid = $subexerciseOutput['id']; } // create attachement in DB and FS if (isset($subexercise['attachments']) && !empty($subexercise['attachments'])) { foreach ($subexercise['attachments'] as &$attachment) { $attachment['exerciseId'] = $linkid; } $attachments = $subexercise['attachments']; $tempAttachments = array(); foreach ($attachments as $attachment) { $temp = Attachment::createAttachment(null, $attachment['exerciseId'], null, null); $temp->setFile($attachment); $tempAttachments[] = $temp; } $res = Request::routeRequest('POST', '/attachment', $header, Attachment::encodeAttachment($tempAttachments), $this->_postAttachment, 'attachment'); // checks the correctness of the query if ($res['status'] >= 200 && $res['status'] <= 299) { // ... } else { $allright = false; break; } } // create ExerciseFileTypes if (isset($FileTypesArrayTemp) && !empty($FileTypesArrayTemp)) { foreach ($FileTypesArrayTemp as $fileType) { $myExerciseFileType = ExerciseFileType::createExerciseFileType(NULL, $fileType['text'], $linkid); $myExerciseFileTypeJSON = ExerciseFileType::encodeExerciseFileType($myExerciseFileType); $URL = $this->lURL . "/DB/exercisefiletype"; $FileTypesAnswer = Request::custom('POST', $URL, $header, $myExerciseFileTypeJSON); if ($FileTypesAnswer['status'] != 201) { $allright = false; break; } } } if ($allright == false) { break; } } else { $allright = false; break; } } } if ($allright == true) { $this->app->response->setBody(Exercise::encodeExercise($result)); $this->app->response->setStatus(201); } else { $this->app->response->setStatus(409); } }
/** * Processes a process * * Called when this component receives an HTTP POST request to * /process(/). */ public function postProcess() { $this->app->response->setStatus(201); $header = $this->app->request->headers->all(); $body = $this->app->request->getBody(); $process = Process::decodeProcess($body); // always been an array $arr = true; if (!is_array($process)) { $process = array($process); $arr = false; } // this array contains the indices of the inserted objects $res = array(); foreach ($process as $pro) { $eid = $pro->getExercise()->getId(); // loads the form from database $result = Request::routeRequest('GET', '/form/exercise/' . $eid, $this->app->request->headers->all(), '', $this->_formDb, 'form'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299) { // only one form as result $forms = Form::decodeForm($result['content']); $forms = $forms[0]; $formdata = $pro->getRawSubmission()->getFile(); $timestamp = $formdata->getTimeStamp(); if ($timestamp === null) { $timestamp = time(); } if ($formdata !== null && $forms !== null) { $formdata = Form::decodeForm($formdata->getBody(true)); if (is_array($formdata)) { $formdata = $formdata[0]; } if ($formdata !== null) { // check the submission $fail = false; $parameter = explode(' ', strtolower($pro->getParameter())); $choices = $formdata->getChoices(); if ($forms->getType() == 0) { foreach ($choices as &$choice) { $i = 0; for ($i < 0; $i < count($parameter); $i++) { $param = $parameter[$i]; if ($param === null || $param === '') { continue; } switch ($param) { case 'isnumeric': if (!@preg_match("%^-?([0-9])+([,]([0-9])+)?\$%", DefaultNormalizer::normalizeText($choice->getText()))) { $fail = true; $pro->addMessage('"' . $choice->getText() . '" ist keine gültige Zahl. <br>Bsp.: -0,00'); } break; case 'isdigit': if (!ctype_digit(DefaultNormalizer::normalizeText($choice->getText()))) { $fail = true; $pro->addMessage('"' . $choice->getText() . '" ist keine gültige Ziffernfolge.'); } break; case 'isprintable': if (!ctype_print(DefaultNormalizer::normalizeText($choice->getText()))) { $fail = true; $pro->addMessage('"' . $choice->getText() . '" enthält nicht-druckbare Zeichen.'); } break; case 'isalpha': if (!ctype_alpha(DefaultNormalizer::normalizeText($choice->getText()))) { $fail = true; $pro->addMessage('"' . $choice->getText() . '" ist keine gültige Buchstabenfolge.'); } break; case 'isalphanum': if (!ctype_alnum(DefaultNormalizer::normalizeText($choice->getText()))) { $fail = true; $pro->addMessage('"' . $choice->getText() . '" ist nicht alphanumerisch.'); } break; case 'ishex': if (!ctype_xdigit(DefaultNormalizer::normalizeText($choice->getText()))) { $fail = true; $pro->addMessage('"' . $choice->getText() . '" ist keine gültige Hexadezimalzahl.'); } break; default: $test = $parameter[$i]; $i++; while ($i < count($parameter)) { if (@preg_match($test, DefaultNormalizer::normalizeText($choice->getText())) !== false) { break; } $test .= ' ' . $parameter[$i]; $i++; } $match = @preg_match($test, DefaultNormalizer::normalizeText($choice->getText())); if ($match === false) { $fail = true; $pro->addMessage('"' . $test . '" ist kein gültiger regulärer Ausdruck.'); } elseif ($match == false) { $fail = true; $pro->addMessage('"' . $choice->getText() . '" entspricht nicht dem regulären Ausdruck "' . $test . '".'); } break; } } } } if ($fail) { // received submission isn't correct $pro->setStatus(409); $res[] = $pro; $this->app->response->setStatus(409); continue; } // save the submission #region Form to PDF if ($pro->getSubmission() === null) { $raw = $pro->getRawSubmission(); $exerciseName = ''; if ($raw !== null) { $exerciseName = $raw->getExerciseName(); } $answer = ""; if ($forms->getType() == 0) { $answer = $formdata->getChoices()[0]->getText(); } if ($forms->getType() == 1) { $answer = $this->ChoiceIdToText($formdata->getChoices()[0]->getText(), $forms->getChoices()); } if ($forms->getType() == 2) { foreach ($formdata->getChoices() as $chosen) { $answer .= $this->ChoiceIdToText($chosen->getText(), $forms->getChoices()) . '<br>'; } } $Text = "<h1>AUFGABE {$exerciseName}</h1>" . "<hr>"; if ($forms->getTask() !== null && trim($forms->getTask()) != '') { $Text .= "<p>" . "<h2>Aufgabenstellung:</h2>" . $forms->getTask() . "</p>"; } $Text .= "<p>" . "<h2>Antwort:</h2>" . $answer . "</p>"; $pdf = Pdf::createPdf($Text); $pdf->setText($Text); //echo Pdf::encodePdf($pdf);return; $result = Request::routeRequest('POST', '/pdf', array(), Pdf::encodePdf($pdf), $this->_pdf, 'pdf'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299) { $pdf = File::decodeFile($result['content']); $pdf->setDisplayName($exerciseName . '.pdf'); $pdf->setTimeStamp($timestamp); $pdf->setBody(null); if (is_object($pro->getRawSubmission())) { $submission = clone $pro->getRawSubmission(); } else { $submission = new Submission(); } $submission->setFile($pdf); $submission->setExerciseId($eid); $pro->setSubmission($submission); } else { $pro->setStatus(409); $res[] = $pro; $this->app->response->setStatus(409); continue; } } #endregion $rawSubmission = $pro->getRawSubmission(); $rawFile = $rawSubmission->getFile(); $rawFile->setBody(Form::encodeForm($formdata), true); $rawSubmission->setFile($rawFile); $rawSubmission->setExerciseId($eid); $pro->setRawSubmission($rawSubmission); $pro->setStatus(201); $res[] = $pro; continue; } } } $this->app->response->setStatus(409); $pro->setStatus(409); $res[] = $pro; } if (!$arr && count($res) == 1) { $this->app->response->setBody(Process::encodeProcess($res[0])); } else { $this->app->response->setBody(Process::encodeProcess($res)); } }
/** * Processes a submissions * * Called when this component receives an HTTP POST request to * /submission(/). */ public function postSubmission() { $this->app->response->setStatus(201); $body = $this->app->request->getBody(); $submissions = Submission::decodeSubmission($body); // always been an array $arr = true; if (!is_array($submissions)) { $submissions = array($submissions); $arr = false; } $res = array(); foreach ($submissions as $submission) { $fail = false; $process = new Process(); $process->setRawSubmission($submission); $eid = $submission->getExerciseId(); // load processor data from database $result = Request::routeRequest('GET', '/process/exercise/' . $eid, array(), '', $this->_processorDb, 'process'); $processors = null; if ($result['status'] >= 200 && $result['status'] <= 299) { $processors = Process::decodeProcess($result['content']); } else { if ($result['status'] != 404) { $submission->addMessage("Interner Fehler"); $res[] = $submission; $this->app->response->setStatus(409); continue; } } $result2 = Request::routeRequest('GET', '/exercisefiletype/exercise/' . $eid, array(), '', $this->_getExerciseExerciseFileType, 'exercisefiletype'); $exerciseFileTypes = null; if ($result2['status'] >= 200 && $result2['status'] <= 299) { $exerciseFileTypes = ExerciseFileType::decodeExerciseFileType($result2['content']); if (!is_array($exerciseFileTypes)) { $exerciseFileTypes = array($exerciseFileTypes); } $filePath = null; if ($submission->getFile() != null) { $file = $submission->getFile()->getBody(true); if ($file !== null) { $fileHash = sha1($file); $filePath = '/tmp/' . $fileHash; if ($submission->getFile()->getDisplayName() != null) { LProcessor::generatepath($filePath); file_put_contents($filePath . '/' . $submission->getFile()->getDisplayName(), $file); $filePath .= '/' . $submission->getFile()->getDisplayName(); } else { LProcessor::generatepath($filePath); file_put_contents($filePath . '/tmp', $file); $filePath .= '/tmp'; } } } // check file type if ($filePath != null) { $found = false; $types = array(); $mimeType = MimeReader::get_mime($filePath); $foundExtension = isset(pathinfo($filePath)['extension']) ? pathinfo($filePath)['extension'] : '-'; foreach ($exerciseFileTypes as $type) { $types[] = $type->getText(); $type = explode(' ', str_replace('*', '', $type->getText())); //echo MimeReader::get_mime($filePath); if (strpos($mimeType, $type[0]) !== false && (!isset($type[1]) || '.' . $foundExtension == $type[1])) { $found = true; break; } } if (!$found && count($exerciseFileTypes) > 0) { $submission->addMessage("falscher Dateityp \nGefunden: " . $mimeType . " ." . $foundExtension . "\nErlaubt: " . implode(',', $types)); $res[] = $submission; $this->app->response->setStatus(409); unlink($filePath); continue; } unlink($filePath); } } else { if ($result2['status'] != 404) { $submission->addMessage("Interner Fehler"); $res[] = $submission; $this->app->response->setStatus(409); continue; } } // process submission if ($processors !== null) { if (!is_array($processors)) { $processors = array($processors); } foreach ($processors as $pro) { $component = $pro->getTarget(); if ($process->getExercise() === null) { $process->setExercise($pro->getExercise()); } $process->setParameter($pro->getParameter()); $process->setAttachment($pro->getAttachment()); $process->setTarget($pro->getTarget()); $process->setWorkFiles($pro->getWorkFiles()); //echo Process::encodeProcess($process)."_______";// return; $result = Request::post($component->getAddress() . '/process', array(), Process::encodeProcess($process)); //echo $result['content'].'_______'; if ($result['status'] >= 200 && $result['status'] <= 299) { $process = Process::decodeProcess($result['content']); } else { $fail = true; $submission->addMessage("Beim Verarbeiten der Einsendung ist ein Fehler aufgetreten"); if (isset($result['content'])) { $content = Process::decodeProcess($result['content']); $submission->setStatus($content->getStatus()); $submission->addMessages($content->getMessages()); } break; } } } if ($fail) { if (isset($submission)) { $submission->setFile(null); } $res[] = $submission; $this->app->response->setStatus(409); continue; } // upload submission $uploadSubmission = $process->getSubmission(); if ($uploadSubmission === null) { $uploadSubmission = $process->getRawSubmission(); if ($uploadSubmission->getFile() != null) { $file = $uploadSubmission->getFile(); if ($file->getDisplayName() == null) { $file->setDisplayName($submission->getExerciseName()); } } } if ($uploadSubmission !== null) { ///echo Submission::encodeSubmission($uploadSubmission);return; $result = Request::routeRequest('POST', '/submission', array(), Submission::encodeSubmission($uploadSubmission), $this->_submission, 'submission'); //var_dump($result);return; // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299) { $queryResult = Submission::decodeSubmission($result['content']); $uploadSubmission->setId($queryResult->getId()); $uploadSubmission->setFile($queryResult->getFile()); if ($process->getMarking() !== null) { $process->getMarking()->setSubmission($queryResult); } } else { $uploadSubmission->addMessage("Beim Speichern der Einsendung ist ein Fehler aufgetreten."); //var_dump($uploadSubmission); return; if (isset($result['content'])) { $content = Submission::decodeSubmission($result['content']); $uploadSubmission->setStatus($content->getStatus()); $uploadSubmission->addMessages($content->getMessages()); } $uploadSubmission->setStatus(409); $res[] = $uploadSubmission; $this->app->response->setStatus(409); continue; } } // upload marking if ($process->getMarking() !== null) { //echo Marking::encodeMarking($process->getMarking()); $result = Request::routeRequest('POST', '/marking', array(), Marking::encodeMarking($process->getMarking()), $this->_marking, 'marking'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299) { $queryResult = Marking::decodeMarking($result['content']); } else { $uploadSubmission->addMessage("Beim Speichern der Korrektur ist ein Fehler aufgetreten"); if (isset($result['content'])) { $content = Marking::decodeMarking($result['content']); $uploadSubmission->addMessages($content->getMessages()); } $res[] = $uploadSubmission; $this->app->response->setStatus(409); continue; } } $rr = $process->getSubmission(); if ($rr === null) { $rr = $process->getRawSubmission(); } $res[] = $rr; } if (!$arr && count($res) == 1) { $this->app->response->setBody(Submission::encodeSubmission($res[0])); } else { $this->app->response->setBody(Submission::encodeSubmission($res)); } }
/** * Returns whether the component is installed for the given course * * Called when this component receives an HTTP GET request to * /link/exists/course/$courseid/extension/$name(/). * * @param int $courseid The id of the course. * @param int $name The name of the component */ public function getExtensionInstalled($courseid, $name) { foreach ($this->_extension as $link) { if ($link->getTargetName() === $name || $link->getTarget() === $name) { $result = Request::routeRequest('GET', '/link/exists/course/' . $courseid, $this->app->request->headers->all(), '', $link, 'course'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299) { $this->app->response->setStatus(200); $this->app->response->setBody(null); if (isset($result['headers']['Content-Type'])) { $this->app->response->headers->set('Content-Type', $result['headers']['Content-Type']); } $this->app->stop(); } else { Logger::Log('POST GetExtensionInstalled failed', LogLevel::ERROR); $this->app->response->setStatus(isset($result['status']) ? $result['status'] : 409); $this->app->stop(); } } } $this->app->response->setStatus(404); $this->app->response->setBody(null); }
/** * Deletes a marking. * * Called when this component receives an HTTP DELETE request to * /marking/marking/$markingid(/). * * @param int $markingid The id of the marking that is being deleted. * * @author Till Uhlig * @date 2014 */ public function deleteMarking($markingid) { $result = Request::routeRequest('DELETE', '/marking/' . $markingid, $this->app->request->headers->all(), '', $this->_marking, 'marking'); if ($result['status'] >= 200 && $result['status'] <= 299) { // marking is deleted $this->app->response->setStatus(201); $this->app->response->setBody(''); if (isset($result['headers']['Content-Type'])) { $this->app->response->headers->set('Content-Type', $result['headers']['Content-Type']); } } else { Logger::Log('DELETE DeleteMarking failed', LogLevel::ERROR); $this->app->response->setStatus(isset($result['status']) ? $result['status'] : 409); $this->app->response->setBody(''); $this->app->stop(); } }
/** * Führt eine Anfrage über $linkName aus, wobei eine Verbindung mit der URI $order genutzt wird * * @param string $linkName Der Name des Ausgangs * @param mixed[] $params Die Ersetzungen für die Platzhalter des Befehls (Bsp.: array('uid'=>2,'cid'=>1) * @param string body Der Inhalt der Anfrage für POST und PUT * @param int $positiveStatus Der Status, welcher als erfolgreiche Antwort gesehen wird (Bsp.: 200) * @param callable $positiveMethod Im positiven Fall wird diese Methode aufgerufen * @param mixed[] $positiveParams Die Werte, welche an die positive Funktion übergeben werden * @param callable $negativeMethod Im negativen Fall wird diese Methode aufgerufen * @param mixed[] $negativeParams Die Werte, welche an die negative Funktion übergeben werden * @param string returnType Ein optionaler Rückgabetyp (es können Structures angegeben werden, sodass automatisch Typ::encodeType() ausgelöst wird) * @return mixed Das Ergebnis der aufgerufenen Resultatfunktion */ public function callByURI($linkName, $order, $params, $body, $positiveStatus, callable $positiveMethod, $positiveParams, callable $negativeMethod, $negativeParams, $returnType = null) { $links = CConfig::getLinks($this->_conf->getLinks(), $linkName); $link = null; $instructions = $this->_com->instruction('', true); // ermittle den zutreffenden Ausgang $selectedInstruction = null; foreach ($instructions as $instruction) { if ($instruction['name'] == $linkName) { $selectedInstruction = $instruction; break; } } if (isset($selectedInstruction['links'][0]['path']) && $selectedInstruction['links'][0]['path'] == $order) { $link = $links[0]; } else { foreach ($links as $li) { $testPath = $li->getPath(); $met = strpos($testPath, ' '); if ($met !== false) { $testPath = substr($testPath, $met + 1); foreach ($params as $key => $param) { $testPath = str_replace(':' . $key, $param, $testPath); } if ($testPath == $order) { $link = $li; break; } } } } if ($link == null) { return call_user_func_array($negativeMethod, $negativeParams); } $method = 'GET'; if ($link->getPath() !== null && $link->getPath() !== '') { $order = $link->getPath(); $met = strpos($order, ' '); if ($met !== false) { $method = substr($order, 0, $met); $order = substr($order, $met + 1); } else { return call_user_func_array($negativeMethod, $negativeParams); } } else { $order = $selectedInstruction['links'][0]['path']; if (isset($selectedInstruction['links'][0]['method'])) { $method = $selectedInstruction['links'][0]['method']; } } // ersetzt die Platzer im Ausgang mit den eingegeben Parametern foreach ($params as $key => $param) { $order = str_replace(':' . $key, $param, $order); } // führe nun den Aufruf aus $result = Request::routeRequest($method, $order, array(), $body, $link); if ($result['status'] == $positiveStatus) { // die Antwort war so, wie wir sie erwartet haben if ($returnType !== null) { // wenn ein erwarteter Rückgabetyp angegeben wurde, wird eine Typ::decodeType() ausgeführt $result['content'] = call_user_func_array('\\' . $returnType . '::decode' . $returnType, array($result['content'])); if (!is_array($result['content'])) { $result['content'] = array($result['content']); } } // rufe nun die positive Methode auf return call_user_func_array($positiveMethod, array_merge(array("input" => $result['content']), $positiveParams)); } // ansonsten rufen wir die negative Methode auf return call_user_func_array($negativeMethod, $negativeParams); }
/** * Returns whether the component is installed for the given course * * Called when this component receives an HTTP GET request to * /link/exists/course/$courseid(/). * * @param int $courseid A course id. */ public function getExistsCourse($courseid) { // hier soll geprüft werden, ob ein entsprechender Eintrag für diese Komponente in der referenzierten Prozesstabelle besteht, // ob sie also als Verarbeitung registriert ist (dazu wird die ID dieser Komponente verwendet ($this->_conf->getId())) $result = Request::routeRequest('GET', '/process/course/' . $courseid . '/component/' . $this->_conf->getId(), array(), '', $this->_getProcess, 'process'); // wenn etwas für die ID dieser Komponente von der DB geantwortet wird, ist die Installation korrekt bzw. vorhanden. if (isset($result['status']) && $result['status'] >= 200 && $result['status'] <= 299 && isset($result['content']) && $this->_conf !== null && $this->_conf->getId() !== null) { $this->app->response->setStatus(200); $this->app->stop(); } // die Datenbank hat keinen Eintrag für diese Komponente geliefert oder ein sonstiger Fehler ist aufgetreten, daher // gilt die Installation als nicht vorhanden/korrekt $this->app->response->setStatus(409); }
/** * Adds an attachment. * * Called when this component receives an HTTP POST request to * /attachment(/). * The request body should contain a JSON object representing the * attachment's attributes. */ public function addAttachment() { $header = $this->app->request->headers->all(); $body = $this->app->request->getBody(); $fileObjects = Attachment::decodeAttachment($body); // always been an array $arr = true; if (!is_array($fileObjects)) { $fileObjects = array($fileObjects); $arr = false; } $res = array(); $files = array(); foreach ($fileObjects as $fileObject) { $files[] = $fileObject->getFile(); } //add the Files $result = Request::routeRequest('POST', '/file', array(), File::encodeFile($files), $this->_postFile, 'file'); $tempFiles = File::decodeFile($result['content']); // checks the correctness of the query if ($result['status'] === 201 && isset($result['content'])) { // upload files $countObjects = count($fileObjects); for ($i = 0; $i < $countObjects; $i++) { if ($tempFiles[$i]->getStatus() === 201) { $fileObjects[$i]->setFile($tempFiles[$i]); if ($files[$i] !== null) { $files[$i]->setStatus(201); } } else { $fileObjects[$i]->setStatus(409); $fileObjects[$i]->addMessage("Die Datei konnte nicht gespeichert werden."); if ($files[$i] !== null) { $files[$i]->setBody(); } } } } else { $this->app->response->setStatus(409); $this->app->response->setBody(Attachment::encodeAttachment(new Attachment())); $this->app->stop(); } // upload attachments $result = Request::routeRequest('POST', '/attachment', array(), Attachment::encodeAttachment($fileObjects), $this->_postAttachment, 'attachment'); if ($result['status'] === 201 && isset($result['content'])) { $tempAttachments = Attachment::decodeAttachment($result['content']); $countObjects = count($fileObjects); for ($i = 0; $i < $countObjects; $i++) { $fileObjects[$i]->setStatus($tempAttachments[$i]->getStatus()); $fileObjects[$i]->addMessages($tempAttachments[$i]->getMessages()); if ($tempAttachments[$i]->getStatus() !== 201) { $fileObjects[$i]->addMessage('Anhang konnte nicht erstellt werden.'); $fileObjects[$i]->getFile()->setBody(); } else { $fileObjects[$i]->setId($tempAttachments[$i]->getId()); } $res[] = $fileObjects[$i]; } } else { $this->app->response->setStatus(409); $this->app->response->setBody(Attachment::encodeAttachment(new Attachment())); $this->app->stop(); } if (!$arr && count($res) == 1) { $res = $res[0]; } $this->app->response->setBody(Attachment::encodeAttachment($res)); $this->app->response->setStatus(201); }
/** * Deletes a course. * * Called when this component receives an HTTP DELETE request to * /course/course/$courseid(/). * * @param int $courseid The id of the course that is being deleted. * * @author Till Uhlig * @date 2014 */ public function deleteCourse($courseid) { Logger::Log('starts DELETE DeleteCourse', LogLevel::DEBUG); $this->app->response->setStatus(201); $header = $this->app->request->headers->all(); $courseid = DBJson::mysql_real_escape_string($courseid); foreach ($this->_deleteCourse as $_link) { $result = Request::routeRequest('DELETE', '/course/' . $courseid, $header, '', $_link, 'course'); // checks the correctness of the query if ($result['status'] == 201) { // ok } else { Logger::Log('DELETE DeleteCourse failed', LogLevel::ERROR); $this->app->response->setStatus(isset($result['status']) ? $result['status'] : 409); $this->app->stop(); } } }
/** * Deletes an exercise sheet. * * Called when this component receives an HTTP DELETE request to * /exercisesheet/exercisesheet/$sheetid(/). * Deletes the exercise sheet information from the database first. At success * the file belongs to this exercise will be deleted from the filesystem. * * @param int $sheetid The id of the exercise sheet that is being deleted. */ public function deleteExerciseSheet($sheetid) { $this->app->response->setStatus(201); Logger::Log('starts DELETE DeleteExerciseSheet', LogLevel::DEBUG); $body = $this->app->request->getBody(); $res = null; // getExerciseSheet $result = Request::routeRequest('GET', '/exercisesheet/' . $sheetid, array(), '', $this->_getExerciseSheet, 'exercisesheet'); // checks the correctness of the query if ($result['status'] >= 200 && $result['status'] <= 299 && isset($result['content'])) { $exerciseSheet = ExerciseSheet::decodeExerciseSheet($result['content']); $sampleFile = $exerciseSheet->getSampleSolution(); $sheetFile = $exerciseSheet->getSheetFile(); // delete exerciseSheet $result = Request::routeRequest('DELETE', '/exercisesheet/' . $sheetid, array(), '', $this->_deleteExerciseSheet, 'exercisesheet'); if ($result['status'] >= 200 && $result['status'] <= 299) { // exerciseSheet is deleted // delete sampleSolution if exists if ($sampleFile !== null) { $result = Request::routeRequest('DELETE', '/file/' . $sampleFile->getFileId(), array(), '', $this->_deleteFile, 'file'); } // delete sheetFile if exists if ($sheetFile !== null) { $result = Request::routeRequest('DELETE', '/file/' . $sheetFile->getFileId(), array(), '', $this->_deleteFile, 'file'); } $res = new ExerciseSheet(); } else { $res = null; $this->app->response->setStatus(409); } } else { $res = null; $this->app->response->setStatus(409); } if ($this->app->response->getStatus() != 201) { Logger::Log('DELETE DeleteExerciseSheet failed', LogLevel::ERROR); } $this->app->response->setBody(ExerciseSheet::encodeExerciseSheet($res)); }
public function uploadZip($userid, $courseid) { // error array of strings $errors = array(); LTutor::generatepath($this->config['DIR']['temp']); $tempDir = $this->tempdir($this->config['DIR']['temp'], 'extractZip', $mode = 0775); $body = File::decodeFile($this->app->request->getBody()); //1 file-Object $filename = $tempDir . '/' . $courseid . '.zip'; file_put_contents($filename, $body->getBody(true)); unset($body); $zip = new ZipArchive(); $zip->open($filename); $zip->extractTo($tempDir . '/files'); $zip->close(); unlink($filename); ///$this->deleteDir(dirname($filename)); unset($zip); $files = $tempDir . '/files'; // check if csv file exists if (file_exists($files . '/Liste.csv')) { $csv = fopen($files . '/Liste.csv', "r"); if (($transactionId = fgetcsv($csv, 0, ';')) === false) { fclose($csv); $this->deleteDir($tempDir); $this->app->response->setStatus(409); $errors[] = 'empty .csv file'; $this->app->response->setBody(json_encode($errors)); $this->app->stop(); } $result = Request::routeRequest('GET', '/transaction/authentication/TutorCSV_' . $userid . '_' . $courseid . '/transaction/' . $transactionId[0], array(), '', $this->_getTransaction, 'transaction'); if (isset($result['status']) && $result['status'] == 200 && isset($result['content'])) { $transaction = Transaction::decodeTransaction($result['content']); $transaction = json_decode($transaction->getContent(), true); unset($result); $defaultOrder = array('ID', 'NAME', 'USERNAME', 'POINTS', 'MAXPOINTS', 'OUTSTANDING', 'STATUS', 'TUTORCOMMENT', 'STUDENTCOMMENT', 'FILE'); $currectOrder = $defaultOrder; $markings = array(); while (($row = fgetcsv($csv, 0, ';')) !== false) { if (substr($row[0], 0, 2) == '--') { $row[0] = substr($row[0], 2); if (in_array(strtoupper($row[0]), $defaultOrder)) { $currectOrder = array(); foreach ($row as $ro) { $currectOrder[strtoupper($ro)] = count($currectOrder); } } } elseif (implode('', $row) != '' && substr($row[0], 0, 2) != '--') { if (isset($currectOrder['ID']) && !isset($row[$currectOrder['ID']]) || isset($currectOrder['POINTS']) && !isset($row[$currectOrder['POINTS']]) || isset($currectOrder['FILE']) && !isset($row[$currectOrder['FILE']]) || isset($currectOrder['TUTORCOMMENT']) && !isset($row[$currectOrder['TUTORCOMMENT']]) || isset($currectOrder['OUTSTANDING']) && !isset($row[$currectOrder['OUTSTANDING']]) || isset($currectOrder['STATUS']) && !isset($row[$currectOrder['STATUS']])) { $errors[] = 'invalid Liste.csv'; fclose($csv); $this->deleteDir($tempDir); $this->app->response->setStatus(409); $this->app->response->setBody(json_encode($errors)); $this->app->stop(); } $markingId = isset($currectOrder['ID']) ? $row[$currectOrder['ID']] : null; $points = isset($currectOrder['POINTS']) ? $row[$currectOrder['POINTS']] : null; $points = str_replace(',', '.', $points); $markingFile = isset($currectOrder['FILE']) ? $row[$currectOrder['FILE']] : null; // check if markingId exists in transaction if (!isset($transaction['markings'][$markingId])) { // unknown markingId fclose($csv); $this->deleteDir($tempDir); $this->app->response->setStatus(409); $errors[] = "unknown ID: {$markingId}"; $this->app->response->setBody(json_encode($errors)); $this->app->stop(); } ///var_dump($transaction['markings'][$markingId]); $markingData = $transaction['markings'][$markingId]; // checks whether the points are less or equal to the maximum points if ($points > $markingData['maxPoints'] || $points < 0) { // too much points ///fclose($csv); ///$this->deleteDir($tempDir); ///$this->app->response->setStatus(409); ///$errors[] = "incorrect points in marking: {$markingId}"; ///$this->app->response->setBody(json_encode($errors)); ///$this->app->stop(); } // checks if file with this markingid exists if ($markingFile == null || $markingFile == '' || file_exists($files . '/' . $markingFile)) { if ($markingFile != '' && $markingFile != null) { $fileAddress = $files . '/' . $markingFile; ///file_get_contents($files.'/'.$markingFile); // file $fileInfo = pathinfo($markingFile); $file = new File(); $file->setDisplayName($fileInfo['basename']); $file->setBody(Reference::createReference($fileAddress)); } else { $file = null; } if (isset($transaction['markings'][$markingId]['submissionId']) && $transaction['markings'][$markingId]['submissionId'] < 0) { // create new submission object $submissionId = $transaction['markings'][$markingId]['submissionId']; $studentId = $transaction['markings'][$markingId]['studentId']; $exerciseId = $transaction['markings'][$markingId]['exerciseId']; $submission = Submission::createSubmission(null, $studentId, null, $exerciseId, null, 1, time(), null, $leaderId, 1); $submission->setSelectedForGroup('1'); ///echo json_encode($submission);return; $result = Request::routeRequest('POST', '/submission', array(), json_encode($submission), $this->_postSubmission, 'submission'); if ($result['status'] == 201) { $transaction['markings'][$markingId]['submissionId'] = json_decode($result['content'], true)['id']; } } // create new marking object $marking = Marking::createMarking($markingId < 0 ? null : $markingId, $userid, null, $transaction['markings'][$markingId]['submissionId'], isset($currectOrder['TUTORCOMMENT']) ? $row[$currectOrder['TUTORCOMMENT']] : null, isset($currectOrder['OUTSTANDING']) ? $row[$currectOrder['OUTSTANDING']] : null, isset($currectOrder['STATUS']) ? $row[$currectOrder['STATUS']] : null, $points, time(), $file == null ? 1 : 0); $marking->setFile($file); /*array( 'id' => ($markingId<0 ? null : $markingId), 'points' => $points, 'outstanding' => isset($currectOrder['OUTSTANDING']) ? $row[$currectOrder['OUTSTANDING']] : null, 'tutorId' => $userid, 'tutorComment' => isset($currectOrder['TUTORCOMMENT']) ? $row[$currectOrder['TUTORCOMMENT']] : null, 'file' => $file, 'status' => isset($currectOrder['STATUS']) ? $row[$currectOrder['STATUS']] : null, 'date' => time(), 'hideFile' => );*/ $markings[] = $marking; } else { //if file with this markingid not exists $errors[] = 'File does not exist: ' . $markingFile; fclose($csv); $this->deleteDir($tempDir); $this->app->response->setStatus(409); $this->app->response->setBody(json_encode($errors)); $this->app->stop(); } } } $mark = @json_encode($markings); if ($mark !== false) { ///echo json_encode($markings); return; //request to database to edit the markings $result = Request::routeRequest('POST', '/marking', array(), $mark, $this->_postMarking, 'marking'); /// TODO: prüfen ob jede hochgeladen wurde if ($result['status'] != 201) { $errors[] = 'send markings failed'; } } else { $errors[] = 'invalid input'; } } else { $errors[] = 'no transaction data'; } fclose($csv); } else { // if csv file does not exist $errors[] = '.csv file does not exist in uploaded zip-Archiv'; } $this->deleteDir($tempDir); $this->app->response->setBody(json_encode($errors)); if (!($errors == array())) { $this->app->response->setStatus(409); } }
/** * Deletes a file. * * This function handles the reqest to the DBFile table to delete the information * belongs to this file as well as the request * to the filesystem to delete the file. * * @param string $database The link of the database. * @param string $filesystem The link of the filesystem. * @param array $header The header of the request. * @param array $file The file that should being deleted. */ public static function delete($database, $filesystem, $header, $file) { if ($file !== null && $file !== array()) { // requests to file-table of DB $answer = Request::routeRequest('DELETE', '/file/' . $file->getFileId(), $header, '', $database, 'file'); // even if file has been deleted from db file table delete it from fs if ($answer['status'] >= 200 && $answer['status'] <= 299 && isset($answer['content']) && !empty($answer['content'])) { $file = File::decodeFile($answer['content']); if (is_object($file) && $file->getAddress() !== null) { // requests to filesystem $answer = Request::routeRequest('DELETE', '/' . $file->getAddress(), $header, '', $filesystem, 'file'); if ($answer['status'] >= 200 && $answer['status'] <= 299) { return File::decodeFile($answer['content']); } else { return null; } } else { return null; } } else { return $file; } } else { return null; } }