From d721c1abf60ca6187ac0851176e6df974146aaa0 Mon Sep 17 00:00:00 2001 From: Gero Lueckemeyer <gero.lueckemeyer@hft-stuttgart.de> Date: Mon, 30 Oct 2023 22:55:14 +0100 Subject: [PATCH] changed variable name camel caps and inline comments according to moodle approval guidelines --- dta.zip | Bin 17975 -> 17729 bytes dta/db/upgrade.php | 2 - dta/lib.php | 3 +- dta/locallib.php | 156 +++++++++++++-------------------- dta/models/DtaResult.php | 40 +++++---- dta/utils/backend.php | 38 ++++---- dta/utils/database.php | 96 ++++++++++----------- dta/utils/view.php | 182 +++++++++++++++++++-------------------- 8 files changed, 240 insertions(+), 277 deletions(-) diff --git a/dta.zip b/dta.zip index 97275a3081dca3d9f2c3bec385c0939025ecf263..7132db0972680920d93e9542d6aa1a3cf551aeb0 100644 GIT binary patch delta 14985 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 AAOHXW delta 15220 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 F{{h*DpgaHo diff --git a/dta/db/upgrade.php b/dta/db/upgrade.php index 66321f5..7ee51ec 100644 --- a/dta/db/upgrade.php +++ b/dta/db/upgrade.php @@ -21,8 +21,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); - /** * Stub for upgrade code * @param int $oldversion diff --git a/dta/lib.php b/dta/lib.php index 058e217..155b3f2 100644 --- a/dta/lib.php +++ b/dta/lib.php @@ -20,7 +20,6 @@ * @package assignsubmission_dta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); /** * Serves assignment submissions and other files. @@ -85,4 +84,4 @@ function assignsubmission_dta_pluginfile( // Download MUST be forced - security! send_stored_file($file, 0, 0, true); -} \ No newline at end of file +} diff --git a/dta/locallib.php b/dta/locallib.php index 25bba02..04c78db 100644 --- a/dta/locallib.php +++ b/dta/locallib.php @@ -16,7 +16,7 @@ defined('MOODLE_INTERNAL') || die(); -// import various files logic is organized in +//Import various entity and application logic files. require_once($CFG->dirroot . '/mod/assign/submission/dta/models/DtaResult.php'); require_once($CFG->dirroot . '/mod/assign/submission/dta/utils/database.php'); require_once($CFG->dirroot . '/mod/assign/submission/dta/utils/backend.php'); @@ -30,18 +30,15 @@ require_once($CFG->dirroot . '/mod/assign/submission/dta/utils/view.php'); */ class assign_submission_dta extends assign_submission_plugin { - // broadly used in logic, parametrized for easier change + //Broadly used in logic, parametrized for easier change. const COMPONENT_NAME = "assignsubmission_dta"; - - // draft file area for dta tests to be uploaded by the teacher + //Draft file area for dta tests to be uploaded by the teacher. const ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST = "tests_draft_dta"; - // file area for dta tests to be uploaded by the teacher + //File area for dta tests to be uploaded by the teacher. const ASSIGNSUBMISSION_DTA_FILEAREA_TEST = "tests_dta"; - // file area for dta submission assignment + //File area for dta submission assignment. const ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION = "submissions_dta"; - // ========== abstract methods to be implemented ========== // - /** * get plugin name * @return string @@ -50,11 +47,6 @@ class assign_submission_dta extends assign_submission_plugin { return get_string("pluginname", self::COMPONENT_NAME); } - // ========== end of section ========== // - - // ========== parent methods overloaded ========== // - - // ===== assignment settings ===== // /** * Get default settings for assignment submission settings * @@ -62,37 +54,31 @@ class assign_submission_dta extends assign_submission_plugin { * @return void */ public function get_settings(MoodleQuickForm $mform): void { - // add draft filemanager to form + //Add draft filemanager to form. $mform->addElement( - // filemanager "filemanager", - // unique element name in form self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST, - // label shown to user left of filemanager get_string("submission_settings_label", self::COMPONENT_NAME), - // attributes null, - // options array $this->get_file_options(true) ); - // add help button to added filemanager + //Add help button to added filemanager. $mform->addHelpButton( - // form-unique element id to add button to + //Form-unique element id to which to add button. self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST, - // key to search for "submission_settings_label", - // language file to use + //Language file to use. self::COMPONENT_NAME ); - // only show filemanager, if our plugin is enabled + //Only show filemanager if plugin is enabled. $mform->hideIf( - // form-unique element id to hide + //Form-unique element id to hide. self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST, - // condition to check + //Condition to check. self::COMPONENT_NAME . '_enabled', - // state to match for hiding + //State to match for hiding. 'notchecked' ); } @@ -104,21 +90,16 @@ class assign_submission_dta extends assign_submission_plugin { * @param array $defaultvalues */ public function data_preprocessing(&$defaultvalues): void { - $draftitemid = file_get_submitted_draft_itemid(self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST); + //Get id of draft area for file manager creation. + $draftitemid = file_get_submitted_draft_itemid(self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST); - // prepare draft area with created draft filearea + //Prepare draft area with created draft filearea. file_prepare_draft_area( - // draft filemanager form-unique id $draftitemid, - // id of current assignment $this->assignment->get_context()->id, - // component name self::COMPONENT_NAME, - // proper filearea self::ASSIGNSUBMISSION_DTA_FILEAREA_TEST, - // entry id 0, - // options array? array('subdirs' => 0) ); @@ -133,69 +114,59 @@ class assign_submission_dta extends assign_submission_plugin { */ public function save_settings(stdClass $data): bool { - // if the assignment has no filemanager for our plugin just leave - $draftFileManagerId = self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST; - if (!isset($data->$draftFileManagerId)) { + //If the assignment has no filemanager for our plugin just leave. + $draftfilemanagerid = self::ASSIGNSUBMISSION_DTA_DRAFT_FILEAREA_TEST; + if (!isset($data->$draftfilemanagerid)) { return true; } - // store files from draft filearea to proper one + //Store files from draft filearea to final one. file_save_draft_area_files( - // form-unique element id of draft filemanager from the edit - $data->$draftFileManagerId, - // id of the assignment we edit right now + //Form-unique element id of draft filemanager from the edit. + $data->$draftfilemanagerid, + //Id of the assignment in edit. $this->assignment->get_context()->id, - // component name self::COMPONENT_NAME, - // proper file area self::ASSIGNSUBMISSION_DTA_FILEAREA_TEST, - // entry id 0 ); - // get files from proper filearea + //Get files from proper filearea. $fs = get_file_storage(); $files = $fs->get_area_files( - // id of current assignment + //Id of the current assignment. $this->assignment->get_context()->id, - // component name self::COMPONENT_NAME, - // proper filearea self::ASSIGNSUBMISSION_DTA_FILEAREA_TEST, - // entry id 0, - // ? 'id', - // ? false ); - // check if a file is uploaded + //Check if a file was uploaded. if (empty($files)) { \core\notification::error(get_string("no_testfile_warning", self::COMPONENT_NAME)); return true; } - // get file + //Get the file. $file = reset($files); - // send file to backend + //Send file to backend. return DtaBackendUtils::sendTestConfigToBackend($this->assignment, $file); } - // ===== student submission ===== // - /** * Add elements to submission form * * @param mixed $submission stdClass|null * @param MoodleQuickForm $mform * @param stdClass $data - * @param int $userid + * @param int $userid * @return bool */ public function get_form_elements_for_user($submissionorgrade, MoodleQuickForm $mform, stdClass $data, $userid): bool { - // prepare submission filearea + //Prepare submission filearea. $data = file_prepare_standard_filemanager( $data, 'tasks', @@ -206,27 +177,26 @@ class assign_submission_dta extends assign_submission_plugin { $submissionorgrade ? $submissionorgrade->id : 0 ); - // add filemanager to form + //Add filemanager to form. $mform->addElement( - // filemanager 'filemanager', - // form-unique identifier + //Form-unique identifier. 'tasks_filemanager', - // label to show next to filemanager + //Label to show next to the filemanager. get_string("submission_label", self::COMPONENT_NAME), - // attributes + //Attributes. null, - // options + //Options. $this->get_file_options(false) ); - // add help button + //Add help button. $mform->addHelpButton( - // what form item to add a helpbutton + //Related form item. "tasks_filemanager", - // what key to use + //Key. "submission_label", - // in which language file to look in + //Language file. self::COMPONENT_NAME ); @@ -239,21 +209,21 @@ class assign_submission_dta extends assign_submission_plugin { */ public function is_empty(stdClass $submission): bool { return $this->count_files($submission->id, self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION) == 0; - } + } /** * Count the number of files in a filearea * - * @param int $submissionId submission id to check - * @param string $areaId filearea id to count + * @param int $submissionid submission id to check + * @param string $areaid filearea id to count * @return int */ - private function count_files($submissionId, $areaId) { + private function count_files($submissionid, $areaid) { $fs = get_file_storage(); $files = $fs->get_area_files($this->assignment->get_context()->id, self::COMPONENT_NAME, - $areaId, - $submissionId, + $areaid, + $submissionid, 'id', false); @@ -278,55 +248,49 @@ class assign_submission_dta extends assign_submission_plugin { $submission->id ); - // if submission is empty leave directly + //If submission is empty leave directly. if ($this->is_empty($submission)) { return true; } - // get submitted files + //Get submitted files. $fs = get_file_storage(); $files = $fs->get_area_files( - // id of current assignment + //Id of current assignment. $this->assignment->get_context()->id, - // component name self::COMPONENT_NAME, - // proper filearea self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION, - // entry id $submission->id, - // ? 'id', - // ? false ); - // check if a file is uploaded + //Check if a file is uploaded. if (empty($files)) { \core\notification::error(get_string("no_submissionfile_warning", self::COMPONENT_NAME)); return true; } - // Get the file and post it to our backend. + //Get the file. $file = reset($files); - + + //Send file to backend. $response = DtaBackendUtils::sendSubmissionToBackend($this->assignment, $file); - // if we got a null response, return with error + //With a null response, return an error. if (is_null($response)) { return false; } - // convert received json to valid class instances - $resultSummary = DtaResultSummary::decodeJson($response); + //Convert received json to valid class instances. + $resultsummary = DtaResultSummary::decodeJson($response); - // persist new results to database - DbUtils::storeResultSummaryToDatabase($this->assignment->get_instance()->id, $submission->id, $resultSummary); + //Persist new results to database. + DbUtils::storeResultSummaryToDatabase($this->assignment->get_instance()->id, $submission->id, $resultsummary); return true; } - // ===== view submission results ===== // - /** * Display a short summary of the test results of the submission * This is diplayed as default view, with the option to expand @@ -358,8 +322,6 @@ class assign_submission_dta extends assign_submission_plugin { ); } - // ========== end of section ========== // - /** * generate array of allowed filetypes to upload. * @@ -371,7 +333,7 @@ class assign_submission_dta extends assign_submission_plugin { private function get_file_options(bool $settings): array { $fileoptions = array('subdirs' => 0, "maxfiles" => 1, - 'accepted_types' => ($settings ? array(".txt") : array(".txt",".zip")), + 'accepted_types' => ($settings ? array(".txt") : array(".txt", ".zip")), 'return_types' => FILE_INTERNAL); return $fileoptions; } @@ -405,7 +367,7 @@ class assign_submission_dta extends assign_submission_plugin { false); foreach ($files as $file) { - // Do we return the full folder path or just the file name? + //Do we return the full folder path or just the file name? if (isset($submission->exportfullpath) && $submission->exportfullpath == false) { $result[$file->get_filename()] = $file; } else { diff --git a/dta/models/DtaResult.php b/dta/models/DtaResult.php index e96e84b..add16c3 100644 --- a/dta/models/DtaResult.php +++ b/dta/models/DtaResult.php @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. +defined('MOODLE_INTERNAL') || die(); + class DtaResult { - public $packageName; - public $className; + public $packageName; + public $className; public $name; /** @@ -66,41 +68,41 @@ class DtaResultSummary { * @param string $jsonString jsonString containing DtaResultSummary * @return DtaResultSummary */ - public static function decodeJson($jsonString): DtaResultSummary { - $response = json_decode($jsonString); + public static function decodeJson($jsonstring): DtaResultSummary { + $response = json_decode($jsonstring); $summary = new DtaResultSummary(); $summary->timestamp = $response->timestamp; - $summary->globalStacktrace = $response->globalStacktrace; - - $summary->successfulTestCompetencyProfile = $response->successfulTestCompetencyProfile; - $summary->overallTestCompetencyProfile = $response->overallTestCompetencyProfile; + $summary->globalStacktrace = $response->globalStacktrace; + + $summary->successfulTestCompetencyProfile = $response->successfulTestCompetencyProfile; + $summary->overallTestCompetencyProfile = $response->overallTestCompetencyProfile; $summary->results = self::decodeJsonResultArray($response->results); return $summary; } - private static function decodeJsonCompetencyArray($jsonArray): array { + private static function decodeJsonCompetencyArray($jsonarray): array { $ret = array(); - foreach ($jsonArray as $entry) { - $ret[] = $entry; - } - return $ret; + foreach ($jsonarray as $entry) { + $ret[] = $entry; + } + return $ret; } /** * @param array $jsonArray decoded json array of results array * @return array of DtaResult */ - private static function decodeJsonResultArray($jsonArray): array { + private static function decodeJsonResultArray($jsonarray): array { $ret = array(); - foreach ($jsonArray as $entry) { + foreach ($jsonarray as $entry) { $value = new DtaResult(); $value->packageName = $entry->packageName; - $value->className = $entry->className; - $value->name = $entry->name; - + $value->className = $entry->className; + $value->name = $entry->name; + $value->state = $entry->state; $value->failureType = $entry->failureType; @@ -122,7 +124,7 @@ class DtaResultSummary { */ public function stateOccurenceCount(int $state): int { $num = 0; - foreach($this->results as $r) { + foreach ($this->results as $r) { if ($r->state == $state) { $num++; } diff --git a/dta/utils/backend.php b/dta/utils/backend.php index 4e790a8..2a4349d 100644 --- a/dta/utils/backend.php +++ b/dta/utils/backend.php @@ -20,13 +20,13 @@ class DtaBackendUtils { * @return string backend host base url */ private static function getBackendBaseUrl(): string { - $backendAddress = get_config(assign_submission_dta::COMPONENT_NAME, "backendHost"); + $backendaddress = get_config(assign_submission_dta::COMPONENT_NAME, "backendHost"); - if (empty($backendAddress)) { + if (empty($backendaddress)) { \core\notification::error(get_string("backendHost_not_set", assign_submission_dta::COMPONENT_NAME)); } - return $backendAddress; + return $backendaddress; } /** @@ -38,21 +38,21 @@ class DtaBackendUtils { * @return bool true if no error occurred */ public static function sendTestConfigToBackend($assignment, $file): bool { - $backendAddress = self::getBackendBaseUrl(); - if (empty($backendAddress)) { + $backendaddress = self::getBackendBaseUrl(); + if (empty($backendaddress)) { return true; } - // set endpoint for test upload - $url = $backendAddress . "/v1/unittest"; + //Set endpoint for test upload. + $url = $backendaddress . "/v1/unittest"; - // prepare params + //Prepare params. $params = array( "unitTestFile" => $file, "assignmentId" => $assignment->get_instance()->id ); - // if request returned null, return false to indicate failure + //If request returned null, return false to indicate failure. if (is_null(self::post($url, $params))) { return false; } else { @@ -69,15 +69,15 @@ class DtaBackendUtils { * @return string json string with testresults or null on error */ public static function sendSubmissionToBackend($assignment, $file): ?string { - $backendAddress = self::getBackendBaseUrl(); - if (empty($backendAddress)) { + $backendaddress = self::getBackendBaseUrl(); + if (empty($backendaddress)) { return true; } - // set endpoint for test upload - $url = $backendAddress . "/v1/task"; + //Set endpoint for test upload. + $url = $backendaddress . "/v1/task"; - // prepare params + //Prepare params. $params = array( "taskFile" => $file, "assignmentId" => $assignment->get_instance()->id @@ -104,14 +104,15 @@ class DtaBackendUtils { $curl = new curl(); $response = $curl->post($url, $params, $options); - // check state of request, if response code is a 2xx return the answer + //Check state of request, if response code is a 2xx return the answer. $info = $curl->get_info(); if ($info["http_code"] >= 200 && $info["http_code"] < 300) { return $response; } - // Something went wrong, return null and give an error msg - debugging(assign_submission_dta::COMPONENT_NAME . ": Post file to server was not successful: http_code=" . $info["http_code"]); + //Something went wrong, return null and give an error message. + debugging(assign_submission_dta::COMPONENT_NAME . ": Post file to server was not successful: http_code=" . + $info["http_code"]); if ($info['http_code'] >= 400 && $info['http_code'] < 500) { \core\notification::error(get_string("http_client_error_msg", assign_submission_dta::COMPONENT_NAME)); @@ -120,7 +121,8 @@ class DtaBackendUtils { \core\notification::error(get_string("http_server_error_msg", assign_submission_dta::COMPONENT_NAME)); return null; } else { - \core\notification::error(get_string("http_unknown_error_msg", assign_submission_dta::COMPONENT_NAME) . $info["http_code"] . $response); + \core\notification::error(get_string("http_unknown_error_msg", assign_submission_dta::COMPONENT_NAME) . + $info["http_code"] . $response); return null; } } diff --git a/dta/utils/database.php b/dta/utils/database.php index a704541..6da56b7 100644 --- a/dta/utils/database.php +++ b/dta/utils/database.php @@ -24,39 +24,39 @@ class DbUtils { /** * get's summary with all corresponding result entries * - * @param int $assignmentId assignment id to search for - * @param int $submissionId submission id to search for + * @param int $assignmentid assignment id to search for + * @param int $submissionid submission id to search for * @return DttResultSummary representing given submission */ public static function getResultSummaryFromDatabase( - int $assignmentId, - int $submissionId + int $assignmentid, + int $submissionid ): DtaResultSummary { global $DB; - // fetch data from database - $summaryDbRecord = $DB->get_record(self::TABLE_SUMMARY, array( - "assignment_id" => $assignmentId, - "submission_id" => $submissionId + //Fetch data from database. + $summary_record = $DB->get_record(self::TABLE_SUMMARY, array( + "assignment_id" => $assignmentid, + "submission_id" => $submissionid )); - $resultsDbArray = $DB->get_records(self::TABLE_RESULT, array( - "assignment_id" => $assignmentId, - "submission_id" => $submissionId + $results_array = $DB->get_records(self::TABLE_RESULT, array( + "assignment_id" => $assignmentid, + "submission_id" => $submissionid )); - // create summary instance + //Create a summary instance. $summary = new DtaResultSummary(); - $summary->timestamp = $summaryDbRecord->timestamp; - $summary->globalStacktrace = $summaryDbRecord->global_stacktrace; - $summary->successfulTestCompetencyProfile = $summaryDbRecord->successful_competencies; - $summary->overallTestCompetencyProfile = $summaryDbRecord->tested_competencies; + $summary->timestamp = $summary_record->timestamp; + $summary->globalStacktrace = $summary_record->global_stacktrace; + $summary->successfulTestCompetencyProfile = $summary_record->successful_competencies; + $summary->overallTestCompetencyProfile = $summary_record->tested_competencies; $summary->results = array(); - // create result instances and add to array of summary instance - foreach($resultsDbArray as $rr) { + //Create result instances and add to array of summary instance. + foreach($results_array as $rr) { $result = new DtaResult(); - $result->packageName = $rr->package_name; + $result->packageName = $rr->package_name; $result->className = $rr->class_name; $result->name = $rr->name; $result->state = $rr->state; @@ -77,33 +77,33 @@ class DbUtils { * save given result summary and single results to database * under given assignment and submission id * - * @param int assignmentId assigment this is submission is linked to - * @param int submissionId submission of this result + * @param int assignmentid assigment this is submission is linked to + * @param int submissionid submission of this result * @param DttResultSummary instance to persist */ public static function storeResultSummaryToDatabase( - int $assignmentId, - int $submissionId, + int $assignmentid, + int $submissionid, DtaResultSummary $summary ): void { global $DB; - // prepare new database entries - $summaryRecord = new stdClass(); - $summaryRecord->assignment_id = $assignmentId; - $summaryRecord->submission_id = $submissionId; - $summaryRecord->successful_competencies = $summary->successfulTestCompetencyProfile; - $summaryRecord->tested_competencies = $summary->overallTestCompetencyProfile; - $summaryRecord->timestamp = $summary->timestamp; - $summaryRecord->global_stacktrace = $summary->globalStacktrace; - - // prepare results to persist to array - $resultRecordArray = array(); + //Prepare new database entries. + $summary_record = new stdClass(); + $summary_record->assignment_id = $assignmentid; + $summary_record->submission_id = $submissionid; + $summary_record->successful_competencies = $summary->successfulTestCompetencyProfile; + $summary_record->tested_competencies = $summary->overallTestCompetencyProfile; + $summary_record->timestamp = $summary->timestamp; + $summary_record->global_stacktrace = $summary->globalStacktrace; + + //Prepare results to persist to array. + $result_records = array(); foreach($summary->results as $r) { $record = new stdClass(); - $record->assignment_id = $assignmentId; - $record->submission_id = $submissionId; - $record->package_name = $r->packageName; + $record->assignment_id = $assignmentid; + $record->submission_id = $submissionid; + $record->package_name = $r->packageName; $record->class_name = $r->className; $record->name = $r->name; $record->state = $r->state; @@ -113,30 +113,30 @@ class DbUtils { $record->column_number = $r->columnNumber; $record->line_number = $r->lineNumber; $record->position = $r->position; - $resultRecordArray[] = $record; + $result_records[] = $record; } - // if results exist yet, delete old values beforehand + //If results already exist, delete old values beforehand. $submission = $DB->get_record(self::TABLE_SUMMARY, array( - 'assignment_id' => $assignmentId, - 'submission_id' => $submissionId + 'assignment_id' => $assignmentid, + 'submission_id' => $submissionid )); if ($submission) { $DB->delete_records(self::TABLE_RESULT, array( - 'assignment_id' => $assignmentId, - 'submission_id' => $submissionId + 'assignment_id' => $assignmentid, + 'submission_id' => $submissionid )); $DB->delete_records(self::TABLE_SUMMARY, array( - 'assignment_id' => $assignmentId, - 'submission_id' => $submissionId + 'assignment_id' => $assignmentid, + 'submission_id' => $submissionid )); } - // create summary and single result entries - $DB->insert_record(self::TABLE_SUMMARY, $summaryRecord); - foreach($resultRecordArray as $rr) { + //Create summary and single result entries. + $DB->insert_record(self::TABLE_SUMMARY, $summary_record); + foreach($result_records as $rr) { $DB->insert_record(self::TABLE_RESULT, $rr); } } diff --git a/dta/utils/view.php b/dta/utils/view.php index 8487870..c211a9b 100644 --- a/dta/utils/view.php +++ b/dta/utils/view.php @@ -19,29 +19,29 @@ class ViewSubmissionUtils { /** * generates a short summary html * - * @param int assignmentId assignment - * @param int submissionId submission to create a report for + * @param int assignmentid assignment + * @param int submissionid submission to create a report for * @return string html */ public static function generateSummaryHtml( - int $assignmentId, - int $submissionId + int $assignmentid, + int $submissionid ): string { - // fetch data - $summary = DbUtils::getResultSummaryFromDatabase($assignmentId, $submissionId); + //Fetch data. + $summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid); $html = ""; - // calculate success rate, if no unknown result states or compilation errors - $successRate = "?"; + //Calculate success rate, if no unknown result states or compilation errors. + $successrate = "?"; if ($summary->unknownCount() == 0 && $summary->compilationErrorCount() == 0) { - $successRate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 ); + $successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 ); } - // generate html + //Generate html. $html .= $summary->successfulCount() . "/"; $html .= ($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0) - ? $summary->resultCount() . " (" . $successRate . "%)" + ? $summary->resultCount() . " (" . $successrate . "%)" : "?"; $html .= " tests successful<br>"; @@ -61,32 +61,32 @@ class ViewSubmissionUtils { /** * generates detailed view html * - * @param int assignmentId assignment - * @param int submissionId submission to create a report for + * @param int assignmentid assignment + * @param int submissionid submission to create a report for */ public static function generateDetailHtml( - int $assignmentId, - int $submissionId + int $assignmentid, + int $submissionid ): string { - // fetch data - $summary = DbUtils::getResultSummaryFromDatabase($assignmentId, $submissionId); + //Fetch data. + $summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid); $html = ""; - // define a few css classes and prepare html attribute arrays - $tableHeaderRowAttributes = array("class" => "dtaTableHeaderRow"); - $tableRowAttributes = array("class" => "dtaTableRow"); - $resultRowAttributes = $tableRowAttributes; - $unknownAttrib = 'dtaResultUnknown'; - $successAttrib = 'dtaResultSuccess'; - $failureAttrib = 'dtaResultFailure'; - $compErrorAttrib = 'dtaResultCompilationError'; + //Define a few css classes and prepare html attribute arrays to beautify the output. + $tableheaderrow_attributes = array("class" => "dtaTableHeaderRow"); + $tablerow_attributes = array("class" => "dtaTableRow"); + $resultrow_attributes = $tablerow_attributes; + $unknown_attributes = 'dtaResultUnknown'; + $success_attributes = 'dtaResultSuccess'; + $failure_attributes = 'dtaResultFailure'; + $compilationerror_attributes = 'dtaResultCompilationError'; - // summary table + //Summary table. $tmp = ""; $tmp .= html_writer::tag("th", "Summary", array("class" => "dtaTableHeader")); $tmp .= html_writer::empty_tag("th", array("class" => "dtaTableHeader")); - $header = html_writer::tag("tr", $tmp, $tableHeaderRowAttributes); + $header = html_writer::tag("tr", $tmp, $tableheaderrow_attributes); $header = html_writer::tag("thead", $header); $body = ""; @@ -102,67 +102,67 @@ class ViewSubmissionUtils { $summary->resultCount(), $attributes); - $resultRowAttributes = $tableRowAttributes; - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $unknownAttrib; + $resultrow_attributes = $tablerow_attributes; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $unknown_attributes; - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); $tmp = ""; $tmp .= html_writer::tag("td", "successes", $attributes); $tmp .= html_writer::tag( "td", $summary->successfulCount(), $attributes); - $resultRowAttributes = $tableRowAttributes; - $successRate = "?"; + $resultrow_attributes = $tablerow_attributes; + $successrate = "?"; if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $unknownAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $unknown_attributes; } else { - $successRate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 ); - if ($successRate < 50) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $compErrorAttrib; - } else if ($successRate < 75) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $failureAttrib; + $successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 ); + if ($successrate < 50) { + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $compilationerror_attributes; + } else if ($successrate < 75) { + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $failure_attributes; } else { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $successAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $success_attributes; } } - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); $tmp = ""; $tmp .= html_writer::tag("td", "failures", $attributes); $tmp .= html_writer::tag("td", $summary->failedCount(), $attributes); - $resultRowAttributes = $tableRowAttributes; + $resultrow_attributes = $tablerow_attributes; if ($summary->failedCount() > 0) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $failureAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $failure_attributes; } else { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $successAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $success_attributes; } - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); $tmp = ""; $tmp .= html_writer::tag("td", "compilation errors", $attributes); $tmp .= html_writer::tag("td", $summary->compilationErrorCount(), $attributes); - $resultRowAttributes = $tableRowAttributes; + $resultrow_attributes = $tablerow_attributes; if ($summary->compilationErrorCount() > 0) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $compErrorAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $compilationerror_attributes; } else { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $successAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $success_attributes; } - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); $tmp = ""; $tmp .= html_writer::tag("td", "unknown state", $attributes); $tmp .= html_writer::tag("td", $summary->unknownCount(), $attributes); - $resultRowAttributes = $tableRowAttributes; + $resultrow_attributes = $tablerow_attributes; if ($summary->unknownCount() > 0) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $unknownAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $unknown_attributes; } else { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $successAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $success_attributes; } - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); $tmp = ""; $tmp .= html_writer::tag("td", html_writer::tag("b","success rate"), $attributes); @@ -170,59 +170,59 @@ class ViewSubmissionUtils { "td", html_writer::tag("b", $summary->successfulCount() . "/" . (($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0) ? $summary->resultCount() - . " (" . $successRate . "%)" + . " (" . $successrate . "%)" : "?")), $attributes); - $resultRowAttributes = $tableRowAttributes; + $resultrow_attributes = $tablerow_attributes; if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $unknownAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $unknown_attributes; } else { - if ($successRate < 50) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $compErrorAttrib; - } else if ($successRate < 75) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $failureAttrib; + if ($successrate < 50) { + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $compilationerror_attributes; + } else if ($successrate < 75) { + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $failure_attributes; } else { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . " " . $successAttrib; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . " " . $success_attributes; } } - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); $body = html_writer::tag("tbody", $body); $table = html_writer::tag("table", $header . $body, array("class" => "dtaTable")); $html .= $table; - // add empty div for spacing between summary and details table + //Add empty div for spacing between summary and details table. $html .= html_writer::empty_tag("div", array("class" => "dtaSpacer")); - // details table + //Details table. $tmp = ""; $tmp .= html_writer::tag("th", "Details", array("class" => "dtaTableHeader")); $tmp .= html_writer::empty_tag("th", array("class" => "dtaTableHeader")); - $header = html_writer::tag("tr", $tmp, $tableHeaderRowAttributes); + $header = html_writer::tag("tr", $tmp, $tableheaderrow_attributes); $header = html_writer::tag("thead", $header); $body = ""; - $spacerRow = null; + $spacerrow = null; foreach($summary->results as $r) { - // add spacer first, if not null - if (!is_null($spacerRow)) { - $body .= $spacerRow; + //Add spacer first if not null. + if (!is_null($spacerrow)) { + $body .= $spacerrow; } - // new copy of base attributes array - $resultRowAttributes = $tableRowAttributes; + //New copy of base attributes array. + $resultrow_attributes = $tablerow_attributes; - // check which css class to add for the colored left-border according to resuls state + //Check which css class to add for the colored left-border according to resuls state. if ($r->state == 0) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . ' dtaResultUnknown'; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . ' dtaResultUnknown'; } else if ($r->state == 1) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . ' dtaResultSuccess'; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . ' dtaResultSuccess'; } else if ($r->state == 2) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . ' dtaResultFailure'; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . ' dtaResultFailure'; } else if ($r->state == 3) { - $resultRowAttributes['class'] = $resultRowAttributes['class'] . ' dtaResultCompilationError'; + $resultrow_attributes['class'] = $resultrow_attributes['class'] . ' dtaResultCompilationError'; } $tmp = ""; @@ -230,12 +230,12 @@ class ViewSubmissionUtils { "td", "name", $attributes); - + $tmp .= html_writer::tag( "td", $r->name, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); $tmp = ""; $tmp .= html_writer::tag( @@ -247,9 +247,9 @@ class ViewSubmissionUtils { "td", DtaResult::getStateName($r->state), $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); - // if state is something different than successful, show additional rows + //If state is something different than successful, show additional rows. if ($r->state != 1) { $tmp = ""; $tmp .= html_writer::tag( @@ -261,21 +261,21 @@ class ViewSubmissionUtils { "td", $r->failureType, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); - + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); + $tmp = ""; $tmp .= html_writer::tag( "td", "failure reason", $attributes); - + $tmp .= html_writer::tag( "td", $r->failureReason, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); - // only show line, column and position if they have useful values + //Only show line, column and position if they have useful values. if (!is_null($r->lineNumber) && $r->lineNumber > 0) { $tmp = ""; $tmp .= html_writer::tag( @@ -287,7 +287,7 @@ class ViewSubmissionUtils { "td", $r->lineNumber, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); } if (!is_null($r->columnNumber) && $r->columnNumber > 0) { @@ -301,7 +301,7 @@ class ViewSubmissionUtils { "td", $r->columnNumber, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); } if (!is_null($r->position) && $r->position > 0) { @@ -315,7 +315,7 @@ class ViewSubmissionUtils { "td", $r->position, $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); } $tmp = ""; @@ -328,12 +328,12 @@ class ViewSubmissionUtils { "td", html_writer::tag("details", $r->stacktrace, array("class" => "dtaStacktraceDetails")), $attributes); - $body .= html_writer::tag("tr", $tmp, $resultRowAttributes); + $body .= html_writer::tag("tr", $tmp, $resultrow_attributes); } - // set spacerRow value if null for next rount separation - if (is_null($spacerRow)) { - $spacerRow = html_writer::empty_tag("tr", array("class" => "dtaTableSpacer")); + //Set spacerrow value if null for next rount separation. + if (is_null($spacerrow)) { + $spacerrow = html_writer::empty_tag("tr", array("class" => "dtaTableSpacer")); } } $html .= html_writer::tag("table", $header . $body, array("class" => "dtaTable")); -- GitLab