Merge branch 'master_MDL-44712' of git://github.com/danmarsden/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 22 Aug 2016 09:33:31 +0000 (10:33 +0100)
committerDan Poltawski <dan@moodle.com>
Mon, 22 Aug 2016 09:33:31 +0000 (10:33 +0100)
admin/settings/server.php
lib/accesslib.php
lib/classes/task/stats_cron_task.php
lib/db/tasks.php
lib/db/upgrade.php
lib/statslib.php
lib/tests/accesslib_test.php
lib/tests/statslib_test.php
version.php

index 548031b..8ef94a7 100644 (file)
@@ -79,7 +79,6 @@ $temp->add(new admin_setting_configselect('statsmaxruntime', new lang_string('st
                                                                                                                                                             60*60*7 => '7 '.new lang_string('hours'),
                                                                                                                                                             60*60*8 => '8 '.new lang_string('hours') )));
 $temp->add(new admin_setting_configtext('statsruntimedays', new lang_string('statsruntimedays', 'admin'), new lang_string('configstatsruntimedays', 'admin'), 31, PARAM_INT));
-$temp->add(new admin_setting_configtime('statsruntimestarthour', 'statsruntimestartminute', new lang_string('statsruntimestart', 'admin'), new lang_string('configstatsruntimestart', 'admin'), array('h' => 0, 'm' => 0)));
 $temp->add(new admin_setting_configtext('statsuserthreshold', new lang_string('statsuserthreshold', 'admin'), new lang_string('configstatsuserthreshold', 'admin'), 0, PARAM_INT));
 $ADMIN->add('server', $temp);
 
