Merge branch 'MDL-55028-master' of git://github.com/junpataleta/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 27 Jun 2016 20:13:48 +0000 (22:13 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 27 Jun 2016 20:13:48 +0000 (22:13 +0200)
22 files changed:
admin/settings/plugins.php
admin/tool/lp/classes/external/course_module_summary_exporter.php
competency/classes/api.php
competency/classes/evidence.php
competency/tests/api_test.php
lib/moodlelib.php
lib/tests/moodlelib_test.php
lib/upgrade.txt
mod/choice/backup/moodle2/backup_choice_stepslib.php
mod/choice/lib.php
mod/forum/lib.php
mod/lesson/mod_form.php
repository/filepicker.php
repository/filesystem/lib.php
repository/lib.php
repository/repository_ajax.php
repository/upgrade.txt
search/classes/manager.php
search/tests/fixtures/mock_search_area.php
search/tests/fixtures/testable_core_search.php
search/tests/manager_test.php
webservice/tests/externallib_test.php

index 1beaca5..680bd3d 100644 (file)
@@ -40,7 +40,9 @@ if ($hassiteconfig) {
         get_string('requiremodintro', 'admin'), get_string('requiremodintro_desc', 'admin'), 0));
     $ADMIN->add('modsettings', $temp);
 
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('mod') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('mod');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\mod $plugin */
         $plugin->load_settings($ADMIN, 'modsettings', $hassiteconfig);
     }
@@ -50,7 +52,9 @@ if ($hassiteconfig) {
     $temp = new admin_settingpage('manageformats', new lang_string('manageformats', 'core_admin'));
     $temp->add(new admin_setting_manageformats());
     $ADMIN->add('formatsettings', $temp);
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('format') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('format');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\format $plugin */
         $plugin->load_settings($ADMIN, 'formatsettings', $hassiteconfig);
     }
@@ -58,7 +62,9 @@ if ($hassiteconfig) {
     // blocks
     $ADMIN->add('modules', new admin_category('blocksettings', new lang_string('blocks')));
     $ADMIN->add('blocksettings', new admin_page_manageblocks());
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('block') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('block');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\block $plugin */
         $plugin->load_settings($ADMIN, 'blocksettings', $hassiteconfig);
     }
@@ -67,7 +73,9 @@ if ($hassiteconfig) {
     $ADMIN->add('modules', new admin_category('messageoutputs', new lang_string('messageoutputs', 'message')));
     $ADMIN->add('messageoutputs', new admin_page_managemessageoutputs());
     $ADMIN->add('messageoutputs', new admin_page_defaultmessageoutputs());
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('message') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('message');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\message $plugin */
         $plugin->load_settings($ADMIN, 'messageoutputs', $hassiteconfig);
     }
@@ -108,7 +116,9 @@ if ($hassiteconfig) {
     $temp = new admin_externalpage('authtestsettings', get_string('testsettings', 'core_auth'), new moodle_url("/auth/test_settings.php"), 'moodle/site:config', true);
     $ADMIN->add('authsettings', $temp);
 
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('auth') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('auth');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\auth $plugin */
         $plugin->load_settings($ADMIN, 'authsettings', $hassiteconfig);
     }
@@ -122,7 +132,9 @@ if ($hassiteconfig) {
     $temp = new admin_externalpage('enroltestsettings', get_string('testsettings', 'core_enrol'), new moodle_url("/enrol/test_settings.php"), 'moodle/site:config', true);
     $ADMIN->add('enrolments', $temp);
 
-    foreach(core_plugin_manager::instance()->get_plugins_of_type('enrol') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('enrol');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\enrol $plugin */
         $plugin->load_settings($ADMIN, 'enrolments', $hassiteconfig);
     }
@@ -133,7 +145,9 @@ if ($hassiteconfig) {
     $temp = new admin_settingpage('manageeditors', new lang_string('editorsettings', 'editor'));
     $temp->add(new admin_setting_manageeditors());
     $ADMIN->add('editorsettings', $temp);
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('editor') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('editor');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\editor $plugin */
         $plugin->load_settings($ADMIN, 'editorsettings', $hassiteconfig);
     }
@@ -143,7 +157,9 @@ if ($hassiteconfig) {
     $temp = new admin_settingpage('manageantiviruses', new lang_string('antivirussettings', 'antivirus'));
     $temp->add(new admin_setting_manageantiviruses());
     $ADMIN->add('antivirussettings', $temp);
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('antivirus') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('antivirus');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /* @var \core\plugininfo\antivirus $plugin */
         $plugin->load_settings($ADMIN, 'antivirussettings', $hassiteconfig);
     }
@@ -182,7 +198,9 @@ if ($hassiteconfig) {
     }
     $ADMIN->add('filtersettings', $temp);
 
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('filter') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('filter');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\filter $plugin */
         $plugin->load_settings($ADMIN, 'filtersettings', $hassiteconfig);
     }
