Merge branch 'install_master' of https://git.in.moodle.com/amosbot/moodle-install...
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Fri, 6 Nov 2020 21:55:34 +0000 (22:55 +0100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Fri, 6 Nov 2020 21:55:34 +0000 (22:55 +0100)
admin/tool/uploaduser/classes/process.php
badges/classes/external/assertion_exporter.php
badges/classes/external/badgeclass_exporter.php
cache/classes/config.php
cache/locallib.php
lib/clilib.php
lib/moodlelib.php
lib/tests/moodlelib_test.php
mod/assign/feedback/editpdf/lib.php

index 12c2101..5321f0e 100644 (file)
@@ -1119,10 +1119,10 @@ class process {
                     $this->upt->track('enrolments', get_string('unknowncourse', 'error', s($shortname)), 'error');
                     continue;
                 }
-                $ccache[$shortname] = $course;
-                $ccache[$shortname]->groups = null;
+                $this->ccache[$shortname] = $course;
+                $this->ccache[$shortname]->groups = null;
             }
-            $courseid      = $ccache[$shortname]->id;
+            $courseid      = $this->ccache[$shortname]->id;
             $coursecontext = \context_course::instance($courseid);
             if (!isset($this->manualcache[$courseid])) {
                 $this->manualcache[$courseid] = false;
@@ -1241,41 +1241,41 @@ class process {
                     continue;
                 }
                 // Build group cache.
-                if (is_null($ccache[$shortname]->groups)) {
-                    $ccache[$shortname]->groups = array();
+                if (is_null($this->ccache[$shortname]->groups)) {
+                    $this->ccache[$shortname]->groups = array();
                     if ($groups = groups_get_all_groups($courseid)) {
                         foreach ($groups as $gid => $group) {
-                            $ccache[$shortname]->groups[$gid] = new \stdClass();
-                            $ccache[$shortname]->groups[$gid]->id   = $gid;
-                            $ccache[$shortname]->groups[$gid]->name = $group->name;
+                            $this->ccache[$shortname]->groups[$gid] = new \stdClass();
+                            $this->ccache[$shortname]->groups[$gid]->id   = $gid;
+                            $this->ccache[$shortname]->groups[$gid]->name = $group->name;
                             if (!is_numeric($group->name)) { // Only non-numeric names are supported!!!
-                                $ccache[$shortname]->groups[$group->name] = new \stdClass();
-                                $ccache[$shortname]->groups[$group->name]->id   = $gid;
-                                $ccache[$shortname]->groups[$group->name]->name = $group->name;
+                                $this->ccache[$shortname]->groups[$group->name] = new \stdClass();
+                                $this->ccache[$shortname]->groups[$group->name]->id   = $gid;
+                                $this->ccache[$shortname]->groups[$group->name]->name = $group->name;
                             }
                         }
                     }
                 }
                 // Group exists?
                 $addgroup = $user->{'group'.$i};
-                if (!array_key_exists($addgroup, $ccache[$shortname]->groups)) {
+                if (!array_key_exists($addgroup, $this->ccache[$shortname]->groups)) {
                     // If group doesn't exist,  create it.
                     $newgroupdata = new \stdClass();
                     $newgroupdata->name = $addgroup;
-                    $newgroupdata->courseid = $ccache[$shortname]->id;
+                    $newgroupdata->courseid = $this->ccache[$shortname]->id;
                     $newgroupdata->description = '';
                     $gid = groups_create_group($newgroupdata);
                     if ($gid) {
-                        $ccache[$shortname]->groups[$addgroup] = new \stdClass();
-                        $ccache[$shortname]->groups[$addgroup]->id   = $gid;
-                        $ccache[$shortname]->groups[$addgroup]->name = $newgroupdata->name;
+                        $this->ccache[$shortname]->groups[$addgroup] = new \stdClass();
+                        $this->ccache[$shortname]->groups[$addgroup]->id   = $gid;
+                        $this->ccache[$shortname]->groups[$addgroup]->name = $newgroupdata->name;
                     } else {
                         $this->upt->track('enrolments', get_string('unknowngroup', 'error', s($addgroup)), 'error');
                         continue;
                     }
                 }
-                $gid   = $ccache[$shortname]->groups[$addgroup]->id;
-                $gname = $ccache[$shortname]->groups[$addgroup]->name;
+                $gid   = $this->ccache[$shortname]->groups[$addgroup]->id;
+                $gname = $this->ccache[$shortname]->groups[$addgroup]->name;
 
                 try {
                     if (groups_add_member($gid, $user->id)) {
index 06b5238..78e86b0 100644 (file)
@@ -39,6 +39,20 @@ use stdClass;
  */
 class assertion_exporter extends exporter {
 
+    /**
+     * Constructor - saves the persistent object, and the related objects.
+     *
+     * @param mixed $data - Either an stdClass or an array of values.
+     * @param array $related - An optional list of pre-loaded objects related to this object.
+     */
+    public function __construct($data, $related = array()) {
+        // Having mixed $data is causing some issues. As this class is treating $data as an object everywhere, it can be converted
+        // to object at this point, to avoid errors and get the expected behaviour always.
+        // $data is an array when this class is a request exporter in backpack_api_mapping, but it is an object when this is
+        // used as a response exporter.
+        parent::__construct((object) $data, $related);
+    }
+
     /**
      * Map from a request response data to the internal structure.
      *
index 4d4880f..9aee956 100644 (file)
@@ -45,6 +45,12 @@ class badgeclass_exporter extends exporter {
      * @param array $related - An optional list of pre-loaded objects related to this object.
      */
     public function __construct($data, $related = array()) {
+        // Having mixed $data is causing some issues. As this class is treating $data as an object everywhere, it can be converted
+        // to object at this point, to avoid errors and get the expected behaviour always.
+        // $data is an array when this class is a request exporter in backpack_api_mapping, but it is an object when this is
+        // used as a response exporter.
+        $data = (object) $data;
+
         $pick = $this->pick_related();
         foreach ($pick as $one) {
             $isarray = false;
index 53d0f1e..021e2a6 100644 (file)
@@ -323,7 +323,7 @@ class cache_config {
      * @throws cache_exception
      */
     protected function include_configuration() {
-        $configuration = array();
+        $configuration = null;
         // We need to allow for late static bindings to allow for class path mudling happending for unit tests.
         $cachefile = static::get_config_file_path();
 
@@ -594,4 +594,4 @@ class cache_config {
         }
         throw new cache_exception('ex_nodefaultlock');
     }
-}
\ No newline at end of file
+}
index b8509ce..db20b05 100644 (file)
@@ -102,13 +102,15 @@ class cache_config_writer extends cache_config {
         $factory = cache_factory::instance();
         $locking = $factory->create_lock_instance($lockconf);
         if ($locking->lock('configwrite', 'config', true)) {
+            $tempcachefile = "{$cachefile}.tmp";
             // Its safe to use w mode here because we have already acquired the lock.
-            $handle = fopen($cachefile, 'w');
+            $handle = fopen($tempcachefile, 'w');
             fwrite($handle, $content);
             fflush($handle);
             fclose($handle);
             $locking->unlock('configwrite', 'config');
-            @chmod($cachefile, $CFG->filepermissions);
+            @chmod($tempcachefile, $CFG->filepermissions);
+            rename($tempcachefile, $cachefile);
             // Tell PHP to recompile the script.
             core_component::invalidate_opcode_php_cache($cachefile);
         } else {
index f43bf8f..e6664cd 100644 (file)
@@ -106,7 +106,8 @@ function cli_get_params(array $longoptions, array $shortmapping=null) {
                 $key   = reset($parts);
                 $value = true;
 
-                if (substr($key, 0, 3) === 'no-') {
+                if (substr($key, 0, 3) === 'no-' && !array_key_exists($key, $longoptions)
+                        && array_key_exists(substr($key, 3), $longoptions)) {
                     // Support flipping the boolean value.
                     $value = !$value;
                     $key = substr($key, 3);
index 5e09703..ae47df3 100644 (file)
@@ -6314,10 +6314,9 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
             require_once($CFG->libdir.'/filelib.php');
             $mimetype = mimeinfo('type', $attachname);
 
-            $attachmentpath = $attachment;
-
             // Before doing the comparison, make sure that the paths are correct (Windows uses slashes in the other direction).
-            $attachpath = str_replace('\\', '/', $attachmentpath);
+            // The absolute (real) path is also fetched to ensure that comparisons to allowed paths are compared equally.
+            $attachpath = str_replace('\\', '/', realpath($attachment));
 
             // Add allowed paths to an array (also check if it's not empty).
             $allowedpaths = array_filter([
@@ -6325,16 +6324,17 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
                 $CFG->dataroot,
                 $CFG->dirroot,
                 $CFG->localcachedir,
-                $CFG->tempdir
+                $CFG->tempdir,
+                $CFG->localrequestdir,
             ]);
             // Set addpath to true.
             $addpath = true;
             // Check if attachment includes one of the allowed paths.
-            foreach ($allowedpaths as $tmpvar) {
+            foreach ($allowedpaths as $allowedpath) {
                 // Make sure both variables are normalised before comparing.
-                $temppath = str_replace('\\', '/', realpath($tmpvar));
+                $allowedpath = str_replace('\\', '/', realpath($allowedpath));
                 // Set addpath to false if the attachment includes one of the allowed paths.
-                if (strpos($attachpath, $temppath) === 0) {
+                if (strpos($attachpath, $allowedpath) === 0) {
                     $addpath = false;
                     break;
                 }
@@ -6343,10 +6343,10 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
             // If the attachment is a full path to a file in the multiple allowed paths, use it as is,
             // otherwise assume it is a relative path from the dataroot (for backwards compatibility reasons).
             if ($addpath == true) {
-                $attachmentpath = $CFG->dataroot . '/' . $attachmentpath;
+                $attachment = $CFG->dataroot . '/' . $attachment;
             }
 
-            $mail->addAttachment($attachmentpath, $attachname, 'base64', $mimetype);
+            $mail->addAttachment($attachment, $attachname, 'base64', $mimetype);
         }
     }
 
index ff52d2c..6962100 100644 (file)
@@ -3446,6 +3446,9 @@ class core_moodlelib_testcase extends advanced_testcase {
             'dirroot' => [$CFG->dirroot],
             'localcachedir' => [$CFG->localcachedir],
             'tempdir' => [$CFG->tempdir],
+            // Paths within $CFG->localrequestdir.
+            'localrequestdir_request_directory' => [make_request_directory()],
+            'localrequestdir_request_storage_directory' => [get_request_storage_directory()],
             // Pass null to indicate we want to test a path relative to $CFG->dataroot.
             'relative' => [null]
         ];
index 701d394..8505f17 100644 (file)
@@ -67,7 +67,7 @@ function assignfeedback_editpdf_pluginfile(
         $options['cacheability'] = 'public';
         $options['immutable'] = true;
 
-        send_stored_file($file, 0, 0, true, $options);
+        send_stored_file($file, null, 0, false, $options);
     }
 
     if ($context->contextlevel == CONTEXT_MODULE) {