Teaching Moodle to Laravel

I had to integrate a Laravel application with a Moodle instance: certain users, under given circumstances, may generate a new course in Moodle, be enroled as teacher, and add other platform's users as students.

The first step has been to setup a unified authentication, implementing a OAuth2 server in Laravel (with Passport) and enabling custom OAuth2 authentication in Moodle. That was (mostly) easy.

Then I enabled Moodle's Web Services, and created a new Service including the functions core_course_create_courses, core_user_create_users, enrol_manual_enrol_users and enrol_manual_unenrol_users. This also was almost easy, given the understanding of the essential Moodle's mechanics about external APIs.

MoodleRest provides a no-brainer PHP package to implement the Moodle API, so there were no problems in implementing the desired flow on the Laravel side.

The only problem - the actual reason for which I'm writing this blog post - was about the creation and first login of new users: even specifying oauth2 as authentication method (the parameter auth in the data submitted through core_user_create_users), Moodle insists in validating the user sending him a verification email. Not exactly the expected behaviour, as the user can only be logged by my own application (which already verified him).

After a bit investigation, I found the Moodle's database table which connects an OAuth2 login with an actual user. And, brutally, when I create a new Moodle user from Laravel I also insert an entry there:

$arr = $moodle->request(
    'core_user_create_users',
    $users,
    MoodleRest::METHOD_GET
);

$moodle_id = $arr[0]->id;

// here, "moodle" is the database name
// and "mdl_auth_oauth2_linked_login" is the target table

DB::table('moodle.mdl_auth_oauth2_linked_login')->insert([
    'timecreated' => time(),
    'timemodified' => time(),
    'usermodified' => 0,
    'userid' => $moodle_id,
    'issuerid' => 1,
    'username' => $email,
    'email' => $email,
    'confirmtoken' => '',
    'confirmtokenexpires' => 0,
]);

This, of course, implies that the user database used for Laravel has a grant also on the Moodle's database.

Dumping data directly into the Moodle's database may not be the most elegant solution but, as always, it works.