@@ -283,7 +301,9 @@ if ($hassiteconfig) {
         new lang_string('createrepository', 'repository'), $url, 'moodle/site:config', true));
     $ADMIN->add('repositorysettings', new admin_externalpage('repositoryinstanceedit',
         new lang_string('editrepositoryinstance', 'repository'), $url, 'moodle/site:config', true));
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('repository') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('repository');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\repository $plugin */
         $plugin->load_settings($ADMIN, 'repositorysettings', $hassiteconfig);
     }
@@ -337,7 +357,9 @@ if ($hassiteconfig) {
                         'admin'), new lang_string('configenablewsdocumentation', 'admin', $wsdoclink), false));
     $ADMIN->add('webservicesettings', $temp);
     /// links to protocol pages
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('webservice') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('webservice');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\webservice $plugin */
         $plugin->load_settings($ADMIN, 'webservicesettings', $hassiteconfig);
     }
@@ -409,7 +431,9 @@ if ($hassiteconfig || has_capability('moodle/question:config', $systemcontext))
             get_string('responsehistory', 'question'), '', 0, $hiddenofvisible));
 
     // Settings for particular question types.
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('qtype') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('qtype');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\qtype $plugin */
         $plugin->load_settings($ADMIN, 'qtypesettings', $hassiteconfig);
     }
@@ -421,7 +445,9 @@ if ($hassiteconfig && !empty($CFG->enableplagiarism)) {
     $ADMIN->add('plagiarism', new admin_externalpage('manageplagiarismplugins', new lang_string('manageplagiarism', 'plagiarism'),
         $CFG->wwwroot . '/' . $CFG->admin . '/plagiarism.php'));
 
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('plagiarism') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('plagiarism');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\plagiarism $plugin */
         $plugin->load_settings($ADMIN, 'plagiarism', $hassiteconfig);
     }
