Access moodle gradebook into another sytem

Re: Access moodle gradebook into another sytem

by Chris Richter -
Number of replies: 5

Hi Tim,

I am interested in the best way to get gradebook results into other systems.

Is the local plugin you mentioned for XML Grades available?

In reply to Chris Richter

Re: Access moodle gradebook into another sytem

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

It looks like we have never shared that plugin. It is rather OU-specific, so we would not want to properly release it, becuase then people might expect us to support it. However, I will see if we can do a dump of the code, so that you can pick it apart, and use the bits you like in your own plugin.

In reply to Tim Hunt

Re: Access moodle gradebook into another sytem

by Gilles-Philippe Leblanc -
Hi Tim,

I would also need to develop a plugin for recovering student grades from an external database and insert them into Moodle.

Question to avoid unnecessary work, do you think you could share it with me so I adapts it to our needs or at least inspire me?

Thank you very much.
In reply to Gilles-Philippe Leblanc

Re: Access moodle gradebook into another sytem

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

The error handling makes it a bit ugly, but the basic idea is:

  1. Get the grade data in a simple XML format, by fetching it from a URL that the other system provides.
  2. Pass that XML to the standard import_xml_grades function provided by the gradebook.
  3. If that seems to have worked OK, call grade_import_commit to actually save the data to the database.

Here is the full version of the key function, copied and pasted from our code. (This runs on cron, so error handling involves sending an email to a certain email address to notify of the error.)

    /**
     * Import the remote data into the gradebook
     * @param string $cronuser the user to email status information to.
     * @return boolean true if successful, false on failure.
     */
    public function import_into_gradebook($cronuser) {
        global $DB;

        // Large files are likely to take their time and memory. Let PHP know
        // that we'll take longer, and that the process should be recycled soon
        // to free up memory.
        set_time_limit(0);
        raise_memory_limit(MEMORY_EXTRA);

        //read the data from the url into a string
        $errormess = '';
        $commitmess = '';

        if (!$text = file_get_contents($this->urlused)) {
            mtrace('sending email to ' . $cronuser->email . ' ...');
            email_to_user($cronuser, $cronuser, get_string('importerroremailsubj', 'externalquiz'),
                    externalquiz_autoimport::format_mail_error_message('importerrorreadfile',
                                                                $this->urlused));
            mtrace(externalquiz_autoimport::format_message('importerrorreadfile', $this->urlused));

            return false;
        }

        if (!$course = $DB->get_record('course', array('id'=>$this->course))) {
            mtrace(externalquiz_autoimport::format_message('nocourseid', $this->course));
        }

        //check its valid XML
        if ($text === false) {
            $errormess = externalquiz_autoimport::format_message(
                    'importerrorreadfile', $this->urlused);
        } else {
            $olderrorsetting = libxml_use_internal_errors(true);
            $a = simplexml_load_string($text);
            libxml_use_internal_errors($olderrorsetting);
            if ($a === false || $a->getName() != 'results') {
                $errormess = externalquiz_autoimport::format_message(
                        'importerrornotvalidxml', $this->urlused);
            } else if ($a->count() == 0) {
                // The file was OK, but empty. In this case, we cannot pass it
                // to Moodle because Moodle treats this as an error.
                $commitmess = 'The file was empty, so nothing to import.';
            } else {
                //It was a valid XML string so lets import
                $error = '';

                if (!$course = $DB->get_record('course', array('id'=> $this->course))) {
                    $errormess = externalquiz_autoimport::format_message(
                            'nocourseid', $this->course);
                } else {
                    $importcode = import_xml_grades($text, $course, $error);
                    if ($importcode !== false) {
                        // comit the code if we are up this far, stick the output
                        // in a string so we can email it.
                        ob_start();
                        if (grade_import_commit($this->course, $importcode, '', true)) {
                            // Bug 8970 we don't want output in the cron log on success.
                        } else {
                            $errormess = externalquiz_autoimport::format_message(
                                    'importcommitedfailed', $this->urlused .
                                    get_string('witherror', 'externalquiz', $error));
                        }
                        $commitmess = ob_get_contents();
                        ob_end_clean();
                    } else {
                        $errormess = externalquiz_autoimport::format_message(
                                'importtoGBfailed', $this->urlused .
                                get_string('witherror', 'externalquiz', $error));
                    }
                }
            }
        }

        if ($errormess) {
            mtrace('sending error email to ' . $cronuser->email . ' ...');
            mtrace($errormess);
            email_to_user($cronuser, $cronuser, get_string('importerroremailsubj', 'externalquiz'),
                    externalquiz_autoimport::format_mail_error_message('importgradeerror',
                                                                $errormess));
        }

        return $commitmess && !$errormess;
    }