function dbFlexigrid($innerFunction, $headers = TRUE) { $userid = getUserID(); $profilingID = beginProfilingEntry(array("activity" => "database", "userid" => $userid)); $page = getSoft($_REQUEST, "page", -1); //flexigrid required $rp = getSoft($_REQUEST, "rp", -1); //flexigrid required: results per page if (!is_numeric($page) || $page <= 0) { $page = 1; } if (!is_numeric($rp) || $rp < 0) { $rp = 1; } // $rp == 0 means you just want the count, it is not a real interface with flexigrid $sortname = trim(getSoft($_REQUEST, "sortname", NULL)); if ($sortname == "undefined") { $sortname = NULL; } $sortorder = trim(getSoft($_REQUEST, "sortorder", "")); // not yet utilized: sortname, sortorder, qtype, query if (strtoupper($sortorder) != "ASC") { $sortorder = "DESC"; } global $db_query_info; $result = $innerFunction(" LIMIT " . ($page - 1) * $rp . ", " . $rp . " ", $sortname, $sortorder); if ($headers) { header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); header("Content-type: text/x-json"); } $activity = "database-"; if (array_key_exists('type', $db_query_info)) { $activity .= $db_query_info['type']; unset($db_query_info['type']); } if (is_array($result)) { // success case $result['page'] = $page; $db_query_info['result'] = 'success'; endProfilingEntry($profilingID, array("activity" => $activity, "meta" => $db_query_info)); return json_encode($result); } else { $db_query_info['result'] = 'error'; endProfilingEntry($profilingID, array("activity" => $activity, "meta" => $db_query_info)); return json_encode("Error: " . $result); // failure case; just sending a string. } }
function run_submission($post) { /************************************************** part 0 : initialization and checking that a valid problem is selected ************************************************/ global $logRow, $beginstamp, $userid, $userinput, $meta, $wpdb, $inputInUse, $facultative, $usertni, $mainProfilingID, $slug, $log_it, $appendix; $beginstamp = time(); $logRow = FALSE; $meta = array(); if ($log_it) { $mainProfilingID = beginProfilingEntry(array("activity" => "submit-code")); } /*if ($_SERVER['REQUEST_METHOD'] != 'POST') return merror('', 'HTTP mangling: method "' . $_SERVER['REQUEST_METHOD'] . '" was requested instead of "POST"', 'suppress');*/ if (count($post) == 0) { return merror('', 'HTTP mangling: request contained no data', 'suppress'); } if (strlen(print_r($post, TRUE)) > POSTLIMIT) { pyboxlog("submit.php got too many bytes of data:" . strlen(print_r($post, TRUE))); return mfail(sprintf(__t('Submitted data (program and/or test input) ' . 'too large. Reduce size or <a href = "%s">' . 'run at home</a>.'), cscurl('install'))); } $id = getSoft($post, "pyId", "EMPTY"); $usercode = tabs_to_spaces(3, getSoft($post, "usercode" . $id, -1)); if (!is_string($usercode)) { return merror("", "No usercode" . $id . "!" . print_r($post, TRUE)); } $usercode = preg_replace('|\\xc2\\xa0|', ' ', $usercode); // nbsp $userinput = getSoft($post, "userinput", ""); $userinput = preg_replace('|\\xc2\\xa0|', ' ', $userinput); //nbsp $hash = $post["hash"]; //$graderArgsString = safeDereference("@file:" . $hash, 'hashes'); //if (!is_string($graderArgsString)) // return merror("", "PyBox error: problem hash " . $hash . " not found."); /************************************************** part 1 : set global variables, build skeleton log row; quit upon justsave. ************************************************/ //$problemArgs = multilineToAssociative($graderArgsString); // foreach ($problemArgs as $key=>$value) // $problemArgs[$key] = stripcslashes($value); $problemArgs = $wpdb->get_var($wpdb->prepare("\nSELECT graderArgs from " . $wpdb->prefix . "pb_problems WHERE hash = %s", $hash)); if ($problemArgs === NULL) { return merror("", sprintf(__t("Pybox error: problem hash %s not found. " . "Try reloading the page."), $hash)); } $problemArgs = json_decode($problemArgs, TRUE); // if ($problemArgs != $problemArgsNew) // pyboxlog("different: " . var_export($problemArgs, TRUE) // . var_export($problemArgsNew, TRUE)); //else // pyboxlog("same", TRUE); $re = '/^(' . implode("|", array_keys(optionsAndDefaults())) . ')([0-9]*)$/'; $problemOptions = optionsAndDefaults(); $subproblemOptions = array(); foreach ($problemArgs as $key => $value) { $match = preg_match($re, $key, $matches); if ($match == 0) { return merror("", "PyBox error: unknown option " . $key); } if ($matches[2] == "") { $problemOptions[$matches[1]] = $value; } else { if (!array_key_exists($matches[2], $subproblemOptions)) { $subproblemOptions[$matches[2]] = array(); } $subproblemOptions[$matches[2]][$matches[1]] = $value; } } foreach ($subproblemOptions as $index => $spo) { foreach ($problemOptions as $option => $value) { if (!array_key_exists($option, $spo)) { $subproblemOptions[$index][$option] = $value; } } } $inputInUse = isSoft($post, "inputInUse", "Y"); /* var_dump( $post, TRUE); echo "eq: " .(($post["inputInUse"] === "Y") ? "T":"F"); echo "inputinuse: " . ($inputInUse ? "T":"F");*/ if ($inputInUse && !isSoft($problemOptions, "allowinput", "Y")) { return merror("", "Pybox error: input not actually allowed"); } $facultative = isSoft($problemOptions, "facultative", "Y") || $inputInUse; $usertni = isSoft($problemOptions, "usertni", "Y"); $userid = is_user_logged_in() ? wp_get_current_user()->ID : -1; $meta['userid'] = $userid; $meta['problem'] = getSoft($problemArgs, 'slug', $hash); $slug = getSoft($problemArgs, 'slug', NULL); //most of submit logging preparation. quitting earlier => not logged in DB if ($log_it and !isSoft($problemOptions, "nolog", "Y")) { $postmisc = $post; unset($postmisc['usercode' . $id]); unset($postmisc['userinput']); unset($postmisc['hash']); $logRow = array('beginstamp' => date('Y-m-d H:i:s', $beginstamp), 'usercode' => $usercode, 'hash' => $hash, 'postmisc' => print_r($postmisc, TRUE), 'problem' => $slug, 'ipaddress' => $_SERVER['REMOTE_ADDR'], 'referer' => $_SERVER['HTTP_REFERER']); if ($inputInUse) { $logRow['userinput'] = $userinput; } $logRow['userid'] = $userid; //if ($logRow['problem']===NULL) //pyboxlog('nameless problem that is not read-only!', TRUE); } // old feature: // $justsave = array_key_exists('justsave', $post); //if ($justsave) // return msave(); /************************************************** part 2 : grading ************************************************/ if ($problemOptions['taboo'] != FALSE) { $taboo = explode(",", $problemOptions['taboo']); foreach ($taboo as $t) { $p = strpos($t, "|"); if ($p === FALSE) { $regex = $t; $display = $t; } else { $display = substr($t, 0, $p); $regex = substr($t, $p + 1); } $match = preg_match("#.*" . trim($regex) . ".*#", $usercode); if ($match != 0) { return mfail(sprintf(__t("You cannot use %s in this exercise."), "<code>" . trim($display) . "</code>")); } } } if ($problemOptions["maxeditdistance"] != FALSE) { $k = $problemOptions["maxeditdistance"]; $S = preg_replace('/\\s+/', '', $usercode); $T = preg_replace('/\\s+/', '', $problemOptions["originalcode"]); $s = strlen($S); $t = strlen($T); $msg = sprintf(__t("You are only allowed to change at most %s " . "characters compared to the original version " . "of the code."), $k); if (abs($s - $t) > 2 * $k + 5) { return mfail($msg) . " " . sprintf(__t("You changed %s or more."), 2 * $k + 5); } else { $DP = array_fill(0, $s + 1, NULL); for ($i = 0; $i <= $s; $i++) { $DP[$i] = array_fill(0, $t + 1, NULL); } for ($i = 0; $i <= $s; $i++) { for ($j = 0; $j <= $t; $j++) { if ($i == 0 || $j == 0) { $DP[$i][$j] = $i + $j; } else { $DP[$i][$j] = $DP[$i - 1][$j - 1]; if ($S[$i - 1] != $T[$j - 1]) { $DP[$i][$j]++; } $DP[$i][$j] = min($DP[$i][$j], 1 + min($DP[$i][$j - 1], $DP[$i - 1][$j])); } } } if ($DP[$s][$t] > 0 + $k) { return mfail($msg . " " . sprintf(__t("You changed %s."), $DP[$s][$t])); } } } /*************** done preprocessing source code, time to execute some things ************************/ if ($inputInUse && $slug != 'console') { global $usertni; $appendix = '<div class="testing-warning">'; if ($usertni) { $appendix .= __t('Note: ran with user tests.'); } else { $appendix .= __t('Note: ran with user inputs.'); } if (!isSoft($problemOptions, "facultative", "Y")) { $appendix .= ' ' . __t(' Click "Go back to grading" to switch back.'); } else { $appendix .= ' ' . __t(' Click "Hide input box" to switch back.'); } } else { $appendix = ''; } if (count($subproblemOptions) == 0) { // if ($problemOptions['grader'] == '*nograder*') $subproblemOptions["1"] = $problemOptions; //else //return merror("", "No test cases found!"); } // $spo: subproblemOptions for the current subproblem $tcTotal = 0; foreach ($subproblemOptions as $N => $spo) { $tcTotal += $spo["repeats"]; } $m = ''; //the result string, built a bit at a time. ksort($subproblemOptions); //test case 1, then 2, ... $tcCurrent = 0; $allCorrect = TRUE; ///*********************************************** main grading loop ***/ foreach ($subproblemOptions as $N => $spo) { // spo: subproblemOptions for current subproblem for ($i = 0; $i < $spo["repeats"]; $i++) { $tcCurrent++; if (!$inputInUse && $tcTotal > 1) { $m .= "<b>" . sprintf(__t('Results for test case %1$s out of %2$s'), $tcCurrent, $tcTotal) . "</b><br/>"; } try { $GLOBALS['pb_translation'] = getSoft($spo, 'translate', NULL); $tcOutcome = doGrading($usercode, $spo); $GLOBALS['pb_translation'] = NULL; $m .= $tcOutcome["message"]; if ($tcOutcome["result"] == "error") { return merror($m, $tcOutcome["errmsg"]); } if ($tcOutcome["result"] == "fail" && $spo["haltonwrong"] == "Y") { return mfail($m); } if ($tcOutcome["result"] == "fail") { $allCorrect = FALSE; } } catch (PyboxException $e) { return merror($m, $e->getMessage()); } if ($inputInUse) { break; } } if ($inputInUse) { break; } } return $allCorrect ? mpass($m) : mfail($m); }