Exemplo n.º 1
0
/**
 * get_activity_tree :: course_modinfo -> integer -> context -> array
 * @param \course_modinfo $modinfo
 * @param integer $section_number
 * @param \context $context
 * @return array
 */
function get_activity_tree(\course_modinfo $modinfo, $section_number, \context $context)
{
    $completion_info = new \completion_info($modinfo->get_course());
    return F\map(F\filter($modinfo->get_section_info_all(), function (\section_info $section_info) {
        return $section_info->visible;
    }), function (\section_info $section_info) use($completion_info, $section_number, $context) {
        $mods = F\map(F\filter($section_info->modinfo->cms, function (\cm_info $cm_info) use($section_info) {
            global $CFG;
            return ($cm_info->uservisible || $CFG->enableavailability && !empty($cm_info->availableinfo)) && (int) $cm_info->sectionnum === (int) $section_info->section;
        }), function (\cm_info $cm_info) use($completion_info, $context) {
            global $CFG;
            $canComplete = $CFG->enablecompletion && isloggedin() && !isguestuser() && (int) $completion_info->is_enabled($cm_info) === COMPLETION_TRACKING_MANUAL;
            $hasCompleted = false;
            if ($canComplete) {
                $completion_data = $completion_info->get_data($cm_info, true);
                $hasCompleted = F\contains([COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS], (int) $completion_data->completionstate);
            }
            return (object) ['id' => (int) $cm_info->id, 'name' => $cm_info->name, 'modname' => $cm_info->modname, 'current' => is_current_mod($cm_info, $context), 'available' => $cm_info->available, 'canComplete' => $canComplete, 'hasCompleted' => $hasCompleted];
        });
        return (object) ['id' => (int) $section_info->id, 'section' => (int) $section_info->section, 'name' => \get_section_name($section_info->modinfo->courseid, $section_info->section), 'current' => is_current_section($section_info, $section_number, $context), 'activities' => array_values($mods)];
    });
}
Exemplo n.º 2
0
 public function test_glossary_view()
 {
     global $CFG;
     $origcompletion = $CFG->enablecompletion;
     $CFG->enablecompletion = true;
     $this->resetAfterTest(true);
     // Generate all the things.
     $c1 = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
     $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1));
     $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1));
     $u1 = $this->getDataGenerator()->create_user();
     $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
     $modinfo = course_modinfo::instance($c1->id);
     $cm1 = $modinfo->get_cm($g1->cmid);
     $cm2 = $modinfo->get_cm($g2->cmid);
     $ctx1 = $cm1->context;
     $completion = new completion_info($c1);
     $this->setUser($u1);
     // Confirm what we've set up.
     $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate);
     $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate);
     // Simulate the view call.
     $sink = $this->redirectEvents();
     glossary_view($g1, $c1, $cm1, $ctx1, 'letter');
     $events = $sink->get_events();
     // Assertions.
     $this->assertCount(3, $events);
     $this->assertEquals('\\core\\event\\course_module_completion_updated', $events[0]->eventname);
     $this->assertEquals('\\core\\event\\course_module_completion_updated', $events[1]->eventname);
     $this->assertEquals('\\mod_glossary\\event\\course_module_viewed', $events[2]->eventname);
     $this->assertEquals($g1->id, $events[2]->objectid);
     $this->assertEquals('letter', $events[2]->other['mode']);
     $this->assertEquals(COMPLETION_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_COMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate);
     $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate);
     // Tear down.
     $sink->close();
     $CFG->enablecompletion = $origcompletion;
 }
Exemplo n.º 3
0
 /**
  * Test convect fetching.
  */
 public function test_concept_fetching()
 {
     global $CFG, $DB;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     $CFG->glossary_linkbydefault = 1;
     $CFG->glossary_linkentries = 0;
     // Create a test courses.
     $course1 = $this->getDataGenerator()->create_course();
     $course2 = $this->getDataGenerator()->create_course();
     $site = $DB->get_record('course', array('id' => SITEID));
     // Create a glossary.
     $glossary1a = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 1));
     $glossary1b = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 1));
     $glossary1c = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 0));
     $glossary2 = $this->getDataGenerator()->create_module('glossary', array('course' => $course2->id, 'mainglossary' => 1, 'usedynalink' => 1));
     $glossary3 = $this->getDataGenerator()->create_module('glossary', array('course' => $site->id, 'mainglossary' => 1, 'usedynalink' => 1, 'globalglossary' => 1));
     /** @var mod_glossary_generator $generator */
     $generator = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
     $entry1a1 = $generator->create_content($glossary1a, array('concept' => 'first', 'usedynalink' => 1), array('prvni', 'erste'));
     $entry1a2 = $generator->create_content($glossary1a, array('concept' => 'A&B', 'usedynalink' => 1));
     $entry1a3 = $generator->create_content($glossary1a, array('concept' => 'neee', 'usedynalink' => 0));
     $entry1b1 = $generator->create_content($glossary1b, array('concept' => 'second', 'usedynalink' => 1));
     $entry1c1 = $generator->create_content($glossary1c, array('concept' => 'third', 'usedynalink' => 1));
     $entry31 = $generator->create_content($glossary3, array('concept' => 'global', 'usedynalink' => 1), array('globalni'));
     $cat1 = $generator->create_category($glossary1a, array('name' => 'special'), array($entry1a1, $entry1a2));
     \mod_glossary\local\concept_cache::reset_caches();
     $concepts1 = \mod_glossary\local\concept_cache::get_concepts($course1->id);
     $this->assertCount(3, $concepts1[0]);
     $this->arrayHasKey($concepts1[0], $glossary1a->id);
     $this->arrayHasKey($concepts1[0], $glossary1b->id);
     $this->arrayHasKey($concepts1[0], $glossary3->id);
     $this->assertCount(3, $concepts1[1]);
     $this->arrayHasKey($concepts1[1], $glossary1a->id);
     $this->arrayHasKey($concepts1[1], $glossary1b->id);
     $this->arrayHasKey($concepts1[0], $glossary3->id);
     $this->assertCount(5, $concepts1[1][$glossary1a->id]);
     foreach ($concepts1[1][$glossary1a->id] as $concept) {
         $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept));
         if ($concept->concept === 'first') {
             $this->assertEquals($entry1a1->id, $concept->id);
             $this->assertEquals($glossary1a->id, $concept->glossaryid);
             $this->assertEquals(0, $concept->category);
         } else {
             if ($concept->concept === 'prvni') {
                 $this->assertEquals($entry1a1->id, $concept->id);
                 $this->assertEquals($glossary1a->id, $concept->glossaryid);
                 $this->assertEquals(0, $concept->category);
             } else {
                 if ($concept->concept === 'erste') {
                     $this->assertEquals($entry1a1->id, $concept->id);
                     $this->assertEquals($glossary1a->id, $concept->glossaryid);
                     $this->assertEquals(0, $concept->category);
                 } else {
                     if ($concept->concept === 'A&B') {
                         $this->assertEquals($entry1a2->id, $concept->id);
                         $this->assertEquals($glossary1a->id, $concept->glossaryid);
                         $this->assertEquals(0, $concept->category);
                     } else {
                         if ($concept->concept === 'special') {
                             $this->assertEquals($cat1->id, $concept->id);
                             $this->assertEquals($glossary1a->id, $concept->glossaryid);
                             $this->assertEquals(1, $concept->category);
                         } else {
                             $this->fail('Unexpected concept: ' . $concept->concept);
                         }
                     }
                 }
             }
         }
     }
     $this->assertCount(1, $concepts1[1][$glossary1b->id]);
     foreach ($concepts1[1][$glossary1b->id] as $concept) {
         $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept));
         if ($concept->concept === 'second') {
             $this->assertEquals($entry1b1->id, $concept->id);
             $this->assertEquals($glossary1b->id, $concept->glossaryid);
             $this->assertEquals(0, $concept->category);
         } else {
             $this->fail('Unexpected concept: ' . $concept->concept);
         }
     }
     $this->assertCount(2, $concepts1[1][$glossary3->id]);
     foreach ($concepts1[1][$glossary3->id] as $concept) {
         $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept));
         if ($concept->concept === 'global') {
             $this->assertEquals($entry31->id, $concept->id);
             $this->assertEquals($glossary3->id, $concept->glossaryid);
             $this->assertEquals(0, $concept->category);
         } else {
             if ($concept->concept === 'globalni') {
                 $this->assertEquals($entry31->id, $concept->id);
                 $this->assertEquals($glossary3->id, $concept->glossaryid);
                 $this->assertEquals(0, $concept->category);
             } else {
                 $this->fail('Unexpected concept: ' . $concept->concept);
             }
         }
     }
     $concepts3 = \mod_glossary\local\concept_cache::get_concepts($site->id);
     $this->assertCount(1, $concepts3[0]);
     $this->arrayHasKey($concepts3[0], $glossary3->id);
     $this->assertCount(1, $concepts3[1]);
     $this->arrayHasKey($concepts3[0], $glossary3->id);
     foreach ($concepts3[1][$glossary3->id] as $concept) {
         $this->assertSame(array('id', 'glossaryid', 'concept', 'casesensitive', 'category', 'fullmatch'), array_keys((array) $concept));
         if ($concept->concept === 'global') {
             $this->assertEquals($entry31->id, $concept->id);
             $this->assertEquals($glossary3->id, $concept->glossaryid);
             $this->assertEquals(0, $concept->category);
         } else {
             if ($concept->concept === 'globalni') {
                 $this->assertEquals($entry31->id, $concept->id);
                 $this->assertEquals($glossary3->id, $concept->glossaryid);
                 $this->assertEquals(0, $concept->category);
             } else {
                 $this->fail('Unexpected concept: ' . $concept->concept);
             }
         }
     }
     $concepts2 = \mod_glossary\local\concept_cache::get_concepts($course2->id);
     $this->assertEquals($concepts3, $concepts2);
     // Test uservisible flag.
     set_config('enableavailability', 1);
     $glossary1d = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id, 'mainglossary' => 1, 'usedynalink' => 1, 'availability' => json_encode(\core_availability\tree::get_root_json(array(\availability_group\condition::get_json())))));
     $entry1d1 = $generator->create_content($glossary1d, array('concept' => 'membersonly', 'usedynalink' => 1));
     $user = $this->getDataGenerator()->create_user();
     $this->getDataGenerator()->enrol_user($user->id, $course1->id);
     $this->getDataGenerator()->enrol_user($user->id, $course2->id);
     \mod_glossary\local\concept_cache::reset_caches();
     $concepts1 = \mod_glossary\local\concept_cache::get_concepts($course1->id);
     $this->assertCount(4, $concepts1[0]);
     $this->assertCount(4, $concepts1[1]);
     $this->setUser($user);
     course_modinfo::clear_instance_cache();
     \mod_glossary\local\concept_cache::reset_caches();
     $concepts1 = \mod_glossary\local\concept_cache::get_concepts($course1->id);
     $this->assertCount(3, $concepts1[0]);
     $this->assertCount(3, $concepts1[1]);
 }