@@ -445,6 +471,7 @@ if ($hassiteconfig) {
     }
     if (!empty($pages)) {
         $ADMIN->add('modules', new admin_category('coursereports', new lang_string('coursereports')));
+        core_collator::asort_objects_by_property($pages, 'visiblename');
         foreach ($pages as $page) {
             $ADMIN->add('coursereports', $page);
         }
@@ -468,6 +495,7 @@ foreach (core_component::get_plugin_list('report') as $report => $plugindir) {
 $ADMIN->add('modules', new admin_category('reportplugins', new lang_string('reports')));
 $ADMIN->add('reportplugins', new admin_externalpage('managereports', new lang_string('reportsmanage', 'admin'),
                                                     $CFG->wwwroot . '/' . $CFG->admin . '/reports.php'));
+core_collator::asort_objects_by_property($pages, 'visiblename');
 foreach ($pages as $page) {
     $ADMIN->add('reportplugins', $page);
 }
@@ -510,6 +538,7 @@ if ($hassiteconfig) {
     }
     $ADMIN->add('searchplugins', $temp);
 
+    core_collator::asort_objects_by_property($pages, 'visiblename');
     foreach ($pages as $page) {
         $ADMIN->add('searchplugins', $page);
     }
@@ -523,7 +552,9 @@ if ($hassiteconfig) {
 }
 
 // Now add various admin tools.
-foreach (core_plugin_manager::instance()->get_plugins_of_type('tool') as $plugin) {
+$plugins = core_plugin_manager::instance()->get_plugins_of_type('tool');
+core_collator::asort_objects_by_property($plugins, 'displayname');
+foreach ($plugins as $plugin) {
     /** @var \core\plugininfo\tool $plugin */
     $plugin->load_settings($ADMIN, null, $hassiteconfig);
 }
@@ -534,6 +565,7 @@ if ($hassiteconfig) {
     $ADMIN->add('cache', new admin_externalpage('cacheconfig', new lang_string('cacheconfig', 'cache'), $CFG->wwwroot .'/cache/admin.php'));
     $ADMIN->add('cache', new admin_externalpage('cachetestperformance', new lang_string('testperformance', 'cache'), $CFG->wwwroot . '/cache/testperformance.php'));
     $ADMIN->add('cache', new admin_category('cachestores', new lang_string('cachestores', 'cache')));
+    $ADMIN->locate('cachestores')->set_sorting(true);
     foreach (core_component::get_plugin_list('cachestore') as $plugin => $path) {
         $settingspath = $path.'/settings.php';
         if (file_exists($settingspath)) {
@@ -547,7 +579,9 @@ if ($hassiteconfig) {
 // Add Calendar type settings.
 if ($hassiteconfig) {
     $ADMIN->add('modules', new admin_category('calendartype', new lang_string('calendartypes', 'calendar')));
-    foreach (core_plugin_manager::instance()->get_plugins_of_type('calendartype') as $plugin) {
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('calendartype');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
         /** @var \core\plugininfo\calendartype $plugin */
         $plugin->load_settings($ADMIN, 'calendartype', $hassiteconfig);
     }
@@ -562,7 +596,9 @@ if ($hassiteconfig) {
 
 // Extend settings for each local plugin. Note that their settings may be in any part of the
 // settings tree and may be visible not only for administrators.
-foreach (core_plugin_manager::instance()->get_plugins_of_type('local') as $plugin) {
+$plugins = core_plugin_manager::instance()->get_plugins_of_type('local');
+core_collator::asort_objects_by_property($plugins, 'displayname');
+foreach ($plugins as $plugin) {
     /** @var \core\plugininfo\local $plugin */
     $plugin->load_settings($ADMIN, null, $hassiteconfig);
 }
index dfd24fd..e776a1a 100644 (file)
@@ -40,14 +40,18 @@ class course_module_summary_exporter extends \core_competency\external\exporter
     }
 
     protected function get_other_values(renderer_base $output) {
-        $context = $this->related['cm']->context;
+        $cm = $this->related['cm'];
+        $context = $cm->context;
 
-        return array(
-            'id' => $this->related['cm']->id,
-            'name' => external_format_string($this->related['cm']->name, $context->id),
-            'url' => $this->related['cm']->url->out(),
-            'iconurl' => $this->related['cm']->get_icon_url()->out()
+        $values = array(
+            'id' => $cm->id,
+            'name' => external_format_string($cm->name, $context->id),
+            'iconurl' => $cm->get_icon_url()->out()
         );
+        if ($cm->url) {
+            $values['url'] = $cm->url->out();
+        }
+        return $values;
     }
 
 
@@ -60,7 +64,8 @@ class course_module_summary_exporter extends \core_competency\external\exporter
                 'type' => PARAM_TEXT
             ),
             'url' => array(
-                'type' => PARAM_URL
+                'type' => PARAM_URL,
+                'optional' => true,
             ),
             'iconurl' => array(
                 'type' => PARAM_URL
index b11daa4..a440bc2 100644 (file)
@@ -4152,7 +4152,7 @@ class api {
      * @param int $limit Number of records to return.
      * @return \core_competency\evidence[]
      */
-    public static function list_evidence_in_course($userid = 0, $courseid = 0, $competencyid = 0, $sort = 'timecreated',
+    public static function list_evidence_in_course($userid = 0, $courseid = 0, $competencyid = 0, $sort = 'timecreated, id',
                                                    $order = 'DESC', $skip = 0, $limit = 0) {
         static::require_enabled();
 
@@ -4166,11 +4166,8 @@ class api {
             return array();
         }
 
-        $params = array(
-            'usercompetencyid' => $usercompetency->get_id(),
-            'contextid' => context_course::instance($courseid)->id
-        );
-        return evidence::get_records($params, $sort, $order, $skip, $limit);
+        $context = context_course::instance($courseid);
+        return evidence::get_records_for_usercompetency($usercompetency->get_id(), $context, $sort, $order, $skip, $limit);
     }
 
     /**
index ed3445d..cc8ec05 100644 (file)
@@ -284,4 +284,52 @@ class evidence extends persistent {
         return has_capability('moodle/competency:evidencedelete', context_user::instance($userid));
     }
 
+    /**
+     * Load a list of records in a context for a user competency.
+     *
+     * @param int $usercompetencyid The id of the user competency.
+     * @param context $context Context to filter the evidence list.
+     * @param string $sort The field from the evidence table to sort on.
+     * @param string $order The sort direction
+     * @param int $skip Limitstart.
+     * @param int $limit Number of rows to return.
+     *
+     * @return \core_competency\persistent[]
+     */
+    public static function get_records_for_usercompetency($usercompetencyid,
+                                                          \context $context,
+                                                          $sort = '',
+                                                          $order = 'ASC',
+                                                          $skip = 0,
+                                                          $limit = 0) {
+        global $DB;
+
+        $params = array(
+            'usercompid' => $usercompetencyid,
+            'path' => $context->path . '/%',
+            'contextid' => $context->id
+        );
+
+        if (!empty($sort)) {
+            $sortcolumns = explode(',', $sort);
+            $sortcolumns = array_map('trim', $sortcolumns);
+            $sort = ' ORDER BY e.' . implode(', e.', $sortcolumns) . ' ' . $order;
+        }
+
+        $sql = 'SELECT e.*
+                  FROM {' . static::TABLE . '} e
+                  JOIN {context} c ON c.id = e.contextid
+                 WHERE (c.path LIKE :path OR c.id = :contextid)
+                   AND e.usercompetencyid = :usercompid
+                 ' . $sort;
+        $records = $DB->get_records_sql($sql, $params, $skip, $limit);
+        $instances = array();
+
+        foreach ($records as $record) {
+            $newrecord = new static(0, $record);
+            array_push($instances, $newrecord);
+        }
+        return $instances;
+    }
+
 }
index 9e5c4d3..44aaf76 100644 (file)
@@ -2579,6 +2579,47 @@ class core_competency_api_testcase extends advanced_testcase {
         $this->assertEquals(null, $ev4->get_actionuserid());
     }
 
+    public function test_list_evidence_in_course() {
+        global $SITE;
+
+        $this->resetAfterTest(true);
+        $dg = $this->getDataGenerator();
+        $lpg = $dg->get_plugin_generator('core_competency');
+        $u1 = $dg->create_user();
+        $course = $dg->create_course();
+        $coursecontext = context_course::instance($course->id);
+
+        $this->setAdminUser();
+        $f = $lpg->create_framework();
+        $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
+        $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
+        $cc = api::add_competency_to_course($course->id, $c->get_id());
+        $cc2 = api::add_competency_to_course($course->id, $c2->get_id());
+
+        $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
+        $page = $pagegenerator->create_instance(array('course' => $course->id));
+
+        $cm = get_coursemodule_from_instance('page', $page->id);
+        $cmcontext = context_module::instance($cm->id);
+        // Add the competency to the course module.
+        $ccm = api::add_competency_to_course_module($cm, $c->get_id());
+
+        // Now add the evidence to the course.
+        $evidence1 = api::add_evidence($u1->id, $c->get_id(), $coursecontext->id, \core_competency\evidence::ACTION_LOG,
+            'invaliddata', 'error');
+
+        $result = api::list_evidence_in_course($u1->id, $course->id, $c->get_id());
+        $this->assertEquals($result[0]->get_id(), $evidence1->get_id());
+
+        // Now add the evidence to the course module.
+        $evidence2 = api::add_evidence($u1->id, $c->get_id(), $cmcontext->id, \core_competency\evidence::ACTION_LOG,
+            'invaliddata', 'error');
+
+        $result = api::list_evidence_in_course($u1->id, $course->id, $c->get_id());
+        $this->assertEquals($result[0]->get_id(), $evidence2->get_id());
+        $this->assertEquals($result[1]->get_id(), $evidence1->get_id());
+    }
+
     public function test_list_course_modules_using_competency() {
         global $SITE;
 
index 33569f6..afbd1e1 100644 (file)
@@ -6256,65 +6256,54 @@ function valid_uploaded_file($newfile) {
 /**
  * Returns the maximum size for uploading files.
  *
- * There are eight possible upload limits:
- * 1. No limit, if the upload isn't using a post request and the user has permission to ignore limits.
- * 2. in Apache using LimitRequestBody (no way of checking or changing this)
- * 3. in php.ini for 'upload_max_filesize' (can not be changed inside PHP)
- * 4. in .htaccess for 'upload_max_filesize' (can not be changed inside PHP)
- * 5. in php.ini for 'post_max_size' (can not be changed inside PHP)
- * 6. by the Moodle admin in $CFG->maxbytes
- * 7. by the teacher in the current course $course->maxbytes
- * 8. by the teacher for the current module, eg $assignment->maxbytes
+ * There are seven possible upload limits:
+ * 1. in Apache using LimitRequestBody (no way of checking or changing this)
+ * 2. in php.ini for 'upload_max_filesize' (can not be changed inside PHP)
+ * 3. in .htaccess for 'upload_max_filesize' (can not be changed inside PHP)
+ * 4. in php.ini for 'post_max_size' (can not be changed inside PHP)
+ * 5. by the Moodle admin in $CFG->maxbytes
+ * 6. by the teacher in the current course $course->maxbytes
+ * 7. by the teacher for the current module, eg $assignment->maxbytes
  *
  * These last two are passed to this function as arguments (in bytes).
  * Anything defined as 0 is ignored.
  * The smallest of all the non-zero numbers is returned.
  *
- * The php.ini settings are only used if $usespost is true. This allows repositories that do not use post requests, such as
- * repository_filesystem, to copy in files that are larger than post_max_size if the user has permission.
+ * @todo Finish documenting this function
  *
  * @param int $sitebytes Set maximum size
  * @param int $coursebytes Current course $course->maxbytes (in bytes)
  * @param int $modulebytes Current module ->maxbytes (in bytes)
- * @param bool $usespost Does the upload we're getting the max size for use a post request?
+ * @param bool $unused This parameter has been deprecated and is not used any more.
  * @return int The maximum size for uploading files.
  */
-function get_max_upload_file_size($sitebytes = 0, $coursebytes = 0, $modulebytes = 0, $usespost = true) {
-    $sizes = array();
-
-    if ($usespost) {
-        if (!$filesize = ini_get('upload_max_filesize')) {
-            $filesize = '5M';
-        }
-        $sizes[] = get_real_size($filesize);
+function get_max_upload_file_size($sitebytes=0, $coursebytes=0, $modulebytes=0, $unused = false) {
 
-        if ($postsize = ini_get('post_max_size')) {
-            $sizes[] = get_real_size($postsize);
-        }
+    if (! $filesize = ini_get('upload_max_filesize')) {
+        $filesize = '5M';
+    }
+    $minimumsize = get_real_size($filesize);
 
-        if ($sitebytes > 0) {
-            $sizes[] = $sitebytes;
-        }
-    } else {
-        if ($sitebytes != 0) {
-            // It's for possible that $sitebytes == USER_CAN_IGNORE_FILE_SIZE_LIMITS (-1).
-            $sizes[] = $sitebytes;
+    if ($postsize = ini_get('post_max_size')) {
+        $postsize = get_real_size($postsize);
+        if ($postsize < $minimumsize) {
+            $minimumsize = $postsize;
         }
     }
 
-    if ($coursebytes > 0) {
-        $sizes[] = $coursebytes;
+    if (($sitebytes > 0) and ($sitebytes < $minimumsize)) {
+        $minimumsize = $sitebytes;
     }
 
-    if ($modulebytes > 0) {
-        $sizes[] = $modulebytes;
+    if (($coursebytes > 0) and ($coursebytes < $minimumsize)) {
+        $minimumsize = $coursebytes;
     }
 
-    if (empty($sizes)) {
-        throw new coding_exception('You must specify at least one filesize limit.');
+    if (($modulebytes > 0) and ($modulebytes < $minimumsize)) {
+        $minimumsize = $modulebytes;
     }
 
-    return min($sizes);
+    return $minimumsize;
 }
 
 /**
@@ -6327,11 +6316,11 @@ function get_max_upload_file_size($sitebytes = 0, $coursebytes = 0, $modulebytes
  * @param int $coursebytes Current course $course->maxbytes (in bytes)
  * @param int $modulebytes Current module ->maxbytes (in bytes)
  * @param stdClass $user The user
- * @param bool $usespost Does the upload we're getting the max size for use a post request?
+ * @param bool $unused This parameter has been deprecated and is not used any more.
  * @return int The maximum size for uploading files.
  */
 function get_user_max_upload_file_size($context, $sitebytes = 0, $coursebytes = 0, $modulebytes = 0, $user = null,
-        $usespost = true) {
+        $unused = false) {
     global $USER;
 
     if (empty($user)) {
@@ -6339,10 +6328,10 @@ function get_user_max_upload_file_size($context, $sitebytes = 0, $coursebytes =
     }
 
     if (has_capability('moodle/course:ignorefilesizelimits', $context, $user)) {
-        return get_max_upload_file_size(USER_CAN_IGNORE_FILE_SIZE_LIMITS, 0, 0, $usespost);
+        return USER_CAN_IGNORE_FILE_SIZE_LIMITS;
     }
 
-    return get_max_upload_file_size($sitebytes, $coursebytes, $modulebytes, $usespost);
+    return get_max_upload_file_size($sitebytes, $coursebytes, $modulebytes);
 }
 
 /**
index 3cfb551..34e05bc 100644 (file)
@@ -2216,84 +2216,6 @@ class core_moodlelib_testcase extends advanced_testcase {
         $this->assertArrayHasKey(get_max_upload_file_size(), $result);
     }
 
-    /**
-     * Provider for get_max_upload_file_size.
-     *
-     * @return array
-     */
-    public function get_max_upload_file_size_provider() {
-        $inisize = min(array(get_real_size(ini_get('post_max_size')), get_real_size(ini_get('upload_max_filesize'))));
-        return [
-            'POST: inisize smallest' => [
-                $inisize + 10,
-                $inisize + 20,
-                $inisize + 30,
-                true,
-                $inisize,
-            ],
-            'POST: sitebytes smallest' => [
-                $inisize - 30,
-                $inisize - 20,
-                $inisize - 10,
-                true,
-                $inisize - 30,
-            ],
-            'POST: coursebytes smallest' => [
-                $inisize - 20,
-                $inisize - 30,
-                $inisize - 10,
-                true,
-                $inisize - 30,
-            ],
-            'POST: modulebytes smallest' => [
-                $inisize - 20,
-                $inisize - 10,
-                $inisize - 30,
-                true,
-                $inisize - 30,
-            ],
-            'POST: User can ignore site limit (respect ini)' => [
-                USER_CAN_IGNORE_FILE_SIZE_LIMITS,
-                0,
-                0,
-                true,
-                $inisize,
-            ],
-            'NOPOST: inisize smallest' => [
-                $inisize + 10,
-                $inisize + 20,
-                $inisize + 30,
-                false,
-                $inisize + 10,
-            ],
-            'NOPOST: User can ignore site limit (no limit)' => [
-                USER_CAN_IGNORE_FILE_SIZE_LIMITS,
-                0,
-                0,
-                false,
-                USER_CAN_IGNORE_FILE_SIZE_LIMITS,
-            ],
-        ];
-    }
-
-    /**
-     * Test get_max_upload_file_size with various combinations.
-     *
-     * @dataProvider get_max_upload_file_size_provider
-     */
-    public function test_get_max_upload_file_size($sitebytes, $coursebytes, $modulebytes, $ispost, $expectation) {
-        $this->assertEquals($expectation, get_max_upload_file_size($sitebytes, $coursebytes, $modulebytes, $ispost));
-    }
-
-    /**
-     * Test that when get_max_upload_file_size is called with no sizes, and no post, an exception is thrown.
-     */
-    public function test_get_max_upload_file_size_no_sizes() {
-        // If not using post we have to provide at least one other limit.
-        $this->setExpectedException('coding_exception', 'You must specify at least one filesize limit.');
-        get_max_upload_file_size(0, 0, 0, false);
-    }
-
     /**
      * Test function password_is_legacy_hash().
      */
index 7218a1e..74666ac 100644 (file)
@@ -4,6 +4,9 @@ information provided here is intended especially for developers.
 === 3.2 ===
 
 * New option 'blanktarget' added to format_text. This option adds target="_blank" to links
+* The parameter $usepost of the following functions has been deprecated and is not used any more:
+  - get_max_upload_file_size()
+  - get_user_max_upload_file_size()
 
 === 3.1 ===
 
index 415ada9..f097099 100644 (file)
@@ -39,7 +39,7 @@ class backup_choice_activity_structure_step extends backup_activity_structure_st
         // Define each element separated
         $choice = new backup_nested_element('choice', array('id'), array(
             'name', 'intro', 'introformat', 'publish',
-            'showresults', 'display', 'allowupdate', 'showunanswered',
+            'showresults', 'display', 'allowupdate', 'allowmultiple', 'showunanswered',
             'limitanswers', 'timeopen', 'timeclose', 'timemodified',
             'completionsubmit', 'showpreview', 'includeinactive'));
 
index 666df96..54c01b6 100644 (file)
@@ -479,7 +479,7 @@ function prepare_choice_show_results($choice, $course, $cm, $allresponses) {
 
     //overwrite options value;
     $display->options = array();
-    $totaluser = 0;
+    $allusers = [];
     foreach ($choice->option as $optionid => $optiontext) {
         $display->options[$optionid] = new stdClass;
         $display->options[$optionid]->text = $optiontext;
@@ -487,13 +487,13 @@ function prepare_choice_show_results($choice, $course, $cm, $allresponses) {
 
         if (array_key_exists($optionid, $allresponses)) {
             $display->options[$optionid]->user = $allresponses[$optionid];
-            $totaluser += count($allresponses[$optionid]);
+            $allusers = array_merge($allusers, array_keys($allresponses[$optionid]));
         }
     }
     unset($display->option);
     unset($display->maxanswers);
 
-    $display->numberofuser = $totaluser;
+    $display->numberofuser = count(array_unique($allusers));
     $context = context_module::instance($cm->id);
     $display->viewresponsecapability = has_capability('mod/choice:readresponses', $context);
     $display->deleterepsonsecapability = has_capability('mod/choice:deleteresponses',$context);
@@ -830,12 +830,13 @@ function choice_extend_settings_navigation(settings_navigation $settings, naviga
         // Big function, approx 6 SQL calls per user.
         $allresponses = choice_get_response_data($choice, $PAGE->cm, $groupmode, $onlyactive);
 
-        $responsecount =0;
+        $allusers = [];
         foreach($allresponses as $optionid => $userlist) {
             if ($optionid) {
-                $responsecount += count($userlist);
+                $allusers = array_merge($allusers, array_keys($userlist));
             }
         }
+        $responsecount = count(array_unique($allusers));
         $choicenode->add(get_string("viewallresponses", "choice", $responsecount), new moodle_url('/mod/choice/report.php', array('id'=>$PAGE->cm->id)));
     }
 }
@@ -917,8 +918,10 @@ function choice_print_overview($courses, &$htmlarray) {
 
             // Display relevant info based on permissions.
             if (has_capability('mod/choice:readresponses', context_module::instance($choice->coursemodule))) {
-                $attempts = $DB->count_records('choice_answers', array('choiceid' => $choice->id));
-                $str .= $OUTPUT->box(get_string('viewallresponses', 'choice', $attempts), 'info');
+                $attempts = $DB->count_records_sql('SELECT COUNT(DISTINCT userid) FROM {choice_answers} WHERE choiceid = ?',
+                    [$choice->id]);
+                $url = new moodle_url('/mod/choice/report.php', ['id' => $choice->coursemodule]);
+                $str .= $OUTPUT->box(html_writer::link($url, get_string('viewallresponses', 'choice', $attempts)), 'info');
 
             } else if (has_capability('mod/choice:choose', context_module::instance($choice->coursemodule))) {
                 // See if the user has submitted anything.
index 8ab2749..4940d41 100644 (file)
@@ -1022,7 +1022,7 @@ function forum_cron() {
 
                 $headerdata = new stdClass();
                 $headerdata->sitename = format_string($site->fullname, true);
-                $headerdata->userprefs = $CFG->wwwroot.'/user/edit.php?id='.$userid.'&amp;course='.$site->id;
+                $headerdata->userprefs = $CFG->wwwroot.'/user/forum.php?id='.$userid.'&amp;course='.$site->id;
 
                 $posttext = get_string('digestmailheader', 'forum', $headerdata)."\n\n";
                 $headerdata->userprefs = '<a target="_blank" href="'.$headerdata->userprefs.'">'.get_string('digestmailprefs', 'forum').'</a>';
index 44b1e14..f0fa12e 100644 (file)
@@ -426,6 +426,12 @@ class mod_lesson_mod_form extends moodleform_mod {
                 $data->completiontimespent = 0;
             }
         }
+        if (!empty($data->completionunlocked)) {
+            $autocompletion = !empty($data->completion) && $data->completion == COMPLETION_TRACKING_AUTOMATIC;
+            if (empty($data->completionendreached) || !$autocompletion) {
+                $data->completionendreached = 0;
+            }
+        }
         return $data;
     }
 }
index dccec42..e488e3d 100644 (file)
@@ -77,8 +77,6 @@ if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
 }
 $PAGE->set_course($course);
 
-$usespost = true;
-
 if ($repo_id) {
     // Get repository instance information
     $repooptions = array(
@@ -89,14 +87,12 @@ if ($repo_id) {
 
     // Check permissions
     $repo->check_capability();
-
-    $usespost = $repo->uses_post_requests();
 }
 
 $context = context::instance_by_id($contextid);
 
 // Make sure maxbytes passed is within site filesize limits.
-$maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $course->maxbytes, $maxbytes, null, $usespost);
+$maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $course->maxbytes, $maxbytes);
 
 $params = array('ctx_id' => $contextid, 'itemid' => $itemid, 'env' => $env, 'course'=>$courseid, 'maxbytes'=>$maxbytes, 'areamaxbytes'=>$areamaxbytes, 'maxfiles'=>$maxfiles, 'subdirs'=>$subdirs, 'sesskey'=>sesskey());
 $params['action'] = 'browse';
index 066ad7e..409ef32 100644 (file)
@@ -810,17 +810,6 @@ class repository_filesystem extends repository {
     public function supports_relative_file() {
         return $this->get_option('relativefiles');
     }
-
-    /**
-     * Helper function to indicate if this repository uses post requests for uploading files.
-     *
-     * Files are copied from the filesystem so don't rely on POST requests.
-     *
-     * @return bool
-     */
-    public function uses_post_requests() {
-        return false;
-    }
 }
 
 /**
index 297ca6f..5d0d905 100644 (file)
@@ -2782,13 +2782,12 @@ abstract class repository implements cacheable_object {
     /**
      * Helper function to indicate if this repository uses post requests for uploading files.
      *
-     * If the respository doesn't rely on uploading via POST requests, this can be overridden to return false,
-     * allowing users with the right permissions to upload files of any size from this repository.
-     *
+     * @deprecated since Moodle 3.2, 3.1.1, 3.0.5
      * @return bool
      */
     public function uses_post_requests() {
-        return true;
+        debugging('The method repository::uses_post_requests() is deprecated and must not be used anymore.', DEBUG_DEVELOPER);
+        return false;
     }
 }
 
index a8c5e82..51ecb3b 100644 (file)
@@ -86,8 +86,7 @@ if (!empty($course)) {
     $coursemaxbytes = $course->maxbytes;
 }
 // Make sure maxbytes passed is within site filesize limits.
-$maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $coursemaxbytes, $maxbytes,
-        null, $repo->uses_post_requests());
+$maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes, $coursemaxbytes, $maxbytes);
 
 // Wait as long as it takes for this script to finish
 core_php_time_limit::raise();
index dc89c4d..ab9c084 100644 (file)
@@ -3,6 +3,10 @@ information provided here is intended especially for developers. Full
 details of the repository API are available on Moodle docs:
 http://docs.moodle.org/dev/Repository_API
 
+=== 3.2 ===
+
+* The method repository::uses_post_requests() has been deprecated and must not be used anymore.
+
 === 3.1 ===
 
 * The following functions, previously used (exclusively) by upgrade steps are not available
index faaf5c1..49824f7 100644 (file)
@@ -346,7 +346,16 @@ class manager {
 
             $systemcontextid = \context_system::instance()->id;
             foreach ($areasbylevel[CONTEXT_SYSTEM] as $areaid => $searchclass) {
-                $areascontexts[$areaid][] = $systemcontextid;
+                $areascontexts[$areaid][$systemcontextid] = $systemcontextid;
+            }
+        }
+
+        if (!empty($areasbylevel[CONTEXT_USER])) {
+            if ($usercontext = \context_user::instance($USER->id, IGNORE_MISSING)) {
+                // Extra checking although only logged users should reach this point, guest users have a valid context id.
+                foreach ($areasbylevel[CONTEXT_USER] as $areaid => $searchclass) {
+                    $areascontexts[$areaid][$usercontext->id] = $usercontext->id;
+                }
             }
         }
 
index 8a638d7..c747685 100644 (file)
@@ -29,6 +29,12 @@ defined('MOODLE_INTERNAL') || die;
 
 class mock_search_area extends \core_search\area\base {
 
+    /**
+     * Multiple context level so we can test get_areas_user_accesses.
+     * @var int[]
+     */
+    protected static $levels = [CONTEXT_SYSTEM, CONTEXT_USER];
+
     /**
      * To make things easier, base class required config stuff.
      *
index 256f0b8..bce1437 100644 (file)
@@ -29,6 +29,11 @@ require_once(__DIR__ . '/mock_search_engine.php');
 /**
  * Core search class adapted to unit test.
  *
+ * Note that by default all core search areas are returned when calling get_search_areas_list,
+ * if you want to use the mock search area you can use testable_core_search::add_search_area
+ * although if you want to add mock search areas on top of the core ones you should call
+ * testable_core_search::add_core_search_areas before calling testable_core_search::add_search_area.
+ *
  * @package    core_search
  * @copyright  2015 David Monllao {@link http://www.davidmonllao.com}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -82,4 +87,14 @@ class testable_core_search extends \core_search\manager {
        self::$enabledsearchareas[$areaid] = $searcharea;
        self::$allsearchareas[$areaid] = $searcharea;
     }
+
+    /**
+     * Loads all core search areas.
+     *
+     * @return void
+     */
+    public function add_core_search_areas() {
+        self::get_search_areas_list(false);
+        self::get_search_areas_list(true);
+    }
 }
index 20db8ab..e6db62d 100644 (file)
@@ -26,6 +26,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 require_once(__DIR__ . '/fixtures/testable_core_search.php');
+require_once(__DIR__ . '/fixtures/mock_search_area.php');
 
 /**
  * Unit tests for search manager.
@@ -165,8 +166,11 @@ class search_manager_testcase extends advanced_testcase {
         $course2 = $this->getDataGenerator()->create_course();
         $course2ctx = context_course::instance($course2->id);
         $teacher = $this->getDataGenerator()->create_user();
+        $teacherctx = context_user::instance($teacher->id);
         $student = $this->getDataGenerator()->create_user();
+        $studentctx = context_user::instance($student->id);
         $noaccess = $this->getDataGenerator()->create_user();
+        $noaccessctx = context_user::instance($noaccess->id);
         $this->getDataGenerator()->enrol_user($teacher->id, $course1->id, 'teacher');
         $this->getDataGenerator()->enrol_user($student->id, $course1->id, 'student');
 
@@ -180,17 +184,23 @@ class search_manager_testcase extends advanced_testcase {
         $context3 = context_module::instance($forum3->cmid);
 
         $search = testable_core_search::instance();
+        $mockareaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
+        $search->add_core_search_areas();
+        $search->add_search_area($mockareaid, new core_mocksearch\search\mock_search_area());
 
         $this->setAdminUser();
         $this->assertTrue($search->get_areas_user_accesses());
 
         $sitectx = \context_course::instance(SITEID);
+        $systemctxid = \context_system::instance()->id;
 
         // Can access the frontpage ones.
         $this->setUser($noaccess);
         $contexts = $search->get_areas_user_accesses();
         $this->assertEquals(array($frontpageforumcontext->id => $frontpageforumcontext->id), $contexts[$this->forumpostareaid]);
         $this->assertEquals(array($sitectx->id => $sitectx->id), $contexts[$this->mycoursesareaid]);
+        $mockctxs = array($noaccessctx->id => $noaccessctx->id, $systemctxid => $systemctxid);
+        $this->assertEquals($mockctxs, $contexts[$mockareaid]);
 
         $this->setUser($teacher);
         $contexts = $search->get_areas_user_accesses();
@@ -199,12 +209,16 @@ class search_manager_testcase extends advanced_testcase {
         $this->assertEquals($frontpageandcourse1, $contexts[$this->forumpostareaid]);
         $this->assertEquals(array($sitectx->id => $sitectx->id, $course1ctx->id => $course1ctx->id),
             $contexts[$this->mycoursesareaid]);
+        $mockctxs = array($teacherctx->id => $teacherctx->id, $systemctxid => $systemctxid);
+        $this->assertEquals($mockctxs, $contexts[$mockareaid]);
 
         $this->setUser($student);
         $contexts = $search->get_areas_user_accesses();
         $this->assertEquals($frontpageandcourse1, $contexts[$this->forumpostareaid]);
         $this->assertEquals(array($sitectx->id => $sitectx->id, $course1ctx->id => $course1ctx->id),
             $contexts[$this->mycoursesareaid]);
+        $mockctxs = array($studentctx->id => $studentctx->id, $systemctxid => $systemctxid);
+        $this->assertEquals($mockctxs, $contexts[$mockareaid]);
 
         // Hide the activity.
         set_coursemodule_visible($forum2->cmid, 0);
index 9d98d35..5c80986 100644 (file)
@@ -151,9 +151,7 @@ class core_webservice_externallib_testcase extends externallib_advanced_testcase
         $siteinfo = external_api::clean_returnvalue(core_webservice_external::get_site_info_returns(), $siteinfo);
 
         $this->assertEquals(0, $siteinfo['userquota']);
-
-        // The max_size is dependant upon the post_max_size, and upload_max_filesize values in php.ini.
-        $this->assertEquals(get_max_upload_file_size(USER_CAN_IGNORE_FILE_SIZE_LIMITS), $siteinfo['usermaxuploadfilesize']);
+        $this->assertEquals(USER_CAN_IGNORE_FILE_SIZE_LIMITS, $siteinfo['usermaxuploadfilesize']);
         $this->assertEquals(true, $siteinfo['usercanmanageownfiles']);
 
         $this->assertEquals(HOMEPAGE_SITE, $siteinfo['userhomepage']);