function safe_var_dump($var, $cnt = 0) { switch (true) { case is_array($var): echo str_repeat(" ", $cnt) . "array(" . count($var) . ") {" . PHP_EOL; foreach ($var as $key => $value) { echo str_repeat(" ", $cnt + 1) . "[" . (is_integer($key) ? $key : '"' . $key . '"') . "]=>" . PHP_EOL; safe_var_dump($value, $cnt + 1); } echo str_repeat(" ", $cnt) . "}" . PHP_EOL; break; case is_integer($var): echo str_repeat(" ", $cnt) . "int(" . $var . ")" . PHP_EOL; break; case is_float($var): echo str_repeat(" ", $cnt) . "float(" . $var . ")" . PHP_EOL; break; case is_bool($var): echo str_repeat(" ", $cnt) . "bool(" . ($var === true ? "true" : "false") . ")" . PHP_EOL; break; case is_string($var): echo str_repeat(" ", $cnt) . "string(" . strlen($var) . ") \"{$var}\"" . PHP_EOL; break; case is_resource($var): echo str_repeat(" ", $cnt) . "resource() of type (" . get_resource_type($var) . ")" . PHP_EOL; break; case is_object($var): echo str_repeat(" ", $cnt) . "object(" . get_class($var) . ")" . PHP_EOL; break; case is_null($var): echo str_repeat(" ", $cnt) . "NULL" . PHP_EOL; break; } }
function safe_var_dump() { static $cnt = 0; foreach (\func_get_args() as $var) { switch (\true) { case \is_array($var): echo \str_repeat(" ", $cnt) . "array(" . \count($var) . ") {" . \PHP_EOL; foreach ($var as $key => $value) { echo \str_repeat(" ", $cnt + 1) . "[" . (\is_integer($key) ? $key : '"' . $key . '"') . "]=>" . \PHP_EOL; ++$cnt; safe_var_dump($value); --$cnt; } echo \str_repeat(" ", $cnt) . "}" . \PHP_EOL; break; case \is_int($var): echo \str_repeat(" ", $cnt) . "int(" . $var . ")" . \PHP_EOL; break; case \is_float($var): echo \str_repeat(" ", $cnt) . "float(" . $var . ")" . \PHP_EOL; break; case \is_bool($var): echo \str_repeat(" ", $cnt) . "bool(" . ($var === \true ? "true" : "false") . ")" . \PHP_EOL; break; case \is_string($var): echo \str_repeat(" ", $cnt) . "string(" . \strlen($var) . ") \"{$var}\"" . \PHP_EOL; break; case \is_resource($var): echo \str_repeat(" ", $cnt) . "resource() of type (" . \get_resource_type($var) . ")" . \PHP_EOL; break; case \is_object($var): echo \str_repeat(" ", $cnt) . "object(" . \get_class($var) . ")" . \PHP_EOL; break; case \is_null($var): echo \str_repeat(" ", $cnt) . "NULL" . \PHP_EOL; break; } } }
require_once "../../config.php"; require_once $CFG->dirroot . "/pdo.php"; require_once $CFG->dirroot . "/lib/lms_lib.php"; require_once "peer_util.php"; use Tsugi\Core\LTIX; // Sanity checks $LTI = LTIX::requireData(); if (!$USER->instructor) { die("Instructor only"); } if (isset($_POST['doClear'])) { session_unset(); die('session unset'); } $OUTPUT->header(); $OUTPUT->bodyStart(); $OUTPUT->flashMessages(); $OUTPUT->welcomeUserCourse(); $OUTPUT->togglePre("Session data", safe_var_dump($_SESSION)); ?> <form method="post"> <input type="submit" name="doExit" onclick="location='<?php echo addSession('index.php'); ?> '; return false;" value="Exit"> <input type="submit" name="doClear" value="Clear Session (will log out out)"> </form> <?php flush(); $OUTPUT->footer();
} // Redirect to ourself header('Location: ' . addSession('index.php')); return; } // Start of the output $OUTPUT->header(); $OUTPUT->bodyStart(); $OUTPUT->flashMessages(); echo "<h1>Grade Test Harness</h1>\n"; $OUTPUT->welcomeUserCourse(); ?> <form method="post"> Enter grade: <input type="number" name="grade" step="0.01" min="0" max="1.0"><br/> <input type="submit" name="send" value="Send grade"> </form> <?php if (isset($_SESSION['debug_log'])) { echo "<p>Debug output from grade send:</p>\n"; $OUTPUT->dumpDebugArray($_SESSION['debug_log']); unset($_SESSION['debug_log']); } echo "<pre>Global Tsugi Objects:\n\n"; var_dump($USER); var_dump($CONTEXT); var_dump($LINK); echo "\n<hr/>\n"; echo "Session data (low level):\n"; echo safe_var_dump($_SESSION); $OUTPUT->footer();
function bodyStart($checkpost = true) { echo "\n</head>\n<body style=\"padding: 15px 15px 15px 15px;\">\n"; if ($checkpost && count($_POST) > 0) { $dump = safe_var_dump($_POST); echo '<p style="color:red">Error - Unhandled POST request</p>'; echo "\n<pre>\n"; echo $dump; echo "\n</pre>\n"; error_log($dump); die_with_error_log("Unhandled POST request"); } }
/** * Extract all of the post data, set up data in tables, and set up session. */ public static function setupSession() { global $CFG, $PDOX; if (!LTI::isRequest()) { return false; } // Pull LTI data out of the incoming $_POST and map into the same // keys that we use in our database (i.e. like $row) $post = self::extractPost(); if ($post === false) { $pdata = safe_var_dump($_POST); error_log('Missing post data: ' . $pdata); require 'lti/nopost.php'; return; } if ($post['key'] == '12345' && !$CFG->DEVELOPER) { die_with_error_log('You can only use key 12345 in developer mode'); } // We make up a Session ID Key because we don't want a new one // each time the same user launches the same link. $session_id = self::getCompositeKey($post, $CFG->sessionsalt); session_id($session_id); session_start(); header('Content-Type: text/html; charset=utf-8'); // Since we might reuse session IDs, clean everything out session_unset(); $_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp // Read all of the data from the database with a very long // LEFT JOIN and get all the data we have back in the $row variable // $row = loadAllData($CFG->dbprefix, false, $post); $row = self::loadAllData($CFG->dbprefix, $CFG->dbprefix . 'profile', $post); $delta = 0; if (isset($_POST['oauth_timestamp'])) { $server_time = $_POST['oauth_timestamp'] + 0; $delta = abs(time() - $server_time); if ($delta > 480) { // More than four minutes is getting close error_log('Warning: Time skew, delta=' . $delta . ' sever_time=' . $server_time . ' our_time=' . time()); } } // Check the nonce to make sure there is no reuse if ($row['nonce'] !== null) { die_with_error_log('OAuth nonce error key=' . $post['key'] . ' nonce=' . $row['nonce']); } // Use returned data to check the OAuth signature on the // incoming data - returns true or an array $valid = LTI::verifyKeyAndSecret($post['key'], $row['secret']); // If there is a new_secret it means an LTI2 re-registration is in progress and we // need to check both the current and new secret until the re-registration is committed if ($valid !== true && strlen($row['new_secret']) > 0 && $row['new_secret'] != $row['secret']) { $valid = LTI::verifyKeyAndSecret($post['key'], $row['new_secret']); if ($valid) { $row['secret'] = $row['new_secret']; } $row['new_secret'] = null; } if ($valid !== true) { print "<pre>\n"; print_r($valid); print "</pre>\n"; die_with_error_log('OAuth validation fail key=' . $post['key'] . ' delta=' . $delta . ' error=' . $valid[0]); } $actions = self::adjustData($CFG->dbprefix, $row, $post); // Record the nonce but first probabilistically check if ($CFG->noncecheck > 0) { if (time() % $CFG->noncecheck == 0) { $PDOX->queryDie("DELETE FROM {$CFG->dbprefix}lti_nonce WHERE\n created_at < DATE_ADD(CURRENT_TIMESTAMP(), INTERVAL -{$CFG->noncetime} SECOND)"); // error_log("Nonce table cleanup done."); } $PDOX->queryDie("INSERT INTO {$CFG->dbprefix}lti_nonce\n (key_id, nonce) VALUES ( :key_id, :nonce)", array(':nonce' => $post['nonce'], ':key_id' => $row['key_id'])); } // If there is an appropriate role override variable, we use that role if (isset($row['role_override']) && isset($row['role']) && $row['role_override'] > $row['role']) { $row['role'] = $row['role_override']; } // Put the information into the row variable // TODO: do AES on the secret $_SESSION['lti'] = $row; $_SESSION['lti_post'] = $_POST; if (isset($_SERVER['HTTP_USER_AGENT'])) { $_SESSION['HTTP_USER_AGENT'] = $_SERVER['HTTP_USER_AGENT']; } if (isset($_SERVER['REMOTE_ADDR'])) { $_SESSION['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR']; } $_SESSION['CSRF_TOKEN'] = uniqid(); // Save this to make sure the user does not wander unless we launched from the root $scp = getScriptPath(); if (strlen($scp) > 0) { $_SESSION['script_path'] = getScriptPath(); } // Check if we can auto-login the system user if (Settings::linkGet('dologin', false) && isset($PDOX) && $PDOX !== false) { loginSecureCookie(); } // Set up basic custom values (legacy) if (isset($_POST['custom_due'])) { $when = strtotime($_POST['custom_due']); if ($when === false) { echo '<p>Error, bad setting for custom_due=' . htmlentities($_POST['custom_due']) . '</p>'; error_log('Bad custom_due=' . $_POST['custom_due']); flush(); } else { $_SESSION['due'] = $_POST['custom_due']; } } if (isset($_POST['custom_timezone'])) { $_SESSION['timezone'] = $_POST['custom_timezone']; } if (isset($_POST['custom_penalty_time'])) { if ($_POST['custom_penalty_time'] + 0 == 0) { echo '<p>Error, bad setting for custom_penalty_time=' . htmlentities($_POST['custom_penalty_time']) . '</p>'; error_log('Bad custom_penalty_time=' . $_POST['custom_penalty_time']); flush(); } else { $_SESSION['penalty_time'] = $_POST['custom_penalty_time']; } } if (isset($_POST['custom_penalty_cost'])) { if ($_POST['custom_penalty_cost'] + 0 == 0) { echo '<p>Error, bad setting for custom_penalty_cost=' . htmlentities($_POST['custom_penalty_cost']) . '</p>'; error_log('Bad custom_penalty_cost=' . $_POST['custom_penalty_cost']); flush(); } else { $_SESSION['penalty_cost'] = $_POST['custom_penalty_cost']; } } $breadcrumb = 'Launch,'; $breadcrumb .= isset($row['key_id']) ? $row['key_id'] : ''; $breadcrumb .= ','; $breadcrumb .= isset($row['user_id']) ? $row['user_id'] : ''; $breadcrumb .= ','; $breadcrumb .= isset($_POST['user_id']) ? str_replace(',', ';', $_POST['user_id']) : ''; $breadcrumb .= ','; $breadcrumb .= $session_id; $breadcrumb .= ','; $breadcrumb .= curPageURL(); $breadcrumb .= ','; $breadcrumb .= isset($_SESSION['email']) ? $_SESSION['email'] : ''; error_log($breadcrumb); return $session_id; }
$('#info').modal(); <? } ?> // I cannot make this reliable :( $(window).resize(function () { compute_divs(); }); window.MOBILE = $(window).width() <= 480; // window.MOBILE = TRUE; load_files(); if ( MOBILE === false ) { compute_divs(); <?php if ( $codemirror ) { ?> load_cm(); <?php } ?> } }); </script> <?php if ( $USER->instructor ) { echo("<!--\n"); echo(">Global Tsugi Objects:\n\n"); var_dump($USER); var_dump($CONTEXT); var_dump($LINK); echo("\n<hr/>\n"); echo("Session data (low level):\n"); echo(safe_var_dump($_SESSION)); echo("\n-->\n"); } ?> <?php $OUTPUT->footerEnd();
/** Send a grade applying the due date logic and only increasing grades * * Puts messages in the session for a redirect. * * @param $gradetosend - The grade in the range 0.0 .. 1.0 * @param $oldgrade - The previous grade in the range 0.0 .. 1.0 (optional) * @param $dueDate - The due date for this assignment */ public static function gradeSendDueDate($gradetosend, $oldgrade = false, $dueDate = false) { if ($gradetosend == 1.0) { $scorestr = "Your answer is correct, score saved."; } else { $scorestr = "Your score of " . $gradetosend * 100.0 . "% has been saved."; } if ($dueDate && $dueDate->penalty > 0) { $gradetosend = $gradetosend * (1.0 - $dueDate->penalty); $scorestr = "Effective Score = " . $gradetosend * 100.0 . "% after " . $dueDate->penalty * 100.0 . " percent late penalty"; } if ($oldgrade && $oldgrade > $gradetosend) { $scorestr = "New score of " . $gradetosend * 100.0 . "% is < than previous grade of " . $oldgrade * 100.0 . "%, previous grade kept"; $gradetosend = $oldgrade; } // Use LTIX to send the grade back to the LMS. $debug_log = array(); $retval = self::gradeSend($gradetosend, false, $debug_log); $_SESSION['debug_log'] = $debug_log; if ($retval === true) { $_SESSION['success'] = $scorestr; } else { if (is_string($retval)) { $_SESSION['error'] = "Grade not sent: " . $retval; } else { $svd = safe_var_dump($retval); error_log("Grade sending error:" . $svd); $_SESSION['error'] = "Grade sending error: " . substr($svd, 0, 100); } } }
$json_content = false; $updated_at = false; if ($row !== false && strlen($row['json_content']) > 0) { $now_str = $row['now']; $now = strtotime($now_str); $updated_at = $row['updated_at']; $updated_time = strtotime($updated_at); $datediff = $now - $updated_time; try { $json_content = json_decode($row['json_content']); if ($json_content == null) { error_log("JSON error in cache for {$address}: " . json_last_error_msg()); } } catch (Exception $e) { error_log("DIE: JSON cache failure, address={$address} sha256={$address_sha256}"); error_log("DIE: " . safe_var_dump($row)); $json_content = null; } if ($json_content != null && $datediff < $expire_seconds) { error_log("Retrieved {$address} from cache delta={$datediff} updated_at=" . $row['updated_at']); echo jsonIndent(json_encode($json_content)); return; } } // Must retrieve the information $getUrl = 'http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=' . urlencode($address); $data = Net::doGet($getUrl); $response = Net::getLastHttpResponse(); $json_data = json_decode($data); if ($json_data == null) { error_log("JSON error from Google for {$address}: " . json_last_error_msg());