Exemplo n.º 4
0
 /**
  * Returns URL of a page that is supposed to contain detailed grade analysis
  *
  * At the moment, only activity modules are supported. The method generates link
  * to the module's file grade.php with the parameters id (cmid), itemid, itemnumber,
  * gradeid and userid. If the grade.php does not exist, null is returned.
  *
  * @return moodle_url|null URL or null if unable to construct it
  */
 public function get_grade_analysis_url(grade_grade $grade)
 {
     global $CFG;
     /** @var array static cache of the grade.php file existence flags */
     static $hasgradephp = array();
     if (empty($grade->grade_item) or !$grade->grade_item instanceof grade_item) {
         throw new coding_exception('Passed grade without the associated grade item');
     }
     $item = $grade->grade_item;
     if (!$item->is_external_item()) {
         // at the moment, only activity modules are supported
         return null;
     }
     if ($item->itemtype !== 'mod') {
         throw new coding_exception('Unknown external itemtype: ' . $item->itemtype);
     }
     if (empty($item->iteminstance) or empty($item->itemmodule) or empty($this->modinfo)) {
         return null;
     }
     if (!array_key_exists($item->itemmodule, $hasgradephp)) {
         if (file_exists($CFG->dirroot . '/mod/' . $item->itemmodule . '/grade.php')) {
             $hasgradephp[$item->itemmodule] = true;
         } else {
             $hasgradephp[$item->itemmodule] = false;
         }
     }
     if (!$hasgradephp[$item->itemmodule]) {
         return null;
     }
     $instances = $this->modinfo->get_instances();
     if (empty($instances[$item->itemmodule][$item->iteminstance])) {
         return null;
     }
     $cm = $instances[$item->itemmodule][$item->iteminstance];
     if (!$cm->uservisible) {
         return null;
     }
     $url = new moodle_url('/mod/' . $item->itemmodule . '/grade.php', array('id' => $cm->id, 'itemid' => $item->id, 'itemnumber' => $item->itemnumber, 'gradeid' => $grade->id, 'userid' => $grade->userid));
     return $url;
 }
 public function test_matching_cacherev()
 {
     global $DB, $CFG;
     $this->resetAfterTest();
     $this->setAdminUser();
     $cache = cache::make('core', 'coursemodinfo');
     // Generate the course and pre-requisite module.
     $course = $this->getDataGenerator()->create_course(array('format' => 'topics', 'numsections' => 3), array('createsections' => true));
     // Make sure the cacherev is set.
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertGreaterThan(0, $cacherev);
     $prevcacherev = $cacherev;
     // Reset course cache and make sure cacherev is bumped up but cache is empty.
     rebuild_course_cache($course->id, true);
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertGreaterThan($prevcacherev, $cacherev);
     $this->assertEmpty($cache->get($course->id));
     $prevcacherev = $cacherev;
     // Build course cache. Cacherev should not change but cache is now not empty. Make sure cacherev is the same everywhere.
     $modinfo = get_fast_modinfo($course->id);
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertEquals($prevcacherev, $cacherev);
     $cachedvalue = $cache->get($course->id);
     $this->assertNotEmpty($cachedvalue);
     $this->assertEquals($cacherev, $cachedvalue->cacherev);
     $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
     $prevcacherev = $cacherev;
     // Little trick to check that cache is not rebuilt druing the next step - substitute the value in MUC and later check that it is still there.
     $cache->set($course->id, (object) array_merge((array) $cachedvalue, array('secretfield' => 1)));
     // Clear static cache and call get_fast_modinfo() again (pretend we are in another request). Cache should not be rebuilt.
     course_modinfo::clear_instance_cache();
     $modinfo = get_fast_modinfo($course->id);
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertEquals($prevcacherev, $cacherev);
     $cachedvalue = $cache->get($course->id);
     $this->assertNotEmpty($cachedvalue);
     $this->assertEquals($cacherev, $cachedvalue->cacherev);
     $this->assertNotEmpty($cachedvalue->secretfield);
     $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
     $prevcacherev = $cacherev;
     // Rebuild course cache. Cacherev must be incremented everywhere.
     rebuild_course_cache($course->id);
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertGreaterThan($prevcacherev, $cacherev);
     $cachedvalue = $cache->get($course->id);
     $this->assertNotEmpty($cachedvalue);
     $this->assertEquals($cacherev, $cachedvalue->cacherev);
     $modinfo = get_fast_modinfo($course->id);
     $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
     $prevcacherev = $cacherev;
     // Update cacherev in DB and make sure the cache will be rebuilt on the next call to get_fast_modinfo().
     increment_revision_number('course', 'cacherev', 'id = ?', array($course->id));
     // We need to clear static cache for course_modinfo instances too.
     course_modinfo::clear_instance_cache();
     $modinfo = get_fast_modinfo($course->id);
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertGreaterThan($prevcacherev, $cacherev);
     $cachedvalue = $cache->get($course->id);
     $this->assertNotEmpty($cachedvalue);
     $this->assertEquals($cacherev, $cachedvalue->cacherev);
     $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
     $prevcacherev = $cacherev;
     // Reset cache for all courses and make sure this course cache is reset.
     rebuild_course_cache(0, true);
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertGreaterThan($prevcacherev, $cacherev);
     $this->assertEmpty($cache->get($course->id));
     // Rebuild again.
     $modinfo = get_fast_modinfo($course->id);
     $cachedvalue = $cache->get($course->id);
     $this->assertNotEmpty($cachedvalue);
     $this->assertEquals($cacherev, $cachedvalue->cacherev);
     $this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
     $prevcacherev = $cacherev;
     // Purge all caches and make sure cacherev is increased and data from MUC erased.
     purge_all_caches();
     $cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
     $this->assertGreaterThan($prevcacherev, $cacherev);
     $this->assertEmpty($cache->get($course->id));
 }
