protected function body()
 {
     if (!$this->userHasPrivileges(User::groupsJoinPrivate, User::groupsJoinPublic, User::groupsRequest)) {
         return false;
     }
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $groupId = $this->getParams('id');
     /**
      * @var $group \Group
      */
     $group = Repositories::findEntity(Repositories::Group, $groupId);
     // Calculate privileges of the user
     $user = User::instance();
     $canJoinPrivate = User::instance()->hasPrivileges(User::groupsJoinPrivate);
     $groupIsPrivate = $group->getType() == \Group::TYPE_PRIVATE;
     $hasSufficientPrivileges = $groupIsPrivate && ($canJoinPrivate || $user->hasPrivileges(User::groupsRequest)) || !$groupIsPrivate && $user->hasPrivileges(User::groupsJoinPublic);
     if (!$hasSufficientPrivileges) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     $status = $canJoinPrivate || !$groupIsPrivate ? \Subscription::STATUS_SUBSCRIBED : \Subscription::STATUS_REQUESTED;
     // Put into database
     $subscription = new \Subscription();
     $subscription->setGroup($group);
     $subscription->setUser(User::instance()->getEntity());
     $subscription->setStatus($status);
     Repositories::persistAndFlush($subscription);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $question \Question
      */
     $question = Repositories::findEntity(Repositories::Question, $id);
     if (!$this->authorizedToManageLecture($question->getLecture())) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     // What if some tests refer to this question? Then the deletion should not be permitted.
     /**
      * @var $xtests \Xtest[]
      */
     $xtests = Repositories::getRepository(Repositories::Xtest)->findAll();
     foreach ($xtests as $xtest) {
         $templateArray = explode(',', $xtest->getTemplate());
         if (in_array($question->getId(), $templateArray)) {
             return $this->death(StringID::CannotDeleteQuestionThatsPartOfATest);
         }
     }
     Repositories::remove($question);
     return true;
 }
 /**
  * Deletes the usertype specified by ID.
  * @return bool Was it successful?
  */
 protected function body()
 {
     if (!$this->userHasPrivileges(User::usersPrivPresets)) {
         return false;
     }
     if (!$this->isInputSet('id')) {
         return false;
     }
     $id = $this->getParams('id');
     if ($id == Repositories::StudentUserType) {
         return $this->death(StringID::CannotRemoveBasicStudentType);
     }
     /**
      * @var $deletedType \UserType
      */
     $deletedType = Repositories::findEntity(Repositories::UserType, $id);
     $users = Repositories::getRepository(Repositories::User)->findBy(['type' => $id]);
     /** @var \UserType $studentType */
     $studentType = Repositories::findEntity(Repositories::UserType, Repositories::StudentUserType);
     foreach ($users as $user) {
         /** @var $user \User */
         $user->setType($studentType);
         Repositories::persist($user);
     }
     Repositories::remove($deletedType);
     Repositories::flushAll();
     return true;
 }
 protected function body()
 {
     $inputs = array('name' => array('isNotEmpty'), 'description' => 'isNotEmpty');
     if (!$this->isInputValid($inputs)) {
         return false;
     }
     $name = $this->getParams('name');
     $description = $this->getParams('description');
     $id = $this->getParams('id');
     $isIdSet = $id !== null && $id !== '';
     $user = User::instance();
     $userId = $user->getId();
     if (!$isIdSet) {
         if (!$this->userHasPrivileges(User::lecturesAdd)) {
             return false;
         }
         $lecture = new \Lecture();
         $lecture->setName($name);
         $lecture->setDescription($description);
         $lecture->setOwner(User::instance()->getEntity());
         Repositories::persistAndFlush($lecture);
     } else {
         if ($isIdSet) {
             $lecture = Repositories::findEntity(Repositories::Lecture, $id);
             if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $lecture->getOwner()->getId() != $userId)) {
                 return $this->death(StringID::InsufficientPrivileges);
             }
             $lecture->setDescription($description);
             Repositories::persistAndFlush($lecture);
         }
     }
     return true;
 }
 protected function body()
 {
     $inputs = array('lecture' => 'isIndex', 'name' => array('isName', 'isNotEmpty'), 'type' => array('isEnum' => array('text', 'code', 'image')));
     if (!$this->isInputValid($inputs)) {
         return false;
     }
     $lectureId = $this->getParams('lecture');
     /** @var \Lecture $lecture */
     $lecture = Repositories::findEntity(Repositories::Lecture, $lectureId);
     $name = $this->getParams('name');
     $type = $this->getParams('type');
     $id = $this->getParams('id');
     $isIdSet = $id !== null && $id !== '';
     $originalName = $this->getUploadedFileName('file');
     if (!$originalName) {
         return false;
     }
     $extensionStart = strrpos($originalName, '.');
     $extension = $extensionStart === false ? '' : substr($originalName, strrpos($originalName, '.'));
     $attachmentFolder = Config::get('paths', 'attachments');
     $filename = $id . '_' . $name . $extension;
     if (!$this->checkTestGenerationPrivileges($lecture)) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     /**
      * @var $attachment \Attachment
      */
     $attachment = null;
     if (!$this->saveUploadedFile('file', $attachmentFolder . $filename)) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     /** @var \Attachment[] $attachmentsWithThisName */
     $attachmentsWithThisName = Repositories::getRepository(Repositories::Attachment)->findBy(['lecture' => $lectureId, 'name' => $name]);
     if ($isIdSet) {
         $attachment = Repositories::findEntity(Repositories::Attachment, $id);
         if (count($attachmentsWithThisName) > 0) {
             if ($attachmentsWithThisName[0]->getId() !== $attachment->getId()) {
                 return $this->death(StringID::AttachmentExists);
             }
         }
     } else {
         if (count($attachmentsWithThisName) > 0) {
             return $this->death(StringID::AttachmentExists);
         }
         $attachment = new \Attachment();
     }
     $attachment->setType($type);
     $attachment->setLecture($lecture);
     $attachment->setName($name);
     $attachment->setFile($filename);
     Repositories::persistAndFlush($attachment);
     return true;
 }
 protected function body()
 {
     $inputs = array('lecture' => 'isIndex', 'text' => 'isNotEmpty', 'type' => array('isEnum' => array('text', 'choice', 'multi')));
     if (!$this->isInputValid($inputs)) {
         return false;
     }
     $lectureId = $this->getParams('lecture');
     $text = $this->getParams('text');
     $type = $this->getParams('type');
     $id = $this->getParams('id');
     $isIdSet = $id !== null && $id !== '';
     $options = $this->getParams('options') . '';
     $attachments = $this->getParams('attachments') . '';
     if (!$this->checkTestGenerationPrivileges($lectureId)) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     $visibleAttachments = CommonQueries::GetAttachmentsVisibleToActiveUser();
     $attTmp = $attachments ? explode(';', $attachments) : array();
     foreach ($visibleAttachments as $va) {
         $aId = $va->getId();
         $index = array_search($aId, $attTmp);
         if ($index !== false) {
             array_splice($attTmp, $index, 1);
             if ($va->getLecture()->getId() != $lectureId) {
                 return $this->death(StringID::AttachmentBelongsToAnotherLecture);
             }
         }
     }
     if (count($attTmp)) {
         return $this->stop(ErrorCause::invalidInput('Following attachment IDs are invalid or inaccessible: ' . implode(', ', $attTmp) . '.', 'attachments'));
     }
     /** @var \Question $question */
     $question = null;
     if (!$isIdSet) {
         $question = new \Question();
     } else {
         $question = Repositories::findEntity(Repositories::Question, $id);
         if ($question->getLecture()->getId() != $lectureId) {
             // This must be a weak comparison, because lectureId comes from user and is text.
             return $this->death(StringID::HackerError);
         }
     }
     $question->setAttachments($attachments);
     /** @var \Lecture $lecture */
     $lecture = Repositories::findEntity(Repositories::Lecture, $lectureId);
     $question->setLecture($lecture);
     $question->setOptions($options);
     $question->setText($text);
     $question->setType($type);
     Repositories::persistAndFlush($question);
     return true;
 }
 protected final function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /** @var \XTest $test */
     $test = Repositories::findEntity(Repositories::Xtest, $id);
     $description = $test->getDescription();
     $questions = $test->getGenerated();
     $lecture = $test->getLecture();
     $user = User::instance();
     if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $lecture->getOwner()->getId() != $user->getId())) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     if (!$questions) {
         return $this->stop('the test has not been generated yet', 'cannot create test');
     }
     $questions = explode(',', $questions);
     $selectedQuestions = array();
     $attachmentIds = array();
     foreach ($questions as $questionId) {
         /** @var \Question $qData */
         $qData = Repositories::findEntity(Repositories::Question, $questionId);
         $options = $qData->getOptions();
         $options = $options ? explode($options[0], substr($options, 1)) : array();
         $qAtt = $qData->getAttachments();
         $qAtt = $qAtt ? explode(';', $qAtt) : array();
         array_push($selectedQuestions, array('text' => $qData->getText(), 'type' => $qData->getType(), 'options' => $options, 'attachments' => $qAtt));
         $attachmentIds = array_merge($attachmentIds, $qAtt);
     }
     $attachmentIds = array_unique($attachmentIds);
     $reverseIndex = array_flip($attachmentIds);
     foreach ($selectedQuestions as &$selQ) {
         $translated = array();
         foreach ($selQ['attachments'] as $selA) {
             array_push($translated, $reverseIndex[$selA] + 1);
         }
         $selQ['attachments'] = $translated;
     }
     $attachments = array();
     $folder = Config::get('paths', 'attachments');
     foreach ($attachmentIds as $attachmentId) {
         /** @var \Attachment $aData */
         $aData = Repositories::findEntity(Repositories::Attachment, $attachmentId);
         array_push($attachments, array('id' => $aData->getId(), 'type' => $aData->getType(), 'file' => $folder . $aData->getFile()));
     }
     $this->setContentType('text/html');
     $this->generateTestHtml($description, $selectedQuestions, $attachments);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $subscription \Subscription
      */
     $subscription = Repositories::findEntity(Repositories::Subscription, $id);
     if ($subscription->getUser()->getId() !== User::instance()->getId()) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     Repositories::remove($subscription);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     /**
      * @var $lecture \Lecture
      */
     $lecture = Repositories::findEntity(Repositories::Lecture, $this->getParams('id'));
     $user = User::instance();
     if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $user->getId() != $lecture->getId())) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     RemovalManager::hideLectureItsProblemsGroupsQuestionsAttachmentsAndXtests($lecture);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputSet('id')) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $subscription \Subscription
      */
     $subscription = Repositories::findEntity(Repositories::Subscription, $id);
     if (User::instance()->getId() !== $subscription->getGroup()->getOwner()->getId()) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     $this->handleRequest($subscription);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     /**
      * @var $group \Group
      */
     $group = Repositories::findEntity(Repositories::Group, $this->getParams('id'));
     $user = User::instance();
     if (!$user->hasPrivileges(User::groupsManageAll) && (!$user->hasPrivileges(User::groupsManageOwn) || $user->getId() != $group->getOwner()->getId())) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     RemovalManager::hideGroupAndItsAssignments($group);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $xtest \Xtest
      */
     $xtest = Repositories::findEntity(Repositories::Xtest, $id);
     if (!$this->checkTestGenerationPrivileges($xtest->getLecture()->getId())) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     Repositories::remove($xtest);
     return true;
 }
 protected function body()
 {
     if (!$this->userHasPrivileges(User::usersRemove)) {
         return false;
     }
     if (!$this->isInputSet('id')) {
         return false;
     }
     $id = $this->getParams('id');
     if ($id == User::instance()->getId()) {
         return $this->death(StringID::YouCannotRemoveYourself);
     }
     /** @var \User $user */
     $user = Repositories::findEntity(Repositories::User, $id);
     RemovalManager::hideUserAndAllHeOwns($user);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     /**
      * @var $assignment \Assignment
      */
     $assignment = Repositories::findEntity(Repositories::Assignment, $this->getParams('id'));
     $user = User::instance();
     if (!$user->hasPrivileges(User::groupsManageAll) && (!$user->hasPrivileges(User::groupsManageOwn) || $user->getId() != $assignment->getGroup()->getOwner()->getId())) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     $assignment->setDeleted(true);
     Repositories::persistAndFlush($assignment);
     return true;
 }
 /**
  * Gets submission with supplied ID if it's accessible to user [stopping].
  * @param int $id submission ID
  * @return \Submission submission or false in case of failure
  */
 protected final function findAccessibleSubmissionById($id)
 {
     /**
      * @var $submission \Submission
      */
     $submission = Repositories::findEntity(Repositories::Submission, $id);
     $userId = User::instance()->getId();
     $authorId = $submission->getUser()->getId();
     $ownerId = $submission->getAssignment()->getGroup()->getOwner()->getId();
     if ($authorId !== $userId && $ownerId !== $userId) {
         if (User::instance()->hasPrivileges(User::groupsManageAll, User::lecturesManageAll, User::otherAdministration)) {
             return $submission;
         }
         return $this->death(StringID::InsufficientPrivileges);
     }
     return $submission;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $submission \Submission
      */
     $submission = Repositories::findEntity(Repositories::Submission, $id);
     $userId = User::instance()->getId();
     if ($submission->getUser()->getId() != $userId) {
         return $this->death(StringID::HackerError);
     }
     // First, if you handed something off previously, it is no longer handed off
     /**
      * @var $yourSubmissions \Submission[]
      */
     $yourSubmissions = Repositories::getRepository(Repositories::Submission)->findBy(['user' => $userId, 'assignment' => $submission->getAssignment()->getId()]);
     foreach ($yourSubmissions as $previouslyHandedOffSubmission) {
         if ($previouslyHandedOffSubmission->getStatus() == \Submission::STATUS_REQUESTING_GRADING || $previouslyHandedOffSubmission->getStatus() == \Submission::STATUS_LATEST) {
             $previouslyHandedOffSubmission->setStatus(\Submission::STATUS_NORMAL);
             Repositories::persistAndFlush($previouslyHandedOffSubmission);
         }
     }
     // Next, hand off the submission
     $submission->setStatus(\Submission::STATUS_REQUESTING_GRADING);
     Repositories::persistAndFlush($submission);
     $emailText = file_get_contents(Config::get("paths", "newSubmissionEmail"));
     $emailText = str_replace("%{RealName}", User::instance()->getRealName(), $emailText);
     $emailText = str_replace("%{Email}", User::instance()->getEmail(), $emailText);
     $emailText = str_replace("%{Link}", Config::getHttpRoot() . "#correctionAll#submission#" . $submission->getId(), $emailText);
     $lines = explode("\n", $emailText);
     $subject = $lines[0];
     // The first line is subject.
     $text = preg_replace('/^.*\\n/', '', $emailText);
     // Everything except the first line.
     $to = $submission->getAssignment()->getGroup()->getOwner();
     if ($to->getSendEmailOnNewSubmission()) {
         if (!Core::sendEmail($to->getEmail(), $subject, $text)) {
             return $this->death(StringID::MailError);
         }
     }
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $problem \Problem
      */
     $problem = Repositories::findEntity(Repositories::Problem, $id);
     $lecture = $problem->getLecture();
     $user = User::instance();
     if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $user->getId() != $lecture->getOwner())) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     RemovalManager::hideProblemAndItsAssignments($problem);
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $attachment \Attachment
      */
     $attachment = Repositories::findEntity(Repositories::Attachment, $id);
     $file = $attachment->getFile();
     $lecture = $attachment->getLecture();
     if (!$this->authorizedToManageLecture($lecture)) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     $this->doNotAttach();
     $this->setOutput(Config::get('paths', 'attachments') . $file);
     return true;
 }
 /**
  * Runs this script.
  * @return bool Is it successful?
  */
 protected function body()
 {
     if (!$this->isInputSet(array('id'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $submission \Submission
      */
     $submission = Repositories::findEntity(Repositories::Submission, $id);
     if ($submission->getUser()->getId() !== User::instance()->getId()) {
         return $this->death(StringID::InsufficientPrivileges);
     }
     if ($submission->getStatus() === \Submission::STATUS_GRADED) {
         return $this->death(StringID::CannotDeleteGradedSubmissions);
     }
     if ($submission->getStatus() === \Submission::STATUS_REQUESTING_GRADING) {
         return $this->death(StringID::CannotDeleteHandsoffSubmissions);
     }
     $status = $submission->getStatus();
     $submission->setStatus(\Submission::STATUS_DELETED);
     Repositories::persist($submission);
     // Make something else latest
     if ($status === \Submission::STATUS_LATEST) {
         $latestSubmission = null;
         /**
          * @var $submissions \Submission[]
          * @var $latestSubmission \Submission
          */
         $submissions = Repositories::getRepository(Repositories::Submission)->findBy(['status' => \Submission::STATUS_NORMAL, 'assignment' => $submission->getAssignment()->getId(), 'user' => User::instance()->getId()]);
         foreach ($submissions as $olderSolution) {
             if ($latestSubmission === null || $olderSolution->getDate() > $latestSubmission->getDate()) {
                 $latestSubmission = $olderSolution;
             }
         }
         if ($latestSubmission !== null) {
             $latestSubmission->setStatus(\Submission::STATUS_LATEST);
             Repositories::persist($latestSubmission);
         }
     }
     Repositories::flushAll();
     return true;
 }
 protected function body()
 {
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $attachment \Attachment
      */
     $attachment = Repositories::findEntity(Repositories::Attachment, $id);
     if (!$this->authorizedToManageLecture($attachment->getLecture())) {
         return false;
     }
     $folder = Config::get('paths', 'attachments');
     $file = $attachment->getFile();
     RemovalManager::deleteAttachmentById($id);
     Filesystem::removeFile($folder . $file);
     return true;
 }
 protected function body()
 {
     if (!$this->userHasPrivileges(User::pluginsRemove)) {
         return false;
     }
     if (!$this->isInputValid(array('id' => 'isIndex'))) {
         return false;
     }
     $id = $this->getParams('id');
     /**
      * @var $plugin \Plugin
      */
     $plugin = Repositories::findEntity(Repositories::Plugin, $id);
     $pluginFolder = Filesystem::combinePaths(Config::get('paths', 'plugins'), $plugin->getName());
     if (!Filesystem::removeDir($pluginFolder)) {
         return $this->death(StringID::FileSystemError);
     }
     RemovalManager::deletePluginById($id);
     return true;
 }
 protected function body()
 {
     $inputs = array('lecture' => 'isIndex', 'name' => 'isNotEmpty', 'description' => array());
     if (!$this->isInputValid($inputs)) {
         return false;
     }
     $lectureIndex = $this->getParams('lecture');
     $groupName = $this->getParams('name');
     $groupDescription = $this->getParams('description');
     $public = $this->paramExists('public') ? 'public' : 'private';
     $groupId = $this->getParams('id');
     $editing = $groupId !== null && $groupId !== '';
     $user = User::instance();
     /** @var \Lecture $lecture */
     $lecture = Repositories::findEntity(Repositories::Lecture, $lectureIndex);
     if ($editing) {
         /**
          * @var $group \Group
          */
         $group = Repositories::findEntity(Repositories::Group, $groupId);
         $group->setName($groupName);
         $group->setDescription($groupDescription);
         $group->setType($public);
         Repositories::persistAndFlush($group);
     } else {
         if (!$this->userHasPrivileges(User::groupsAdd)) {
             return $this->death(StringID::InsufficientPrivileges);
         }
         $group = new \Group();
         $group->setDeleted(false);
         $group->setDescription($groupDescription);
         $group->setLecture($lecture);
         $group->setName($groupName);
         $group->setOwner($user->getEntity());
         $group->setType($public);
         Repositories::persistAndFlush($group);
     }
     return true;
 }
 /**
  * Deletes test with supplied ID (with input & output files).
  * @param int $id test ID
  * @return array error properties provided by removalError() or retrievalError(),
  * or false in case of success
  */
 public static function deleteTestById($id)
 {
     /**
      * @var $test \PluginTest
      */
     $test = Repositories::findEntity(Repositories::PluginTest, $id);
     $testFolder = Config::get('paths', 'tests');
     // Delete input solution file
     if (is_file(Filesystem::combinePaths($testFolder, $test->getInput()))) {
         Filesystem::removeFile(Filesystem::combinePaths($testFolder, $test->getInput()));
     }
     // Delete plugin test output
     if (is_file(Filesystem::combinePaths($testFolder, $test->getOutput()))) {
         Filesystem::removeFile(Filesystem::combinePaths($testFolder, $test->getOutput()));
     }
     Repositories::remove($test);
     return false;
 }
Beispiel #24
0
 /**
  * Launches plugin and updates database with results.
  * @param string $pluginType one of 'php', 'java', or 'exe'
  * @param string $pluginFile plugin file path
  * @param string $inputFile input file path
  * @param boolean $isTest is this a plugin test or a submission? true if plugin test
  * @param int $rowId ID of row to be updated
  * @param array $arguments plugin arguments
  * @return bool true if no error occurred
  */
 public static function launchPlugin($pluginType, $pluginFile, $inputFile, $isTest, $rowId, $arguments = array())
 {
     try {
         $response = null;
         if (!is_file($pluginFile) || !is_file($inputFile)) {
             $error = "plugin file and/or input file don't exist";
         } else {
             array_unshift($arguments, $inputFile);
             $cwd = getcwd();
             chdir(dirname($pluginFile));
             switch ($pluginType) {
                 case 'php':
                     $launcher = new PhpLauncher();
                     ob_start();
                     $error = $launcher->launch($pluginFile, $arguments, $response);
                     ob_end_clean();
                     break;
                 case 'java':
                     $launcher = new JavaLauncher();
                     $error = $launcher->launch($pluginFile, $arguments, $responseString);
                     break;
                 case 'exe':
                     $launcher = new ExeLauncher();
                     $error = $launcher->launch($pluginFile, $arguments, $responseString);
                     break;
                 default:
                     $error = "unsupported plugin type '{$pluginType}'";
             }
             chdir($cwd);
         }
         if (!$error) {
             if (isset($responseString)) {
                 try {
                     $response = PluginResponse::fromXmlString($responseString);
                 } catch (Exception $ex) {
                     $response = PluginResponse::createError('Internal error. Plugin did not supply valid response XML and this error occurred: ' . $ex->getMessage() . '. Plugin instead supplied this response string: ' . $responseString);
                 }
             }
         } else {
             $response = PluginResponse::createError('Plugin cannot be launched (' . $error . ').');
         }
         $outputFile = $response->getOutput();
         if ($outputFile) {
             $outputFolder = Config::get('paths', 'output');
             $newFile = $outputFolder . date('Y-m-d_H-i-s_') . StringUtils::randomString(10) . '.zip';
             if (rename($outputFile, $newFile)) {
                 $outputFile = $newFile;
             } else {
                 $outputFile = 'tmp-file-rename-failed';
             }
         }
         /**
          * @var $pluginTest \PluginTest
          * @var $submission \Submission
          * @var $previousSubmissions \Submission[]
          */
         if ($isTest) {
             $pluginTest = Repositories::findEntity(Repositories::PluginTest, $rowId);
             $pluginTest->setStatus(\PluginTest::STATUS_COMPLETED);
             $pluginTest->setSuccess($response->getFulfillment());
             $pluginTest->setInfo($response->getDetails());
             $pluginTest->setOutput($outputFile);
             Repositories::persistAndFlush($pluginTest);
         } else {
             $submission = Repositories::findEntity(Repositories::Submission, $rowId);
             // There is a sort of a race condition in here.
             // It is, in theory, possible, that there will be two submissions with the "latest" status after all is done
             // This should not happen in practice, though, and even if it does, it will have negligible negative effects.
             $previousSubmissions = Repositories::makeDqlQuery("SELECT s FROM \\Submission s WHERE s.user = :sameUser AND s.assignment = :sameAssignment AND s.status != 'graded' AND s.status != 'deleted'")->setParameter('sameUser', $submission->getUser()->getId())->setParameter('sameAssignment', $submission->getAssignment()->getId())->getResult();
             foreach ($previousSubmissions as $previousSubmission) {
                 $previousSubmission->setStatus(\Submission::STATUS_NORMAL);
                 Repositories::getEntityManager()->persist($previousSubmission);
             }
             $submission->setStatus(\Submission::STATUS_LATEST);
             $submission->setInfo($response->getDetails());
             $submission->setSuccess($response->getFulfillment());
             $submission->setOutputfile($outputFile);
             Repositories::getEntityManager()->persist($submission);
             Repositories::flushAll();
         }
         return !$error;
     } catch (Exception $exception) {
         $errorInformation = "Internal error. Plugin launcher or plugin failed with an internal error. Exception information: " . $exception->getMessage() . " in " . $exception->getFile() . " at " . $exception->getLine();
         if ($isTest) {
             $pluginTest = Repositories::findEntity(Repositories::PluginTest, $rowId);
             $pluginTest->setStatus(\PluginTest::STATUS_COMPLETED);
             $pluginTest->setSuccess(0);
             $pluginTest->setInfo($errorInformation);
             Repositories::persistAndFlush($pluginTest);
         } else {
             $submission = Repositories::findEntity(Repositories::Submission, $rowId);
             $submission->setStatus(\Submission::STATUS_NORMAL);
             $submission->setInfo($errorInformation);
             Repositories::persistAndFlush($submission);
         }
         return false;
     }
 }
 /**
  * Runs this script.
  * @return bool Is it successful?
  * @throws \Exception Should never occur.
  */
 protected function body()
 {
     $inputs = array('name' => array('isAlphaNumeric', 'hasLength' => array('min_length' => Constants::UsernameMinLength, 'max_length' => Constants::UsernameMaxLength)), 'realname' => array('isNotEmpty', 'isName'), 'email' => 'isEmail', 'pass' => array(), 'repass' => array());
     if (!$this->isInputValid($inputs)) {
         return false;
     }
     // Extract input data
     $username = strtolower($this->getParams('name'));
     $realname = $this->getParams('realname');
     $email = $this->getParams('email');
     $pass = $this->getParams('pass');
     $repass = $this->getParams('repass');
     $id = $this->getParams('id');
     $type = $this->getParams('type');
     $user = null;
     $isIdSet = $id !== null && $id !== '';
     $isTypeSet = $type !== null && $type !== '';
     // Extract database data
     if ($id) {
         $user = Repositories::findEntity(Repositories::User, $id);
     }
     $userExists = $user != null;
     $sameNameUserExists = count(Repositories::getRepository(Repositories::User)->findBy(['name' => $username])) > 0;
     // Custom verification of input data
     if ($pass !== $repass) {
         return $this->death(StringID::InvalidInput);
     }
     if ($userExists) {
         if ((strlen($pass) < Constants::PasswordMinLength || strlen($pass) > Constants::PasswordMaxLength) && $pass !== "") {
             return $this->death(StringID::InvalidInput);
         }
     } else {
         // A new user must have full password
         if (strlen($pass) < Constants::PasswordMinLength || strlen($pass) > Constants::PasswordMaxLength) {
             return $this->death(StringID::InvalidInput);
         }
     }
     $code = '';
     $unhashedPass = $pass;
     $pass = Security::hash($pass, Security::HASHTYPE_PHPASS);
     $canAddUsers = User::instance()->hasPrivileges(User::usersAdd);
     $canEditUsers = User::instance()->hasPrivileges(User::usersManage);
     $isEditingSelf = $id == User::instance()->getId();
     // This must not be a strict comparison.
     /**
      * @var $user \User
      */
     if (!$userExists && !$sameNameUserExists) {
         if ($this->getParams('fromRegistrationForm')) {
             if ($type != Repositories::StudentUserType) {
                 return $this->death(StringID::InsufficientPrivileges);
             }
             $code = md5(uniqid(mt_rand(), true));
             $emailText = file_get_contents(Config::get("paths", "registrationEmail"));
             $emailText = str_replace("%{Username}", $username, $emailText);
             $emailText = str_replace("%{ActivationCode}", $code, $emailText);
             $emailText = str_replace("%{Link}", Config::getHttpRoot() . "#activate", $emailText);
             $lines = explode("\n", $emailText);
             $subject = $lines[0];
             // The first line is subject.
             $text = preg_replace('/^.*\\n/', '', $emailText);
             // Everything except the first line.
             $returnCode = Core::sendEmail($email, $subject, $text);
             if (!$returnCode) {
                 return $this->stop(ErrorCode::mail, 'user registration failed', 'email could not be sent');
             }
         } else {
             if (!$canAddUsers) {
                 return $this->death(StringID::InsufficientPrivileges);
             }
         }
         $user = new \User();
         /** @var \UserType $typeEntity */
         $typeEntity = Repositories::findEntity(Repositories::UserType, $type);
         $user->setType($typeEntity);
         $user->setPass($pass);
         $user->setName($username);
         $user->setEmail($email);
         $user->setActivationCode($code);
         $user->setEncryptionType(Security::HASHTYPE_PHPASS);
         $user->setRealName($realname);
         Repositories::persistAndFlush($user);
     } elseif ($isIdSet) {
         if (!$canEditUsers && ($isTypeSet || !$isEditingSelf)) {
             return $this->stop(ErrorCode::lowPrivileges, 'cannot edit data of users other than yourself');
         }
         $type = $isTypeSet ? $type : $user->getType()->getId();
         /** @var \UserType $typeEntity */
         $typeEntity = Repositories::findEntity(Repositories::UserType, $type);
         if ($unhashedPass) {
             $user->setPass($pass);
             $user->setEncryptionType(Security::HASHTYPE_PHPASS);
         }
         $user->setType($typeEntity);
         $user->setEmail($email);
         $user->setActivationCode('');
         $user->setRealName($realname);
         Repositories::persistAndFlush($user);
     } else {
         return $this->death(StringID::UserNameExists);
     }
     return true;
 }