/** * Retrieves ajax parameters for content and update or delete * user data depending on params. * * @throws \coding_exception */ public static function handle_ajax() { global $DB; // Query String Parameters. $content_id = required_param('content_id', PARAM_INT); $data_id = required_param('data_type', PARAM_RAW); $sub_content_id = required_param('sub_content_id', PARAM_INT); // Form Data. $data = optional_param('data', null, PARAM_RAW); $pre_load = optional_param('preload', null, PARAM_INT); $invalidate = optional_param('invalidate', null, PARAM_INT); if ($content_id === null || $data_id === null || $sub_content_id === null) { \H5PCore::ajaxError(get_string('missingparameters', 'hvp')); exit; // Missing parameters. } // Saving data if ($data !== NULL && $pre_load !== NULL && $invalidate !== NULL) { // Validate token if (!\H5PCore::validToken('contentuserdata', required_param('token', PARAM_RAW))) { \H5PCore::ajaxError(get_string('invalidtoken', 'hvp')); exit; } // Use context id if supplied $context_id = optional_param('contextId', null, PARAM_INT); if ($context_id) { $context = \context::instance_by_id($context_id); } else { // Otherwise try to find it from content id $context = \context_course::instance($DB->get_field('hvp', 'course', array('id' => $content_id))); } // Check permissions if (!has_capability('mod/hvp:savecontentuserdata', $context)) { \H5PCore::ajaxError(get_string('nopermissiontosavecontentuserdata', 'hvp')); http_response_code(403); exit; } if ($data === '0') { // Delete user data. self::delete_user_data($content_id, $sub_content_id, $data_id); } else { // Save user data. self::save_user_data($content_id, $sub_content_id, $data_id, $pre_load, $invalidate, $data); } \H5PCore::ajaxSuccess(); } else { // Fetch user data $user_data = self::get_user_data($content_id, $sub_content_id, $data_id); if ($user_data === false) { // Did not find data, return nothing \H5PCore::ajaxSuccess(); } else { // Found data, return encoded data \H5PCore::ajaxSuccess($user_data->data); } } exit; }
public static function handle_ajax() { global $DB, $USER; if (!\H5PCore::validToken('result', required_param('token', PARAM_RAW))) { \H5PCore::ajaxError(get_string('invalidtoken', 'hvp')); exit; } // Content parameters $content_id = required_param('contentId', PARAM_INT); $score = required_param('score', PARAM_INT); $max_score = required_param('maxScore', PARAM_INT); // Time values not usable by gradebook // $opened = required_param('opened', PARAM_INT); // $finished = required_param('finished', PARAM_INT); // Get hvp data from contentId $hvp = $DB->get_record('hvp', array('id' => $content_id)); // Check permissions $context = \context_course::instance($hvp->course); if (!has_capability('mod/hvp:saveresults', $context)) { \H5PCore::ajaxError(get_string('nopermissiontosaveresult', 'hvp')); http_response_code(403); exit; } // Create grade object and set grades $grade = (object) array('userid' => $USER->id); // Get course module id from db, required for grade item $cm_id_sql = "SELECT cm.id, h.name\n FROM {course_modules} cm, {hvp} h, {modules} m\n WHERE cm.instance = h.id AND h.id = ? AND m.name = 'hvp' AND m.id = cm.module"; $result = $DB->get_record_sql($cm_id_sql, array($content_id)); // Set grade using Gradebook API $hvp->cmidnumber = $result->id; $hvp->name = $result->name; $hvp->rawgrade = $score; $hvp->rawgrademax = $max_score; hvp_grade_item_update($hvp, $grade); // Get content info for log $content = $DB->get_record_sql("SELECT c.name AS title, l.machine_name AS name, l.major_version, l.minor_version\n FROM {hvp} c\n JOIN {hvp_libraries} l ON l.id = c.main_library_id\n WHERE c.id = ?", array($content_id)); // Log view new \mod_hvp\event('results', 'set', $content_id, $content->title, $content->name, $content->major_version . '.' . $content->minor_version); \H5PCore::ajaxSuccess(); exit; }
/** * Print results data */ public function print_results() { global $DB; // Check permission $course = $DB->get_field('hvp', 'course', array('id' => $this->content_id)); $context = \context_course::instance($course); if (!has_capability('mod/hvp:viewresults', $context)) { \H5PCore::ajaxError(get_string('nopermissiontoviewresult', 'hvp')); http_response_code(403); exit; } $results = $this->get_results(); // Make data readable for humans $rows = array(); foreach ($results as $result) { $rows[] = array(\html_writer::link(new \moodle_url('/user/view.php', array('id' => $result->user_id, 'course' => $course)), \fullname($result)), $result->rawgrade === null ? '—' : (int) $result->rawgrade, $result->rawgrade === null ? '—' : (int) $result->rawgrademax, empty($result->timemodified) ? '—' : date('Y/m/d – H:i', $result->timemodified)); } // Print header('Cache-Control: no-cache'); header('Content-type: application/json'); print json_encode(array('num' => $this->get_results_num(), 'rows' => $rows)); }
/** * Handle file uploads through AJAX. * * @since 1.1.0 */ public function ajax_files() { $plugin = H5P_Plugin::get_instance(); $files_directory = $plugin->get_h5p_path(); if (!wp_verify_nonce(filter_input(INPUT_GET, 'token', FILTER_SANITIZE_STRING), 'h5p_editor_ajax')) { H5PCore::ajaxError(__('Invalid security token. Please reload the editor.', $this->plugin_slug)); exit; } $contentId = filter_input(INPUT_POST, 'contentId', FILTER_SANITIZE_NUMBER_INT); if ($contentId) { $files_directory .= '/content/' . $contentId; } else { $files_directory .= '/editor'; } $editor = $this->get_h5peditor_instance(); $interface = $plugin->get_h5p_instance('interface'); $file = new H5peditorFile($interface, $files_directory); if (!$file->isLoaded()) { H5PCore::ajaxError(__('File not found on server. Check file upload settings.', $this->plugin_slug)); exit; } if ($file->validate() && $file->copy()) { // Keep track of temporary files so they can be cleaned up later. $editor->addTmpFile($file); } header('Cache-Control: no-cache'); // Must support IE, so cannot use application/json header('Content-type: text/plain; charset=utf-8'); print $file->getResult(); exit; }
* int contextId */ case 'files': global $DB; // TODO: Check permissions if (!\H5PCore::validToken('editorajax', required_param('token', PARAM_RAW))) { \H5PCore::ajaxError(get_string('invalidtoken', 'hvp')); exit; } // Get Content ID and Context ID for upload $contentid = required_param('contentId', PARAM_INT); $contextid = required_param('contextId', PARAM_INT); // Create file $file = new H5peditorFile(\mod_hvp\framework::instance('interface')); if (!$file->isLoaded()) { H5PCore::ajaxError(get_string('filenotfound', 'hvp')); break; } // Make sure file is valid if ($file->validate()) { $core = \mod_hvp\framework::instance('core'); // Save the valid file $file_id = $core->fs->saveFile($file, $contentid, $contextid); // Track temporary files for later cleanup $DB->insert_record_raw('hvp_tmpfiles', array('id' => $file_id), false, false, true); } $file->printResult(); break; /* * Throw error if AJAX isnt handeled */
// Make sure file is valid if ($file->validate()) { $core = \mod_hvp\framework::instance('core'); // Save the valid file $file_id = $core->fs->saveFile($file, $contentid, $contextid); // Track temporary files for later cleanup $DB->insert_record_raw('hvp_tmpfiles', array('id' => $file_id), false, false, true); } $file->printResult(); break; case 'logxapievent': global $CFG; // Trigger a Moodle log event for each xAPI statement // that is dispatched by the H5P (hvp) object. if (!\H5PCore::validToken('logxapievent', required_param('token', PARAM_RAW))) { \H5PCore::ajaxError(get_string('invalidtoken', 'hvp')); exit; } $hvpid = optional_param('hvpid', null, PARAM_INT); $courseid = optional_param('courseid', null, PARAM_INT); $jsonxapistatement = optional_param('xapistatement', null, PARAM_RAW); $xapistatement = json_decode($jsonxapistatement, true); $context = \context_module::instance($hvpid); $event = \mod_hvp\event\hvp_xapi::create(array('objectid' => $hvpid, 'context' => $context, 'other' => array('statement' => $xapistatement['data']['statement']), 'courseid' => $courseid)); $event->trigger(); // Debugging... if (!empty($CFG->debug) and $CFG->debug >= DEBUG_DEVELOPER) { $msg = "xAPI '" . $xapistatement['data']['statement']['verb']['display']['en-US'] . "' statement dispatched"; \H5PCore::ajaxSuccess($msg); http_response_code(200); }
/** * Handle user results reported by the H5P content. * * @since 1.5.0 */ public function ajax_contents_user_data() { global $wpdb; $content_id = filter_input(INPUT_GET, 'content_id'); $data_id = filter_input(INPUT_GET, 'data_type'); $sub_content_id = filter_input(INPUT_GET, 'sub_content_id'); $current_user = wp_get_current_user(); if ($content_id === NULL || $data_id === NULL || $sub_content_id === NULL || !$current_user->ID) { return; // Missing parameters } $response = (object) array('success' => TRUE); $data = filter_input(INPUT_POST, 'data'); $preload = filter_input(INPUT_POST, 'preload'); $invalidate = filter_input(INPUT_POST, 'invalidate'); if ($data !== NULL && $preload !== NULL && $invalidate !== NULL) { if (!wp_verify_nonce(filter_input(INPUT_POST, 'token'), 'h5p_contentuserdata')) { H5PCore::ajaxError(__('Invalid security token', $this->plugin_slug)); exit; } if ($data === '0') { // Remove data $wpdb->delete($wpdb->prefix . 'h5p_contents_user_data', array('content_id' => $content_id, 'data_id' => $data_id, 'user_id' => $current_user->ID, 'sub_content_id' => $sub_content_id), array('%d', '%s', '%d', '%d')); } else { // Wash values to ensure 0 or 1. $preload = $preload === '0' ? 0 : 1; $invalidate = $invalidate === '0' ? 0 : 1; // Determine if we should update or insert $update = $wpdb->get_var($wpdb->prepare("SELECT content_id\n FROM {$wpdb->prefix}h5p_contents_user_data\n WHERE content_id = %d\n AND user_id = %d\n AND data_id = %s\n AND sub_content_id = %d", $content_id, $current_user->ID, $data_id, $sub_content_id)); if ($update === NULL) { // Insert new data $wpdb->insert($wpdb->prefix . 'h5p_contents_user_data', array('user_id' => $current_user->ID, 'content_id' => $content_id, 'sub_content_id' => $sub_content_id, 'data_id' => $data_id, 'data' => $data, 'preload' => $preload, 'invalidate' => $invalidate, 'updated_at' => current_time('mysql', 1)), array('%d', '%d', '%d', '%s', '%s', '%d', '%d', '%s')); } else { // Update old data $wpdb->update($wpdb->prefix . 'h5p_contents_user_data', array('data' => $data, 'preload' => $preload, 'invalidate' => $invalidate, 'updated_at' => current_time('mysql', 1)), array('user_id' => $current_user->ID, 'content_id' => $content_id, 'data_id' => $data_id, 'sub_content_id' => $sub_content_id), array('%s', '%d', '%d', '%s'), array('%d', '%d', '%s', '%d')); } } // Inserted, updated or deleted H5PCore::ajaxSuccess(); exit; } else { // Fetch data $response->data = $wpdb->get_var($wpdb->prepare("SELECT hcud.data\n FROM {$wpdb->prefix}h5p_contents_user_data hcud\n WHERE user_id = %d\n AND content_id = %d\n AND data_id = %s\n AND sub_content_id = %d", $current_user->ID, $content_id, $data_id, $sub_content_id)); if ($response->data === NULL) { unset($response->data); } } header('Cache-Control: no-cache'); header('Content-type: application/json; charset=utf-8'); print json_encode($response); exit; }