index a2c4eb8..19033df 100644 (file)
@@ -4208,15 +4208,32 @@ function get_role_users($roleid, context $context, $parent = false, $fields = ''
     // Adding the fields from $sort that are not present in $fields.
     $sortarray = preg_split('/,\s*/', $sort);
     $fieldsarray = preg_split('/,\s*/', $fields);
+
+    // Discarding aliases from the fields.
+    $fieldnames = array();
+    foreach ($fieldsarray as $key => $field) {
+        list($fieldnames[$key]) = explode(' ', $field);
+    }
+
     $addedfields = array();
     foreach ($sortarray as $sortfield) {
         // Throw away any additional arguments to the sort (e.g. ASC/DESC).
-        list ($sortfield) = explode(' ', $sortfield);
-        if (!in_array($sortfield, $fieldsarray)) {
+        list($sortfield) = explode(' ', $sortfield);
+        list($tableprefix) = explode('.', $sortfield);
+        $fieldpresent = false;
+        foreach ($fieldnames as $fieldname) {
+            if ($fieldname === $sortfield || $fieldname === $tableprefix.'.*') {
+                $fieldpresent = true;
+                break;
+            }
+        }
+
+        if (!$fieldpresent) {
             $fieldsarray[] = $sortfield;
             $addedfields[] = $sortfield;
         }
     }
+
     $fields = implode(', ', $fieldsarray);
     if (!empty($addedfields)) {
         $addedfields = implode(', ', $addedfields);
index 5ce0791..f9f5465 100644 (file)
@@ -44,28 +44,19 @@ class stats_cron_task extends scheduled_task {
     public function execute() {
         global $CFG;
 
-        $timenow = time();
         // Run stats as at the end because they are known to take very long time on large sites.
         if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) {
             require_once($CFG->dirroot.'/lib/statslib.php');
-            // Check we're not before our runtime.
-            $timetocheck = stats_get_base_daily() + $CFG->statsruntimestarthour * 60 * 60 + $CFG->statsruntimestartminute * 60;
-
-            if ($timenow > $timetocheck) {
-                // Process configured number of days as max (defaulting to 31).
-                $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays);
-                if (stats_cron_daily($maxdays)) {
-                    if (stats_cron_weekly()) {
-                        if (stats_cron_monthly()) {
-                            stats_clean_old();
-                        }
+            // Process configured number of days as max (defaulting to 31).
+            $maxdays = empty($CFG->statsruntimedays) ? 31 : abs($CFG->statsruntimedays);
+            if (stats_cron_daily($maxdays)) {
+                if (stats_cron_weekly()) {
+                    if (stats_cron_monthly()) {
+                        stats_clean_old();
                     }
                 }
-                \core_php_time_limit::raise();
-            } else {
-                mtrace('Next stats run after:'. userdate($timetocheck));
             }
+            \core_php_time_limit::raise();
         }
     }
-
 }
index 49863b8..f7296c5 100644 (file)
@@ -306,7 +306,7 @@ $tasks = array(
         'classname' => 'core\task\stats_cron_task',
         'blocking' => 0,
         'minute' => '0',
-        'hour' => '*',
+        'hour' => '0',
         'day' => '*',
         'dayofweek' => '*',
         'month' => '*'
index 3476d07..3fd023e 100644 (file)
@@ -2083,5 +2083,46 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2016081700.00);
     }
 
+    if ($oldversion < 2016081700.02) {
+        // Default schedule values.
+        $hour = 0;
+        $minute = 0;
+
+        // Get the old settings.
+        if (isset($CFG->statsruntimestarthour)) {
+            $hour = $CFG->statsruntimestarthour;
+        }
+        if (isset($CFG->statsruntimestartminute)) {
+            $minute = $CFG->statsruntimestartminute;
+        }
+
+        // Retrieve the scheduled task record first.
+        $stattask = $DB->get_record('task_scheduled', array('component' => 'moodle', 'classname' => '\core\task\stats_cron_task'));
+
+        // Don't touch customised scheduling.
+        if ($stattask && !$stattask->customised) {
+
+            $nextruntime = mktime($hour, $minute, 0, date('m'), date('d'), date('Y'));
+            if ($nextruntime < $stattask->lastruntime) {
+                // Add 24 hours to the next run time.
+                $newtime = new DateTime();
+                $newtime->setTimestamp($nextruntime);
+                $newtime->add(new DateInterval('P1D'));
+                $nextruntime = $newtime->getTimestamp();
+            }
+            $stattask->nextruntime = $nextruntime;
+            $stattask->minute = $minute;
+            $stattask->hour = $hour;
+            $stattask->customised = 1;
+            $DB->update_record('task_scheduled', $stattask);
+        }
+        // These settings are no longer used.
+        unset_config('statsruntimestarthour');
+        unset_config('statsruntimestartminute');
+        unset_config('statslastexecution');
+
+        upgrade_main_savepoint(true, 2016081700.02);
+    }
+
     return true;
 }
index 23fa555..a414fae 100644 (file)
@@ -138,22 +138,6 @@ function stats_cron_daily($maxdays=1) {
         set_config('statslastdaily', $timestart);
     }
 
-    // calculate scheduled time
-    $scheduledtime = stats_get_base_daily() + $CFG->statsruntimestarthour*60*60 + $CFG->statsruntimestartminute*60;
-
-    // Note: This will work fine for sites running cron each 4 hours or less (hopefully, 99.99% of sites). MDL-16709
-    // check to make sure we're due to run, at least 20 hours after last run
-    if (isset($CFG->statslastexecution) && ((time() - 20*60*60) < $CFG->statslastexecution)) {
-        mtrace("...preventing stats to run, last execution was less than 20 hours ago.");
-        return false;
-    // also check that we are a max of 4 hours after scheduled time, stats won't run after that
-    } else if (time() > $scheduledtime + 4*60*60) {
-        mtrace("...preventing stats to run, more than 4 hours since scheduled time.");
-        return false;
-    } else {
-        set_config('statslastexecution', time()); /// Grab this execution as last one
-    }
-
     $nextmidnight = stats_get_next_day_start($timestart);
 
     // are there any days that need to be processed?
@@ -161,7 +145,6 @@ function stats_cron_daily($maxdays=1) {
         return true; // everything ok and up-to-date
     }
 
-
     $timeout = empty($CFG->statsmaxruntime) ? 60*60*24 : $CFG->statsmaxruntime;
 
     if (!set_cron_lock('statsrunning', $now + $timeout)) {
@@ -1041,13 +1024,10 @@ function stats_get_base_monthly($time=0) {
  */
 function stats_get_next_day_start($time) {
     $next = stats_get_base_daily($time);
-    $next = $next + 60*60*26;
-    $next = stats_get_base_daily($next);
-    if ($next <= $time) {
-        //DST trouble - prevent infinite loops
-        $next = $next + 60*60*24;
-    }
-    return $next;
+    $nextdate = new DateTime();
+    $nextdate->setTimestamp($next);
+    $nextdate->add(new DateInterval('P1D'));
+    return $nextdate->getTimestamp();
 }
 
 /**
@@ -1057,13 +1037,10 @@ function stats_get_next_day_start($time) {
  */
 function stats_get_next_week_start($time) {
     $next = stats_get_base_weekly($time);
-    $next = $next + 60*60*24*9;
-    $next = stats_get_base_weekly($next);
-    if ($next <= $time) {
-        //DST trouble - prevent infinite loops
-        $next = $next + 60*60*24*7;
-    }
-    return $next;
+    $nextdate = new DateTime();
+    $nextdate->setTimestamp($next);
+    $nextdate->add(new DateInterval('P1W'));
+    return $nextdate->getTimestamp();
 }
 
 /**
@@ -1073,13 +1050,10 @@ function stats_get_next_week_start($time) {
  */
 function stats_get_next_month_start($time) {
     $next = stats_get_base_monthly($time);
-    $next = $next + 60*60*24*33;
-    $next = stats_get_base_monthly($next);
-    if ($next <= $time) {
-        //DST trouble - prevent infinite loops
-        $next = $next + 60*60*24*31;
-    }
-    return $next;
+    $nextdate = new DateTime();
+    $nextdate->setTimestamp($next);
+    $nextdate->add(new DateInterval('P1M'));
+    return $nextdate->getTimestamp();
 }
 
 /**
index e3a2f99..04686f6 100644 (file)
@@ -1453,6 +1453,22 @@ class core_accesslib_testcase extends advanced_testcase {
         $this->assertObjectHasAttribute('lastname', $users[$user3->id]);
         $this->assertObjectHasAttribute('firstname', $users[$user3->id]);
 
+        $users = get_role_users($teacherrole->id, $coursecontext, false, 'u.*');
+        $this->assertDebuggingNotCalled();
+        $this->assertCount(2, $users);
+
+        $users = get_role_users($teacherrole->id, $coursecontext, false, 'u.id AS id_alias');
+        $this->assertDebuggingCalled('get_role_users() adding u.lastname, u.firstname to the query result because they were required by $sort but missing in $fields');
+        $this->assertCount(2, $users);
+        $this->assertArrayHasKey($user1->id, $users);
+        $this->assertObjectHasAttribute('id_alias', $users[$user1->id]);
+        $this->assertObjectHasAttribute('lastname', $users[$user1->id]);
+        $this->assertObjectHasAttribute('firstname', $users[$user1->id]);
+        $this->assertArrayHasKey($user3->id, $users);
+        $this->assertObjectHasAttribute('id_alias', $users[$user3->id]);
+        $this->assertObjectHasAttribute('lastname', $users[$user3->id]);
+        $this->assertObjectHasAttribute('firstname', $users[$user3->id]);
+
         $users = get_role_users($teacherrole->id, $coursecontext, false, 'u.id, u.email, u.idnumber', 'u.idnumber', null, $group->id);
         $this->assertCount(1, $users);
         $this->assertArrayHasKey($user3->id, $users);
index aa7a251..66089a4 100644 (file)
@@ -61,7 +61,6 @@ class core_statslib_testcase extends advanced_testcase {
         core_date::set_default_server_timezone();
         $CFG->statsfirstrun           = 'all';
         $CFG->statslastdaily          = 0;
-        $CFG->statslastexecution      = 0;
 
         // Figure out the broken day start so I can figure out when to the start time should be.
         $time   = time();
@@ -74,9 +73,6 @@ class core_statslib_testcase extends advanced_testcase {
 
         $shour  = intval(($time - $stime) / (60*60));
 
-        $CFG->statsruntimestarthour   = $shour;
-        $CFG->statsruntimestartminute = 0;
-
         if ($DB->record_exists('user', array('username' => 'user1'))) {
             return;
         }
@@ -392,6 +388,22 @@ class core_statslib_testcase extends advanced_testcase {
     public function test_statslib_get_next_day_start() {
         $this->setTimezone(0);
         $this->assertEquals(1272758400, stats_get_next_day_start(1272686410));
+
+        // Try setting timezone to some place in the US.
+        $this->setTimezone('America/New_York', 'America/New_York');
+        // Then set the time for midnight before daylight savings.
+        // 1425790800 is midnight in New York (2015-03-08) Daylight saving will occur in 2 hours time.
+        // 1425873600 is midnight the next day.
+        $this->assertEquals(1425873600, stats_get_next_day_start(1425790800));
+        $this->assertEquals(23, ((1425873600 - 1425790800) / 60 ) / 60);
+        // Then set the time for midnight before daylight savings ends.
+        // 1446350400 is midnight in New York (2015-11-01) Daylight saving will finish in 2 hours time.
+        // 1446440400 is midnight the next day.
+        $this->assertEquals(1446440400, stats_get_next_day_start(1446350400));
+        $this->assertEquals(25, ((1446440400 - 1446350400) / 60 ) / 60);
+        // The next day should be normal.
+        $this->assertEquals(1446526800, stats_get_next_day_start(1446440400));
+        $this->assertEquals(24, ((1446526800 - 1446440400) / 60 ) / 60);
     }
 
     /**
index ef4693f..f67a899 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2016081700.01;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2016081700.02;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.