Merge branch 'MDL-63958-master' of git://github.com/jleyva/moodle
authorSara Arjona <sara@moodle.com>
Mon, 21 Jan 2019 14:17:53 +0000 (15:17 +0100)
committerSara Arjona <sara@moodle.com>
Mon, 21 Jan 2019 14:17:53 +0000 (15:17 +0100)
1  2 
course/tests/externallib_test.php
mod/resource/locallib.php

@@@ -409,14 -409,6 +409,14 @@@ class core_course_externallib_testcase 
          // Enable course themes.
          set_config('allowcoursethemes', 1);
  
 +        // Custom fields.
 +        $fieldcategory = self::getDataGenerator()->create_custom_field_category(['name' => 'Other fields']);
 +
 +        $customfield = ['shortname' => 'test', 'name' => 'Custom field', 'type' => 'text',
 +            'categoryid' => $fieldcategory->get('id'),
 +            'configdata' => ['visibility' => \core_course\customfield\course_handler::VISIBLETOALL]];
 +        $field = self::getDataGenerator()->create_custom_field($customfield);
 +
          // Set the required capabilities by the external function
          $contextid = context_system::instance()->id;
          $roleid = $this->assignUserCapability('moodle/course:create', $contextid);
          foreach ($course3options as $key => $value) {
              $course3['courseformatoptions'][] = array('name' => $key, 'value' => $value);
          }
 -        $courses = array($course1, $course2, $course3);
 +        $course4['fullname'] = 'Test course with custom fields';
 +        $course4['shortname'] = 'Testcoursecustomfields';
 +        $course4['categoryid'] = $category->id;
 +        $course4['customfields'] = [['shortname' => $customfield['shortname'], 'value' => 'Test value']];
 +        $courses = array($course4, $course1, $course2, $course3);
  
          $createdcourses = core_course_external::create_courses($courses);
  
          $createdcourses = external_api::clean_returnvalue(core_course_external::create_courses_returns(), $createdcourses);
  
          // Check that right number of courses were created.
 -        $this->assertEquals(3, count($createdcourses));
 +        $this->assertEquals(4, count($createdcourses));
  
          // Check that the courses were correctly created.
          foreach ($createdcourses as $createdcourse) {
                  $this->assertEquals(course_get_format($createdcourse['id'])->get_last_section_number(),
                      $course3options['numsections']);
                  $this->assertEquals($courseinfo->coursedisplay, $course3options['coursedisplay']);
 +            } else if ($createdcourse['shortname'] == $course4['shortname']) {
 +                $this->assertEquals($courseinfo->fullname, $course4['fullname']);
 +                $this->assertEquals($courseinfo->shortname, $course4['shortname']);
 +                $this->assertEquals($courseinfo->category, $course4['categoryid']);
 +
 +                $handler = core_course\customfield\course_handler::create();
 +                $customfields = $handler->export_instance_data_object($createdcourse['id']);
 +                $this->assertEquals((object)['test' => 'Test value'], $customfields);
              } else {
                  throw new moodle_exception('Unexpected shortname');
              }
          $coursedata['summaryformat'] = FORMAT_MOODLE;
          $course1  = self::getDataGenerator()->create_course($coursedata);
  
 +        $fieldcategory = self::getDataGenerator()->create_custom_field_category(
 +            ['name' => 'Other fields']);
 +
 +        $customfield = ['shortname' => 'test', 'name' => 'Custom field', 'type' => 'text',
 +            'categoryid' => $fieldcategory->get('id')];
 +        $field = self::getDataGenerator()->create_custom_field($customfield);
 +
 +        $customfieldvalue = ['shortname' => 'test', 'value' => 'Test value'];
 +
          $generatedcourses[$course1->id] = $course1;
          $course2  = self::getDataGenerator()->create_course();
          $generatedcourses[$course2->id] = $course2;
          $course3  = self::getDataGenerator()->create_course(array('format' => 'topics'));
          $generatedcourses[$course3->id] = $course3;
 +        $course4  = self::getDataGenerator()->create_course(['customfields' => [$customfieldvalue]]);
 +        $generatedcourses[$course4->id] = $course4;
  
          // Set the required capabilities by the external function.
          $context = context_system::instance();
                  context_course::instance($course2->id)->id, $roleid);
          $this->assignUserCapability('moodle/course:update',
                  context_course::instance($course3->id)->id, $roleid);
 +        $this->assignUserCapability('moodle/course:update',
 +                context_course::instance($course4->id)->id, $roleid);
  
          $courses = core_course_external::get_courses(array('ids' =>
 -            array($course1->id, $course2->id)));
 +            array($course1->id, $course2->id, $course4->id)));
  
          // We need to execute the return values cleaning process to simulate the web service server.
          $courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses);
  
 -        // Check we retrieve the good total number of categories.
 -        $this->assertEquals(2, count($courses));
 +        // Check we retrieve the good total number of courses.
 +        $this->assertEquals(3, count($courses));
  
          foreach ($courses as $course) {
              $coursecontext = context_course::instance($course['id']);
                      array('name' => 'coursedisplay', 'value' => $dbcourse->coursedisplay),
                  ));
              }
 +            if ($dbcourse->id == 4) {
 +                $this->assertEquals($course['customfields'], [array_merge($customfield, $customfieldvalue)]);
 +            }
          }
  
          // Get all courses in the DB
          $page = new moodle_page();
          $page->set_course($course2);
          $page->blocks->add_blocks([BLOCK_POS_LEFT => ['news_items'], BLOCK_POS_RIGHT => []], 'course-view-*');
 +
          // Search by name.
          $results = core_course_external::search_courses('search', 'FIRST');
          $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results);
                  array('TAG-LABEL ON SECOND COURSE'));
          $taginstance = $DB->get_record('tag_instance',
                  array('itemtype' => 'course', 'itemid' => $course2->id), '*', MUST_EXIST);
 +
          // Search by tagid.
          $results = core_course_external::search_courses('tagid', $taginstance->tagid);
          $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results);
          $this->assertEquals(1, $results['total']);
          $this->assertEquals($coursedata1['fullname'], $results['courses'][0]['fullname']);
  
 -        // Check that we can see both without the limit to enrolled setting.
 +        // Check that we can see all courses without the limit to enrolled setting.
          $results = core_course_external::search_courses('search', 'COURSE', 0, 0, array(), 0);
          $results = external_api::clean_returnvalue(core_course_external::search_courses_returns(), $results);
          $this->assertCount(2, $results['courses']);
          // Search by block (use news_items default block). Should fail (only admins allowed).
          $this->expectException('required_capability_exception');
          $results = core_course_external::search_courses('blocklist', $blockid);
 -
      }
  
      /**
          $this->assertArrayNotHasKey('completiondata', $result[0]['modules'][0]);
      }
  
+     /**
+      * Test mimetype is returned for resources with showtype set.
+      */
+     public function test_get_course_contents_including_mimetype() {
+         $this->resetAfterTest(true);
+         $this->setAdminUser();
+         $course = self::getDataGenerator()->create_course();
+         $record = new stdClass();
+         $record->course = $course->id;
+         $record->showtype = 1;
+         $resource = self::getDataGenerator()->create_module('resource', $record);
+         $result = core_course_external::get_course_contents($course->id);
+         $result = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $result);
+         $this->assertCount(1, $result[0]['modules']);   // One module, first section.
+         $customdata = unserialize(json_decode($result[0]['modules'][0]['customdata']));
+         $this->assertEquals('text/plain', $customdata['filedetails']['mimetype']);
+     }
      /**
       * Test duplicate_course
       */
          $contextid = context_system::instance()->id;
          $roleid = $this->assignUserCapability('moodle/course:update', $contextid);
          $this->assignUserCapability('moodle/course:changecategory', $contextid, $roleid);
 +        $this->assignUserCapability('moodle/course:changelockedcustomfields', $contextid, $roleid);
          $this->assignUserCapability('moodle/course:changefullname', $contextid, $roleid);
          $this->assignUserCapability('moodle/course:changeshortname', $contextid, $roleid);
          $this->assignUserCapability('moodle/course:changeidnumber', $contextid, $roleid);
          $this->assignUserCapability('moodle/course:viewhiddencourses', $contextid, $roleid);
          $this->assignUserCapability('moodle/course:setforcedlanguage', $contextid, $roleid);
  
 -        // Create category and course.
 +        // Create category and courses.
          $category1  = self::getDataGenerator()->create_category();
          $category2  = self::getDataGenerator()->create_category();
 +
          $originalcourse1 = self::getDataGenerator()->create_course();
          self::getDataGenerator()->enrol_user($USER->id, $originalcourse1->id, $roleid);
 +
          $originalcourse2 = self::getDataGenerator()->create_course();
          self::getDataGenerator()->enrol_user($USER->id, $originalcourse2->id, $roleid);
  
 +        // Course with custom fields.
 +        $fieldcategory = self::getDataGenerator()->create_custom_field_category(['name' => 'Other fields']);
 +        $customfield = ['shortname' => 'test', 'name' => 'Custom field', 'type' => 'text',
 +            'categoryid' => $fieldcategory->get('id'),
 +            'configdata' => ['visibility' => \core_course\customfield\course_handler::VISIBLETOALL, 'locked' => 1]];
 +        $field = self::getDataGenerator()->create_custom_field($customfield);
 +
 +        $originalcourse3 = self::getDataGenerator()->create_course(['customfield_test' => 'Test value']);
 +        self::getDataGenerator()->enrol_user($USER->id, $originalcourse3->id, $roleid);
 +
          // Course values to be updated.
          $course1['id'] = $originalcourse1->id;
          $course1['fullname'] = 'Updated test course 1';
          $course1['shortname'] = 'Udestedtestcourse1';
          $course1['categoryid'] = $category1->id;
 +
          $course2['id'] = $originalcourse2->id;
          $course2['fullname'] = 'Updated test course 2';
          $course2['shortname'] = 'Updestedtestcourse2';
          $course2['enablecompletion'] = 1;
          $course2['lang'] = 'en';
          $course2['forcetheme'] = 'bootstrapbase';
 -        $courses = array($course1, $course2);
 +
 +        $course3['id'] = $originalcourse3->id;
 +        $updatedcustomfieldvalue = ['shortname' => 'test', 'value' => 'Updated test value'];
 +        $course3['customfields'] = [$updatedcustomfieldvalue];
 +        $courses = array($course1, $course2, $course3);
  
          $updatedcoursewarnings = core_course_external::update_courses($courses);
          $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(),
 -                                                                    $updatedcoursewarnings);
 +                $updatedcoursewarnings);
          $COURSE = $origcourse; // Restore $COURSE. Instead of using the OLD one set by the previous line.
  
          // Check that right number of courses were created.
          // Check that the courses were correctly created.
          foreach ($courses as $course) {
              $courseinfo = course_get_format($course['id'])->get_course();
 +            $customfields = \core_course\customfield\course_handler::create()->export_instance_data_object($course['id']);
              if ($course['id'] == $course2['id']) {
                  $this->assertEquals($course2['fullname'], $courseinfo->fullname);
                  $this->assertEquals($course2['shortname'], $courseinfo->shortname);
                  }
  
                  $this->assertEquals($course2['enablecompletion'], $courseinfo->enablecompletion);
 +                $this->assertEquals(['test' => null], (array)$customfields);
              } else if ($course['id'] == $course1['id']) {
                  $this->assertEquals($course1['fullname'], $courseinfo->fullname);
                  $this->assertEquals($course1['shortname'], $courseinfo->shortname);
                  $this->assertEquals(5, course_get_format($course['id'])->get_last_section_number());
                  $this->assertEquals(0, $courseinfo->newsitems);
                  $this->assertEquals(FORMAT_MOODLE, $courseinfo->summaryformat);
 +                $this->assertEquals(['test' => null], (array)$customfields);
 +            } else if ($course['id'] == $course3['id']) {
 +                $this->assertEquals(['test' => $updatedcustomfieldvalue['value']], (array)$customfields);
              } else {
                  throw new moodle_exception('Unexpected shortname');
              }
          $updatedcoursewarnings = external_api::clean_returnvalue(core_course_external::update_courses_returns(),
                                                                      $updatedcoursewarnings);
          $this->assertEquals(1, count($updatedcoursewarnings['warnings']));
 +
 +        // Try update course custom fields without capability.
 +        $this->unassignUserCapability('moodle/course:changelockedcustomfields', $contextid, $roleid);
 +        $user = self::getDataGenerator()->create_user();
 +        $this->setUser($user);
 +        self::getDataGenerator()->enrol_user($user->id, $course3['id'], $roleid);
 +
 +        $newupdatedcustomfieldvalue = ['shortname' => 'test', 'value' => 'New updated value'];
 +        $course3['customfields'] = [$newupdatedcustomfieldvalue];
 +
 +        core_course_external::update_courses([$course3]);
 +
 +        // Custom field was not updated.
 +        $customfields = \core_course\customfield\course_handler::create()->export_instance_data_object($course3['id']);
 +        $this->assertEquals(['test' => $updatedcustomfieldvalue['value']], (array)$customfields);
      }
  
      /**
@@@ -66,8 -66,9 +66,8 @@@ function resource_display_embed($resour
      $clicktoopen = resource_get_clicktoopen($file, $resource->revision);
  
      $context = context_module::instance($cm->id);
 -    $path = '/'.$context->id.'/mod_resource/content/'.$resource->revision.$file->get_filepath().$file->get_filename();
 -    $fullurl = file_encode_url($CFG->wwwroot.'/pluginfile.php', $path, false);
 -    $moodleurl = new moodle_url('/pluginfile.php' . $path);
 +    $moodleurl = moodle_url::make_pluginfile_url($context->id, 'mod_resource', 'content', $resource->revision,
 +            $file->get_filepath(), $file->get_filename());
  
      $mimetype = $file->get_mimetype();
      $title    = $resource->name;
      );
  
      if (file_mimetype_in_typegroup($mimetype, 'web_image')) {  // It's an image
 -        $code = resourcelib_embed_image($fullurl, $title);
 +        $code = resourcelib_embed_image($moodleurl->out(), $title);
  
      } else if ($mimetype === 'application/pdf') {
          // PDF document
 -        $code = resourcelib_embed_pdf($fullurl, $title, $clicktoopen);
 +        $code = resourcelib_embed_pdf($moodleurl->out(), $title, $clicktoopen);
  
      } else if ($mediamanager->can_embed_url($moodleurl, $embedoptions)) {
          // Media (audio/video) file.
@@@ -304,6 -305,7 +304,7 @@@ function resource_get_file_details($res
          if (!empty($options['showtype'])) {
              if ($mainfile) {
                  $filedetails['type'] = get_mimetype_description($mainfile);
+                 $filedetails['mimetype'] = $mainfile->get_mimetype();
                  // Only show type if it is not unknown.
                  if ($filedetails['type'] === get_mimetype_description('document/unknown')) {
                      $filedetails['type'] = '';