<?php use asm\core\Config, asm\core\Core, asm\utils\ErrorHandler, asm\core\UiResponse, asm\core\Error; /** * @file * Handles core requests coming from UI. * * 1. Starts session. * 2. Starts the Composer autoloader. * 3. Loads configuration from the config.ini and internal.ini files. * 4. Activates the custom error handler. * 5. Calls Core::handleUiRequest with data from user. */ // Session is used to keep track of logged in user, and is used for file uploads. session_start(); // Load up the Composer-generated autoloader. All PHP classes are loaded using this autoloader. require_once __DIR__ . "/../vendor/autoload.php"; // Load configuration from the "config.ini" file. Config::init(__DIR__ . '/config.ini', __DIR__ . '/internal.ini'); // If ever an exception occurs or a PHP error occurs, log it and send it to the user. ErrorHandler::register(); ErrorHandler::bind(['asm\\core\\Core', 'logException']); ErrorHandler::bind(function (Exception $e) { Core::sendUiResponse(UiResponse::create([], [Error::create(Error::levelFatal, $e->getMessage() . "[details: code " . $e->getCode() . ", file " . $e->getFile() . ", line " . $e->getLine() . ", trace: \n" . $e->getTraceAsString() . "]", \asm\core\lang\Language::get(\asm\core\lang\StringID::ServerSideRuntimeError))])); }); // Process the AJAX request. // Usually, the Javascript part of XML Check sends a POST request but in some special cases, a GET request is needed. Core::handleUiRequest(empty($_POST) ? $_GET : $_POST, $_FILES);
protected function body() { // Validate input. $inputs = array('group' => 'isIndex', 'problem' => 'isIndex', 'deadline' => 'isDate', 'reward' => 'isNonNegativeInt'); if (!$this->isInputValid($inputs)) { return false; } // Load input $id = $this->getParams('id'); $group = $this->getParams('group'); $problem = $this->getParams('problem'); $deadline = $this->getParams('deadline'); $reward = $this->getParams('reward'); // Adjust input $deadline = $deadline . ' 23:59:59'; // Load from database /** * @var $groupEntity \Group * @var $assignmentEntity \Assignment * @var $problemEntity \Problem */ $groupEntity = Repositories::getEntityManager()->find('Group', $group); $problemEntity = Repositories::getEntityManager()->find('Problem', $problem); if ($groupEntity === null || $problemEntity === null) { return $this->stop('Group or problem does not exist.', 'Assignment cannot be edited.'); } // Authenticate $user = User::instance(); if (!$user->hasPrivileges(User::groupsManageAll) && (!$user->hasPrivileges(User::groupsManageOwn) || $groupEntity->getOwner()->getId() !== $user->getId())) { return $this->stop(Language::get(StringID::InsufficientPrivileges)); } // Already exists? if ($id !== null && $id !== '') { $assignmentEntity = Repositories::getEntityManager()->find('Assignment', $id); $assignmentEntity->setDeadline(\DateTime::createFromFormat("Y-m-d H:i:s", $deadline)); $assignmentEntity->setReward($reward); Repositories::getEntityManager()->persist($assignmentEntity); Repositories::getEntityManager()->flush($assignmentEntity); } else { // Verify integrity if ($problemEntity->getLecture()->getId() !== $groupEntity->getLecture()->getId()) { return $this->stop('You are adding an assignment for problem belonging to lecture X to a group that belongs to lecture Y. This is not possible.'); } // Create new $assignmentEntity = new \Assignment(); $assignmentEntity->setGroup($groupEntity); $assignmentEntity->setProblem($problemEntity); $assignmentEntity->setDeadline(\DateTime::createFromFormat("Y-m-d H:i:s", $deadline)); $assignmentEntity->setReward($reward); Repositories::getEntityManager()->persist($assignmentEntity); Repositories::getEntityManager()->flush($assignmentEntity); // Send e-mail /** * @var $subscription \Subscription */ $query = Repositories::getEntityManager()->createQuery('SELECT s, u FROM Subscription s JOIN s.user u WHERE s.group = :group'); $query->setParameter('group', $groupEntity); $subscriptions = $query->getResult(); foreach ($subscriptions as $subscription) { if (!$subscription->getUser()->getSendEmailOnNewAssignment()) { continue; } $to = $subscription->getUser()->getEmail(); $email = file_get_contents(Config::get("paths", "newAssignmentEmail")); $email = str_replace("%{Problem}", $problemEntity->getName(), $email); $email = str_replace("%{Deadline}", $deadline, $email); $email = str_replace("%{Group}", $groupEntity->getName(), $email); $email = str_replace("%{Link}", Config::getHttpRoot() . "#studentAssignments#" . $assignmentEntity->getId(), $email); $email = str_replace("%{Date}", date("Y-m-d H:i:s"), $email); $lines = explode("\n", $email); $subject = $lines[0]; // The first line is subject. $text = preg_replace('/^.*\\n/', '', $email); // Everything except the first line. if (!Core::sendEmail($to, trim($subject), $text)) { Core::logError(Error::create(Error::levelWarning, "E-mail could not be sent to {$to}.")); } } } return true; }
/** * Logs supplied exception. * @param Exception $e * @see logError() */ public static function logException(Exception $e) { self::logError(Error::create(Error::levelFatal, self::getCustomMessage($e), 'Runtime error', self::getCustomTrace($e))); }
/** * Stores error (warning, notice) to be appended to script output. * * Sets @ref $failed flag to true if error is level is Error::levelError or higher. * @param int $level error severity (@ref Error "Error::level*" constant) * @param mixed $cause error cause code (int) or message (string) * @param string $effect error effect * @param string $details additional error info * @see getErrors() * @see clearErrors() */ protected final function addError($level, $cause, $effect = null, $details = null) { $this->errors[] = Error::create($level, $cause, $effect, $details); if ($level >= Error::levelError) { $this->failed = true; } }