-
Notifications
You must be signed in to change notification settings - Fork 13
Webservice
The services are what specify what functions the Javascript can call within PHP.
Link to Moodle's documentation of services
When creating a service to allow Javascript to call a function in PHP 4 files are necessary to create/edit.
These files are:
- db/services.php (edit)
- classes/external/name_of_class.php (create)
- amd/src/repository.js (edit)
- amd/src/JS_file_that_calls_php_function.js (create/edit)
The services.php file is the file that defines what functions that the PHP should allow to be called by the Javascript.
In this file there is a list of functions that is defined, here is an example of a function:
'mod_livequiz_save_question' => [
'classname' => 'mod_livequiz\external\save_question',
'description' => 'Save a question.',
'type' => 'write',
'ajax' => true,
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
],
We only need to edit the classname and the description. Here it is important that the classname links to the correct class in the external folder.
This is the class that will be called when calling from the Javascript.
This class must have three methods: execute, execute_parameters, and execute_returns.
This is the method that will be called from the Javascript, this is where the logic should be placed. (One can make other methods within the class to call)
Here is an example of a execute method, that also calls a private static function of the class:
public static function execute(array $questiondata, int $lecturerid, int $quizid): array {
self::validate_parameters(self::execute_parameters(), [
'question' => $questiondata,
'lecturerid' => $lecturerid,
'quizid' => $quizid,
]);
$services = livequiz_services::get_singleton_service_instance();
$livequiz = $services->get_livequiz_instance($quizid);// Get livequiz object and add the new question to it.
$questionid = $questiondata['id'];
if ($questionid === 0) {// The question is new.
$livequiz->add_question(self::new_question($questiondata));
} else if ($questionid > 0) {// The question is already in the database.
// Get the question from the livequiz and set new attributes.
$question = $livequiz->get_question_by_id($questionid);
self::set_question_attributes($question, $questiondata);
}
try {
$livequiz = $services->submit_quiz($livequiz, $lecturerid);// Submit the livequiz to the database.
$templatelivequiz = $livequiz->prepare_for_template();
$templatequestions = $templatelivequiz->questions;
return $templatequestions;
} catch (dml_exception $dmle) {
debugging('Error inserting livequiz into database: ' . $dmle->getMessage());
throw $dmle;
}
}
The repository.js file is where the Javascript defines the PHP functions that can be called.
Here is an example of a function definition:
export const saveQuestion = (question, lecturerid, quizid) => fetchMany([
{
methodname: 'mod_livequiz_save_question',
args: {
question,
lecturerid,
quizid
},
}
])[0];
It is important that the methodname is correct, such that it will consist of the module name in this case mod_livequiz_ and the name of the class in this case save_question.
Thus the only thing to edit is the method name and the corresponding arguments.
This is the file that will call the function in PHP, it is important to import the function from repository.js.
Once the function is imported it can be called like any other asynchronous function in Javascript, here an example:
saveQuestion(savedQuestion, lecturerId, quizId).then((questions) => {
rerenderSavedQuestionsList(questions, updateEventListeners); // Re-render saved questions list.
rerenderTakeQuizButton(takeQuizUrl, true); // Re-render take quiz button.
})
.catch((error) => window.console.log(error));