Exemplo n.º 6
0
 /**
  * Render contents of main part of subpage
  * @param mod_subpage $subpage
  * @param course_modinfo $modinfo
  * @param array $sections
  * @param boolean $editing whether the user is allowed to edit this page
  * @param int $moveitem (currently not used)
  * @param boolean $movesection whether the user is allowed to move sections
  * @return string html for display
  */
 public function render_subpage($subpage, $modinfo, $sections, $editing, $moveitem, $movesection)
 {
     global $PAGE, $OUTPUT, $CFG, $USER;
     $this->subpagecm = $subpage->get_course_module()->id;
     if (!empty($USER->activitycopy) && $movesection) {
         $content = $this->render_cancel_link($this->subpagecm);
     } else {
         $content = '';
     }
     $content .= $this->render_intro($subpage);
     $streditsummary = get_string('editsummary');
     $strdelete = get_string('delete');
     if ($editing) {
         $strmoveup = get_string('moveup');
         $strmovedown = get_string('movedown');
         $strhide = get_string('hide');
         $strshow = get_string('show');
         $strstealth = get_string('stealth', 'subpage');
         $strunstealth = get_string('unstealth', 'subpage');
     }
     $coursecontext = get_context_instance(CONTEXT_COURSE, $subpage->get_course()->id);
     get_all_mods($subpage->get_course()->id, $mods, $modnames, $modnamesplural, $modnamesused);
     foreach ($mods as $modid => $unused) {
         if (!isset($modinfo->cms[$modid])) {
             rebuild_course_cache($subpage->get_course()->id);
             $modinfo =& get_fast_modinfo($subpage->get_course());
             debugging('Rebuilding course cache', DEBUG_DEVELOPER);
             break;
         }
     }
     $lastpageorder = $subpage->get_last_section_pageorder();
     if ($subpage->get_course()->format == 'weeks') {
         $content .= html_writer::start_tag('ul', array('class' => 'weeks'));
     } else {
         $content .= html_writer::start_tag('ul', array('class' => 'topics'));
     }
     foreach ($sections as $section) {
         // Check to see whether cms within the section are visible or not
         // If all cms are not visible then we don't show the section at all,
         // unless editing
         $visible = false;
         if ($section->sequence) {
             // get cm_info for this resources
             $instances = explode(',', $section->sequence);
         } else {
             $instances = array();
         }
         foreach ($instances as $instance) {
             $cm = $modinfo->get_cm($instance);
             // check to see whether cm is visible
             if ($cm->uservisible) {
                 $visible = true;
                 break;
             }
         }
         // If section is empty so should be hidden, record that in object
         $section->autohide = !$visible;
         $content .= html_writer::start_tag('li', array('class' => 'section main clearfix', 'id' => 'section-' . $section->section));
         $content .= html_writer::tag('div', ' ', array('class' => 'left side'));
         $content .= html_writer::start_tag('div', array('class' => 'right side'));
         if ($editing && has_capability('moodle/course:update', $coursecontext)) {
             // Show the hide/show eye
             if ($section->visible) {
                 $content .= html_writer::start_tag('a', array('href' => 'view.php?id=' . $subpage->get_course_module()->id . '&hide=' . $section->section . '&sesskey=' . sesskey() . '#section-' . $section->id, 'title' => $strhide));
                 $content .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/hide'), 'class' => 'icon hide', 'alt' => $strhide));
                 $content .= html_writer::end_tag('a');
             } else {
                 $content .= html_writer::start_tag('a', array('href' => 'view.php?id=' . $subpage->get_course_module()->id . '&show=' . $section->section . '&sesskey=' . sesskey() . '#section-' . $section->id, 'title' => $strshow));
                 $content .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/show'), 'class' => 'icon show', 'alt' => $strshow));
                 $content .= html_writer::end_tag('a');
             }
             // Show the stealth/unstealth section link
             if ($section->stealth) {
                 $content .= html_writer::start_tag('form', array('method' => 'post', 'action' => 'stealth.php'));
                 $content .= html_writer::start_tag('div');
                 $content .= html_writer::empty_tag('input', array('name' => 'id', 'value' => $subpage->get_course_module()->id, 'type' => 'hidden'));
                 $content .= html_writer::empty_tag('input', array('name' => 'sesskey', 'value' => sesskey(), 'type' => 'hidden'));
                 $content .= html_writer::empty_tag('input', array('name' => 'unstealth', 'value' => $section->id, 'type' => 'hidden'));
                 $content .= html_writer::empty_tag('input', array('name' => 'icon', 'src' => $OUTPUT->pix_url('unstealth', 'mod_subpage'), 'type' => 'image', 'title' => $strunstealth, 'alt' => $strunstealth));
                 $content .= html_writer::end_tag('div');
                 $content .= html_writer::end_tag('form');
             } else {
                 $content .= html_writer::start_tag('form', array('method' => 'post', 'action' => 'stealth.php'));
                 $content .= html_writer::start_tag('div');
                 $content .= html_writer::empty_tag('input', array('name' => 'id', 'value' => $subpage->get_course_module()->id, 'type' => 'hidden'));
                 $content .= html_writer::empty_tag('input', array('name' => 'sesskey', 'value' => sesskey(), 'type' => 'hidden'));
                 $content .= html_writer::empty_tag('input', array('name' => 'stealth', 'value' => $section->id, 'type' => 'hidden'));
                 $content .= html_writer::empty_tag('input', array('name' => 'icon', 'src' => $OUTPUT->pix_url('stealth', 'mod_subpage'), 'type' => 'image', 'title' => $strstealth, 'alt' => $strstealth));
                 $content .= html_writer::end_tag('div');
                 $content .= html_writer::end_tag('form');
             }
             $content .= html_writer::empty_tag('br', array());
             if ($movesection) {
                 $content .= html_writer::start_tag('span', array('class' => 'section_move_commands'));
                 if ($section->pageorder > 1) {
                     // Add a arrow to move section up
                     $content .= html_writer::start_tag('a', array('href' => 'view.php?id=' . $subpage->get_course_module()->id . '&random=' . rand(1, 10000) . '&section=' . $section->id . '&move=-1&sesskey=' . sesskey() . '#section-' . ($section->id - 1), 'title' => $strmoveup));
                     $content .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/up'), 'class' => 'icon up', 'alt' => $strmoveup));
                     $content .= html_writer::end_tag('a');
                     $content .= html_writer::empty_tag('br', array());
                 }
                 if ($section->pageorder < $lastpageorder) {
                     // Add an arrow to move section down
                     $content .= html_writer::start_tag('a', array('href' => 'view.php?id=' . $subpage->get_course_module()->id . '&random=' . rand(1, 10000) . '&section=' . $section->id . '&move=1&sesskey=' . sesskey() . '#section-' . ($section->id + 1), 'title' => $strmovedown));
                     $content .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/down'), 'class' => 'icon down', 'alt' => $strmovedown));
                     $content .= html_writer::end_tag('a');
                     $content .= html_writer::empty_tag('br', array());
                 }
                 $content .= html_writer::end_tag('span');
             }
         }
         $content .= html_writer::end_tag('div');
         $content .= html_writer::start_tag('div', array('class' => 'content'));
         // Only show the section if visible and not stealthed or to users with permission
         if (($section->visible && !$section->stealth || has_capability('moodle/course:viewhiddensections', $coursecontext)) && ($editing || !$section->autohide)) {
             if ($section->stealth) {
                 $content .= html_writer::start_tag('div', array('class' => 'stealthed'));
             }
             if (!empty($section->name)) {
                 $content .= html_writer::tag('h3', format_string($section->name), array('class' => 'sectionname'));
             }
             $summary = '';
             if ($section->summary) {
                 $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $section->id);
                 $summaryformatoptions = new stdClass();
                 $summaryformatoptions->noclean = true;
                 $summaryformatoptions->overflowdiv = true;
                 $summary .= format_text($summarytext, $section->summaryformat, $summaryformatoptions);
             }
             if ($editing && has_capability('moodle/course:update', $coursecontext)) {
                 $summary .= html_writer::start_tag('a', array('href' => $CFG->wwwroot . '/course/editsection.php?id=' . $section->id . '&returnurl=' . urlencode($CFG->wwwroot . '/mod/subpage/view.php?id=' . $subpage->get_course_module()->id . '&recache=1&sesskey=' . sesskey()), 'title' => $streditsummary));
                 $summary .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/edit'), 'class' => 'icon edit', 'alt' => $streditsummary));
                 $summary .= html_writer::end_tag('a');
                 $summary .= html_writer::empty_tag('br', array());
                 $summary .= html_writer::start_tag('a', array('href' => $CFG->wwwroot . '/mod/subpage/view.php?id=' . $subpage->get_course_module()->id . '&delete=' . $section->id . '&sesskey=' . sesskey(), 'title' => $strdelete));
                 if (empty($section->sequence)) {
                     $summary .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('t/delete'), 'class' => 'icon delete', 'alt' => $strdelete));
                 }
                 $summary .= html_writer::end_tag('a');
                 $summary .= html_writer::empty_tag('br', array());
                 $summary .= html_writer::empty_tag('br', array());
             }
             if ($summary !== '') {
                 $content .= html_writer::tag('div', $summary, array('class' => 'summary'));
             }
             $content .= $this->render_section($subpage, $modinfo, $section, $editing, $moveitem, $mods, $modnamesused);
             if ($editing) {
                 $content .= print_section_add_menus($subpage->get_course(), $section->section, $modnames, false, true);
                 if (!empty($CFG->enablecourseajax) and $PAGE->theme->enablecourseajax) {
                     // hacky way to add list to empty section to allow drag/drop into
                     // empty sections
                     $content = str_replace('</div><div class="section_add_menus">', '</div><ul class="section img-text"><li></li></ul>' . '<div class="section_add_menus">', $content);
                 }
             }
             //now add returnto links to editing links:
             $pattern = '/mod.php\\?[A-Za-z0-9-&;=%:\\/\\-.]+/';
             $content = preg_replace_callback($pattern, 'mod_subpage_renderer::subpage_url_regex', $content);
             if ($section->stealth) {
                 $content .= html_writer::end_tag('div');
             }
         }
         $content .= html_writer::end_tag('div');
         //end of div class=content
         $content .= html_writer::end_tag('li');
     }
     $content .= html_writer::end_tag('ul');
     if ($editing) {
         $content .= $this->render_add_button($subpage);
         $content .= $this->render_bulkmove_buttons($subpage);
     }
     return $content;
 }
 /**
  * Test get_calendar_events
  */
 public function test_get_calendar_events()
 {
     global $DB, $USER;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     // Create a few stuff to test with.
     $user = $this->getDataGenerator()->create_user();
     $course = $this->getDataGenerator()->create_course();
     $record = new stdClass();
     $record->courseid = $course->id;
     $group = $this->getDataGenerator()->create_group($record);
     $beforecount = $DB->count_records('event');
     // Let's create a few events.
     $siteevent = $this->create_calendar_event('site', $USER->id, 'site');
     $record = new stdClass();
     $record->courseid = $course->id;
     $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record);
     $userevent = $this->create_calendar_event('user', $USER->id);
     $record = new stdClass();
     $record->courseid = $course->id;
     $record->groupid = $group->id;
     $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
     $paramevents = array('eventids' => array($siteevent->id), 'courseids' => array($course->id), 'groupids' => array($group->id));
     $options = array('siteevents' => true, 'userevents' => true);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     // Check to see if we got all events.
     $this->assertEquals(5, count($events['events']));
     $this->assertEquals(0, count($events['warnings']));
     $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + 7 * WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(5, count($events['events']));
     $this->assertEquals(0, count($events['warnings']));
     // Let's play around with caps.
     $this->setUser($user);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(2, count($events['events']));
     // site, user.
     $this->assertEquals(2, count($events['warnings']));
     // course, group.
     $role = $DB->get_record('role', array('shortname' => 'student'));
     $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(4, count($events['events']));
     // site, user, both course events.
     $this->assertEquals(1, count($events['warnings']));
     // group.
     $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(3, count($events['events']));
     // site, user, one course event.
     $this->assertEquals(1, count($events['warnings']));
     // group.
     groups_add_member($group, $user);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(4, count($events['events']));
     // site, user, group, one course event.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('courseids' => array($course->id), 'groupids' => array($group->id));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(4, count($events['events']));
     // site, user, group, one course event.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('groupids' => array($group->id, 23));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(3, count($events['events']));
     // site, user, group.
     $this->assertEquals(1, count($events['warnings']));
     $paramevents = array('courseids' => array(23));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(2, count($events['events']));
     // site, user.
     $this->assertEquals(1, count($events['warnings']));
     $paramevents = array();
     $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(0, count($events['events']));
     // nothing returned.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('eventids' => array($siteevent->id, $groupevent->id));
     $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(2, count($events['events']));
     // site, group.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('eventids' => array($siteevent->id));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(1, count($events['events']));
     // site.
     $this->assertEquals(0, count($events['warnings']));
     // Try getting a course event by its id.
     $paramevents = array('eventids' => array($courseevent->id));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(1, count($events['events']));
     $this->assertEquals(0, count($events['warnings']));
     // Now, create an activity event.
     $this->setAdminUser();
     $nexttime = time() + DAYSECS;
     $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime));
     $this->setUser($user);
     $paramevents = array('courseids' => array($course->id));
     $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertCount(5, $events['events']);
     // Hide the assignment.
     set_coursemodule_visible($assign->cmid, 0);
     // Empty all the caches that may be affected  by this change.
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     // Expect one less.
     $this->assertCount(4, $events['events']);
 }
Exemplo n.º 8
0
 /**
  * Works out whether activity is visible *for current user* - if this is false, they
  * aren't allowed to access it.
  * @return void
  */
 private function update_user_visible()
 {
     global $CFG;
     $modcontext = get_context_instance(CONTEXT_MODULE, $this->id);
     $userid = $this->modinfo->get_user_id();
     $this->uservisible = true;
     if ((!$this->visible or !$this->available) and !has_capability('moodle/course:viewhiddenactivities', $modcontext, $userid)) {
         // If the activity is hidden or unavailable, and you don't have viewhiddenactivities,
         // set it so that user can't see or access it
         $this->uservisible = false;
     } else {
         if (!empty($CFG->enablegroupmembersonly) and !empty($this->groupmembersonly) and !has_capability('moodle/site:accessallgroups', $modcontext, $userid)) {
             // If the activity has 'group members only' and you don't have accessallgroups...
             $groups = $this->modinfo->get_groups($this->groupingid);
             if (empty($groups)) {
                 // ...and you don't belong to a group, then set it so you can't see/access it
                 $this->uservisible = false;
             }
         }
     }
 }
Exemplo n.º 9
0
 /**
  * Gets the data required to fill the test plan template with the database contents.
  *
  * @param int $targetcourseid The target course id
  * @return stdClass The ids required by the test plan
  */
 protected static function get_course_test_data($targetcourseid)
 {
     global $DB, $USER;
     $data = new stdClass();
     // Getting course contents info as the current user (will be an admin).
     $course = new stdClass();
     $course->id = $targetcourseid;
     $courseinfo = new course_modinfo($course, $USER->id);
     // Getting the first page module instance.
     if (!($pages = $courseinfo->get_instances_of('page'))) {
         print_error('error_nopageinstances', 'tool_generator');
     }
     $data->pageid = reset($pages)->id;
     // Getting the first forum module instance and it's first discussion and reply as well.
     if (!($forums = $courseinfo->get_instances_of('forum'))) {
         print_error('error_noforuminstances', 'tool_generator');
     }
     $forum = reset($forums);
     // Getting the first discussion (and reply).
     if (!($discussions = forum_get_discussions($forum, 'd.timemodified ASC', false, -1, 1))) {
         print_error('error_noforumdiscussions', 'tool_generator');
     }
     $discussion = reset($discussions);
     $data->forumid = $forum->id;
     $data->forumdiscussionid = $discussion->discussion;
     $data->forumreplyid = $discussion->id;
     // According to the current test plan.
     return $data;
 }
