/** * Renders HTML to display one course module in a course section * * This includes link, content, availability, completion info and additional information * that module type wants to display (i.e. number of unread forum posts) * * This function calls: * {@link core_course_renderer::course_section_cm_name()} * {@link cm_info::get_after_link()} * {@link core_course_renderer::course_section_cm_text()} * {@link core_course_renderer::course_section_cm_availability()} * {@link core_course_renderer::course_section_cm_completion()} * {@link course_get_cm_edit_actions()} * {@link core_course_renderer::course_section_cm_edit_actions()} * * @param \stdClass $course * @param \completion_info $completioninfo * @param \cm_info $mod * @param int|null $sectionreturn * @param array $displayoptions * @return string */ public function course_section_cm($course, &$completioninfo, cm_info $mod, $sectionreturn, $displayoptions = array()) { global $COURSE; $output = ''; // We return empty string (because course module will not be displayed at all) // if: // 1) The activity is not visible to users // and // 2) The 'availableinfo' is empty, i.e. the activity was // hidden in a way that leaves no info, such as using the // eye icon. if (!$mod->uservisible && empty($mod->availableinfo)) { return $output; } $output .= '<div class="asset-wrapper">'; // TODO - add if can edit. // Drop section notice. $output .= '<a class="snap-move-note" href="#">' . get_string('movehere', 'theme_snap') . '</a>'; // Start the div for the activity content. $output .= "<div class='activityinstance'>"; // Display the link to the module (or do nothing if module has no url). $cmname = $this->course_section_cm_name($mod, $displayoptions); $assetlink = ''; // SHAME - For moodles ajax show/hide call to work it needs activityinstance > a to add a class of dimmed to. // This dimmed class is of course inaccessible junk. if (!empty($cmname)) { $assetlink = '<a></a><h4 class="snap-asset-link">' . $cmname . '</h4>'; } // Asset content. $contentpart = $this->course_section_cm_text($mod, $displayoptions); // Activity/resource type. $snapmodtype = $this->get_mod_type($mod)[0]; $assetmeta = "<span class='snap-assettype'>" . $snapmodtype . "</span>"; // Groups, Restriction and all that jazz metadata. // Completion tracking. $completiontracking = $this->course_section_cm_completion($course, $completioninfo, $mod, $displayoptions); // Due date, feedback available and all the nice snap things. $snapcompletiondata = $this->module_meta_html($mod); $assetcompletionmeta = "<div class='snap-completion-meta'>" . $completiontracking . $snapcompletiondata . "</div>"; // Draft status - always output, shown via css of parent. $assetrestrictions = "<div class='draft-tag text text-warning'>" . get_string('draft', 'theme_snap') . "</div>"; $canmanagegroups = has_capability('moodle/course:managegroups', context_course::instance($mod->course)); if ($canmanagegroups && $mod->effectivegroupmode != NOGROUPS) { if ($mod->effectivegroupmode == VISIBLEGROUPS) { $groupinfo = get_string('groupsvisible'); } else { if ($mod->effectivegroupmode == SEPARATEGROUPS) { $groupinfo = get_string('groupsseparate'); } } $assetrestrictions .= "<div class='text'>{$groupinfo}</div>"; } // TODO - ask what this is... if (!empty($mod->groupingid) && $canmanagegroups) { // Grouping label. $groupings = groups_get_all_groupings($mod->course); $assetrestrictions .= "<div class='text text-danger'>" . format_string($groupings[$mod->groupingid]->name) . "</div>"; // TBD - add a title to show this is the Grouping... } $canviewhidden = has_capability('moodle/course:viewhiddenactivities', $mod->context); // If the module isn't available, or we are a teacher (can view hidden activities) then get availability // info. $availabilityinfo = ''; if (!$mod->available || $canviewhidden) { $availabilityinfo = $this->course_section_cm_availability($mod, $displayoptions); } if ($availabilityinfo !== '') { $conditionalinfo = get_string('conditional', 'theme_snap'); $assetrestrictions .= "<div class='text text-danger'>{$conditionalinfo}.{$availabilityinfo}</div>"; } $assetrestrictions = "<div class='snap-restrictions-meta'>{$assetrestrictions}</div>"; $assetmeta .= $assetcompletionmeta . $assetrestrictions; // Build output. $postcontent = '<div class="snap-asset-meta" data-cmid="' . $mod->id . '">' . $mod->afterlink . $assetmeta . '</div>'; $output .= $assetlink . $contentpart . $postcontent; // Bail at this point if we aren't using a supported format. (Folder view is only partially supported). $supported = ['folderview', 'topics', 'weeks', 'site']; if (!in_array($COURSE->format, $supported)) { return parent::course_section_cm($course, $completioninfo, $mod, $sectionreturn, $displayoptions) . $assetmeta; } // Build up edit actions. $actions = ''; $actionsadvanced = array(); $coursecontext = context_course::instance($mod->course); $modcontext = context_module::instance($mod->id); $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey())); if (has_capability('moodle/course:update', $modcontext)) { $str = get_strings(array('delete', 'move', 'duplicate', 'hide', 'show', 'roles'), 'moodle'); // TODO - add snap strings here. // Move, Edit, Delete. if (has_capability('moodle/course:manageactivities', $modcontext)) { $movealt = get_string('move', 'theme_snap', $mod->get_formatted_name()); $moveicon = "<img title='{$movealt}' aria-hidden='true' class='svg-icon' src='" . $this->output->pix_url('move', 'theme') . "' />"; $editalt = get_string('edit', 'theme_snap', $mod->get_formatted_name()); $editicon = "<img title='{$editalt}' alt='{$editalt}' class='svg-icon' src='" . $this->output->pix_url('edit', 'theme') . "'/>"; $actions .= "<input id='snap-move-mod-{$mod->id}' class='js-snap-asset-move sr-only' type='checkbox'><label class='snap-asset-move' for='snap-move-mod-{$mod->id}'><span class='sr-only'>{$movealt}</span>{$moveicon}</label>"; $actions .= "<a class='snap-edit-asset' href='" . new moodle_url($baseurl, array('update' => $mod->id)) . "'>{$editicon}</a>"; $actionsadvanced[] = "<a href='" . new moodle_url($baseurl, array('delete' => $mod->id)) . "'>{$str->delete}</a>"; } // Hide/Show. if (has_capability('moodle/course:activityvisibility', $modcontext)) { $actionsadvanced[] = "<a href='" . new moodle_url($baseurl, array('hide' => $mod->id)) . "' class='editing_hide js_snap_hide'>{$str->hide}</a>"; $actionsadvanced[] = "<a href='" . new moodle_url($baseurl, array('show' => $mod->id)) . "' class='editing_show js_snap_show'>{$str->show}</a>"; // AX click to change. } // Duplicate. $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport'); if (has_all_capabilities($dupecaps, $coursecontext) && plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2) && plugin_supports('mod', $mod->modname, 'duplicate', true)) { $actionsadvanced[] = "<a href='" . new moodle_url($baseurl, array('duplicate' => $mod->id)) . "' class='js_snap_duplicate'>{$str->duplicate}</a>"; } // Asign roles. if (has_capability('moodle/role:assign', $modcontext)) { $actionsadvanced[] = "<a href='" . new moodle_url('/admin/roles/assign.php', array('contextid' => $modcontext->id)) . "'>{$str->roles}</a>"; } // Give local plugins a chance to add icons. $localplugins = array(); foreach (get_plugin_list_with_function('local', 'extend_module_editing_buttons') as $function) { $localplugins = array_merge($localplugins, $function($mod)); } // TODO - pld string is far too long.... $locallinks = ''; foreach ($localplugins as $localplugin) { $url = $localplugin->url; $text = $localplugin->text; $class = $localplugin->attributes['class']; $actionsadvanced[] = "<a href='{$url}' class='{$class}'>{$text}</a>"; } } $advancedactions = ''; if (!empty($actionsadvanced)) { $moreicon = "<img title='" . get_string('more', 'theme_snap') . "' alt='" . get_string('more', 'theme_snap') . "' class='svg-icon' src='" . $this->output->pix_url('more', 'theme') . "'/>"; $advancedactions = "<div class='dropdown snap-edit-more-dropdown'>\n <a href='#' class='dropdown-toggle snap-edit-asset-more' data-toggle='dropdown' aria-expanded='false' aria-haspopup='true'>{$moreicon}</a>\n <ul class='dropdown-menu'>"; foreach ($actionsadvanced as $action) { $advancedactions .= "<li>{$action}</li>"; } $advancedactions .= "</ul></div>"; } // Add actions menu. if ($actions) { $output .= "<div class='snap-asset-actions' role='region' aria-label='actions'>"; $output .= $actions . $advancedactions; $output .= "</div>"; } $output .= "</div>"; // Close .activityinstance. $output .= "</div>"; // Close .asset-wrapper. return $output; }