public function errorAction() { $errors = $this->_getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // 404 error -- controller or action not found $this->getResponse()->setHttpResponseCode(404); $this->view->message = 'Page not found'; break; default: // application error $this->getResponse()->setHttpResponseCode(500); $this->view->message = 'Application error'; break; } // Log exception, if logger available if ($log = $this->getLog()) { $log->crit($this->view->message, $errors->exception); } // Log to file if we can Model_Shell_Debug::getInstance()->log("Exception Occured: " . $errors->exception->getMessage() . "\n" . $errors->exception->getTraceAsString()); Model_Shell_Debug::getInstance()->saveToDisk(); // conditionally display exceptions if ($this->getInvokeArg('displayExceptions') == true) { $this->view->exception = $errors->exception; } $this->view->request = $errors->request; }
/** * Get the instance of the debug class * * @return Model_Shell_Debug */ public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; }
/** * Generates a bank of questions for a question identifier provided * Expects parameters [question_id], [questions_to_generate_num], [max_errors_num] */ public function generatequestionbankAction() { // Check to see that all the parameters get passed $parameters = $this->_getAllParams(); $check_errors = array(); foreach (array("question_id" => "Question Identifier", "questions_to_generate_num" => "Number of Questions to Generate", "max_errors_num" => "Maximum number of Errors") as $check_key => $check_text) { if (!array_key_exists($check_key, $parameters) || !is_numeric($parameters[$check_key]) || $parameters[$check_key] < 0) { $check_errors[] = $check_text . " [" . $check_key . "] was not passed, or not a positive number."; } } if (sizeof($check_errors) > 0) { cronlog("The following validation errors occured:"); foreach ($check_errors as $ce) { cronlog($ce); } exit; } //cronlog('ok so far'); $question_base_id = intval($parameters['question_id']); $number_of_questions = intval($parameters['questions_to_generate_num']); $maximum_errors = intval($parameters['max_errors_num']); cronlog("Generating {$number_of_questions} questions from Question Base Identifier {$question_base_id} ; Maximum Error threshold is {$maximum_errors}"); $vQuestionBase = Model_Quiz_QuestionBase::fromID($question_base_id); if (is_null($vQuestionBase)) { throw new Exception("The question base identifier passed was invalid"); } $question_counter = 0; $error_counter = 0; My_Logger::log(__METHOD__ . " number_of_questions: {$number_of_questions}"); My_Logger::log(__METHOD__ . " maximum_errors: {$maximum_errors}"); while ($question_counter <= $number_of_questions && $error_counter <= $maximum_errors) { My_Logger::log(__METHOD__ . " question_counter: {$question_counter}"); My_Logger::log(__METHOD__ . " error_counter: {$error_counter}"); try { $vGeneratedQuestion = Model_Quiz_GeneratedQuestion::generateNewFromQuestionBase($vQuestionBase); } catch (Exception $e) { cronlog("Could not generate question. " . $e->getMessage()); echo Model_Shell_Debug::getInstance()->getLog(); $error_counter++; } } cronlog("Finished. Generated " . $question_counter . " questions; " . $error_counter . " errornous questions generated (but discarded)"); }
/** * Selects the next question base appropriate for the quiz attempt passed * @param Model_Quiz_QuizAttempt $vQuizAttempt * @param boolean $debug Being Phased out TODO * @throws Exception * @return Model_Quiz_QuestionBase|NULL NULL Should only be returned in exceptional circumstances */ public static function select_next_question($vQuizAttempt, $debug = false) { //Get all the concepts this quiz tests $vQuiz = $vQuizAttempt->getQuiz(); $vTestedConcepts = $vQuiz->getTestedConcepts(); if (sizeof($vTestedConcepts) < 1) { throw new Exception("This quiz is not ready yet - reason: No testedConcepts specified."); } //Foreach concept tested, see how many questions we've attempted foreach ($vTestedConcepts as $vTestedConcept) { Model_Shell_Debug::getInstance()->log("Looking at TestedConcept: " . $vTestedConcept->getConcept()->getConcept_name()); $vQuestionAttempts = Model_Quiz_QuestionAttempt::getAllFromQuizAttemptAndConcept($vQuizAttempt, $vTestedConcept->getConcept()); Model_Shell_Debug::getInstance()->log("Done " . sizeof($vQuestionAttempts) . "/" . $vTestedConcept->getNumber_tested()); //If we haven't attempted enough in this concept, we need to choose a question difficulty if (sizeof($vQuestionAttempts) < $vTestedConcept->getNumber_tested()) { //What difficulties are there being tested within this concept? $vLowest = $vTestedConcept->getLower_difficulty(); $vHighest = $vTestedConcept->getHigher_difficulty(); //Find out how many questions I should allocate for each difficulty $mQuestionsPerDifficultyLevel = floor(0.8 / ($vHighest + 1 - $vLowest) * $vTestedConcept->getNumber_tested()); $mBuffer = $vTestedConcept->getNumber_tested() - ($vHighest + 1 - $vLowest) * $mQuestionsPerDifficultyLevel; //If there's only one difficulty, that settles that if ($vLowest == $vHighest) { return Model_Shell_QuestionChooser::select_next_question_2($vQuizAttempt, $vTestedConcept->getConcept(), $vLowest); } //Were there any previous attempts at this concept? If not, we need to start a Q at the lowest specified difficulty $vQuestionAttempts = $vQuizAttempt->getQuestionAttempts($vTestedConcept->getConcept()); //echo "Size of vQuestionAttempts:".sizeof($vQuestionAttempts)."<br/>"; if (sizeof($vQuestionAttempts) == 0) { return Model_Shell_QuestionChooser::select_next_question_2($vQuizAttempt, $vTestedConcept->getConcept(), $vLowest); } //Find the highest attempted difficulty done so far $vHighestSoFar = $vQuizAttempt->getHighestDifficultyTestedSoFar(); //echo "The highest difficulty so far: $vHighestSoFar<br/>"; if ($vHighestSoFar >= $vHighest) { //Already at the highest difficulty, the next question will be at this difficulty too return Model_Shell_QuestionChooser::select_next_question_2($vQuizAttempt, $vTestedConcept->getConcept(), $vHighest); } //Look at the last attempts in this difficulty. Were they below-par (use a percentage?)? $vTotal = 0; $vTotalRight = 0; Model_Shell_Debug::getInstance()->log("Checking your previous attempts...Size of vQuestionAttempts:" . sizeof($vQuestionAttempts)); foreach ($vQuestionAttempts as $vQA) { $vQB = $vQA->getQuestion_base(); //echo "Looking at " . $vQB->getDifficulty() . " vs $vHighestSoFar<br/>"; if ($vQB->getDifficulty() == $vHighestSoFar) { $vTotal++; if ($vQB->getEstimated_time() > $vQA->getTime_finished() - $vQA->getTime_started()) { //You did this question in a reasonable time... did you get it right first time? if ($vQA->getInitial_result() == "1") { $vTotalRight++; } } } } //Note, a divide by 0 happened here before... if ($vTotal == 0 || $vTotalRight / $vTotal > 0.8) { //OK. If they WERE good attempts, I should move on if I've hit my quota for this difficulty if ($vTotal >= $mQuestionsPerDifficultyLevel) { //Reached our minumum quota for this difficulty level. NEXT! return Model_Shell_QuestionChooser::select_next_question_2($vQuizAttempt, $vTestedConcept->getConcept(), $vHighestSoFar + 1); } else { //We've done well so far, but we need to do more in this difficulty return Model_Shell_QuestionChooser::select_next_question_2($vQuizAttempt, $vTestedConcept->getConcept(), $vHighestSoFar); } } else { //Your previous attempts weren't all that good. //Figure out how much buffer we have left. Can we afford to give you a question at $vHighestSoFar? Or do we have to move onto something harder? $mBuffer = $vTestedConcept->getNumber_tested() - ($vHighest - $vHighestSoFar) * $mQuestionsPerDifficultyLevel - sizeof($vQuestionAttempts); if ($mBuffer > 1) { //We can afford to give you another easier question return Model_Shell_QuestionChooser::select_next_question_2($vQuizAttempt, $vTestedConcept->getConcept(), $vHighestSoFar); } else { //Sorry.. buffer is dry. You weren't going too well, but you gotta do the harder stuff return Model_Shell_QuestionChooser::select_next_question_2($vQuizAttempt, $vTestedConcept->getConcept(), $vHighestSoFar + 1); } } } //End If } //End Foreach testedConcept //We shouldn't really ever get here, but in case we do -> null return null; }
/** * This action is the quiz shell. * It ensures permissions, creates new attempts etc etc. * * @author Ben Evans */ public function attemptAction() { Model_Shell_Debug::getInstance()->log("User Entered the Attempt Action"); $identity = Zend_Auth::getInstance()->getIdentity(); $username = $identity->username; $auth_model = Model_Auth_General::getAuthModel(); /* Before we do anything, test to make sure we've passed a VALID QUIZ which WE ARE ENTITLED to sit. */ $quiz_id = $this->_getParam("quiz"); if (is_null($quiz_id)) { throw new Exception("No quiz was passed. Cannot continue."); } $vQuiz = Model_Quiz_Quiz::fromID($quiz_id); if ($vQuiz == null) { throw new Exception("Quiz ID passed was invalid. Cannot continue."); } $mFinished = false; $mMarking = false; //Permissions if ($auth_model->userInGroup($username, $vQuiz->getPermissions_group()) && $vQuiz->getOpen_date() <= strtotime("now")) { //Have we run out of attempts? $vAttempts = Model_Quiz_QuizAttempt::getAllFromUser($username, $vQuiz); if (sizeof($vAttempts) >= $vQuiz->getMax_attempts()) { //It is possible that we're on our last attempt, and that it's "in progress"...check $bInProgress = false; foreach ($vAttempts as $vAttempt) { if ($vAttempt->getDate_finished() == null) { $bInProgress = true; } } if (!$bInProgress) { throw new Exception("You've exceeded your maximum attempts for this quiz. Cannot continue"); } } } else { if (!$this->view->is_admin) { throw new Exception("Insufficient Permissions to take this quiz / Quiz not open yet"); } $vAttempts = Model_Quiz_QuizAttempt::getAllFromUser($username, $vQuiz); } /* Ok. We're allowed to TAKE the quiz. Are we resuming, or starting a new one? */ $mQuizAttempt = null; if (is_array($vAttempts)) { foreach ($vAttempts as $vAttempt) { if ($vAttempt->getDate_finished() == null) { $mQuizAttempt = $vAttempt; break; } } //End Foreach } //End If if ($mQuizAttempt == null) { $mQuizAttempt = Model_Quiz_QuizAttempt::fromScratch(strtotime("now"), $vQuiz, $username); } /* Calculate the total questions needed for this quiz */ $vTCs = $vQuiz->getTestedConcepts(); $vTotalQuestions = 0; foreach ($vTCs as $vTC) { $vTotalQuestions = $vTotalQuestions + $vTC->getNumber_tested(); } /* We have our quizAttempt ready to go. Now we look to see if we're resuming a question or not */ $mQuestionAttempt = $mQuizAttempt->getLastIncompleteQuestion(); if (is_object($mQuestionAttempt) && !$mQuestionAttempt->isValid()) { $mQuestionAttempt->destroy(); // Remove the Question attempt (Database was reinitialised or something) $mQuestionAttempt = null; } if ($mQuestionAttempt != null) { /* Are we getting an ANSWER for this question? */ if (array_key_exists("marking", $_POST) && $_POST['marking'] == "1") { /* Mark it */ $mMarking = true; } /* If we reach here, the page has probably been refreshed. We just re-display the last question */ } else { /* Have we finished this quiz? */ if ($mQuizAttempt->getQuestionAttemptCount() >= $vTotalQuestions) { //Close this attempt and display a result later on down the page $mQuizAttempt->setDate_finished(strtotime("now")); //Calculate and store the final score $mQuizAttempt->setTotal_score($mQuizAttempt->getTotal_score()); $mFinished = true; } else { /* QuizAttempt isn't finished... Fetch a questionBase */ $vQuestionBase = Model_Shell_QuestionChooser::select_next_question($mQuizAttempt, true); /* Make a GeneratedQuestion */ $vCounter = 0; //Make sure we don't get any fluke no-text answers while ($vCounter < 3) { Model_Shell_Debug::getInstance()->log("vQuestionBase: " . isset($vQuestionBase)); Model_Shell_Debug::getInstance()->log("Generating... from " . $vQuestionBase->getXml()); $vGen = Model_Quiz_GeneratedQuestion::fromQuestionBase($vQuestionBase); if ($vGen->getCorrect_answer() != "" && $vGen->getCorrect_answer() != "\r\n") { break; } else { $vGen->remove(); } $vCounter++; } if ($vGen->getCorrect_answer() == "" || $vGen->getCorrect_answer() == "\r\n") { throw new Exception("Error. While generating a question for you, blank answers appeared > 3 times. This should never happen. Either try to refresh this page, or consult your lecturer..."); } /* Make a QuestionAttempt */ $mQuestionAttempt = Model_Quiz_QuestionAttempt::fromScratch($vQuestionBase, strtotime("now"), strtotime("now"), $mQuizAttempt, $vGen); } //End-if_finished_quizAttempt } // Pass all relevant information to the view $this->view->quiz = $vQuiz; $this->view->question_attempt = $mQuestionAttempt; $this->view->finished = $mFinished; $this->view->marking = $mMarking; $this->view->mQuizAttempt = $mQuizAttempt; $this->view->vTotalQuestions = $vTotalQuestions; }
/** * Compiles the question and returns the correct output * @return string */ public function getCorrectOutput() { if (isset($this->mActualAnswer)) { return $this->mActualAnswer; } Model_Shell_Debug::getInstance()->log(" Attempting to generate correct answer for Question.", __METHOD__); $this->mActualAnswer = Model_Shell_Compiler::compileAndReturn(time() . rand(1, 99999), $this->mProblem); $this->mSubstitutions['ans'] = $this->mActualAnswer; return $this->mActualAnswer; }
protected function makeQuestionAttempt($quizAttempt, $now) { $questionBase = Model_Shell_QuestionChooser::select_next_question($quizAttempt, true); $path = $this->getFrontController()->getParam('xml_path'); // This way we can set it externally from our tests. If not set, called code will just use the configuration value /* Make a GeneratedQuestion */ $cnt = 0; // Make sure we don't get any fluke no-text answers while ($cnt < 3) { Model_Shell_Debug::getInstance()->log("vQuestionBase: " . isset($questionBase)); Model_Shell_Debug::getInstance()->log("Generating... from " . $questionBase->getXml()); $vGen = Model_Quiz_GeneratedQuestion::fromQuestionBase($questionBase, $path); if ($vGen->getCorrect_answer() != "" && $vGen->getCorrect_answer() != "\r\n") { break; } else { $vGen->remove(); } $cnt++; } if ($vGen->getCorrect_answer() == "" || $vGen->getCorrect_answer() == "\r\n") { throw new Exception("Error. While generating a question for you, blank answers appeared > 3 times. This should never happen. Either try to refresh this page, or consult your lecturer..."); } /* Make a QuestionAttempt */ return Model_Quiz_QuestionAttempt::fromScratch($questionBase, $now, $now, $quizAttempt, $vGen); }
/** * This will remove ALL pre-generated questions that haven't been used in a quiz */ public static function removePregeneratedQuestions() { $db = Zend_Registry::get("db"); /* @var $db Zend_DB_Adapter_Abstract */ Model_Shell_Debug::getInstance()->log("Removing all Pre-generated questions"); $rows = $db->query("SELECT generated_id FROM generated_questions \n\t\t\tWHERE generated_id NOT IN(SELECT generated_questionsgenerated_id AS generated_id FROM question_attempt)")->fetchAll(); foreach ($rows as $row) { $db->delete("generated_questions", "generated_id = " . $db->quote($row['generated_id'])); } }
/** * Java-Specific Compilation * * @param string $mTempFolder * @param string $vFilePrefix * @param string $mSource * @return string * @author Ben Evans */ private static function java_compile_and_return($mTempFolder, $vFilePrefix, $mSource) { Model_Shell_Debug::getInstance()->log("Entering Java Compilation"); Model_Shell_Debug::getInstance()->log("Temporary Folder Given: {$mTempFolder} . File Prefix: {$vFilePrefix}"); Model_Shell_Debug::getInstance()->log("Source passed was:\n{$mSource}"); if (in_array(strtolower(PHP_OS), explode(",", self::NIX_OSES))) { // Clean up any old existing files if (file_exists(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java"))) { Model_Shell_Debug::getInstance()->log("Existing file exists. Removing"); unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java")); } if (file_exists(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix))) { Model_Shell_Debug::getInstance()->log("Existing folder exists. Removing"); unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix)); } $mTempFolder = self::os_slash($mTempFolder); // Output the program that's been generated into a File. $fh = fopen(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java"), 'w'); fwrite($fh, $mSource); fclose($fh); if (!is_writable($mTempFolder)) { throw new Exception("Cannot write to {$mTempFolder} Please ensure permissions are correctly set"); } // Java sometimes generates more than one class... so we put the compiled things in a directory mkdir($mTempFolder . "/" . $vFilePrefix); // Run the program that we outputted to a file into a fully functioning Executable $toExec = "javac \"" . $mTempFolder . "/" . $vFilePrefix . ".java\" -d \"" . $mTempFolder . "/" . $vFilePrefix . "\""; Model_Shell_Debug::getInstance()->log("Attempted to execute: {$toExec}"); $execResult = exec($toExec); Model_Shell_Debug::getInstance()->log("Execution result was: " . $execResult); // OK Now we need to see what classes have been generated in this directory, and then call that when executing $directory_contents = scandir($mTempFolder . "/" . $vFilePrefix); if (sizeof($directory_contents) < 3) { throw new Exception("When Trying to generate a new randomised question, Compilation Failed. Reason: " . $execResult); } // At this point, I'm assuming we have only 1 main class $program_to_run = null; foreach ($directory_contents as $dc) { if (strlen($dc) > 5) { $program_to_run = str_replace(".class", "", $dc); } } if (!is_null($program_to_run)) { // Most linuxes and Unixes come with the GNU timeout program. However, OSX doesn't if (in_array(strtolower(PHP_OS), array('darwin'))) { $toExec = realpath(APPLICATION_PATH . "/../resources/osx_timeout.sh") . " 5 java -cp \"" . $mTempFolder . "/" . $vFilePrefix . "\" " . $program_to_run . " > \"" . $mTempFolder . "/" . $vFilePrefix . ".txt\""; } else { $toExec = "timeout 5 java -cp \"" . $mTempFolder . "/" . $vFilePrefix . "\" " . $program_to_run . " > \"" . $mTempFolder . "/" . $vFilePrefix . ".txt\""; } $execution_result = exec($toExec); Model_Shell_Debug::getInstance()->log("Java program compiled. Now executing: " . $toExec); // Model_Shell_Debug::getInstance()->log("The shell Execution result (not expecting anything) was: " . $execution_result); $vContents = file_get_contents(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".txt")); Model_Shell_Debug::getInstance()->log("File Execution result was: " . trim($vContents)); //Delete all the stuff we made unlink("{$mTempFolder}/" . $vFilePrefix . ".java"); unlink("{$mTempFolder}/" . $vFilePrefix . ".txt"); Model_Utils_Filesystem::delete_directory($mTempFolder . "/" . $vFilePrefix); return $vContents; } else { return "Compilation failed! Reason:" . $execResult; } } else { //We're running Windows (probably) // We have to make sure that the user has defined the JAVA Path (unlike Linux where it's just in the PATH) if (!defined("JAVAC_PATH")) { throw new Exception("The Windows Javac.exe Path is not defined. Please define it in general.php"); } else { if (!file_exists(JAVAC_PATH)) { throw new Exception("The JavaC Path defined (Windows) is not accessible by this application"); } } // Remove all old stuff if (file_exists("{$mTempFolder}/" . $vFilePrefix . ".java")) { unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java")); } if (file_exists("{$mTempFolder}/" . $vFilePrefix . ".exe")) { unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".exe")); } $fh = fopen(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java"), 'w'); fwrite($fh, $mSource); fclose($fh); // Java sometimes generates more than one class... so we put the compiled things in a directory mkdir($mTempFolder . "\\" . $vFilePrefix); $toExec = "\"" . JAVAC_PATH . "\" \"" . $mTempFolder . "\\" . $vFilePrefix . ".java\" -d \"" . $mTempFolder . "\\" . $vFilePrefix . "\""; $execResult = exec($toExec); // OK Now we need to see what classes have been generated in this directory, and then call that when executing $directory_contents = scandir($mTempFolder . "\\" . $vFilePrefix); if (sizeof($directory_contents) < 3) { throw new Exception("When Trying to generate a new randomised question, Compilation Failed. Reason: " . $execResult); } // At this point, I'm assuming we have only 1 main class $program_to_run = null; foreach ($directory_contents as $dc) { if (strlen($dc) > 5) { $program_to_run = str_replace(".class", "", $dc); } } if (!is_null($program_to_run)) { $toExec = "java -cp \"" . $mTempFolder . "\\" . $vFilePrefix . "\" " . $program_to_run . " > \"" . $mTempFolder . "\\" . $vFilePrefix . ".txt\""; $fh = fopen("{$mTempFolder}/" . $vFilePrefix . ".bat", 'w'); fwrite($fh, $toExec); fclose($fh); $toExec = '"' . $mTempFolder . "\\limitexec.exe\" 5 " . $vFilePrefix; //echo "EXECUTING: " . $toExec; exec($toExec); $vContents = file_get_contents(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".txt")); //Delete all the stuff we made unlink("{$mTempFolder}/" . $vFilePrefix . ".bat"); unlink("{$mTempFolder}/" . $vFilePrefix . ".java"); unlink("{$mTempFolder}/" . $vFilePrefix . ".txt"); exec("rmdir \"" . $mTempFolder . "\\" . $vFilePrefix . "\" /S /Q"); return $vContents; } else { return "Compilation failed! Reason:" . $execResult; } } //End Windows-specific code }
protected static function java_linux($mTempFolder, $vFilePrefix, $mSource) { // Clean up any old existing files if (file_exists(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java"))) { Model_Shell_Debug::getInstance()->log("Existing file exists. Removing"); unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java")); } if (file_exists(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix))) { Model_Shell_Debug::getInstance()->log("Existing folder exists. Removing"); unlink(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix)); } $mTempFolder = self::os_slash($mTempFolder); // Output the program that's been generated into a File. $fh = fopen(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".java"), 'w'); fwrite($fh, $mSource); fclose($fh); if (!is_writable($mTempFolder)) { throw new Exception("Cannot write to {$mTempFolder} Please ensure permissions are correctly set"); } // Java sometimes generates more than one class... so we put the compiled things in a directory mkdir($mTempFolder . "/" . $vFilePrefix); $error_file = $mTempFolder . '/' . $vFilePrefix . '.error.txt'; // Capture error messages here - Ivan // Run the program that we outputted to a file into a fully functioning Executable $toExec = "javac \"" . $mTempFolder . "/" . $vFilePrefix . ".java\" -d \"" . $mTempFolder . "/" . $vFilePrefix . "\"" . ' 2> "' . $error_file . '"'; Model_Shell_Debug::getInstance()->log("Attempted to execute: {$toExec}"); $execResult = exec($toExec); Model_Shell_Debug::getInstance()->log("Execution result was: " . $execResult); self::proccessErrorFile($error_file); // Ivan // OK Now we need to see what classes have been generated in this directory, and then call that when executing $directory_contents = scandir($mTempFolder . "/" . $vFilePrefix); if (sizeof($directory_contents) < 3) { throw new Exception("When Trying to generate a new randomised question, Compilation Failed. Reason: " . $execResult); } // At this point, I'm assuming we have only 1 main class $program_to_run = null; foreach ($directory_contents as $dc) { if (strlen($dc) > 5) { $program_to_run = str_replace(".class", "", $dc); } } if (!is_null($program_to_run)) { // Most linuxes and Unixes come with the GNU timeout program. However, OSX doesn't if (in_array(strtolower(PHP_OS), array('darwin'))) { $toExec = realpath(APPLICATION_PATH . "/../resources/osx_timeout.sh") . " 5 java -cp \"" . $mTempFolder . "/" . $vFilePrefix . "\" " . $program_to_run . " > \"" . $mTempFolder . "/" . $vFilePrefix . ".txt\""; } else { // For now we will only support our target platform (Ubuntu) - Ivan $toExec = "timeout 5 java -cp \"" . $mTempFolder . "/" . $vFilePrefix . "\" " . $program_to_run . " > \"" . $mTempFolder . "/" . $vFilePrefix . ".txt\""; } $execution_result = exec($toExec); Model_Shell_Debug::getInstance()->log("Java program compiled. Now executing: " . $toExec); // Model_Shell_Debug::getInstance()->log("The shell Execution result (not expecting anything) was: " . $execution_result); $vContents = file_get_contents(Model_Shell_Compiler::os_slash("{$mTempFolder}/" . $vFilePrefix . ".txt")); Model_Shell_Debug::getInstance()->log("File Execution result was: " . trim($vContents)); // Delete all the stuff we made unlink("{$mTempFolder}/" . $vFilePrefix . ".java"); unlink("{$mTempFolder}/" . $vFilePrefix . ".txt"); Model_Utils_Filesystem::delete_directory($mTempFolder . "/" . $vFilePrefix); return $vContents; } else { return "Compilation failed! Reason:" . $execResult; } }
/** * An Administrative function that tests Question Generation * * @return void * @author Ben Evans */ public function testquestiongenerationAction() { if (!$this->view->is_admin) { throw new Exception("Access Denied"); } $this->_helper->layout->disableLayout(); //$xml_path = APPLICATION_PATH . '/../xml/questions'; $config = new Zend_Config_Ini(APPLICATION_PATH . "/configs/application.ini", APPLICATION_ENV); $xml_path = $config->xml->import_path; My_Logger::log($xml_path); $this->view->available_files = $this->getAvailableFiles($xml_path); // See what Question we're looking at... $this->view->selected_xml = $selected_xml = $this->_getParam("q"); if (isset($selected_xml) && !is_null($selected_xml)) { // Get the Question XML try { $mQuestion = new Model_Shell_GenericQuestion($xml_path . "/" . $selected_xml . ".xml"); $this->view->question = $mQuestion; } catch (Exception $e) { //throw $e; } // Just make a new random question, so we get access to functions like Randset $temp = new Model_Quiz_GeneratedQuestion(); } //added by Ivan. Force for now, comment out in release Model_Shell_Debug::getInstance()->saveToDisk(); }