Exemplo n.º 10
0
 /**
  * Return an array of modules that can be moved in this situation
  *    The Array is keyed first with sections (subpage or main course)
  *    and then the modules within each section by cmid
  * @param Object $subpage current subpage
  * @param Array $allsubpages
  * @param Array $coursesections
  * @param Object $modinfo
  * @param String $move to or from
  * @return Array mixed
  */
 public static function moveable_modules($subpage, $allsubpages, $coursesections, course_modinfo $modinfo, $move)
 {
     global $OUTPUT;
     get_all_mods($subpage->get_course()->id, $allmods, $modnames, $modnamesplural, $modnamesused);
     $mods = array();
     $subsections = array();
     if (!empty($allsubpages) && $move === 'to') {
         foreach ($allsubpages as $sub) {
             $subsections += $sub->get_sections();
         }
         $sections = $coursesections;
     } else {
         $subsections = $subpage->get_sections();
         $sections = $subsections;
     }
     if ($sections) {
         foreach ($sections as $section) {
             if (!empty($section->sequence)) {
                 if ($move === 'to' && array_key_exists($section->id, $subsections)) {
                     continue;
                 }
                 $sectionalt = isset($section->pageorder) ? $section->pageorder : $section->section;
                 if ($move === 'to') {
                     // Include the required course/format library.
                     global $CFG;
                     require_once "{$CFG->dirroot}/course/format/" . $subpage->get_course()->format . "/lib.php";
                     $callbackfunction = 'callback_' . $subpage->get_course()->format . '_get_section_name';
                     if (function_exists($callbackfunction)) {
                         $name = $callbackfunction($subpage->get_course(), $section);
                     } else {
                         $name = $section->name ? $section->name : get_string('section') . ' ' . $sectionalt;
                     }
                 } else {
                     $name = $section->name ? $section->name : get_string('section') . ' ' . $sectionalt;
                 }
                 $sectionmods = explode(',', $section->sequence);
                 foreach ($sectionmods as $modnumber) {
                     if (empty($allmods[$modnumber]) || $modnumber === $subpage->get_course_module()->id) {
                         continue;
                     }
                     $instancename = format_string($modinfo->cms[$modnumber]->name, true, $subpage->get_course()->id);
                     $icon = $modinfo->get_cm($modnumber)->get_icon_url();
                     $mod = $allmods[$modnumber];
                     $mods[$section->section]['section'] = $name;
                     $mods[$section->section]['pageorder'] = $sectionalt;
                     $mods[$section->section]['mods'][$modnumber] = "<span><img src='{$icon}' /> " . $instancename . "</span>";
                 }
             }
         }
     }
     return $mods;
 }
Exemplo n.º 11
0
 private function get_activity_link($element)
 {
     global $CFG;
     $itemtype = $element['object']->itemtype;
     $itemmodule = $element['object']->itemmodule;
     $iteminstance = $element['object']->iteminstance;
     // Links only for module items that have valid instance, module and are
     // called from grade_tree with valid modinfo
     if ($itemtype != 'mod' || !$iteminstance || !$itemmodule || !$this->modinfo) {
         return null;
     }
     // Get $cm efficiently and with visibility information using modinfo
     $instances = $this->modinfo->get_instances();
     if (empty($instances[$itemmodule][$iteminstance])) {
         return null;
     }
     $cm = $instances[$itemmodule][$iteminstance];
     // Do not add link if activity is not visible to the current user
     if (!$cm->uservisible) {
         return null;
     }
     // If module has grade.php, link to that, otherwise view.php
     $dir = $CFG->dirroot . '/mod/' . $itemmodule;
     if (file_exists($dir . '/grade.php')) {
         return new moodle_url('/mod/' . $itemmodule . '/grade.php', array('id' => $cm->id));
     } else {
         return new moodle_url('/mod/' . $itemmodule . '/view.php', array('id' => $cm->id));
     }
 }
Exemplo n.º 12
0
 /**
  * Test start_attempt
  */
 public function test_start_attempt()
 {
     global $DB;
     // Create a new quiz with attempts.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $data = array('course' => $this->course->id, 'sumgrades' => 1);
     $quiz = $quizgenerator->create_instance($data);
     $context = context_module::instance($quiz->cmid);
     try {
         mod_quiz_external::start_attempt($quiz->id);
         $this->fail('Exception expected due to missing questions.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('noquestionsfound', $e->errorcode);
     }
     // Create a question.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $question = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
     quiz_add_quiz_question($question->id, $quiz);
     $quizobj = quiz::create($quiz->id, $this->student->id);
     // Set grade to pass.
     $item = grade_item::fetch(array('courseid' => $this->course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'outcomeid' => null));
     $item->gradepass = 80;
     $item->update();
     $this->setUser($this->student);
     // Try to open attempt in closed quiz.
     $quiz->timeopen = time() - WEEKSECS;
     $quiz->timeclose = time() - DAYSECS;
     $DB->update_record('quiz', $quiz);
     $result = mod_quiz_external::start_attempt($quiz->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::start_attempt_returns(), $result);
     $this->assertEquals([], $result['attempt']);
     $this->assertCount(1, $result['warnings']);
     // Now with a password.
     $quiz->timeopen = 0;
     $quiz->timeclose = 0;
     $quiz->password = '******';
     $DB->update_record('quiz', $quiz);
     try {
         mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'bad')));
         $this->fail('Exception expected due to invalid passwod.');
     } catch (moodle_exception $e) {
         $this->assertEquals(get_string('passworderror', 'quizaccess_password'), $e->errorcode);
     }
     // Now, try everything correct.
     $result = mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'abc')));
     $result = external_api::clean_returnvalue(mod_quiz_external::start_attempt_returns(), $result);
     $this->assertEquals(1, $result['attempt']['attempt']);
     $this->assertEquals($this->student->id, $result['attempt']['userid']);
     $this->assertEquals($quiz->id, $result['attempt']['quiz']);
     $this->assertCount(0, $result['warnings']);
     $attemptid = $result['attempt']['id'];
     // We are good, try to start a new attempt now.
     try {
         mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'abc')));
         $this->fail('Exception expected due to attempt not finished.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('attemptstillinprogress', $e->errorcode);
     }
     // Finish the started attempt.
     // Process some responses from the student.
     $timenow = time();
     $attemptobj = quiz_attempt::create($attemptid);
     $tosubmit = array(1 => array('answer' => '3.14'));
     $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attemptid);
     $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
     $attemptobj->process_finish($timenow, false);
     // We should be able to start a new attempt.
     $result = mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'abc')));
     $result = external_api::clean_returnvalue(mod_quiz_external::start_attempt_returns(), $result);
     $this->assertEquals(2, $result['attempt']['attempt']);
     $this->assertEquals($this->student->id, $result['attempt']['userid']);
     $this->assertEquals($quiz->id, $result['attempt']['quiz']);
     $this->assertCount(0, $result['warnings']);
     // Test user with no capabilities.
     // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles.
     assign_capability('mod/quiz:attempt', CAP_PROHIBIT, $this->studentrole->id, $context->id);
     // Empty all the caches that may be affected  by this change.
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     try {
         mod_quiz_external::start_attempt($quiz->id);
         $this->fail('Exception expected due to missing capability.');
     } catch (required_capability_exception $e) {
         $this->assertEquals('nopermissions', $e->errorcode);
     }
 }
