/**
  * Verify that an array is returned and it matches the content that
  * was created
  */
 public function test_coursetable_content()
 {
     global $CFG;
     $courses = array();
     $contentrows = '';
     $contenthead = get_string('emailgridhead', 'local_rruopencourses');
     $contentfoot = get_string('emailgridfoot', 'local_rruopencourses');
     $rowdata = new stdClass();
     $rowdata->id = 100;
     $rowdata->idnumber = 'IHMN440__Y1314P-01';
     $rowdata->fullname = 'TEST Course 1';
     $rowdata->url = $CFG->wwwroot . '/course/view.php?id=100';
     $courses[] = $rowdata;
     $contentrows = get_string('emailgridrow', 'local_rruopencourses', $rowdata);
     $content = $contenthead . $contentrows . $contentfoot;
     $coursetable = coursetable($courses);
     $this->assertEquals($content, $coursetable);
 }
Beispiel #2
0
/**
 * Open the courses that are due to open today.
 *
 * Typically invoked by the server's cron.  This function:
 * - Queries the course table for courses that are not open but start today
 * - Opens those courses
 * - Emails notifications to a configured list of recipients
 * - Emails a notification to an admin address if there are any errors.
 *
 * @author Gerald Albion
 * date    2013-09-25
 * @global object $DB  Moodle Database object
 * @global object $CFG Moodle configuration object
 *
 */
function rruopencourses_run()
{
    global $DB, $CFG;
    define('ROC_SEC_PER_DAY', 86400);
    // Security: Is this being called by the Moodle cron?
    // If not, $_SERVER['REMOTE_ADDR'] will be set and we should reject the request.
    if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
        die('Sorry, this function is not available from your location.');
    }
    // Setup: Clear errors.
    $errors = '';
    // Setup: Get the number of days in advance to open the course.
    $advance = get_config('local_rruopencourses', 'roc_opencoursedate') * ROC_SEC_PER_DAY;
    // Setup: query to select courses that are due to start but have not been opened yet.
    $sqlselect = "SELECT id, idnumber, fullname\n         FROM {course}\n         WHERE visible = 0\n         AND LEFT(from_unixtime(CAST(startdate AS SIGNED) - " . $advance . "), 10) = curdate()\n         ORDER BY fullname";
    // Setup: query to open courses that are due to start but have not been opened yet.
    $sqlopen = "UPDATE {course}\n         SET visible = 1\n         WHERE visible = 0\n         AND LEFT(from_unixtime(CAST(startdate AS SIGNED) - " . $advance . "), 10) = curdate()";
    // Build a list of courses that need to be opened now.
    try {
        $coursestoopen = $DB->get_records_sql($sqlselect);
    } catch (Exception $e) {
        $error = "Error retrieving list of courses to open: " . $e->getMessage() . "<br>";
        $errors .= $error;
        print $error;
    }
    // Were there any courses to open?
    if (0 == count($coursestoopen)) {
        print "No courses to open today.\n";
        return;
    }
    // Open the courses.
    try {
        $DB->execute($sqlopen);
    } catch (Exception $e) {
        $error = "\nError opening courses: " . $e->getMessage() . "\n<br>" . $sqlopen . "\n<br>";
        $errors .= $error;
        print $error;
    }
    // Identify the courses that failed to open.
    // The same query that built our list of courses will return the failed openings now that we have attempted to open them all.
    try {
        $coursesthatfailed = $DB->get_records_sql($sqlselect);
    } catch (Exception $e) {
        $error = "Error retrieving list of courses that failed to open: " . $e->getMessage() . "<br>";
        $errors .= $error;
        print $error;
    }
    // Now that we have opened the courses, change the list of courses "to be opened" into
    // a list of courses "that actually opened".  This list plus the list of failed
    // openings equals the original list of courses to change.  This is so we can report
    // only the courses that DID open in the email before reporting the ones that failed.
    foreach ($coursesthatfailed as $coursefailed) {
        $id = $coursefailed->id;
        if (isset($coursestoopen[$id])) {
            unset($coursestoopen[$id]);
        }
    }
    // Setup field strings.
    $todaysdate = date('M j, Y');
    // The site's full name is available in Course ID 1 (Thanks, Andy!)
    $servernamequery = "SELECT fullname FROM {course} WHERE id=1";
    try {
        $firstcourse = $DB->get_record_sql($servernamequery);
    } catch (Exception $e) {
        $error = "Error trying to get server name: " . $e->getMessage() . "<br>";
        $errors .= $error;
        print $error;
    }
    $servername = $firstcourse->fullname;
    // What if we couldn't get the site's full name from the course table?
    if ('' == $servername) {
        $servername = php_uname('n');
        if (false === $servername) {
            $servername = "localhost";
        }
    }
    // Setup email notification(s).
    $subjfields = new stdClass();
    $subjfields->date = $todaysdate;
    $subjfields->servername = $servername;
    $emailsubject = get_string('emailsubj', 'local_rruopencourses', $subjfields);
    $headerfields = new stdClass();
    $headerfields->fromemail = 'Course Notification <' . $CFG->noreplyaddress . '>';
    $headerfields->ver = phpversion();
    $headers = get_string('emailheaders', 'local_rruopencourses', $headerfields);
    // Build a notification email body. This will be sent to each email address in the settings.
    $bodyfields = new stdClass();
    $bodyfields->servername = $servername;
    $bodyfields->coursetable = coursetable($coursestoopen);
    $emailbody = get_string('emailbody', 'local_rruopencourses', $bodyfields);
    // Were there failed openings?  If so, add the fail section to the email body.
    if (0 != count($coursesthatfailed)) {
        // Build the optional fail section of the email body.
        $failfields = new stdClass();
        $failfields->servername = $servername;
        $failfields->coursetable = coursetable($coursesthatfailed);
        $errortable = get_string('emailfail', 'local_rruopencourses', $failfields);
        $emailbody .= $errortable;
        $errors .= "<br/>Some courses could not be opened:<br/>" . $errortable . "<br/>";
    }
    // Add the email footer, which appears after the fail section (if any).
    $emailbody .= get_string('emailfoot', 'local_rruopencourses');
    // Send the notifications.
    $emaillist = get_config('local_rruopencourses', 'roc_emails');
    $emails = explode(';', $emaillist);
    foreach ($emails as $email) {
        print "\n\nSending mail to {$email}\n";
        $errors .= local_rrusendmailto($email, $emailsubject, $emailbody, $headers);
    }
    // Were there errors?  If so, attempt to send one email containing all of them.
    if ('' != $errors) {
        $errors = "<html><head></head><body><p>There were errors opening courses:</p>\n<p>" . $errors . "</p></body></html>";
        $headers = get_string('emailheaders', 'local_rruopencourses', phpversion());
        $warningerror = local_rrusendmailto($CFG->noreplyaddress, 'Error(s) opening courses', $errors, $headers);
        if ('' != $warningerror) {
            $error = "\n\n*** NOTICE ***\n\n" . "There were error(s) and the module was unable to send an email notification of those errors.\n\n" . "The error sending email was: \n" . $warningerror . "\n\n" . "The original error(s) being reported were:\n" . $errors . "\n\n";
            file_put_contents('php://stderr', $error);
            // Output all the errors to stderr.
        }
    }
}