/** * Add appropriate form elements to the critieria form * * @param moodleform $mform Moodle forms object * @param stdClass $data details of various modules */ public function config_form_display(&$mform, $data = null) { $modnames = get_module_types_names(); $mform->addElement('checkbox', 'criteria_activity[' . $data->id . ']', $modnames[self::get_mod_name($data->module)] . ' - ' . format_string($data->name)); if ($this->id) { $mform->setDefault('criteria_activity[' . $data->id . ']', 1); } }
public function test_cm_info_properties() { global $DB, $CFG; $this->resetAfterTest(); $oldcfgenableavailability = $CFG->enableavailability; $oldcfgenablecompletion = $CFG->enablecompletion; set_config('enableavailability', 1); set_config('enablecompletion', 1); $this->setAdminUser(); // Generate the course and pre-requisite module. $course = $this->getDataGenerator()->create_course(array('format' => 'topics', 'numsections' => 3, 'enablecompletion' => 1, 'groupmode' => SEPARATEGROUPS, 'forcegroupmode' => 0), array('createsections' => true)); $coursecontext = context_course::instance($course->id); $prereqforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), array('completion' => 1)); // Generate module and add availability conditions. $availability = '{"op":"&","showc":[true,true,true],"c":[' . '{"type":"completion","cm":' . $prereqforum->cmid . ',"e":"' . COMPLETION_COMPLETE . '"},' . '{"type":"grade","id":666,"min":0.4},' . '{"type":"profile","op":"contains","sf":"email","v":"test"}' . ']}'; $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id), array('idnumber' => 123, 'groupmode' => VISIBLEGROUPS, 'availability' => $availability)); rebuild_course_cache($course->id, true); // Retrieve all related records from DB. $assigndb = $DB->get_record('assign', array('id' => $assign->id)); $moduletypedb = $DB->get_record('modules', array('name' => 'assign')); $moduledb = $DB->get_record('course_modules', array('module' => $moduletypedb->id, 'instance' => $assign->id)); $sectiondb = $DB->get_record('course_sections', array('id' => $moduledb->section)); $modnamessingular = get_module_types_names(false); $modnamesplural = get_module_types_names(true); // Create and enrol a student. $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); $student = $this->getDataGenerator()->create_user(); role_assign($studentrole->id, $student->id, $coursecontext); $enrolplugin = enrol_get_plugin('manual'); $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual')); $enrolplugin->enrol_user($enrolinstance, $student->id); $this->setUser($student); // Emulate data used in building course cache to receive the same instance of cached_cm_info as was used in building modinfo. $rawmods = get_course_mods($course->id); $cachedcminfo = assign_get_coursemodule_info($rawmods[$moduledb->id]); // Get modinfo. $modinfo = get_fast_modinfo($course->id); $cm = $modinfo->instances['assign'][$assign->id]; $this->assertEquals($moduledb->id, $cm->id); $this->assertEquals($assigndb->id, $cm->instance); $this->assertEquals($moduledb->course, $cm->course); $this->assertEquals($moduledb->idnumber, $cm->idnumber); $this->assertEquals($moduledb->added, $cm->added); $this->assertEquals($moduledb->visible, $cm->visible); $this->assertEquals($moduledb->visibleold, $cm->visibleold); $this->assertEquals($moduledb->groupmode, $cm->groupmode); $this->assertEquals(VISIBLEGROUPS, $cm->groupmode); $this->assertEquals($moduledb->groupingid, $cm->groupingid); $this->assertEquals($course->groupmodeforce, $cm->coursegroupmodeforce); $this->assertEquals($course->groupmode, $cm->coursegroupmode); $this->assertEquals(SEPARATEGROUPS, $cm->coursegroupmode); $this->assertEquals($course->groupmodeforce ? $course->groupmode : $moduledb->groupmode, $cm->effectivegroupmode); // (since mod_assign supports groups). $this->assertEquals(VISIBLEGROUPS, $cm->effectivegroupmode); $this->assertEquals($moduledb->indent, $cm->indent); $this->assertEquals($moduledb->completion, $cm->completion); $this->assertEquals($moduledb->completiongradeitemnumber, $cm->completiongradeitemnumber); $this->assertEquals($moduledb->completionview, $cm->completionview); $this->assertEquals($moduledb->completionexpected, $cm->completionexpected); $this->assertEquals($moduledb->showdescription, $cm->showdescription); $this->assertEquals(null, $cm->extra); // Deprecated field. Used in module types that don't return cached_cm_info. $this->assertEquals($cachedcminfo->icon, $cm->icon); $this->assertEquals($cachedcminfo->iconcomponent, $cm->iconcomponent); $this->assertEquals('assign', $cm->modname); $this->assertEquals($moduledb->module, $cm->module); $this->assertEquals($cachedcminfo->name, $cm->name); $this->assertEquals($sectiondb->section, $cm->sectionnum); $this->assertEquals($moduledb->section, $cm->section); $this->assertEquals($availability, $cm->availability); $this->assertEquals(context_module::instance($moduledb->id), $cm->context); $this->assertEquals($modnamessingular['assign'], $cm->modfullname); $this->assertEquals($modnamesplural['assign'], $cm->modplural); $this->assertEquals(new moodle_url('/mod/assign/view.php', array('id' => $moduledb->id)), $cm->url); $this->assertEquals($cachedcminfo->customdata, $cm->customdata); // Deprecated field. $this->assertEquals(0, $cm->groupmembersonly); $this->assertDebuggingCalled(); // Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type). $this->assertNotEmpty($cm->availableinfo); // Lists all unmet availability conditions. $this->assertEquals(0, $cm->uservisible); $this->assertEquals('', $cm->extraclasses); $this->assertEquals('', $cm->onclick); $this->assertEquals(null, $cm->afterlink); $this->assertEquals(null, $cm->afterediticons); $this->assertEquals('', $cm->content); // Attempt to access and set non-existing field. $this->assertTrue(empty($modinfo->somefield)); $this->assertFalse(isset($modinfo->somefield)); $cm->somefield; $this->assertDebuggingCalled(); $cm->somefield = 'Some value'; $this->assertDebuggingCalled(); $this->assertEmpty($cm->somefield); $this->assertDebuggingCalled(); // Attempt to overwrite an existing field. $prevvalue = $cm->name; $this->assertNotEmpty($cm->name); $this->assertFalse(empty($cm->name)); $this->assertTrue(isset($cm->name)); $cm->name = 'Illegal overwriting'; $this->assertDebuggingCalled(); $this->assertEquals($prevvalue, $cm->name); $this->assertDebuggingNotCalled(); // Restore settings. set_config('enableavailability', $oldcfgenableavailability); set_config('enablecompletion', $oldcfgenablecompletion); }
/** * Returns a number of useful structures for course displays * * Function get_all_mods() is deprecated in 2.4 * Instead of: * <code> * get_all_mods($courseid, $mods, $modnames, $modnamesplural, $modnamesused); * </code> * please use: * <code> * $mods = get_fast_modinfo($courseorid)->get_cms(); * $modnames = get_module_types_names(); * $modnamesplural = get_module_types_names(true); * $modnamesused = get_fast_modinfo($courseorid)->get_used_module_names(); * </code> * * @deprecated since 2.4 * * @param int $courseid id of the course to get info about * @param array $mods (return) list of course modules * @param array $modnames (return) list of names of all module types installed and available * @param array $modnamesplural (return) list of names of all module types installed and available in the plural form * @param array $modnamesused (return) list of names of all module types used in the course */ function get_all_mods($courseid, &$mods, &$modnames, &$modnamesplural, &$modnamesused) { debugging('Function get_all_mods() is deprecated. Use get_fast_modinfo() and get_module_types_names() instead. See phpdocs for details', DEBUG_DEVELOPER); global $COURSE; $modnames = get_module_types_names(); $modnamesplural = get_module_types_names(true); $modinfo = get_fast_modinfo($courseid); $mods = $modinfo->get_cms(); $modnamesused = $modinfo->get_used_module_names(); }
/** * Renders HTML for the menus to add activities and resources to the current course * * Note, if theme overwrites this function and it does not use modchooser, * see also {@link core_course_renderer::add_modchoosertoggle()} * * @param stdClass $course * @param int $section relative section number (field course_sections.section) * @param int $sectionreturn The section to link back to * @param array $displayoptions additional display options, for example blocks add * option 'inblock' => true, suggesting to display controls vertically * @return string */ function course_section_add_cm_control($course, $section, $sectionreturn = null, $displayoptions = array()) { global $CFG; $vertical = !empty($displayoptions['inblock']); // check to see if user can add menus and there are modules to add if (!has_capability('moodle/course:manageactivities', context_course::instance($course->id)) || !$this->page->user_is_editing() || !($modnames = get_module_types_names()) || empty($modnames)) { return ''; } // Retrieve all modules with associated metadata $modules = get_module_metadata($course, $modnames, $sectionreturn); $urlparams = array('section' => $section); // We'll sort resources and activities into two lists $activities = array(MOD_CLASS_ACTIVITY => array(), MOD_CLASS_RESOURCE => array()); foreach ($modules as $module) { if (isset($module->types)) { // This module has a subtype // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!! $subtypes = array(); foreach ($module->types as $subtype) { $link = $subtype->link->out(true, $urlparams); $subtypes[$link] = $subtype->title; } // Sort module subtypes into the list $activityclass = MOD_CLASS_ACTIVITY; if ($module->archetype == MOD_CLASS_RESOURCE) { $activityclass = MOD_CLASS_RESOURCE; } if (!empty($module->title)) { // This grouping has a name $activities[$activityclass][] = array($module->title => $subtypes); } else { // This grouping does not have a name $activities[$activityclass] = array_merge($activities[$activityclass], $subtypes); } } else { // This module has no subtypes $activityclass = MOD_CLASS_ACTIVITY; if ($module->archetype == MOD_ARCHETYPE_RESOURCE) { $activityclass = MOD_CLASS_RESOURCE; } else { if ($module->archetype === MOD_ARCHETYPE_SYSTEM) { // System modules cannot be added by user, do not add to dropdown continue; } } $link = $module->link->out(true, $urlparams); $activities[$activityclass][$link] = $module->title; } } $straddactivity = get_string('addactivity'); $straddresource = get_string('addresource'); $sectionname = get_section_name($course, $section); $strresourcelabel = get_string('addresourcetosection', null, $sectionname); $stractivitylabel = get_string('addactivitytosection', null, $sectionname); $output = html_writer::start_tag('div', array('class' => 'section_add_menus', 'id' => 'add_menus-section-' . $section)); if (!$vertical) { $output .= html_writer::start_tag('div', array('class' => 'horizontal')); } if (!empty($activities[MOD_CLASS_RESOURCE])) { $select = new url_select($activities[MOD_CLASS_RESOURCE], '', array('' => $straddresource), "ressection{$section}"); $select->set_help_icon('resources'); $select->set_label($strresourcelabel, array('class' => 'accesshide')); $output .= $this->output->render($select); } if (!empty($activities[MOD_CLASS_ACTIVITY])) { $select = new url_select($activities[MOD_CLASS_ACTIVITY], '', array('' => $straddactivity), "section{$section}"); $select->set_help_icon('activities'); $select->set_label($stractivitylabel, array('class' => 'accesshide')); $output .= $this->output->render($select); } if (!$vertical) { $output .= html_writer::end_tag('div'); } $output .= html_writer::end_tag('div'); if (course_ajax_enabled($course) && $course->id == $this->page->course->id) { // modchooser can be added only for the current course set on the page! $straddeither = get_string('addresourceoractivity'); // The module chooser link $modchooser = html_writer::start_tag('div', array('class' => 'mdl-right')); $modchooser .= html_writer::start_tag('div', array('class' => 'section-modchooser')); $icon = $this->output->pix_icon('t/add', ''); $span = html_writer::tag('span', $straddeither, array('class' => 'section-modchooser-text')); $modchooser .= html_writer::tag('span', $icon . $span, array('class' => 'section-modchooser-link')); $modchooser .= html_writer::end_tag('div'); $modchooser .= html_writer::end_tag('div'); // Wrap the normal output in a noscript div $usemodchooser = get_user_preferences('usemodchooser', $CFG->modchooserdefault); if ($usemodchooser) { $output = html_writer::tag('div', $output, array('class' => 'hiddenifjs addresourcedropdown')); $modchooser = html_writer::tag('div', $modchooser, array('class' => 'visibleifjs addresourcemodchooser')); } else { // If the module chooser is disabled, we need to ensure that the dropdowns are shown even if javascript is disabled $output = html_writer::tag('div', $output, array('class' => 'show addresourcedropdown')); $modchooser = html_writer::tag('div', $modchooser, array('class' => 'hide addresourcemodchooser')); } $output = $this->course_modchooser($modules, $course) . $modchooser . $output; } return $output; }
/** * Returns a localised human-readable name of the module type * * @param bool $plural return plural form * @return string */ public function get_module_type_name($plural = false) { $modnames = get_module_types_names($plural); if (isset($modnames[$this->modname])) { return $modnames[$this->modname]; } else { return null; } }
/** * Returns list of recent changes in course structure * * It includes adding, editing or deleting of the resources or activities * Excludes changes on modules without a view link (i.e. labels), and also * if activity was both added and deleted * * @return array array of changes. Each element is an array containing attributes: * 'action' - one of: 'add mod', 'update mod', 'delete mod' * 'module' - instance of cm_info (for 'delete mod' it is an object with attributes modname and modfullname) */ protected function get_structural_changes() { global $DB; $course = $this->page->course; $context = context_course::instance($course->id); $canviewdeleted = has_capability('block/recent_activity:viewdeletemodule', $context); $canviewupdated = has_capability('block/recent_activity:viewaddupdatemodule', $context); if (!$canviewdeleted && !$canviewupdated) { return; } $timestart = $this->get_timestart(); $changelist = array(); // The following query will retrieve the latest action for each course module in the specified course. // Also the query filters out the modules that were created and then deleted during the given interval. $sql = "SELECT\n cmid, MIN(action) AS minaction, MAX(action) AS maxaction, MAX(modname) AS modname\n FROM {block_recent_activity}\n WHERE timecreated > ? AND courseid = ?\n GROUP BY cmid\n ORDER BY MAX(timecreated) ASC"; $params = array($timestart, $course->id); $logs = $DB->get_records_sql($sql, $params); if (isset($logs[0])) { // If special record for this course and cmid=0 is present, migrate logs. self::migrate_logs($course); $logs = $DB->get_records_sql($sql, $params); } if ($logs) { $modinfo = get_fast_modinfo($course); foreach ($logs as $log) { // We used aggregate functions since constants CM_CREATED, CM_UPDATED and CM_DELETED have ascending order (0,1,2). $wasdeleted = $log->maxaction == block_recent_activity_observer::CM_DELETED; $wascreated = $log->minaction == block_recent_activity_observer::CM_CREATED; if ($wasdeleted && $wascreated) { // Activity was created and deleted within this interval. Do not show it. continue; } else { if ($wasdeleted && $canviewdeleted) { if (plugin_supports('mod', $log->modname, FEATURE_NO_VIEW_LINK, false)) { // Better to call cm_info::has_view() because it can be dynamic. // But there is no instance of cm_info now. continue; } // Unfortunately we do not know if the mod was visible. $modnames = get_module_types_names(); $changelist[$log->cmid] = array('action' => 'delete mod', 'module' => (object) array('modname' => $log->modname, 'modfullname' => isset($modnames[$log->modname]) ? $modnames[$log->modname] : $log->modname)); } else { if (!$wasdeleted && isset($modinfo->cms[$log->cmid]) && $canviewupdated) { // Module was either added or updated during this interval and it currently exists. // If module was both added and updated show only "add" action. $cm = $modinfo->cms[$log->cmid]; if ($cm->has_view() && $cm->uservisible) { $changelist[$log->cmid] = array('action' => $wascreated ? 'add mod' : 'update mod', 'module' => $cm); } } } } } } return $changelist; }
/** * Renders HTML for the menus to add activities and resources to the current course * * Note, if theme overwrites this function and it does not use modchooser, * see also {@link core_course_renderer::add_modchoosertoggle()} * * @param stdClass $course * @param int $section relative section number (field course_sections.section) * @param int $sectionreturn The section to link back to * @param array $displayoptions additional display options, for example blocks add * option 'inblock' => true, suggesting to display controls vertically * @return string */ public function course_section_add_cm_control($course, $section, $sectionreturn = null, $displayoptions = array()) { // Check to see if user can add menus and there are modules to add. if (!has_capability('moodle/course:manageactivities', context_course::instance($course->id)) || !($modnames = get_module_types_names()) || empty($modnames)) { return ''; } // Retrieve all modules with associated metadata. $modules = get_module_metadata($course, $modnames, $sectionreturn); $urlparams = array('section' => $section); // S Lamour Aug 2015 - show activity picker // moodle is adding a link around the span in a span with js - yay!! go moodle... $modchooser = "<div class='snap-modchooser btn btn-default section_add_menus'>\n <span class='section-modchooser-link'><span>" . get_string('addresourceoractivity', 'theme_snap') . "</span></span>\n </div>"; $output = $this->courserenderer->course_modchooser($modules, $course) . $modchooser; // Add zone for quick uploading of files. $upload = '<form class="snap-dropzone"> <label for="snap-drop-file-' . $section . '" class="snap-dropzone-label h6">' . get_string('dropzonelabel', 'theme_snap') . '</label> <input type="file" multiple name="snap-drop-file-' . $section . '" id="snap-drop-file-' . $section . '" class="js-snap-drop-file sr-only"/> </form>'; return $output . $upload; }
// values. echo html_writer::start_tag('form', array('action' => '.', 'method' => 'get')); echo html_writer::start_tag('div'); echo html_writer::empty_tag('input', array('type' => 'hidden', 'id' => 'completion_dynamic_change', 'name' => 'completion_dynamic_change', 'value' => '0')); echo html_writer::end_tag('div'); echo html_writer::end_tag('form'); } // Course wrapper start. echo html_writer::start_tag('div', array('class' => 'course-content')); // make sure that section 0 exists (this function will create one if it is missing) course_create_sections_if_missing($course, 0); // get information about course modules and existing module types // format.php in course formats may rely on presence of these variables $modinfo = get_fast_modinfo($course); $modnames = get_module_types_names(); $modnamesplural = get_module_types_names(true); $modnamesused = $modinfo->get_used_module_names(); $mods = $modinfo->get_cms(); $sections = $modinfo->get_section_info_all(); // CAUTION, hacky fundamental variable defintion to follow! // Note that because of the way course fromats are constructed though // inclusion we pass parameters around this way.. $displaysection = $section; // Include the actual course format. require $CFG->dirroot . '/course/format/' . $course->format . '/format.php'; /** * Show button Ler Mais * @author André Rodrigues <Math> * @date 2015/12/27 */ ?>
public function test_cm_info_properties() { global $DB, $CFG; $this->resetAfterTest(); $oldcfgenableavailability = $CFG->enableavailability; $oldcfgenablecompletion = $CFG->enablecompletion; set_config('enableavailability', 1); set_config('enablecompletion', 1); $this->setAdminUser(); // Generate the course and pre-requisite module. $course = $this->getDataGenerator()->create_course(array('format' => 'topics', 'numsections' => 3, 'enablecompletion' => 1, 'groupmode' => SEPARATEGROUPS, 'forcegroupmode' => 0), array('createsections' => true)); $coursecontext = context_course::instance($course->id); $prereqforum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), array('completion' => 1)); // Generate the module and add availability conditions. $conditionscompletion = array($prereqforum->cmid => COMPLETION_COMPLETE); $conditionsgrade = array(666 => (object) array('min' => 0.4, 'max' => null, 'name' => '!missing')); $conditionsfield = array('email' => (object) array('fieldname' => 'email', 'operator' => 'contains', 'value' => 'test')); $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id), array('idnumber' => 123, 'groupmode' => VISIBLEGROUPS, 'availablefrom' => time() + 3600, 'availableuntil' => time() + 5 * 3600)); $ci = new condition_info((object) array('id' => $assign->cmid), CONDITION_MISSING_EVERYTHING); foreach ($conditionscompletion as $cmid => $requiredcompletion) { $ci->add_completion_condition($cmid, $requiredcompletion); } foreach ($conditionsgrade as $gradeid => $conditiongrade) { $ci->add_grade_condition($gradeid, $conditiongrade->min, $conditiongrade->max, true); } foreach ($conditionsfield as $conditionfield) { $ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value); } // Direct access to condition_info functions does not reset course cache, do it manually. rebuild_course_cache($course->id, true); // Retrieve all related records from DB. $assigndb = $DB->get_record('assign', array('id' => $assign->id)); $moduletypedb = $DB->get_record('modules', array('name' => 'assign')); $moduledb = $DB->get_record('course_modules', array('module' => $moduletypedb->id, 'instance' => $assign->id)); $sectiondb = $DB->get_record('course_sections', array('id' => $moduledb->section)); $modnamessingular = get_module_types_names(false); $modnamesplural = get_module_types_names(true); // Create and enrol a student. $studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST); $student = $this->getDataGenerator()->create_user(); role_assign($studentrole->id, $student->id, $coursecontext); $enrolplugin = enrol_get_plugin('manual'); $enrolinstance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'manual')); $enrolplugin->enrol_user($enrolinstance, $student->id); $this->setUser($student); // Emulate data used in building course cache to receive the same instance of cached_cm_info as was used in building modinfo. $rawmods = get_course_mods($course->id); $cachedcminfo = assign_get_coursemodule_info($rawmods[$moduledb->id]); // Get modinfo. $modinfo = get_fast_modinfo($course->id); $cm = $modinfo->instances['assign'][$assign->id]; $this->assertEquals($moduledb->id, $cm->id); $this->assertEquals($assigndb->id, $cm->instance); $this->assertEquals($moduledb->course, $cm->course); $this->assertEquals($moduledb->idnumber, $cm->idnumber); $this->assertEquals($moduledb->added, $cm->added); $this->assertEquals($moduledb->visible, $cm->visible); $this->assertEquals($moduledb->visibleold, $cm->visibleold); $this->assertEquals($moduledb->groupmode, $cm->groupmode); $this->assertEquals(VISIBLEGROUPS, $cm->groupmode); $this->assertEquals($moduledb->groupingid, $cm->groupingid); $this->assertEquals($moduledb->groupmembersonly, $cm->groupmembersonly); $this->assertEquals($course->groupmodeforce, $cm->coursegroupmodeforce); $this->assertEquals($course->groupmode, $cm->coursegroupmode); $this->assertEquals(SEPARATEGROUPS, $cm->coursegroupmode); $this->assertEquals($course->groupmodeforce ? $course->groupmode : $moduledb->groupmode, $cm->effectivegroupmode); // (since mod_assign supports groups). $this->assertEquals(VISIBLEGROUPS, $cm->effectivegroupmode); $this->assertEquals($moduledb->indent, $cm->indent); $this->assertEquals($moduledb->completion, $cm->completion); $this->assertEquals($moduledb->completiongradeitemnumber, $cm->completiongradeitemnumber); $this->assertEquals($moduledb->completionview, $cm->completionview); $this->assertEquals($moduledb->completionexpected, $cm->completionexpected); $this->assertEquals($moduledb->availablefrom, $cm->availablefrom); $this->assertEquals($moduledb->availableuntil, $cm->availableuntil); $this->assertEquals($moduledb->showavailability, $cm->showavailability); $this->assertEquals($moduledb->showdescription, $cm->showdescription); $this->assertEquals(null, $cm->extra); // Deprecated field. Used in module types that don't return cached_cm_info. $this->assertEquals($cachedcminfo->icon, $cm->icon); $this->assertEquals($cachedcminfo->iconcomponent, $cm->iconcomponent); $this->assertEquals('assign', $cm->modname); $this->assertEquals($moduledb->module, $cm->module); $this->assertEquals($cachedcminfo->name, $cm->name); $this->assertEquals($sectiondb->section, $cm->sectionnum); $this->assertEquals($moduledb->section, $cm->section); $this->assertEquals($conditionscompletion, $cm->conditionscompletion); $this->assertEquals($conditionsgrade, $cm->conditionsgrade); $this->assertEquals($conditionsfield, $cm->conditionsfield); $this->assertEquals(context_module::instance($moduledb->id), $cm->context); $this->assertEquals($modnamessingular['assign'], $cm->modfullname); $this->assertEquals($modnamesplural['assign'], $cm->modplural); $this->assertEquals(new moodle_url('/mod/assign/view.php', array('id' => $moduledb->id)), $cm->url); $this->assertEquals($cachedcminfo->customdata, $cm->customdata); // Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type). $this->assertNotEmpty($cm->availableinfo); // Lists all unmet availability conditions. $this->assertEquals(0, $cm->uservisible); $this->assertEquals('', $cm->extraclasses); $this->assertEquals('', $cm->onclick); $this->assertEquals(null, $cm->afterlink); $this->assertEquals(null, $cm->afterediticons); $this->assertEquals('', $cm->content); // Attempt to access and set non-existing field. $this->assertTrue(empty($modinfo->somefield)); $this->assertFalse(isset($modinfo->somefield)); $cm->somefield; $this->assertDebuggingCalled(); $cm->somefield = 'Some value'; $this->assertDebuggingCalled(); $this->assertEmpty($cm->somefield); $this->assertDebuggingCalled(); // Attempt to overwrite an existing field. $prevvalue = $cm->name; $this->assertNotEmpty($cm->name); $this->assertFalse(empty($cm->name)); $this->assertTrue(isset($cm->name)); $cm->name = 'Illegal overwriting'; $this->assertDebuggingCalled(); $this->assertEquals($prevvalue, $cm->name); $this->assertDebuggingNotCalled(); // Restore settings. set_config('enableavailability', $oldcfgenableavailability); set_config('enablecompletion', $oldcfgenablecompletion); }
protected function definition() { global $PAGE; $mform =& $this->_form; $courseid = $this->_customdata['courseid']; $postid = $this->_customdata['postid']; $modinfo = get_fast_modinfo($courseid); $cms = $modinfo->get_cms(); $attachedrecentactivities = array(); // Add activities area. $modulenames = get_module_types_names(); $existingnames = array(); foreach ($cms as $mod) { $existingnames[$mod->modname] = $modulenames[$mod->modname]; } core_collator::asort($existingnames); $typeelements = array(); foreach ($existingnames as $type => $modname) { $typeelements[$type] = $mform->createElement('checkbox', 'type_' . $type, '', $modname, array('id' => 'type_' . $type)); $mform->setDefault('filterbytype[type_' . $type . ']', 1); } if (!empty($typeelements)) { // Module type filter. $mform->addElement('header', 'filtersheader', get_string('filtersheader', 'format_socialwall')); $mform->addGroup($typeelements, 'filterbytype'); $params = array('size' => '30', 'placeholder' => get_string('searchbyname', 'format_socialwall')); $mform->addElement('text', 'searchbyname', '', $params); $mform->setType('searchbyname', PARAM_TEXT); // Recent activities area. $mform->addElement('header', 'recentactivitiesheader', get_string('recentactivities', 'format_socialwall')); $mform->setExpanded('recentactivitiesheader'); $courserenderer = $PAGE->get_renderer('course'); $modids = array(); $cache = cache::make('format_socialwall', 'attachedrecentactivities'); if ($attachedrecentactivities = $cache->get($courseid . '_' . $postid)) { $modids = array_flip($attachedrecentactivities); } // Order cms by name. if (!empty($cms)) { uasort($cms, array($this, 'compare_modules')); } foreach ($cms as $mod) { $name = $courserenderer->course_section_cm_name($mod); $type = $mod->modname; // In case of empty name, try to get content. if (empty($name)) { $contentpart = $courserenderer->course_section_cm_text($mod); $url = $mod->url; if (empty($url)) { $name = shorten_text($contentpart, 70); } } $mform->addElement('checkbox', 'module_' . $type . '_' . $mod->id, '', $name, array('id' => 'module_' . $mod->id)); if (isset($modids[$mod->id])) { $mform->setDefault('module_' . $type . '_' . $mod->id, 1); } } } else { $mform->addElement('html', get_string('norecentactivities', 'format_socialwall')); } $args = array('courseid' => $courseid, 'attachedrecentactivities' => $attachedrecentactivities); $PAGE->requires->strings_for_js(array('addrecentactivity', 'attach', 'cancel'), 'format_socialwall'); $PAGE->requires->yui_module('moodle-format_socialwall-addactivity', 'M.format_socialwall.addactivityinit', array($args), null, true); }
/** * Specifies which values for the log 'module' field count as resources * when tracking resource views * * @return array The list of appropriate field values */ function get_resource_modules() { global $CFG, $SITE; // course API require_once $CFG->dirroot . '/course/lib.php'; // retrieve information about all modules on the site $modnames = get_module_types_names(); // make sure to always count 'resource' for legacy reasons $result = array('resource'); foreach ($modnames as $modname => $modnamestr) { // make sure the module is valid $libfile = "{$CFG->dirroot}/mod/{$modname}/lib.php"; if (!file_exists($libfile)) { continue; } //check to see if the module is considered a resource in a "legacy" way include_once $libfile; $gettypesfunc = $modname . '_get_types'; if (function_exists($gettypesfunc)) { //look through supported "types" for resource if (($types = $gettypesfunc()) && $types !== MOD_SUBTYPE_NO_CHILDREN) { foreach ($types as $type) { if ($type->modclass == MOD_CLASS_RESOURCE) { $result[] = $modname; break; } } } } else { //determine if the the module supports resource functionality $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); if ($archetype == MOD_ARCHETYPE_RESOURCE) { $result[] = $modname; } } } return $result; }
if (!empty($param->user)) { if (!($u = $DB->get_record('user', array('id' => $param->user)))) { print_error("That's an invalid user!"); } $userinfo = fullname($u); } $strrecentactivity = get_string('recentactivity'); $PAGE->navbar->add($strrecentactivity, new moodle_url('/course/recent.php', array('id' => $course->id))); $PAGE->navbar->add($userinfo); $PAGE->set_title("{$course->shortname}: {$strrecentactivity}"); $PAGE->set_heading($course->fullname); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($course->fullname) . ": {$userinfo}", 2); $mform->display(); $modinfo = get_fast_modinfo($course); $modnames = get_module_types_names(); if (has_capability('moodle/course:viewhiddensections', $context)) { $hiddenfilter = ""; } else { $hiddenfilter = "AND cs.visible = 1"; } $sections = array(); foreach ($modinfo->get_section_info_all() as $i => $section) { if (!empty($section->uservisible)) { $sections[$i] = $section; } } if ($param->modid === 'all') { // ok } else { if (strpos($param->modid, 'mod/') === 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 mod_subpage $subpage Current subpage * @param array $allsubpages Array of other subpage objects * @param array $coursesections Array of course sections * @param course_modinfo $modinfo Modinfo object * @param string $move Whether to move 'to' or 'from' the current subpage * @return array An array of items organised by section */ public static function moveable_modules(mod_subpage $subpage, array $allsubpages, $coursesections, course_modinfo $modinfo, $move) { $modinfo = get_fast_modinfo($subpage->get_course()->id); $allmods = $modinfo->get_cms(); $modnames = get_module_types_names(); $modnamesplural = get_module_types_names(true); $mods = array(); if ($move === 'to') { $parentcmids = array(); // Get the subpage cm that owns each section. $subpagesectioncm = array(); foreach ($modinfo->get_instances_of('subpage') as $subpageid => $cm) { // Get sectionsids array stored in the customdata. $cmdata = $cm->customdata; if ($cmdata) { foreach ($cmdata->sectionids as $sectionid) { $subpagesectioncm[$sectionid] = $cm; } } } // Loop through ancestor subpages. $cm = $modinfo->get_cm($subpage->get_course_module()->id); while (true) { if (array_key_exists($cm->section, $subpagesectioncm)) { $cm = $subpagesectioncm[$cm->section]; // In case of a subpage within itself, prevent endless loop. if (array_key_exists($cm->id, $parentcmids)) { break; } $parentcmids[$cm->id] = true; } else { break; } } } $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; } if ($move === 'to') { // Prevent moving a parent subpage to its child. if (!empty($parentcmids[$modnumber])) { 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; }
/** * Prints the menus to add activities and resources. * * @param stdClass $course The course * @param int $section relative section number (field course_sections.section) * @param null|array $modnames An array containing the list of modules and their names * if omitted will be taken from get_module_types_names() * @param bool $vertical Vertical orientation * @param bool $return Return the menus or send them to output * @param int $sectionreturn The section to link back to * @return void|string depending on $return */ function print_section_add_menus($course, $section, $modnames = null, $vertical = false, $return = false, $sectionreturn = null) { global $CFG, $OUTPUT; if ($modnames === null) { $modnames = get_module_types_names(); } // check to see if user can add menus and there are modules to add if (!has_capability('moodle/course:manageactivities', context_course::instance($course->id)) || empty($modnames)) { if ($return) { return ''; } else { return false; } } // Retrieve all modules with associated metadata $modules = get_module_metadata($course, $modnames, $sectionreturn); // We'll sort resources and activities into two lists $resources = array(); $activities = array(); // We need to add the section section to the link for each module $sectionlink = '§ion=' . $section . '&sr=' . $sectionreturn; foreach ($modules as $module) { if (isset($module->types)) { // This module has a subtype // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!! $subtypes = array(); foreach ($module->types as $subtype) { $subtypes[$subtype->link . $sectionlink] = $subtype->title; } // Sort module subtypes into the list if (!empty($module->title)) { // This grouping has a name if ($module->archetype == MOD_CLASS_RESOURCE) { $resources[] = array($module->title => $subtypes); } else { $activities[] = array($module->title => $subtypes); } } else { // This grouping does not have a name if ($module->archetype == MOD_CLASS_RESOURCE) { $resources = array_merge($resources, $subtypes); } else { $activities = array_merge($activities, $subtypes); } } } else { // This module has no subtypes if ($module->archetype == MOD_ARCHETYPE_RESOURCE) { $resources[$module->link . $sectionlink] = $module->title; } else { if ($module->archetype === MOD_ARCHETYPE_SYSTEM) { // System modules cannot be added by user, do not add to dropdown } else { $activities[$module->link . $sectionlink] = $module->title; } } } } $straddactivity = get_string('addactivity'); $straddresource = get_string('addresource'); $sectionname = get_section_name($course, $section); $strresourcelabel = get_string('addresourcetosection', null, $sectionname); $stractivitylabel = get_string('addactivitytosection', null, $sectionname); $output = html_writer::start_tag('div', array('class' => 'section_add_menus', 'id' => 'add_menus-section-' . $section)); if (!$vertical) { $output .= html_writer::start_tag('div', array('class' => 'horizontal')); } if (!empty($resources)) { $select = new url_select($resources, '', array('' => $straddresource), "ressection{$section}"); $select->set_help_icon('resources'); $select->set_label($strresourcelabel, array('class' => 'accesshide')); $output .= $OUTPUT->render($select); } if (!empty($activities)) { $select = new url_select($activities, '', array('' => $straddactivity), "section{$section}"); $select->set_help_icon('activities'); $select->set_label($stractivitylabel, array('class' => 'accesshide')); $output .= $OUTPUT->render($select); } if (!$vertical) { $output .= html_writer::end_tag('div'); } $output .= html_writer::end_tag('div'); if (course_ajax_enabled($course)) { $straddeither = get_string('addresourceoractivity'); // The module chooser link $modchooser = html_writer::start_tag('div', array('class' => 'mdl-right')); $modchooser .= html_writer::start_tag('div', array('class' => 'section-modchooser')); $icon = $OUTPUT->pix_icon('t/add', ''); $span = html_writer::tag('span', $straddeither, array('class' => 'section-modchooser-text')); $modchooser .= html_writer::tag('span', $icon . $span, array('class' => 'section-modchooser-link')); $modchooser .= html_writer::end_tag('div'); $modchooser .= html_writer::end_tag('div'); // Wrap the normal output in a noscript div $usemodchooser = get_user_preferences('usemodchooser', $CFG->modchooserdefault); if ($usemodchooser) { $output = html_writer::tag('div', $output, array('class' => 'hiddenifjs addresourcedropdown')); $modchooser = html_writer::tag('div', $modchooser, array('class' => 'visibleifjs addresourcemodchooser')); } else { // If the module chooser is disabled, we need to ensure that the dropdowns are shown even if javascript is disabled $output = html_writer::tag('div', $output, array('class' => 'show addresourcedropdown')); $modchooser = html_writer::tag('div', $modchooser, array('class' => 'hide addresourcemodchooser')); } $output = $modchooser . $output; } if ($return) { return $output; } else { echo $output; } }
/** * * @param grade_item $item * @return type */ function blended_get_item_name($item) { $mod_names = get_module_types_names(); if ($item->itemtype == 'course') { $itemtypename = get_string('course'); } else { if ($item->itemtype == 'mod') { $itemtypename = $mod_names[$item->itemmodule]; } else { $itemtypename = $item->itemtype; } } return $itemtypename . ': ' . $item->itemname; }
/** * Generate the list of modules for the given course. * * @param stdClass $course The course to get modules for */ protected function get_course_modules($course) { global $CFG; // This function is included when we include course/lib.php at the top // of this file $modnames = get_module_types_names(); $resources = array(); $activities = array(); foreach ($modnames as $modname => $modnamestr) { if (!course_allowed_module($course, $modname)) { continue; } $libfile = "{$CFG->dirroot}/mod/{$modname}/lib.php"; if (!file_exists($libfile)) { continue; } include_once $libfile; $gettypesfunc = $modname . '_get_types'; if (function_exists($gettypesfunc)) { $types = $gettypesfunc(); foreach ($types as $type) { if (!isset($type->modclass) || !isset($type->typestr)) { debugging('Incorrect activity type in ' . $modname); continue; } if ($type->modclass == MOD_CLASS_RESOURCE) { $resources[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr; } else { $activities[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr; } } } else { $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); if ($archetype == MOD_ARCHETYPE_RESOURCE) { $resources[$modname] = $modnamestr; } else { // all other archetypes are considered activity $activities[$modname] = $modnamestr; } } } return array($resources, $activities); }
/** * Get the activities supported by the format. * * Here we ignore the modules that do not have a page of their own, like the label. * * @return array array($module => $name of the module). */ public static function get_supported_activities() { $availabletypes = get_module_types_names(); foreach ($availabletypes as $module => $name) { if (plugin_supports('mod', $module, FEATURE_NO_VIEW_LINK, false)) { unset($availabletypes[$module]); } } return $availabletypes; }
function get_course_mods($id, $username = '') { global $CFG, $DB; $username = utf8_decode($username); $username = strtolower($username); if ($username) { $user = get_complete_user_data('username', $username); } $modinfo = get_fast_modinfo($id); $sections = $modinfo->get_section_info_all(); $forum = forum_get_course_forum($id, 'news'); $news_forum_id = $forum->id; $mods = get_fast_modinfo($id)->get_cms(); $modnames = get_module_types_names(); $modnamesplural = get_module_types_names(true); $modnamesused = get_fast_modinfo($id)->get_used_module_names(); $rawmods = get_course_mods($id); $context = context_course::instance($id); // Kludge to use username param to get non visible sections and modules $username_orig = $username; if ($username_orig == 'joomdle_get_not_visible') { $username = ''; } $e = array(); foreach ($sections as $section) { if ($username_orig != 'joomdle_get_not_visible') { if (!$section->visible) { continue; } } $sectionmods = explode(",", $section->sequence); foreach ($sectionmods as $modnumber) { if (empty($mods[$modnumber])) { continue; } $mod = $mods[$modnumber]; if ($username_orig != 'joomdle_get_not_visible') { if (!$mod->visible) { continue; } } $resource['completion_info'] = ''; if ($username) { $cm = get_coursemodule_from_id(false, $mod->id); if (!\core_availability\info_module::is_user_visible($cm, $user->id)) { if (empty($mod->availableinfo)) { // Mod not visible, and no completion info to show continue; } $resource['available'] = 0; $ci = new condition_info($mod); $resource['completion_info'] = $ci->get_full_information(); } else { $resource['available'] = 1; } } else { $resource['available'] = 1; } $e[$section->section]['section'] = $section->section; $e[$section->section]['name'] = $section->name; $e[$section->section]['summary'] = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $context->id, 'course', 'section', $section->id); $e[$section->section]['summary'] = str_replace('pluginfile.php', '/auth/joomdle/pluginfile_joomdle.php', $e[$section->section]['summary']); $resource['id'] = $mod->id; $resource['name'] = $mod->name; $resource['mod'] = $mod->modname; // Get content $resource['content'] = ''; $modname = $mod->modname; $functionname = $modname . "_get_coursemodule_info"; if (file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) { include_once "{$CFG->dirroot}/mod/{$modname}/lib.php"; if ($hasfunction = function_exists($functionname)) { if ($info = $functionname($rawmods[$modnumber])) { $resource['content'] = $info->content; } } } // Format for mod->icon is: f/type-24 $type = substr($mod->icon, 2); $parts = explode('-', $type); $type = $parts[0]; $resource['type'] = $type; //In forum, type is unused, so we use it for forum type: news/general if ($mod->modname == 'forum') { $cm = get_coursemodule_from_id('forum', $mod->id); if ($cm->instance == $news_forum_id) { $resource['type'] = 'news'; } } /* if ($mod->modname == 'resource') { // Get display options for resource $params = array ($mod->instance); $query = "SELECT display from {$CFG->prefix}resource where id = ?"; $record = $DB->get_record_sql ($query, $params); $resource['display'] = $record->display; } else $resource['display'] = 0; */ $resource['display'] = $this->get_display($mod->modname, $mod->instance); $e[$section->section]['mods'][] = $resource; } } return $e; }
/** * Parent class version of this function simply returns NULL This should be implemented by the derived class to return the content object. * * @return object The content object */ public function get_content() { global $USER, $CFG, $DB, $OUTPUT; if ($this->content !== null) { return $this->content; } $this->content = new stdClass(); $this->content->items = array(); $this->content->icons = array(); $this->content->footer = ''; if (empty($this->instance)) { if (!isset($this->content)) { $this->content = new stdClass(); } return $this->content; } if (!isset($this->config->title)) { if (!isset($this->config)) { $this->config = new stdClass(); } $this->config->title = ''; } $course = $this->page->course; require_once $CFG->dirroot . '/course/lib.php'; $context = context_course::instance($course->id); $isediting = $this->page->user_is_editing() && has_capability('moodle/course:manageactivities', $context); // Create a new section for this block (if necessary). if (empty($this->config->section)) { require_once $CFG->dirroot . '/blocks/side_bar/locallib.php'; if (null == ($section = block_side_bar_create_section($course))) { return $this->content; } $this->config->section = $section->section; $this->config->section_id = $section->id; parent::instance_config_commit(); } else { if (empty($this->config->section_id)) { $params = array('course' => $course->id, 'section' => $this->config->section); $section = $DB->get_record('course_sections', $params); $this->config->section_id = $section->id; parent::instance_config_commit(); } else { $section = $DB->get_record('course_sections', array('id' => $this->config->section_id)); if (empty($section)) { require_once $CFG->dirroot . '/blocks/side_bar/locallib.php'; if (null == ($section = block_side_bar_create_section($course))) { return $this->content; } $this->config->section = $section->section; $this->config->section_id = $section->id; parent::instance_config_commit(); } } // Double check that the section number hasn't been modified by something else. // Fixes problem found by Charlotte Owen when moving 'center column' course sections. if ($section->section != $this->config->section) { $section->section = $this->config->section; $DB->update_record('course_sections', $section); } } // extra fast view mode $modinfo = get_fast_modinfo($course); if (!$isediting) { if (!empty($modinfo->sections[$this->config->section])) { $options = array('overflowdiv' => true); foreach ($modinfo->sections[$this->config->section] as $cmid) { $cm = $modinfo->cms[$cmid]; if (!$cm->uservisible) { continue; } $content = $cm->get_formatted_content(array('overflowdiv' => true, 'noclean' => true)); $instancename = $cm->get_formatted_name(); if (!($url = $cm->url)) { $this->content->items[] = $content; $this->content->icons[] = ''; } else { $linkcss = $cm->visible ? '' : ' class="dimmed" '; // Accessibility: incidental image - should be empty Alt text $icon = '<img src="' . $cm->get_icon_url() . '" class="icon" alt="" /> '; $this->content->items[] = '<a title="' . $cm->modplural . '" ' . $linkcss . ' ' . $cm->extra . ' href="' . $url . '">' . $icon . $instancename . '</a>'; } } } return $this->content; } // slow & hacky editing mode $courserenderer = $this->page->get_renderer('core', 'course'); $ismoving = ismoving($course->id); if (!($cs = $DB->get_record('course_sections', array('section' => $this->config->section, 'course' => $course->id)))) { debugging('Could not get course section record for section ' . $this->config->section, DEBUG_DEVELOPER); return $this->content; } $modinfo = get_fast_modinfo($course); $section = $modinfo->get_section_info($this->config->section); $modnames = get_module_types_names(); $groupbuttons = $course->groupmode; $groupbuttonslink = !$course->groupmodeforce; if ($ismoving) { $strmovehere = get_string('movehere'); $strmovefull = strip_tags(get_string('movefull', '', "'{$USER->activitycopyname}'")); $strcancel = get_string('cancel'); $stractivityclipboard = $USER->activitycopyname; } else { $strmove = get_string('move'); } // Casting $course->modinfo to string prevents one notice when the field is null $editbuttons = ''; if ($ismoving) { $this->content->icons[] = '<img src="' . $OUTPUT->pix_url('t/move') . '" class="iconsmall" alt="" />'; $this->content->items[] = $USER->activitycopyname . ' (<a href="' . $CFG->wwwroot . '/course/mod.php?cancelcopy=true&sesskey=' . sesskey() . '">' . $strcancel . '</a>)'; } if (!empty($modinfo->sections[$this->config->section])) { $options = array('overflowdiv' => true); foreach ($modinfo->sections[$this->config->section] as $modnumber) { $mod = $modinfo->cms[$modnumber]; if (!$mod->uservisible) { continue; } if (!$ismoving) { $actions = course_get_cm_edit_actions($mod, -1); // Prepend list of actions with the 'move' action. $actions = array('move' => new action_menu_link_primary(new moodle_url('/course/mod.php', array('sesskey' => sesskey(), 'copy' => $mod->id)), new pix_icon('t/move', $strmove, 'moodle', array('class' => 'iconsmall', 'title' => '')), $strmove)) + $actions; $editactions = $courserenderer->course_section_cm_edit_actions($actions, $mod, array('donotenhance' => true)); $editbuttons = html_writer::tag('div', $editactions, array('class' => 'buttons')); } else { $editbuttons = ''; } if ($mod->visible || has_capability('moodle/course:viewhiddenactivities', $context)) { if ($ismoving) { if ($mod->id == $USER->activitycopy) { continue; } $this->content->items[] = '<a title="' . $strmovefull . '" href="' . $CFG->wwwroot . '/course/mod.php' . '?moveto=' . $mod->id . '&sesskey=' . sesskey() . '"><img style="height:16px; width:80px; border:0px"' . ' src="' . $OUTPUT->pix_url('movehere') . '" alt="' . $strmovehere . '" /></a>'; $this->content->icons[] = ''; } $content = $mod->get_formatted_content(array('overflowdiv' => true, 'noclean' => true)); $instancename = $mod->get_formatted_name(); $linkcss = $mod->visible ? '' : ' class="dimmed" '; if (!($url = $mod->url)) { $this->content->items[] = $content . $editbuttons; $this->content->icons[] = ''; } else { // Accessibility: incidental image - should be empty Alt text $icon = '<img src="' . $mod->get_icon_url() . '" class="icon" alt="" /> '; $this->content->items[] = '<a title="' . $mod->modfullname . '" ' . $linkcss . ' ' . $mod->extra . ' href="' . $url . '">' . $icon . $instancename . '</a>' . $editbuttons; } } } } if ($ismoving) { $this->content->items[] = '<a title="' . $strmovefull . '" href="' . $CFG->wwwroot . '/course/mod.php?' . 'movetosection=' . $section->id . '&sesskey=' . sesskey() . '"><img style="height' . ':16px; width:80px; border:0px" src="' . $OUTPUT->pix_url('movehere') . '" alt="' . $strmovehere . '" /></a>'; $this->content->icons[] = ''; } $this->content->footer = $courserenderer->course_section_add_cm_control($course, $this->config->section, null, array('inblock' => true)); // Replace modchooser with dropdown $this->content->footer = str_replace('hiddenifjs addresourcedropdown', 'visibleifjs addresourcedropdown', $this->content->footer); $this->content->footer = str_replace('visibleifjs addresourcemodchooser', 'hiddenifjs addresourcemodchooser', $this->content->footer); return $this->content; }
/** * 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 bool $canmovesection Whether the user is allowed to move sections * @param bool $canhidesection Whether the user is allowed to hide/stealth. * @return string html for display */ public function render_subpage(mod_subpage $subpage, course_modinfo $modinfo, array $sections, $editing, $moveitem, $canmovesection, $canhidesection) { global $PAGE, $OUTPUT, $CFG, $USER, $COURSE; $courserenderer = $PAGE->get_renderer('core_course'); $this->subpagecm = $subpage->get_course_module()->id; if (!empty($USER->activitycopy) && $canmovesection) { $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 = context_course::instance($subpage->get_course()->id); $modinfo = get_fast_modinfo($subpage->get_course()->id); $mods = $modinfo->get_cms(); $modnames = get_module_types_names(); $modnamesplural = get_module_types_names(true); 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(); $content .= html_writer::start_tag('ul', array('class' => 'topics')); $PAGE->requires->js('/course/format/topics/format.js'); 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(); } $cms = $modinfo->get_cms(); foreach ($instances as $instance) { if (!array_key_exists($instance, $cms)) { // This can happen if you have e.g. a feed present, but // feed has been disabled at site level. debugging('No module with cmid: ' . $instance, DEBUG_DEVELOPER); continue; } $cm = $cms[$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) { if ($canhidesection) { // 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 ($canmovesection) { $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) . '§ion=' . $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) . '§ion=' . $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'); $autohide = $section->autohide; $sectioninfo = $modinfo->get_section_info($section->section, MUST_EXIST); if (!$sectioninfo->uservisible && $sectioninfo->availableinfo) { $autohide = false; } $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 || !$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')); } if (!empty($section->groupingid) && has_capability('moodle/course:managegroups', $coursecontext)) { // Get all groupings (this is cached, so quicker than single one). $groupings = groups_get_all_groupings($modinfo->get_course_id()); $name = $groupings[$section->groupingid]->name; $content .= html_writer::div(s($name), 'groupinglabel'); } $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')); } // Display restricted info in this section. $sectioninfo = $modinfo->get_section_info($section->section, MUST_EXIST); $context = context_course::instance($COURSE->id); $content .= $this->section_availability_message($sectioninfo, has_capability('moodle/course:viewhiddensections', $context)); // Don't show contents of section when not visible to user. if ($sectioninfo->uservisible) { $content .= $this->render_section($subpage, $modinfo, $section, $editing, $moveitem, $mods); } if ($editing) { $content .= $courserenderer->course_section_add_cm_control($subpage->get_course(), $section->section); 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); } } 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'); } // 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); // Add backto field to completion toggle forms. $backto = new moodle_url('/mod/subpage/view.php', array('id' => $subpage->get_course_module()->id)); $content = preg_replace('~<form[^>]* class="[^"]*togglecompletion[^>]*>[^<]*<div>~', '$0<input type="hidden" name="backto" value="' . $backto->out(true) . '" />', $content); $content .= html_writer::end_tag('ul'); if ($editing) { $content .= html_writer::start_div('controlbuttons'); $content .= $this->render_add_button($subpage); $content .= $this->render_bulkmove_buttons($subpage); $content .= html_writer::end_div(); } return $content; }