Exemplo n.º 13
0
    /**
     * Fill the table with data.
     *
     * @param $element - An array containing the table data for the current row.
     */
    private function fill_table_recursive(&$element) {
        global $DB, $CFG;

        $type = $element['type'];
        $depth = $element['depth'];
        $grade_object = $element['object'];
        $eid = $grade_object->id;
        $element['userid'] = $this->user->id;
        $fullname = $this->gtree->get_element_header($element, true, true, true, true, true);
        $data = array();
        $hidden = '';
        $excluded = '';
        $itemlevel = ($type == 'categoryitem' || $type == 'category' || $type == 'courseitem') ? $depth : ($depth + 1);
        $class = 'level' . $itemlevel . ' level' . ($itemlevel % 2 ? 'odd' : 'even');
        $classfeedback = '';

        // If this is a hidden grade category, hide it completely from the user
        if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && (
                $this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN ||
                ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil()))) {
            return false;
        }

        if ($type == 'category') {
            $this->evenodd[$depth] = (($this->evenodd[$depth] + 1) % 2);
        }
        $alter = ($this->evenodd[$depth] == 0) ? 'even' : 'odd';

        /// Process those items that have scores associated
        if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') {
            $header_row = "row_{$eid}_{$this->user->id}";
            $header_cat = "cat_{$grade_object->categoryid}_{$this->user->id}";

            if (! $grade_grade = grade_grade::fetch(array('itemid'=>$grade_object->id,'userid'=>$this->user->id))) {
                $grade_grade = new grade_grade();
                $grade_grade->userid = $this->user->id;
                $grade_grade->itemid = $grade_object->id;
            }

            $grade_grade->load_grade_item();

            /// Hidden Items
            if ($grade_grade->grade_item->is_hidden()) {
                $hidden = ' dimmed_text';
            }

            $hide = false;
            // If this is a hidden grade item, hide it completely from the user.
            if ($grade_grade->is_hidden() && !$this->canviewhidden && (
                    $this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN ||
                    ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil()))) {
                $hide = true;
            } else if (!empty($grade_object->itemmodule) && !empty($grade_object->iteminstance)) {
                // The grade object can be marked visible but still be hidden if
                // the student cannot see the activity due to conditional access
                // and it's set to be hidden entirely.
                $instances = $this->modinfo->get_instances_of($grade_object->itemmodule);
                if (!empty($instances[$grade_object->iteminstance])) {
                    $cm = $instances[$grade_object->iteminstance];
                    if (!$cm->uservisible) {
                        // If there is 'availableinfo' text then it is only greyed
                        // out and not entirely hidden.
                        if (!$cm->availableinfo) {
                            $hide = true;
                        }
                    }
                }
            }

            // Actual Grade - We need to calculate this whether the row is hidden or not.
            $gradeval = $grade_grade->finalgrade;
            $hint = $grade_grade->get_aggregation_hint();
            if (!$this->canviewhidden) {
                /// Virtual Grade (may be calculated excluding hidden items etc).
                $adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($this->courseid,
                                                                             $grade_grade->grade_item,
                                                                             $gradeval);

                $gradeval = $adjustedgrade['grade'];

                // We temporarily adjust the view of this grade item - because the min and
                // max are affected by the hidden values in the aggregation.
                $grade_grade->grade_item->grademax = $adjustedgrade['grademax'];
                $grade_grade->grade_item->grademin = $adjustedgrade['grademin'];
                $hint['status'] = $adjustedgrade['aggregationstatus'];
                $hint['weight'] = $adjustedgrade['aggregationweight'];
            } else {
                // The max and min for an aggregation may be different to the grade_item.
                if (!is_null($gradeval)) {
                    $grade_grade->grade_item->grademax = $grade_grade->rawgrademax;
                    $grade_grade->grade_item->grademin = $grade_grade->rawgrademin;
                }
            }


            if (!$hide) {
                /// Excluded Item
                /**
                if ($grade_grade->is_excluded()) {
                    $fullname .= ' ['.get_string('excluded', 'grades').']';
                    $excluded = ' excluded';
                }
                **/

                /// Other class information
                $class .= $hidden . $excluded;
                if ($this->switch) { // alter style based on whether aggregation is first or last
                   $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " ".$alter."d$depth baggt b2b" : " item b1b";
                } else {
                   $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " ".$alter."d$depth baggb" : " item b1b";
                }
                if ($type == 'categoryitem' or $type == 'courseitem') {
                    $header_cat = "cat_{$grade_object->iteminstance}_{$this->user->id}";
                }

                /// Name
                $data['itemname']['content'] = $fullname;
                $data['itemname']['class'] = $class;
                $data['itemname']['colspan'] = ($this->maxdepth - $depth);
                $data['itemname']['celltype'] = 'th';
                $data['itemname']['id'] = $header_row;

                if ($this->showfeedback) {
                    // Copy $class before appending itemcenter as feedback should not be centered
                    $classfeedback = $class;
                }
                $class .= " itemcenter ";
                if ($this->showweight) {
                    $data['weight']['class'] = $class;
                    $data['weight']['content'] = '-';
                    $data['weight']['headers'] = "$header_cat $header_row weight";
                    // has a weight assigned, might be extra credit

                    // This obliterates the weight because it provides a more informative description.
                    if (is_numeric($hint['weight'])) {
                        $data['weight']['content'] = format_float($hint['weight'] * 100.0, 2) . ' %';
                    }
                    if ($hint['status'] != 'used' && $hint['status'] != 'unknown') {
                        $data['weight']['content'] .= '<br>' . get_string('aggregationhint' . $hint['status'], 'grades');
                    }
                }

                if ($this->showgrade) {
                    if ($grade_grade->grade_item->needsupdate) {
                        $data['grade']['class'] = $class.' gradingerror';
                        $data['grade']['content'] = get_string('error');
                    } else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden()
                           and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) {
                        // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
                        $class .= ' datesubmitted';
                        $data['grade']['class'] = $class;
                        $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort')));

                    } else if ($grade_grade->is_hidden()) {
                        $data['grade']['class'] = $class.' dimmed_text';
                        $data['grade']['content'] = '-';
                        if ($this->canviewhidden) {
                            $data['grade']['content'] = grade_format_gradevalue($gradeval,
                                                                                $grade_grade->grade_item,
                                                                                true);
                        }
                    } else {
                        $data['grade']['class'] = $class;
                        $data['grade']['content'] = grade_format_gradevalue($gradeval,
                                                                            $grade_grade->grade_item,
                                                                            true);
                    }
                    $data['grade']['headers'] = "$header_cat $header_row grade";
                }

                // Range
                if ($this->showrange) {
                    $data['range']['class'] = $class;
                    $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals);
                    $data['range']['headers'] = "$header_cat $header_row range";
                }

                // Percentage
                if ($this->showpercentage) {
                    if ($grade_grade->grade_item->needsupdate) {
                        $data['percentage']['class'] = $class.' gradingerror';
                        $data['percentage']['content'] = get_string('error');
                    } else if ($grade_grade->is_hidden()) {
                        $data['percentage']['class'] = $class.' dimmed_text';
                        $data['percentage']['content'] = '-';
                        if ($this->canviewhidden) {
                            $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
                        }
                    } else {
                        $data['percentage']['class'] = $class;
                        $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
                    }
                    $data['percentage']['headers'] = "$header_cat $header_row percentage";
                }

                // Lettergrade
                if ($this->showlettergrade) {
                    if ($grade_grade->grade_item->needsupdate) {
                        $data['lettergrade']['class'] = $class.' gradingerror';
                        $data['lettergrade']['content'] = get_string('error');
                    } else if ($grade_grade->is_hidden()) {
                        $data['lettergrade']['class'] = $class.' dimmed_text';
                        if (!$this->canviewhidden) {
                            $data['lettergrade']['content'] = '-';
                        } else {
                            $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER);
                        }
                    } else {
                        $data['lettergrade']['class'] = $class;
                        $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER);
                    }
                    $data['lettergrade']['headers'] = "$header_cat $header_row lettergrade";
                }

                // Rank
                if ($this->showrank) {
                    if ($grade_grade->grade_item->needsupdate) {
                        $data['rank']['class'] = $class.' gradingerror';
                        $data['rank']['content'] = get_string('error');
                        } elseif ($grade_grade->is_hidden()) {
                            $data['rank']['class'] = $class.' dimmed_text';
                            $data['rank']['content'] = '-';
                    } else if (is_null($gradeval)) {
                        // no grade, no rank
                        $data['rank']['class'] = $class;
                        $data['rank']['content'] = '-';

                    } else {
                        /// find the number of users with a higher grade
                        $sql = "SELECT COUNT(DISTINCT(userid))
                                  FROM {grade_grades}
                                 WHERE finalgrade > ?
                                       AND itemid = ?
                                       AND hidden = 0";
                        $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1;

                        $data['rank']['class'] = $class;
                        $data['rank']['content'] = "$rank/".$this->get_numusers(false); // total course users
                    }
                    $data['rank']['headers'] = "$header_cat $header_row rank";
                }

                // Average
                if ($this->showaverage) {
                    $data['average']['class'] = $class;
                    if (!empty($this->gtree->items[$eid]->avg)) {
                        $data['average']['content'] = $this->gtree->items[$eid]->avg;
                    } else {
                        $data['average']['content'] = '-';
                    }
                    $data['average']['headers'] = "$header_cat $header_row average";
                }

                // Feedback
                if ($this->showfeedback) {
                    if ($grade_grade->overridden > 0 AND ($type == 'categoryitem' OR $type == 'courseitem')) {
                    $data['feedback']['class'] = $classfeedback.' feedbacktext';
                        $data['feedback']['content'] = get_string('overridden', 'grades').': ' . format_text($grade_grade->feedback, $grade_grade->feedbackformat);
                    } else if (empty($grade_grade->feedback) or (!$this->canviewhidden and $grade_grade->is_hidden())) {
                        $data['feedback']['class'] = $classfeedback.' feedbacktext';
                        $data['feedback']['content'] = '&nbsp;';
                    } else {
                        $data['feedback']['class'] = $classfeedback.' feedbacktext';
                        $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat);
                    }
                    $data['feedback']['headers'] = "$header_cat $header_row feedback";
                }
                // Contribution to the course total column.
                if ($this->showcontributiontocoursetotal) {
                    $data['contributiontocoursetotal']['class'] = $class;
                    $data['contributiontocoursetotal']['content'] = '-';
                    $data['contributiontocoursetotal']['headers'] = "$header_cat $header_row contributiontocoursetotal";

                }
            }
            // We collect the aggregation hints whether they are hidden or not.
            if ($this->showcontributiontocoursetotal) {
                $hint['grademax'] = $grade_grade->grade_item->grademax;
                $hint['grademin'] = $grade_grade->grade_item->grademin;
                $hint['grade'] = $gradeval;
                $parent = $grade_object->load_parent_category();
                if ($grade_object->is_category_item()) {
                    $parent = $parent->load_parent_category();
                }
                $hint['parent'] = $parent->load_grade_item()->id;
                $this->aggregationhints[$grade_grade->itemid] = $hint;
            }
        }

        /// Category
        if ($type == 'category') {
            $data['leader']['class'] = $class.' '.$alter."d$depth b1t b2b b1l";
            $data['leader']['rowspan'] = $element['rowspan'];

            if ($this->switch) { // alter style based on whether aggregation is first or last
               $data['itemname']['class'] = $class.' '.$alter."d$depth b1b b1t";
            } else {
               $data['itemname']['class'] = $class.' '.$alter."d$depth b2t";
            }
            $data['itemname']['colspan'] = ($this->maxdepth - $depth + count($this->tablecolumns) - 1);
            $data['itemname']['content'] = $fullname;
            $data['itemname']['celltype'] = 'th';
            $data['itemname']['id'] = "cat_{$grade_object->id}_{$this->user->id}";
        }

        /// Add this row to the overall system
        foreach ($data as $key => $celldata) {
            $data[$key]['class'] .= ' column-' . $key;
        }
        $this->tabledata[] = $data;

        /// Recursively iterate through all child elements
        if (isset($element['children'])) {
            foreach ($element['children'] as $key=>$child) {
                $this->fill_table_recursive($element['children'][$key]);
            }
        }

        // Check we are showing this column, and we are looking at the root of the table.
        // This should be the very last thing this fill_table_recursive function does.
        if ($this->showcontributiontocoursetotal && ($type == 'category' && $depth == 1)) {
            // We should have collected all the hints by now - walk the tree again and build the contributions column.

            $this->fill_contributions_column($element);
        }
    }
Exemplo n.º 14
0
 /**
  * Test test_view_submission_status
  */
 public function test_view_submission_status()
 {
     global $DB;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     // Setup test data.
     $course = $this->getDataGenerator()->create_course();
     $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
     $context = context_module::instance($assign->cmid);
     $cm = get_coursemodule_from_instance('assign', $assign->id);
     // Test invalid instance id.
     try {
         mod_assign_external::view_submission_status(0);
         $this->fail('Exception expected due to invalid mod_assign instance id.');
     } catch (moodle_exception $e) {
         $this->assertEquals('invalidrecord', $e->errorcode);
     }
     // Test not-enrolled user.
     $user = self::getDataGenerator()->create_user();
     $this->setUser($user);
     try {
         mod_assign_external::view_submission_status($assign->id);
         $this->fail('Exception expected due to not enrolled user.');
     } catch (moodle_exception $e) {
         $this->assertEquals('requireloginerror', $e->errorcode);
     }
     // Test user with full capabilities.
     $studentrole = $DB->get_record('role', array('shortname' => 'student'));
     $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
     // Trigger and capture the event.
     $sink = $this->redirectEvents();
     $result = mod_assign_external::view_submission_status($assign->id);
     $result = external_api::clean_returnvalue(mod_assign_external::view_submission_status_returns(), $result);
     $events = $sink->get_events();
     $this->assertCount(1, $events);
     $event = array_shift($events);
     // Checking that the event contains the expected values.
     $this->assertInstanceOf('\\mod_assign\\event\\submission_status_viewed', $event);
     $this->assertEquals($context, $event->get_context());
     $moodleurl = new \moodle_url('/mod/assign/view.php', array('id' => $cm->id));
     $this->assertEquals($moodleurl, $event->get_url());
     $this->assertEventContextNotUsed($event);
     $this->assertNotEmpty($event->get_name());
     // Test user with no capabilities.
     // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles.
     assign_capability('mod/assign:view', CAP_PROHIBIT, $studentrole->id, $context->id);
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     try {
         mod_assign_external::view_submission_status($assign->id);
         $this->fail('Exception expected due to missing capability.');
     } catch (moodle_exception $e) {
         $this->assertEquals('requireloginerror', $e->errorcode);
     }
 }
Exemplo n.º 15
0
 /**
  * Returns the contexts the user can access.
  *
  * The returned value is a multidimensional array because some search engines can group
  * information and there will be a performance benefit on passing only some contexts
  * instead of the whole context array set.
  *
  * @return bool|array Indexed by area identifier (component + area name). Returns true if the user can see everything.
  */
 protected function get_areas_user_accesses()
 {
     global $CFG, $USER;
     // All results for admins. Eventually we could add a new capability for managers.
     if (is_siteadmin()) {
         return true;
     }
     $areasbylevel = array();
     // Split areas by context level so we only iterate only once through courses and cms.
     $searchareas = static::get_search_areas_list(true);
     foreach ($searchareas as $areaid => $unused) {
         $classname = static::get_area_classname($areaid);
         $searcharea = new $classname();
         foreach ($classname::get_levels() as $level) {
             $areasbylevel[$level][$areaid] = $searcharea;
         }
     }
     // This will store area - allowed contexts relations.
     $areascontexts = array();
     if (!empty($areasbylevel[CONTEXT_SYSTEM])) {
         // We add system context to all search areas working at this level. Here each area is fully responsible of
         // the access control as we can not automate much, we can not even check guest access as some areas might
         // want to allow guests to retrieve data from them.
         $systemcontextid = \context_system::instance()->id;
         foreach ($areasbylevel[CONTEXT_SYSTEM] as $areaid => $searchclass) {
             $areascontexts[$areaid][] = $systemcontextid;
         }
     }
     // Get the courses where the current user has access.
     $courses = enrol_get_my_courses(array('id', 'cacherev'));
     $courses[SITEID] = get_course(SITEID);
     $site = \course_modinfo::instance(SITEID);
     foreach ($courses as $course) {
         // Info about the course modules.
         $modinfo = get_fast_modinfo($course);
         if (!empty($areasbylevel[CONTEXT_COURSE])) {
             // Add the course contexts the user can view.
             $coursecontext = \context_course::instance($course->id);
             foreach ($areasbylevel[CONTEXT_COURSE] as $areaid => $searchclass) {
                 if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
                     $areascontexts[$areaid][$coursecontext->id] = $coursecontext->id;
                 }
             }
         }
         if (!empty($areasbylevel[CONTEXT_MODULE])) {
             // Add the module contexts the user can view (cm_info->uservisible).
             foreach ($areasbylevel[CONTEXT_MODULE] as $areaid => $searchclass) {
                 // Removing the plugintype 'mod_' prefix.
                 $modulename = substr($searchclass->get_component_name(), 4);
                 $modinstances = $modinfo->get_instances_of($modulename);
                 foreach ($modinstances as $modinstance) {
                     if ($modinstance->uservisible) {
                         $areascontexts[$areaid][$modinstance->context->id] = $modinstance->context->id;
                     }
                 }
             }
         }
     }
     return $areascontexts;
 }
