MDL-56602 themes: Use version number as base themerev
authorAndrew Nicols <andrew@nicols.co.uk>
Tue, 8 Nov 2016 01:16:32 +0000 (09:16 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Thu, 10 Nov 2016 00:02:31 +0000 (08:02 +0800)
lib/moodlelib.php
lib/outputlib.php
lib/tests/moodlelib_test.php

index f1451d5..75b843f 100644 (file)
@@ -9620,6 +9620,35 @@ function get_course_display_name_for_list($course) {
     }
 }
 
+/**
+ * Convert a Moodle Version formatted number into a guaranteed incrementing timestamp.
+ *
+ * @param float $version The version to convert
+ * @return int The calculated timestamp
+ */
+function version_to_timestamp($version) {
+    // Moodle version numbers are in stored in one of the following formats:
+    // * YYYYMMDDRR.II
+    // * YYYYMMDDRR
+    //
+    // To convert these into a value akin to a Unix Time Stamp, we take the timestamp of the YYYYMMDD component. and add
+    // a calculation of the RR.II component.
+
+    // The hours/minutes/seconds must be specified otherwise the current time is used.
+    $date = DateTime::createFromFormat('YmdHis', substr($version, 0, 8) . '000000');
+    $revision = $date->format('U');
+
+    // To ensure a unique incrementing timestamp, we multiple the $rr value by a value larger than the max of $ii,
+    // and then add $ii.
+    // As a two-digit number, the max value of $ii is 99, so we multiply by 100.
+    $revision += (100 * (int) substr($version, 8, 2));
+
+    // Note: If there is no .II value, or it is 00, then the substr will return false, but be calculated as 0 when cast to int.
+    $revision += (int) substr($version, 11, 2);
+
+    return $revision;
+}
+
 /**
  * The lang_string class
  *
index 4daeab8..b68e070 100644 (file)
@@ -86,7 +86,13 @@ function theme_get_revision() {
 
     if (empty($CFG->themedesignermode)) {
         if (empty($CFG->themerev)) {
-            return -1;
+            // If theme designer mode is not set, and there is no themerev, this is almost certainly part of the installation.
+            // We attempt to set a themerev based on the Moodle version number to avoid costly rebuilds of the dynamic
+            // theme files between each page load.
+            $version = null;
+            require("{$CFG->dirroot}/version.php");
+
+            return version_to_timestamp($version);
         } else {
             return $CFG->themerev;
         }
index af169a5..bc9bf47 100644 (file)
@@ -3282,4 +3282,26 @@ class core_moodlelib_testcase extends advanced_testcase {
              'samecourse' => false, 'result' => false],
         ];
     }
+
+    /**
+     * Unit tests for the version_to_timestamp function.
+     */
+    public function test_version_to_timestamp() {
+        $baseversion = 2016110100.00;
+        $basestamp = version_to_timestamp($baseversion);
+        $this->assertEquals(1477929600, $basestamp);
+
+        // Adding 00.99 to the version should increase the timestamp.
+        $stamp = version_to_timestamp($baseversion + .99);
+        $this->assertGreaterThan($basestamp, $stamp);
+
+        // Adding 01.00 to the base version should increase the stamp higher than the 00.99 version.
+        $newstamp = version_to_timestamp($baseversion + 01.00);
+        $this->assertGreaterThan($basestamp, $newstamp);
+        $this->assertGreaterThan($stamp, $newstamp);
+
+        // The previous day's timestamp at it's highest increment should be lower than the base version.
+        $stamp = version_to_timestamp($baseversion - 00.01);
+        $this->assertLessThan($basestamp, $stamp);
+    }
 }