Overdose
Overdose

Reputation: 585

Moodle : is it possible to access user from javascript ONLY

My purpose is simply being able to retrieve basic user info (id, username, lastname, firstname) in javascript on ANY moodle page WITHOUT having to create a plugin.

I've seen that there is a javascript global variable in Moodle : M but no user info in there.

Is there a way to access user info (id at least) from a logged in user on any page only in javascript another way ?

I've tried the generico filter to create a block i would be able to retrieve information from

<span data-firstname="@@USER:firstname@@" data-lastname="@@USER:lastname@@" data-userid="@@USER:id@@" id="useriddata"></span>

But since i want it on any page, i've tried on the Moodle > Extra HTML textarea. Sadly it doesn't work since the HTML seems not to be filtered there.

Creating a plugin for such a small information seems wrong. What can i do ?

Upvotes: 2

Views: 2064

Answers (2)

Chuck Terry
Chuck Terry

Reputation: 266

You can get the user's ID from several different places on the page if the user is logged in. Afterwards, you can fetch information about the user from the edit profile page. You can also easily pull course information and grading using similar methodology, but that's beyond the scope of this question. Below is some code to get you started:

function getUserId() {
    // First we look for the user's id in the link to their profile page
    const profileLink = document.querySelector('.logininfo > .logininfo > a');
    if (profileLink !== null) {
        const urlParameters = profileLink.href.split('?')[1].split('&');
        const count = urlParameters.length;
        for (let index = 0; index < length; index++) {
            const parameter = urlParameters[index];
            const [key, value] = parameter.split('=');
            if (key === 'id') {
                return value;
            }
        }
    }
    // Next we look for any element with the data-user-id attribute
    const userIdDatasetElement = document.querySelector('*[data-user-id]');
    if (userIdDatasetElement !== null) {
        const userId = userIdDatasetElement?.dataset?.userId;
        if (typeof userId === 'string') {
            return userId;
        }
    }
    // When that doesn't work we try to find an element with the data-route-param attribute
    const fallbackElement = document.querySelector('*[data-route-param]');
    if (fallbackElement !== null) {
        const userId = fallbackElement?.dataset?.userId;
        if (typeof userId === 'string') {
            return userId;
        }
    }
    // And finally, we fail silently if we can't find it
    return '0';
}

async function getUserDetails(host = location.host, userId = getUserId()) {
    // Fetch the edit page for the user's profile
    const response = await fetch(`https://${host}/user/edit.php?id=${userId}&course=1`);
    const text = await response.text();
    // Parse it into a DOM object, alternatively you could use RegExp on the text if resources are scarce
    const parser = new DOMParser();
    const dom = parser.parseFromString(text, "text/html");
    // Pull the values from the necessary fields, these may differ by installation, update as needed
    const firstName = dom.querySelector('#id_firstname')?.value;
    const lastName = dom.querySelector('#id_lastname')?.value;
    const altName = dom.querySelector('#id_alternatename')?.value;
    const email = dom.querySelector('#id_email')?.value;
    const emailVisibility = dom.querySelector('#id_maildisplay > option[selected]')?.innerText;
    const moodleNetProfileId = dom.querySelector('#id_moodlenetprofile')?.value;
    const city = dom.querySelector('#id_city')?.value;
    const country = dom.querySelector('#id_country > option[selected]')?.innerText;
    const timeZone = dom.querySelector('#id_timezone > option[selected]')?.innerText;
    const description = dom.querySelector('#id_description_editor')?.value;
    const image = dom.querySelector('img.userpicture')?.src;
    // Finally, we return the information
    return {
        userId,
        firstName,
        lastName,
        altName,
        email,
        emailVisibility,
        moodleNetProfileId,
        city,
        country,
        timeZone,
        description,
        image
    };
}

// Here's an example.  Run it in the DevTools console on your Moodle installation to see the magic :)
getUserDetails().then((userObject) => console.dir(userObject));

Upvotes: 0

Evgeniy Voevodin
Evgeniy Voevodin

Reputation: 241

You may request user info via Web Services using ajax, e.g. core_user_get_users_by_field. You should, however, determine userid first, which can probably be retrieved from top menu links after signin (profile link etc.). But I would recommend to develop the plugin anyway

Upvotes: 1

Related Questions