Exemplo n.º 16
0
/**
 * Retrieves the forced language of the course of null if not forced language.
 * @param course_modinfo $course_info : course_modinfo object of the course
 * @return string|NULL $lang: forced language of the course or null if not language is forced
 */
function block_intuitel_get_course_lang($course_info)
{
    $course = $course_info->get_course();
    if ($course->lang != null) {
        $lang = block_intuitel_get_parent_lang($course->lang);
    } else {
        $lang = null;
    }
    return $lang;
}
Exemplo n.º 17
0
 /**
  * Works out whether activity is visible *for current user* - if this is false, they
  * aren't allowed to access it.
  * @return void
  */
 private function update_user_visible()
 {
     global $CFG;
     $modcontext = get_context_instance(CONTEXT_MODULE, $this->id);
     $userid = $this->modinfo->get_user_id();
     $this->uservisible = true;
     // Check visibility/availability conditions.
     if ((!$this->visible or !$this->available) and !has_capability('moodle/course:viewhiddenactivities', $modcontext, $userid)) {
         // If the activity is hidden or unavailable, and you don't have viewhiddenactivities,
         // set it so that user can't see or access it.
         $this->uservisible = false;
     }
     // Check group membership. The grouping option makes the activity
     // completely invisible as it does not apply to the user at all.
     if (!empty($CFG->enablegroupmembersonly) and !empty($this->groupmembersonly) and !has_capability('moodle/site:accessallgroups', $modcontext, $userid)) {
         // If the activity has 'group members only' and you don't have accessallgroups...
         $groups = $this->modinfo->get_groups($this->groupingid);
         if (empty($groups)) {
             // ...and you don't belong to a group, then set it so you can't see/access it
             $this->uservisible = false;
             // Ensure activity is completely hidden from user.
             $this->showavailability = 0;
         }
     }
 }
 /**
  * Returns the LOId of the sections (not empty, with a summary or with cms) of a course
  * @param course_modinfo $rawData : course_modinfo object
  * @return \intuitel\LOId : array with LOID of children
  */
 private function getChildren($rawData)
 {
     $sections = $rawData->get_section_info_all();
     $hasChildren = array();
     foreach ($sections as $section) {
         $sectionFactory = new SectionLOFactory();
         $sectionLO = $sectionFactory->createLOFromNative($section);
         if ($sectionLO != null) {
             //empty section: no name or summary
             $sectionLOid = $sectionLO->getloId();
             $hasChildren[] = $sectionLOid;
         }
     }
     return $hasChildren;
 }
Exemplo n.º 19
0
 /**
  * Test view_lti
  */
 public function test_view_lti()
 {
     global $DB;
     // Test invalid instance id.
     try {
         mod_lti_external::view_lti(0);
         $this->fail('Exception expected due to invalid mod_lti instance id.');
     } catch (moodle_exception $e) {
         $this->assertEquals('invalidrecord', $e->errorcode);
     }
     // Test not-enrolled user.
     $usernotenrolled = self::getDataGenerator()->create_user();
     $this->setUser($usernotenrolled);
     try {
         mod_lti_external::view_lti($this->lti->id);
         $this->fail('Exception expected due to not enrolled user.');
     } catch (moodle_exception $e) {
         $this->assertEquals('requireloginerror', $e->errorcode);
     }
     // Test user with full capabilities.
     $this->setUser($this->student);
     // Trigger and capture the event.
     $sink = $this->redirectEvents();
     $result = mod_lti_external::view_lti($this->lti->id);
     $result = external_api::clean_returnvalue(mod_lti_external::view_lti_returns(), $result);
     $events = $sink->get_events();
     $this->assertCount(1, $events);
     $event = array_shift($events);
     // Checking that the event contains the expected values.
     $this->assertInstanceOf('\\mod_lti\\event\\course_module_viewed', $event);
     $this->assertEquals($this->context, $event->get_context());
     $moodlelti = new \moodle_url('/mod/lti/view.php', array('id' => $this->cm->id));
     $this->assertEquals($moodlelti, $event->get_url());
     $this->assertEventContextNotUsed($event);
     $this->assertNotEmpty($event->get_name());
     // Test user with no capabilities.
     // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles.
     assign_capability('mod/lti:view', CAP_PROHIBIT, $this->studentrole->id, $this->context->id);
     // Empty all the caches that may be affected by this change.
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     try {
         mod_lti_external::view_lti($this->lti->id);
         $this->fail('Exception expected due to missing capability.');
     } catch (moodle_exception $e) {
         $this->assertEquals('requireloginerror', $e->errorcode);
     }
 }
Exemplo n.º 20
0
 /**
  * Returns course ID - from course_sections table
  *
  * @return int
  */
 private function get_course() {
     return $this->modinfo->get_course_id();
 }
Exemplo n.º 21
0
 /**
  * Checks whether the module's conditional access settings mean that the user cannot see the activity at all
  *
  * @return bool True if the user cannot see the module. False if the activity is either available or should be greyed out.
  */
 public function is_user_access_restricted_by_conditional_access()
 {
     global $CFG, $USER;
     if (empty($CFG->enableavailability)) {
         return false;
     }
     // If module will always be visible anyway (but greyed out), don't bother checking anything else
     if ($this->showavailability == CONDITION_STUDENTVIEW_SHOW) {
         return false;
     }
     // Can the user see hidden modules?
     $modcontext = context_module::instance($this->id);
     $userid = $this->modinfo->get_user_id();
     if (has_capability('moodle/course:viewhiddenactivities', $modcontext, $userid)) {
         return false;
     }
     // Is the module hidden due to unmet conditions?
     if (!$this->available) {
         return true;
     }
     return false;
 }
