Skip to content

Commit

Permalink
GH-723 Update logic to store responses in central instance
Browse files Browse the repository at this point in the history
  • Loading branch information
davidszkiba committed Nov 8, 2024
1 parent a0f6183 commit 2662929
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 46 deletions.
84 changes: 38 additions & 46 deletions classes/external/submit_responses.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ public static function execute_parameters() {
return new external_function_parameters([
'responses' => new external_multiple_structure(
new external_single_structure([
'questionid' => new external_value(PARAM_INT, 'The ID of the question'),
'response' => new external_value(PARAM_RAW, 'The response data'),
'timestamp' => new external_value(PARAM_INT, 'Unix timestamp of the response'),
'questionhash' => new external_value(PARAM_TEXT, 'Hash of the question'),
'fraction' => new external_value(PARAM_TEXT, 'Response fraction value'),
'remoteuserid' => new external_value(PARAM_INT, 'User ID from remote instance'),
'timestamp' => new external_value(PARAM_TEXT, 'Unix timestamp of the response')
])
),
)
]);
}

Expand All @@ -77,11 +78,11 @@ public static function execute_returns() {
'message' => new external_value(PARAM_TEXT, 'Status message'),
'responses' => new external_multiple_structure(
new external_single_structure([
'questionid' => new external_value(PARAM_INT, 'The ID of the question'),
'questionhash' => new external_value(PARAM_TEXT, 'Hash of the question'),
'status' => new external_value(PARAM_BOOL, 'Individual response status'),
'message' => new external_value(PARAM_TEXT, 'Individual response message'),
'message' => new external_value(PARAM_TEXT, 'Individual response message')
])
),
)
]);
}

Expand All @@ -92,9 +93,6 @@ public static function execute_returns() {
* @return array The status and processed responses
*/
public static function execute($responses) {
// The $USER is the local user for whom the token was created.
global $USER, $DB;

// Parameter validation.
$params = self::validate_parameters(self::execute_parameters(), ['responses' => $responses]);

Expand All @@ -107,32 +105,43 @@ public static function execute($responses) {
$results = [];
$overallstatus = true;
$sourceurl = self::get_remote_source_url();

foreach ($params['responses'] as $response) {
try {
// Validate that the question exists.
if (!$DB->record_exists('question', ['id' => $response['questionid']])) {
throw new invalid_parameter_exception('Invalid question ID: ' . $response['questionid']);
// Basic validation of the fraction value.
if (!is_numeric($response['fraction'])) {
throw new invalid_parameter_exception('Invalid fraction value for question ' . $response['questionhash']);
}

// Basic validation of the timestamp.
if (!is_numeric($response['timestamp'])) {
throw new invalid_parameter_exception('Invalid timestamp for question ' . $response['questionhash']);
}

// Here you would process and store the response.
// This is a placeholder for your actual response processing logic.
$status = self::process_response($response);
// Store the response using the response handler.
$success = \local_catquiz\remote\response\response_handler::store_response(
$response['questionhash'],
$response['fraction'],
$response['remoteuserid'],
$sourceurl
);

$results[] = [
'questionid' => $response['questionid'],
'status' => $status,
'message' => $status ? 'Success' : 'Failed to process response',
'questionhash' => $response['questionhash'],
'status' => $success,
'message' => $success ? 'Success' : 'Failed to store response'
];

if (!$status) {
if (!$success) {
$overallstatus = false;
}

} catch (\Exception $e) {
$results[] = [
'questionid' => $response['questionid'],
'questionhash' => $response['questionhash'],
'status' => false,
'message' => $e->getMessage(),
'message' => $e->getMessage()
];
$overallstatus = false;
}
Expand All @@ -141,35 +150,18 @@ public static function execute($responses) {
return [
'status' => $overallstatus,
'message' => $overallstatus ? 'All responses processed successfully' : 'Some responses failed',
'responses' => $results,
'responses' => $results
];
}

/**
* Process a single response.
* Get the source URL of the remote instance.
*
* @param array $response The response data
* @return bool Success status
* @return string The source URL
*/
private static function process_response($response) {
global $DB, $USER;

try {
// Add your response processing logic here.
// This is where you would store the response in your plugin's tables.
// For example:
$record = new \stdClass();
$record->questionid = $response['questionid'];
$record->response = $response['response'];
$record->timestamp = $response['timestamp'];
$record->userid = $USER->id;

// Insert into your responses table.
// $DB->insert_record('local_catquiz_responses', $record);

return true;
} catch (\Exception $e) {
return false;
}
private static function get_remote_source_url() {
global $CFG;
// This should be the URL that uniquely identifies this Moodle instance.
return $CFG->wwwroot;
}
}
124 changes: 124 additions & 0 deletions classes/remote/response/response_handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

namespace local_catquiz\remote\response;

defined('MOODLE_INTERNAL') || die();

use local_catquiz\remote\hash\question_hasher;

/**
* Handles storage and processing of remote responses.
*
* @package local_catquiz
* @copyright 2024 Wunderbyte GmbH <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class response_handler {

/**
* Store a response from a remote instance.
*
* @param string $questionhash The question hash
* @param string $response The response data
* @param int $remoteuserid The user ID from remote instance
* @param string $sourceurl The source URL
* @return bool Success status
*/
public static function store_response($questionhash, $response, $remoteuserid, $sourceurl) {
global $DB;

$record = new \stdClass();
$record->questionhash = $questionhash;
$record->remoteuserid = $remoteuserid;
$record->response = $response;
$record->sourceurl = $sourceurl;
$record->timecreated = time();

try {
$DB->insert_record('local_catquiz_remote_responses', $record);
return true;
} catch (\Exception $e) {
debugging('Error storing remote response: ' . $e->getMessage(), DEBUG_DEVELOPER);
return false;
}
}

/**
* Process stored responses.
*
* @param int $batchsize Number of responses to process in one batch
* @return array Processing results
*/
public static function process_responses($batchsize = 100) {
global $DB;

$responses = $DB->get_records('local_catquiz_remote_responses',
['timeprocessed' => null],
'timecreated ASC',
'*',
0,
$batchsize);

$results = ['processed' => 0, 'errors' => 0];

foreach ($responses as $response) {
$questionid = question_hasher::get_questionid_from_hash($response->questionhash);
if (!$questionid) {
self::mark_response_error($response, 'Question not found');
$results['errors']++;
continue;
}

try {
// Process response using existing model_responses class.
// This needs to be implemented based on your existing logic.
self::mark_response_processed($response);
$results['processed']++;
} catch (\Exception $e) {
self::mark_response_error($response, $e->getMessage());
$results['errors']++;
}
}

return $results;
}

/**
* Marks a response as processed.
*
* @param \stdClass $response The response record
*/
private static function mark_response_processed($response) {
global $DB;
$response->timeprocessed = time();
$response->processinginfo = json_encode(['status' => 'success']);
$DB->update_record('local_catquiz_remote_responses', $response);
}

/**
* Marks a response as failed with error information.
*
* @param \stdClass $response The response record
* @param string $error The error message
*/
private static function mark_response_error($response, $error) {
global $DB;
$response->timeprocessed = time();
$response->processinginfo = json_encode(['status' => 'error', 'message' => $error]);
$DB->update_record('local_catquiz_remote_responses', $response);
}
}

0 comments on commit 2662929

Please sign in to comment.