Exemplo n.º 22
0
 /**
  * Test validate_attempt
  */
 public function test_validate_attempt()
 {
     global $DB;
     // Create a new quiz with one attempt started.
     list($quiz, $context, $quizobj, $attempt, $attemptobj) = $this->create_quiz_with_questions(true);
     $this->setUser($this->student);
     // Invalid attempt.
     try {
         $params = array('attemptid' => -1, 'page' => 0);
         testable_mod_quiz_external::validate_attempt($params);
         $this->fail('Exception expected due to invalid attempt id.');
     } catch (dml_missing_record_exception $e) {
         $this->assertEquals('invalidrecord', $e->errorcode);
     }
     // Test OK case.
     $params = array('attemptid' => $attempt->id, 'page' => 0);
     $result = testable_mod_quiz_external::validate_attempt($params);
     $this->assertEquals($attempt->id, $result[0]->get_attempt()->id);
     $this->assertEquals([], $result[1]);
     // Test with preflight data.
     $quiz->password = '******';
     $DB->update_record('quiz', $quiz);
     try {
         $params = array('attemptid' => $attempt->id, 'page' => 0, 'preflightdata' => array(array("name" => "quizpassword", "value" => 'bad')));
         testable_mod_quiz_external::validate_attempt($params);
         $this->fail('Exception expected due to invalid passwod.');
     } catch (moodle_exception $e) {
         $this->assertEquals(get_string('passworderror', 'quizaccess_password'), $e->errorcode);
     }
     // Now, try everything correct.
     $params['preflightdata'][0]['value'] = 'abc';
     $result = testable_mod_quiz_external::validate_attempt($params);
     $this->assertEquals($attempt->id, $result[0]->get_attempt()->id);
     $this->assertEquals([], $result[1]);
     // Page out of range.
     $DB->update_record('quiz', $quiz);
     $params['page'] = 4;
     try {
         testable_mod_quiz_external::validate_attempt($params);
         $this->fail('Exception expected due to page out of range.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('Invalid page number', $e->errorcode);
     }
     $params['page'] = 0;
     // Try to open attempt in closed quiz.
     $quiz->timeopen = time() - WEEKSECS;
     $quiz->timeclose = time() - DAYSECS;
     $DB->update_record('quiz', $quiz);
     // This should work, ommit access rules.
     testable_mod_quiz_external::validate_attempt($params, false);
     // Get a generic error because prior to checking the dates the attempt is closed.
     try {
         testable_mod_quiz_external::validate_attempt($params);
         $this->fail('Exception expected due to passed dates.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('attempterror', $e->errorcode);
     }
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attempt->id);
     $attemptobj->process_finish(time(), false);
     try {
         testable_mod_quiz_external::validate_attempt($params, false);
         $this->fail('Exception expected due to attempt finished.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('attemptalreadyclosed', $e->errorcode);
     }
     // Test user with no capabilities.
     // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles.
     assign_capability('mod/quiz:attempt', CAP_PROHIBIT, $this->studentrole->id, $context->id);
     // Empty all the caches that may be affected  by this change.
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     try {
         testable_mod_quiz_external::validate_attempt($params);
         $this->fail('Exception expected due to missing permissions.');
     } catch (required_capability_exception $e) {
         $this->assertEquals('nopermissions', $e->errorcode);
     }
     // Now try with a different user.
     $this->setUser($this->teacher);
     $params['page'] = 0;
     try {
         testable_mod_quiz_external::validate_attempt($params);
         $this->fail('Exception expected due to not your attempt.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('notyourattempt', $e->errorcode);
     }
 }
Exemplo n.º 23
0
 /**
  * Test get_calendar_events
  */
 public function test_get_calendar_events()
 {
     global $DB, $USER;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     // Create a few stuff to test with.
     $user = $this->getDataGenerator()->create_user();
     $course = $this->getDataGenerator()->create_course();
     $record = new stdClass();
     $record->courseid = $course->id;
     $group = $this->getDataGenerator()->create_group($record);
     $beforecount = $DB->count_records('event');
     // Let's create a few events.
     $siteevent = $this->create_calendar_event('site', $USER->id, 'site');
     // This event will have description with an inline fake image.
     $draftidfile = file_get_unused_draft_itemid();
     $usercontext = context_course::instance($course->id);
     $filerecord = array('contextid' => $usercontext->id, 'component' => 'user', 'filearea' => 'draft', 'itemid' => $draftidfile, 'filepath' => '/', 'filename' => 'fakeimage.png');
     $fs = get_file_storage();
     $fs->create_file_from_string($filerecord, 'img contents');
     $record = new stdClass();
     $record->courseid = $course->id;
     $record->description = array('format' => FORMAT_HTML, 'text' => 'Text with img <img src="@@PLUGINFILE@@/fakeimage.png">', 'itemid' => $draftidfile);
     $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record);
     $userevent = $this->create_calendar_event('user', $USER->id);
     $record = new stdClass();
     $record->courseid = $course->id;
     $record->groupid = $group->id;
     $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
     $paramevents = array('eventids' => array($siteevent->id), 'courseids' => array($course->id), 'groupids' => array($group->id));
     $options = array('siteevents' => true, 'userevents' => true);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     // Check to see if we got all events.
     $this->assertEquals(5, count($events['events']));
     $this->assertEquals(0, count($events['warnings']));
     $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + 7 * WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(5, count($events['events']));
     $this->assertEquals(0, count($events['warnings']));
     // Expect the same URL in the description of two different events (because they are repeated).
     $coursecontext = context_course::instance($course->id);
     $expectedurl = "webservice/pluginfile.php/{$coursecontext->id}/calendar/event_description/{$courseevent->id}/fakeimage.png";
     $withdescription = 0;
     foreach ($events['events'] as $event) {
         if (!empty($event['description'])) {
             $withdescription++;
             $this->assertContains($expectedurl, $event['description']);
         }
     }
     $this->assertEquals(2, $withdescription);
     // Let's play around with caps.
     $this->setUser($user);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(2, count($events['events']));
     // site, user.
     $this->assertEquals(2, count($events['warnings']));
     // course, group.
     $role = $DB->get_record('role', array('shortname' => 'student'));
     $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(4, count($events['events']));
     // site, user, both course events.
     $this->assertEquals(1, count($events['warnings']));
     // group.
     $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(3, count($events['events']));
     // site, user, one course event.
     $this->assertEquals(1, count($events['warnings']));
     // group.
     groups_add_member($group, $user);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(4, count($events['events']));
     // site, user, group, one course event.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('courseids' => array($course->id), 'groupids' => array($group->id));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(4, count($events['events']));
     // site, user, group, one course event.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('groupids' => array($group->id, 23));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(3, count($events['events']));
     // site, user, group.
     $this->assertEquals(1, count($events['warnings']));
     $paramevents = array('courseids' => array(23));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(2, count($events['events']));
     // site, user.
     $this->assertEquals(1, count($events['warnings']));
     $paramevents = array();
     $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(0, count($events['events']));
     // nothing returned.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('eventids' => array($siteevent->id, $groupevent->id));
     $options = array('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7 * WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(2, count($events['events']));
     // site, group.
     $this->assertEquals(0, count($events['warnings']));
     $paramevents = array('eventids' => array($siteevent->id));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(1, count($events['events']));
     // site.
     $this->assertEquals(0, count($events['warnings']));
     // Try getting a course event by its id.
     $paramevents = array('eventids' => array($courseevent->id));
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertEquals(1, count($events['events']));
     $this->assertEquals(0, count($events['warnings']));
     // Now, create an activity event.
     $this->setAdminUser();
     $nexttime = time() + DAYSECS;
     $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime));
     $this->setUser($user);
     $paramevents = array('courseids' => array($course->id));
     $options = array('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS);
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     $this->assertCount(5, $events['events']);
     // Hide the assignment.
     set_coursemodule_visible($assign->cmid, 0);
     // Empty all the caches that may be affected  by this change.
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     $events = core_calendar_external::get_calendar_events($paramevents, $options);
     $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
     // Expect one less.
     $this->assertCount(4, $events['events']);
 }
Exemplo n.º 24
0
 private function fill_table_recursive(&$element)
 {
     global $DB, $CFG;
     $type = $element['type'];
     $depth = $element['depth'];
     $grade_object = $element['object'];
     $eid = $grade_object->id;
     $element['userid'] = $this->user->id;
     $fullname = $this->gtree->get_element_header($element, true, true, true);
     $data = array();
     $hidden = '';
     $excluded = '';
     $class = '';
     $classfeedback = '';
     // If this is a hidden grade category, hide it completely from the user
     if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil())) {
         return false;
     }
     if ($type == 'category') {
         $this->evenodd[$depth] = ($this->evenodd[$depth] + 1) % 2;
     }
     $alter = $this->evenodd[$depth] == 0 ? 'even' : 'odd';
     /// Process those items that have scores associated
     if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') {
         $header_row = "row_{$eid}_{$this->user->id}";
         $header_cat = "cat_{$grade_object->categoryid}_{$this->user->id}";
         if (!($grade_grade = grade_grade::fetch(array('itemid' => $grade_object->id, 'userid' => $this->user->id)))) {
             $grade_grade = new grade_grade();
             $grade_grade->userid = $this->user->id;
             $grade_grade->itemid = $grade_object->id;
         }
         $grade_grade->load_grade_item();
         /// Hidden Items
         if ($grade_grade->grade_item->is_hidden()) {
             $hidden = ' dimmed_text';
         }
         $hide = false;
         // If this is a hidden grade item, hide it completely from the user.
         if ($grade_grade->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil())) {
             $hide = true;
         } else {
             if (!empty($grade_object->itemmodule) && !empty($grade_object->iteminstance)) {
                 // The grade object can be marked visible but still be hidden if
                 // the student cannot see the activity due to conditional access
                 // and it's set to be hidden entirely.
                 $instances = $this->modinfo->get_instances_of($grade_object->itemmodule);
                 if (!empty($instances[$grade_object->iteminstance])) {
                     $cm = $instances[$grade_object->iteminstance];
                     if (!$cm->uservisible) {
                         // If there is 'availableinfo' text then it is only greyed
                         // out and not entirely hidden.
                         if (!$cm->availableinfo) {
                             $hide = true;
                         }
                     }
                 }
             }
         }
         if (!$hide) {
             /// Excluded Item
             if ($grade_grade->is_excluded()) {
                 $fullname .= ' [' . get_string('excluded', 'grades') . ']';
                 $excluded = ' excluded';
             }
             /// Other class information
             $class = "{$hidden} {$excluded}";
             if ($this->switch) {
                 // alter style based on whether aggregation is first or last
                 $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggt b2b" : " item b1b";
             } else {
                 $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggb" : " item b1b";
             }
             if ($type == 'categoryitem' or $type == 'courseitem') {
                 $header_cat = "cat_{$grade_object->iteminstance}_{$this->user->id}";
             }
             /// Name
             $data['itemname']['content'] = $fullname;
             $data['itemname']['class'] = $class;
             $data['itemname']['colspan'] = $this->maxdepth - $depth;
             $data['itemname']['celltype'] = 'th';
             $data['itemname']['id'] = $header_row;
             /// Actual Grade
             $gradeval = $grade_grade->finalgrade;
             if (!$this->canviewhidden) {
                 /// Virtual Grade (may be calculated excluding hidden items etc).
                 $adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($this->courseid, $grade_grade->grade_item, $gradeval);
                 $gradeval = $adjustedgrade['grade'];
                 // We temporarily adjust the view of this grade item - because the min and
                 // max are affected by the hidden values in the aggregation.
                 $grade_grade->grade_item->grademax = $adjustedgrade['grademax'];
                 $grade_grade->grade_item->grademin = $adjustedgrade['grademin'];
             }
             if ($this->showfeedback) {
                 // Copy $class before appending itemcenter as feedback should not be centered
                 $classfeedback = $class;
             }
             $class .= " itemcenter ";
             if ($this->showweight) {
                 $data['weight']['class'] = $class;
                 $data['weight']['content'] = '-';
                 $data['weight']['headers'] = "{$header_cat} {$header_row} weight";
                 // has a weight assigned, might be extra credit
                 if ($grade_object->aggregationcoef > 0 && $type != 'courseitem') {
                     $data['weight']['content'] = number_format($grade_object->aggregationcoef, 2);
                 }
             }
             if ($this->showgrade) {
                 if ($grade_grade->grade_item->needsupdate) {
                     $data['grade']['class'] = $class . ' gradingerror';
                     $data['grade']['content'] = get_string('error');
                 } else {
                     if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden() and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) {
                         // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
                         $class .= ' datesubmitted';
                         $data['grade']['class'] = $class;
                         $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort')));
                     } else {
                         if ($grade_grade->is_hidden()) {
                             $data['grade']['class'] = $class . ' dimmed_text';
                             $data['grade']['content'] = '-';
                             if ($this->canviewhidden) {
                                 $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true);
                             }
                         } else {
                             $data['grade']['class'] = $class;
                             $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true);
                         }
                     }
                 }
                 $data['grade']['headers'] = "{$header_cat} {$header_row} grade";
             }
             // Range
             if ($this->showrange) {
                 $data['range']['class'] = $class;
                 $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals);
                 $data['range']['headers'] = "{$header_cat} {$header_row} range";
             }
             // Percentage
             if ($this->showpercentage) {
                 if ($grade_grade->grade_item->needsupdate) {
                     $data['percentage']['class'] = $class . ' gradingerror';
                     $data['percentage']['content'] = get_string('error');
                 } else {
                     if ($grade_grade->is_hidden()) {
                         $data['percentage']['class'] = $class . ' dimmed_text';
                         $data['percentage']['content'] = '-';
                         if ($this->canviewhidden) {
                             $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
                         }
                     } else {
                         $data['percentage']['class'] = $class;
                         $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
                     }
                 }
                 $data['percentage']['headers'] = "{$header_cat} {$header_row} percentage";
             }
             // Lettergrade
             if ($this->showlettergrade) {
                 if ($grade_grade->grade_item->needsupdate) {
                     $data['lettergrade']['class'] = $class . ' gradingerror';
                     $data['lettergrade']['content'] = get_string('error');
                 } else {
                     if ($grade_grade->is_hidden()) {
                         $data['lettergrade']['class'] = $class . ' dimmed_text';
                         if (!$this->canviewhidden) {
                             $data['lettergrade']['content'] = '-';
                         } else {
                             $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER);
                         }
                     } else {
                         $data['lettergrade']['class'] = $class;
                         $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER);
                     }
                 }
                 $data['lettergrade']['headers'] = "{$header_cat} {$header_row} lettergrade";
             }
             // Rank
             if ($this->showrank) {
                 if ($grade_grade->grade_item->needsupdate) {
                     $data['rank']['class'] = $class . ' gradingerror';
                     $data['rank']['content'] = get_string('error');
                 } elseif ($grade_grade->is_hidden()) {
                     $data['rank']['class'] = $class . ' dimmed_text';
                     $data['rank']['content'] = '-';
                 } else {
                     if (is_null($gradeval)) {
                         // no grade, no rank
                         $data['rank']['class'] = $class;
                         $data['rank']['content'] = '-';
                     } else {
                         /// find the number of users with a higher grade
                         $sql = "SELECT COUNT(DISTINCT(userid))\n                                  FROM {grade_grades}\n                                 WHERE finalgrade > ?\n                                       AND itemid = ?\n                                       AND hidden = 0";
                         $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1;
                         $data['rank']['class'] = $class;
                         $data['rank']['content'] = "{$rank}/" . $this->get_numusers(false);
                         // total course users
                     }
                 }
                 $data['rank']['headers'] = "{$header_cat} {$header_row} rank";
             }
             // Average
             if ($this->showaverage) {
                 $data['average']['class'] = $class;
                 if (!empty($this->gtree->items[$eid]->avg)) {
                     $data['average']['content'] = $this->gtree->items[$eid]->avg;
                 } else {
                     $data['average']['content'] = '-';
                 }
                 $data['average']['headers'] = "{$header_cat} {$header_row} average";
             }
             // Feedback
             if ($this->showfeedback) {
                 if ($grade_grade->overridden > 0 and ($type == 'categoryitem' or $type == 'courseitem')) {
                     $data['feedback']['class'] = $classfeedback . ' feedbacktext';
                     $data['feedback']['content'] = get_string('overridden', 'grades') . ': ' . format_text($grade_grade->feedback, $grade_grade->feedbackformat);
                 } else {
                     if (empty($grade_grade->feedback) or !$this->canviewhidden and $grade_grade->is_hidden()) {
                         $data['feedback']['class'] = $classfeedback . ' feedbacktext';
                         $data['feedback']['content'] = '&nbsp;';
                     } else {
                         $data['feedback']['class'] = $classfeedback . ' feedbacktext';
                         $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat);
                     }
                 }
                 $data['feedback']['headers'] = "{$header_cat} {$header_row} feedback";
             }
         }
     }
     /// Category
     if ($type == 'category') {
         $data['leader']['class'] = $class . ' ' . $alter . "d{$depth} b1t b2b b1l";
         $data['leader']['rowspan'] = $element['rowspan'];
         if ($this->switch) {
             // alter style based on whether aggregation is first or last
             $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b1b b1t";
         } else {
             $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b2t";
         }
         $data['itemname']['colspan'] = $this->maxdepth - $depth + count($this->tablecolumns) - 1;
         $data['itemname']['content'] = $fullname;
         $data['itemname']['celltype'] = 'th';
         $data['itemname']['id'] = "cat_{$grade_object->id}_{$this->user->id}";
     }
     /// Add this row to the overall system
     $this->tabledata[] = $data;
     /// Recursively iterate through all child elements
     if (isset($element['children'])) {
         foreach ($element['children'] as $key => $child) {
             $this->fill_table_recursive($element['children'][$key]);
         }
     }
 }
$coursecontext = context_course::instance($course->id);
if (!has_capability('moodle/course:manageactivities', $coursecontext)) {
    echo get_string('progress_dating_error_access', 'block_snap');
    //check the start dates for the course
} elseif (!$course->startdate) {
    echo html_writer::tag('p', get_string('progress_dating_error', 'block_snap'), array('class' => 'alert alert-danger'));
    //check to see if completion is enabled for the course
} elseif (!$course->enablecompletion) {
    echo html_writer::tag('p', get_string('no_completion_tracking', 'block_snap'), array('class' => 'alert alert-danger'));
    //otherwise, display the dating tool
} else {
    echo html_writer::tag('p', get_string('progress_dating_description', 'block_snap'), array('class' => 'alert alert-info'));
    //create a warning about having javascript disabled that we will remove with javascript
    echo '<noscript>' . html_writer::tag('p', get_string('progress_dating_nojs', 'block_snap'), array('class' => 'snap-nojs alert alert-danger')) . '</noscript>';
    //pull the modules
    course_modinfo::clear_instance_cache($course);
    $modinfo = get_fast_modinfo($course);
    $modlist = array();
    $callist = array();
    //establish the start date of the course
    $start = new DateTime();
    $start->setTimestamp($course->startdate);
    //show when the course starts
    echo '<h3 class="course-starts">' . get_string('starts_on', 'block_snap') . ' <span>' . $start->format('l, F j, Y') . '</span></h3>' . PHP_EOL;
    //iterate all the modules and create each item for dragging around
    foreach ($modinfo->cms as $mod) {
        //if completion is not enabled, then skip it
        if (!$mod->completion) {
            continue;
        }
        //create the html for the module icon
Exemplo n.º 26
0
/**
 * Preloads the list of active filters for all activities (modules) on the course
 * using two database queries.
 *
 * @param course_modinfo $modinfo Course object from get_fast_modinfo
 */
function filter_preload_activities(course_modinfo $modinfo)
{
    global $DB, $FILTERLIB_PRIVATE;
    if (!isset($FILTERLIB_PRIVATE)) {
        $FILTERLIB_PRIVATE = new stdClass();
    }
    // Don't repeat preload
    if (!isset($FILTERLIB_PRIVATE->preloaded)) {
        $FILTERLIB_PRIVATE->preloaded = array();
    }
    if (!empty($FILTERLIB_PRIVATE->preloaded[$modinfo->get_course_id()])) {
        return;
    }
    $FILTERLIB_PRIVATE->preloaded[$modinfo->get_course_id()] = true;
    // Get contexts for all CMs
    $cmcontexts = array();
    $cmcontextids = array();
    foreach ($modinfo->get_cms() as $cm) {
        $modulecontext = context_module::instance($cm->id);
        $cmcontextids[] = $modulecontext->id;
        $cmcontexts[] = $modulecontext;
    }
    // Get course context and all other parents...
    $coursecontext = context_course::instance($modinfo->get_course_id());
    $parentcontextids = explode('/', substr($coursecontext->path, 1));
    $allcontextids = array_merge($cmcontextids, $parentcontextids);
    // Get all filter_active rows relating to all these contexts
    list($sql, $params) = $DB->get_in_or_equal($allcontextids);
    $filteractives = $DB->get_records_select('filter_active', "contextid {$sql}", $params);
    // Get all filter_config only for the cm contexts
    list($sql, $params) = $DB->get_in_or_equal($cmcontextids);
    $filterconfigs = $DB->get_records_select('filter_config', "contextid {$sql}", $params);
    // Note: I was a bit surprised that filter_config only works for the
    // most specific context (i.e. it does not need to be checked for course
    // context if we only care about CMs) however basede on code in
    // filter_get_active_in_context, this does seem to be correct.
    // Build course default active list. Initially this will be an array of
    // filter name => active score (where an active score >0 means it's active)
    $courseactive = array();
    // Also build list of filter_active rows below course level, by contextid
    $remainingactives = array();
    // Array lists filters that are banned at top level
    $banned = array();
    // Add any active filters in parent contexts to the array
    foreach ($filteractives as $row) {
        $depth = array_search($row->contextid, $parentcontextids);
        if ($depth !== false) {
            // Find entry
            if (!array_key_exists($row->filter, $courseactive)) {
                $courseactive[$row->filter] = 0;
            }
            // This maths copes with reading rows in any order. Turning on/off
            // at site level counts 1, at next level down 4, at next level 9,
            // then 16, etc. This means the deepest level always wins, except
            // against the -9999 at top level.
            $courseactive[$row->filter] += ($depth + 1) * ($depth + 1) * $row->active;
            if ($row->active == TEXTFILTER_DISABLED) {
                $banned[$row->filter] = true;
            }
        } else {
            // Build list of other rows indexed by contextid
            if (!array_key_exists($row->contextid, $remainingactives)) {
                $remainingactives[$row->contextid] = array();
            }
            $remainingactives[$row->contextid][] = $row;
        }
    }
    // Chuck away the ones that aren't active.
    foreach ($courseactive as $filter => $score) {
        if ($score <= 0) {
            unset($courseactive[$filter]);
        } else {
            $courseactive[$filter] = array();
        }
    }
    // Loop through the contexts to reconstruct filter_active lists for each
    // cm on the course.
    if (!isset($FILTERLIB_PRIVATE->active)) {
        $FILTERLIB_PRIVATE->active = array();
    }
    foreach ($cmcontextids as $contextid) {
        // Copy course list
        $FILTERLIB_PRIVATE->active[$contextid] = $courseactive;
        // Are there any changes to the active list?
        if (array_key_exists($contextid, $remainingactives)) {
            foreach ($remainingactives[$contextid] as $row) {
                if ($row->active > 0 && empty($banned[$row->filter])) {
                    // If it's marked active for specific context, add entry
                    // (doesn't matter if one exists already).
                    $FILTERLIB_PRIVATE->active[$contextid][$row->filter] = array();
                } else {
                    // If it's marked inactive, remove entry (doesn't matter
                    // if it doesn't exist).
                    unset($FILTERLIB_PRIVATE->active[$contextid][$row->filter]);
                }
            }
        }
    }
    // Process all config rows to add config data to these entries.
    foreach ($filterconfigs as $row) {
        if (isset($FILTERLIB_PRIVATE->active[$row->contextid][$row->filter])) {
            $FILTERLIB_PRIVATE->active[$row->contextid][$row->filter][$row->name] = $row->value;
        }
    }
}
Exemplo n.º 27
0
 /**
  * Test get_imscps_by_courses
  */
 public function test_get_imscps_by_courses()
 {
     global $DB, $USER;
     $this->resetAfterTest(true);
     // As admin.
     $this->setAdminUser();
     $course1 = self::getDataGenerator()->create_course();
     $imscpoptions1 = array('course' => $course1->id, 'name' => 'First IMSCP');
     $imscp1 = self::getDataGenerator()->create_module('imscp', $imscpoptions1);
     $course2 = self::getDataGenerator()->create_course();
     $imscpoptions2 = array('course' => $course2->id, 'name' => 'Second IMSCP');
     $imscp2 = self::getDataGenerator()->create_module('imscp', $imscpoptions2);
     $student1 = $this->getDataGenerator()->create_user();
     $studentrole = $DB->get_record('role', array('shortname' => 'student'));
     // Enroll Student1 in Course1.
     self::getDataGenerator()->enrol_user($student1->id, $course1->id, $studentrole->id);
     $this->setUser($student1);
     $imscps = mod_imscp_external::get_imscps_by_courses(array());
     $imscps = external_api::clean_returnvalue(mod_imscp_external::get_imscps_by_courses_returns(), $imscps);
     $this->assertCount(1, $imscps['imscps']);
     $this->assertEquals('First IMSCP', $imscps['imscps'][0]['name']);
     // As Student you cannot see some IMSCP properties like 'section'.
     $this->assertFalse(isset($imscps['imscps'][0]['section']));
     // Student1 is not enrolled in this Course.
     // The webservice will give a warning!
     $imscps = mod_imscp_external::get_imscps_by_courses(array($course2->id));
     $imscps = external_api::clean_returnvalue(mod_imscp_external::get_imscps_by_courses_returns(), $imscps);
     $this->assertCount(0, $imscps['imscps']);
     $this->assertEquals(1, $imscps['warnings'][0]['warningcode']);
     // Now as admin.
     $this->setAdminUser();
     // As Admin we can see this IMSCP.
     $imscps = mod_imscp_external::get_imscps_by_courses(array($course2->id));
     $imscps = external_api::clean_returnvalue(mod_imscp_external::get_imscps_by_courses_returns(), $imscps);
     $this->assertCount(1, $imscps['imscps']);
     $this->assertEquals('Second IMSCP', $imscps['imscps'][0]['name']);
     // As an Admin you can see some IMSCP properties like 'section'.
     $this->assertEquals(0, $imscps['imscps'][0]['section']);
     // Now, prohibit capabilities.
     $this->setUser($student1);
     $contextcourse1 = context_course::instance($course1->id);
     // Prohibit capability = mod:imscp:view on Course1 for students.
     assign_capability('mod/imscp:view', CAP_PROHIBIT, $studentrole->id, $contextcourse1->id);
     // Empty all the caches that may be affected by this change.
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     $imscps = mod_imscp_external::get_imscps_by_courses(array($course1->id));
     $imscps = external_api::clean_returnvalue(mod_imscp_external::get_imscps_by_courses_returns(), $imscps);
     $this->assertCount(0, $imscps['imscps']);
 }