Example #1
0
 /**
  * Parse all callbacks and builds the tree.
  *
  * @param integer   $user ID of the user for which the profile is displayed.
  * @param bool      $iscurrentuser true if the profile being viewed is of current user, else false.
  * @param \stdClass $course Course object
  *
  * @return tree Fully build tree to be rendered on my profile page.
  */
 public static function build_tree($user, $iscurrentuser, $course = null)
 {
     global $CFG;
     $tree = new tree();
     // Add core nodes.
     require_once $CFG->libdir . "/myprofilelib.php";
     core_myprofile_navigation($tree, $user, $iscurrentuser, $course);
     // Core components.
     $components = \core_component::get_core_subsystems();
     foreach ($components as $component => $directory) {
         if (empty($directory)) {
             continue;
         }
         $file = $directory . "/lib.php";
         if (is_readable($file)) {
             require_once $file;
             $function = "core_" . $component . "_myprofile_navigation";
             if (function_exists($function)) {
                 $function($tree, $user, $iscurrentuser, $course);
             }
         }
     }
     // Plugins.
     $types = \core_component::get_plugin_types();
     foreach ($types as $type => $dir) {
         $pluginlist = get_plugin_list_with_function($type, "myprofile_navigation", "lib.php");
         foreach ($pluginlist as $function) {
             $function($tree, $user, $iscurrentuser, $course);
         }
     }
     $tree->sort_categories();
     return $tree;
 }
Example #2
0
/**
 * Display overview for courses
 *
 * @param array $courses courses for which overview needs to be shown
 * @return array html overview
 */
function block_course_overview_get_overviews($courses)
{
    $htmlarray = array();
    if ($modules = get_plugin_list_with_function('mod', 'print_overview')) {
        foreach ($modules as $fname) {
            $fname($courses, $htmlarray);
        }
    }
    return $htmlarray;
}
 /**
  * Gather a list of dndupload handlers from the different mods
  *
  * @param object $course The course this is being added to (to check course_allowed_module() )
  */
 public function __construct($course, $modnames = null)
 {
     global $CFG, $PAGE;
     // Add some default types to handle.
     // Note: 'Files' type is hard-coded into the Javascript as this needs to be ...
     // ... treated a little differently.
     $this->register_type('url', array('url', 'text/uri-list', 'text/x-moz-url'), get_string('addlinkhere', 'moodle'), get_string('nameforlink', 'moodle'), get_string('whatforlink', 'moodle'), 10);
     $this->register_type('text/html', array('text/html'), get_string('addpagehere', 'moodle'), get_string('nameforpage', 'moodle'), get_string('whatforpage', 'moodle'), 20);
     $this->register_type('text', array('text', 'text/plain'), get_string('addpagehere', 'moodle'), get_string('nameforpage', 'moodle'), get_string('whatforpage', 'moodle'), 30);
     // Loop through all modules to find handlers.
     $mods = get_plugin_list_with_function('mod', 'dndupload_register');
     foreach ($mods as $component => $funcname) {
         list($modtype, $modname) = normalize_component($component);
         if ($modnames && !array_key_exists($modname, $modnames)) {
             continue;
             // Module is deactivated (hidden) at the site level.
         }
         if (!course_allowed_module($course, $modname)) {
             continue;
             // User does not have permission to add this module to the course.
         }
         $resp = $funcname();
         if (!$resp) {
             continue;
         }
         if (isset($resp['files'])) {
             foreach ($resp['files'] as $file) {
                 $this->register_file_handler($file['extension'], $modname, $file['message']);
             }
         }
         if (isset($resp['addtypes'])) {
             foreach ($resp['addtypes'] as $type) {
                 if (isset($type['priority'])) {
                     $priority = $type['priority'];
                 } else {
                     $priority = 100;
                 }
                 if (!isset($type['handlermessage'])) {
                     $type['handlermessage'] = '';
                 }
                 $this->register_type($type['identifier'], $type['datatransfertypes'], $type['addmessage'], $type['namemessage'], $type['handlermessage'], $priority);
             }
         }
         if (isset($resp['types'])) {
             foreach ($resp['types'] as $type) {
                 $noname = !empty($type['noname']);
                 $this->register_type_handler($type['identifier'], $modname, $type['message'], $noname);
             }
         }
         $PAGE->requires->string_for_js('pluginname', $modname);
     }
 }
Example #4
0
/**
 * Display overview for courses
 *
 * @param array $courses courses for which overview needs to be shown
 * @return array html overview
 */
function block_course_overview_get_overviews($courses)
{
    $htmlarray = array();
    if ($modules = get_plugin_list_with_function('mod', 'print_overview')) {
        // Split courses list into batches with no more than MAX_MODINFO_CACHE_SIZE courses in one batch.
        // Otherwise we exceed the cache limit in get_fast_modinfo() and rebuild it too often.
        if (defined('MAX_MODINFO_CACHE_SIZE') && MAX_MODINFO_CACHE_SIZE > 0 && count($courses) > MAX_MODINFO_CACHE_SIZE) {
            $batches = array_chunk($courses, MAX_MODINFO_CACHE_SIZE, true);
        } else {
            $batches = array($courses);
        }
        foreach ($batches as $courses) {
            foreach ($modules as $fname) {
                $fname($courses, $htmlarray);
            }
        }
    }
    return $htmlarray;
}
Example #5
0
 /**
  * This function gives local plugins an opportunity to modify the settings navigation.
  */
 protected function load_local_plugin_settings()
 {
     foreach (get_plugin_list_with_function('local', 'extend_settings_navigation') as $function) {
         $function($this, $this->context);
     }
 }
 /**
  * This function loads all of the front page settings into the settings navigation.
  * This function is called when the user is on the front page, or $COURSE==$SITE
  * @param bool $forceopen (optional)
  * @return navigation_node
  */
 protected function load_front_page_settings($forceopen = false)
 {
     global $SITE, $CFG;
     $course = clone $SITE;
     $coursecontext = context_course::instance($course->id);
     // Course context
     $frontpage = $this->add(get_string('frontpagesettings'), null, self::TYPE_SETTING, null, 'frontpage');
     if ($forceopen) {
         $frontpage->force_open();
     }
     $frontpage->id = 'frontpagesettings';
     if ($this->page->user_allowed_editing()) {
         // Add the turn on/off settings
         $url = new moodle_url('/course/view.php', array('id' => $course->id, 'sesskey' => sesskey()));
         if ($this->page->user_is_editing()) {
             $url->param('edit', 'off');
             $editstring = get_string('turneditingoff');
         } else {
             $url->param('edit', 'on');
             $editstring = get_string('turneditingon');
         }
         $frontpage->add($editstring, $url, self::TYPE_SETTING, null, null, new pix_icon('i/edit', ''));
     }
     if (has_capability('moodle/course:update', $coursecontext)) {
         // Add the course settings link
         $url = new moodle_url('/admin/settings.php', array('section' => 'frontpagesettings'));
         $frontpage->add(get_string('editsettings'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', ''));
     }
     // add enrol nodes
     enrol_add_course_navigation($frontpage, $course);
     // Manage filters
     if (has_capability('moodle/filter:manage', $coursecontext) && count(filter_get_available_in_context($coursecontext)) > 0) {
         $url = new moodle_url('/filter/manage.php', array('contextid' => $coursecontext->id));
         $frontpage->add(get_string('filters', 'admin'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/filter', ''));
     }
     // View course reports.
     if (has_capability('moodle/site:viewreports', $coursecontext)) {
         // Basic capability for listing of reports.
         $frontpagenav = $frontpage->add(get_string('reports'), null, self::TYPE_CONTAINER, null, 'frontpagereports', new pix_icon('i/stats', ''));
         $coursereports = core_component::get_plugin_list('coursereport');
         foreach ($coursereports as $report => $dir) {
             $libfile = $CFG->dirroot . '/course/report/' . $report . '/lib.php';
             if (file_exists($libfile)) {
                 require_once $libfile;
                 $reportfunction = $report . '_report_extend_navigation';
                 if (function_exists($report . '_report_extend_navigation')) {
                     $reportfunction($frontpagenav, $course, $coursecontext);
                 }
             }
         }
         $reports = get_plugin_list_with_function('report', 'extend_navigation_course', 'lib.php');
         foreach ($reports as $reportfunction) {
             $reportfunction($frontpagenav, $course, $coursecontext);
         }
     }
     // Backup this course
     if (has_capability('moodle/backup:backupcourse', $coursecontext)) {
         $url = new moodle_url('/backup/backup.php', array('id' => $course->id));
         $frontpage->add(get_string('backup'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/backup', ''));
     }
     // Restore to this course
     if (has_capability('moodle/restore:restorecourse', $coursecontext)) {
         $url = new moodle_url('/backup/restorefile.php', array('contextid' => $coursecontext->id));
         $frontpage->add(get_string('restore'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/restore', ''));
     }
     // Questions
     require_once $CFG->libdir . '/questionlib.php';
     question_extend_settings_navigation($frontpage, $coursecontext)->trim_if_empty();
     // Manage files
     if ($course->legacyfiles == 2 and has_capability('moodle/course:managefiles', $this->context)) {
         //hiden in new installs
         $url = new moodle_url('/files/index.php', array('contextid' => $coursecontext->id));
         $frontpage->add(get_string('sitelegacyfiles'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/folder', ''));
     }
     // Let plugins hook into frontpage navigation.
     $pluginsfunction = get_plugins_with_function('extend_navigation_frontpage', 'lib.php');
     foreach ($pluginsfunction as $plugintype => $plugins) {
         foreach ($plugins as $pluginfunction) {
             $pluginfunction($frontpage, $course, $coursecontext);
         }
     }
     return $frontpage;
 }
Example #7
0
/**
 * Clear a course out completely, deleting all content but don't delete the course itself.
 *
 * This function does not verify any permissions.
 *
 * Please note this function also deletes all user enrolments,
 * enrolment instances and role assignments by default.
 *
 * $options:
 *  - 'keep_roles_and_enrolments' - false by default
 *  - 'keep_groups_and_groupings' - false by default
 *
 * @param int $courseid The id of the course that is being deleted
 * @param bool $showfeedback Whether to display notifications of each action the function performs.
 * @param array $options extra options
 * @return bool true if all the removals succeeded. false if there were any failures. If this
 *             method returns false, some of the removals will probably have succeeded, and others
 *             failed, but you have no way of knowing which.
 */
function remove_course_contents($courseid, $showfeedback = true, array $options = null)
{
    global $CFG, $DB, $OUTPUT;
    require_once $CFG->libdir . '/badgeslib.php';
    require_once $CFG->libdir . '/completionlib.php';
    require_once $CFG->libdir . '/questionlib.php';
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->dirroot . '/group/lib.php';
    require_once $CFG->dirroot . '/tag/coursetagslib.php';
    require_once $CFG->dirroot . '/comment/lib.php';
    require_once $CFG->dirroot . '/rating/lib.php';
    require_once $CFG->dirroot . '/notes/lib.php';
    // Handle course badges.
    badges_handle_course_deletion($courseid);
    // NOTE: these concatenated strings are suboptimal, but it is just extra info...
    $strdeleted = get_string('deleted') . ' - ';
    // Some crazy wishlist of stuff we should skip during purging of course content.
    $options = (array) $options;
    $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
    $coursecontext = context_course::instance($courseid);
    $fs = get_file_storage();
    // Delete course completion information, this has to be done before grades and enrols.
    $cc = new completion_info($course);
    $cc->clear_criteria();
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . get_string('completion', 'completion'), 'notifysuccess');
    }
    // Remove all data from gradebook - this needs to be done before course modules
    // because while deleting this information, the system may need to reference
    // the course modules that own the grades.
    remove_course_grades($courseid, $showfeedback);
    remove_grade_letters($coursecontext, $showfeedback);
    // Delete course blocks in any all child contexts,
    // they may depend on modules so delete them first.
    $childcontexts = $coursecontext->get_child_contexts();
    // Returns all subcontexts since 2.2.
    foreach ($childcontexts as $childcontext) {
        blocks_delete_all_for_context($childcontext->id);
    }
    unset($childcontexts);
    blocks_delete_all_for_context($coursecontext->id);
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . get_string('type_block_plural', 'plugin'), 'notifysuccess');
    }
    // Delete every instance of every module,
    // this has to be done before deleting of course level stuff.
    $locations = core_component::get_plugin_list('mod');
    foreach ($locations as $modname => $moddir) {
        if ($modname === 'NEWMODULE') {
            continue;
        }
        if ($module = $DB->get_record('modules', array('name' => $modname))) {
            include_once "{$moddir}/lib.php";
            // Shows php warning only if plugin defective.
            $moddelete = $modname . '_delete_instance';
            // Delete everything connected to an instance.
            $moddeletecourse = $modname . '_delete_course';
            // Delete other stray stuff (uncommon).
            if ($instances = $DB->get_records($modname, array('course' => $course->id))) {
                foreach ($instances as $instance) {
                    if ($cm = get_coursemodule_from_instance($modname, $instance->id, $course->id)) {
                        // Delete activity context questions and question categories.
                        question_delete_activity($cm, $showfeedback);
                    }
                    if (function_exists($moddelete)) {
                        // This purges all module data in related tables, extra user prefs, settings, etc.
                        $moddelete($instance->id);
                    } else {
                        // NOTE: we should not allow installation of modules with missing delete support!
                        debugging("Defective module '{$modname}' detected when deleting course contents: missing function {$moddelete}()!");
                        $DB->delete_records($modname, array('id' => $instance->id));
                    }
                    if ($cm) {
                        // Delete cm and its context - orphaned contexts are purged in cron in case of any race condition.
                        context_helper::delete_instance(CONTEXT_MODULE, $cm->id);
                        $DB->delete_records('course_modules', array('id' => $cm->id));
                    }
                }
            }
            if (function_exists($moddeletecourse)) {
                // Execute ptional course cleanup callback.
                $moddeletecourse($course, $showfeedback);
            }
            if ($instances and $showfeedback) {
                echo $OUTPUT->notification($strdeleted . get_string('pluginname', $modname), 'notifysuccess');
            }
        } else {
            // Ooops, this module is not properly installed, force-delete it in the next block.
        }
    }
    // We have tried to delete everything the nice way - now let's force-delete any remaining module data.
    // Remove all data from availability and completion tables that is associated
    // with course-modules belonging to this course. Note this is done even if the
    // features are not enabled now, in case they were enabled previously.
    $DB->delete_records_select('course_modules_completion', 'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)', array($courseid));
    // Remove course-module data.
    $cms = $DB->get_records('course_modules', array('course' => $course->id));
    foreach ($cms as $cm) {
        if ($module = $DB->get_record('modules', array('id' => $cm->module))) {
            try {
                $DB->delete_records($module->name, array('id' => $cm->instance));
            } catch (Exception $e) {
                // Ignore weird or missing table problems.
            }
        }
        context_helper::delete_instance(CONTEXT_MODULE, $cm->id);
        $DB->delete_records('course_modules', array('id' => $cm->id));
    }
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . get_string('type_mod_plural', 'plugin'), 'notifysuccess');
    }
    // Cleanup the rest of plugins.
    $cleanuplugintypes = array('report', 'coursereport', 'format');
    foreach ($cleanuplugintypes as $type) {
        $plugins = get_plugin_list_with_function($type, 'delete_course', 'lib.php');
        foreach ($plugins as $plugin => $pluginfunction) {
            $pluginfunction($course->id, $showfeedback);
        }
        if ($showfeedback) {
            echo $OUTPUT->notification($strdeleted . get_string('type_' . $type . '_plural', 'plugin'), 'notifysuccess');
        }
    }
    // Delete questions and question categories.
    question_delete_course($course, $showfeedback);
    if ($showfeedback) {
        echo $OUTPUT->notification($strdeleted . get_string('questions', 'question'), 'notifysuccess');
    }
    // Make sure there are no subcontexts left - all valid blocks and modules should be already gone.
    $childcontexts = $coursecontext->get_child_contexts();
    // Returns all subcontexts since 2.2.
    foreach ($childcontexts as $childcontext) {
        $childcontext->delete();
    }
    unset($childcontexts);
    // Remove all roles and enrolments by default.
    if (empty($options['keep_roles_and_enrolments'])) {
        // This hack is used in restore when deleting contents of existing course.
        role_unassign_all(array('contextid' => $coursecontext->id, 'component' => ''), true);
        enrol_course_delete($course);
        if ($showfeedback) {
            echo $OUTPUT->notification($strdeleted . get_string('type_enrol_plural', 'plugin'), 'notifysuccess');
        }
    }
    // Delete any groups, removing members and grouping/course links first.
    if (empty($options['keep_groups_and_groupings'])) {
        groups_delete_groupings($course->id, $showfeedback);
        groups_delete_groups($course->id, $showfeedback);
    }
    // Filters be gone!
    filter_delete_all_for_context($coursecontext->id);
    // Notes, you shall not pass!
    note_delete_all($course->id);
    // Die comments!
    comment::delete_comments($coursecontext->id);
    // Ratings are history too.
    $delopt = new stdclass();
    $delopt->contextid = $coursecontext->id;
    $rm = new rating_manager();
    $rm->delete_ratings($delopt);
    // Delete course tags.
    coursetag_delete_course_tags($course->id, $showfeedback);
    // Delete calendar events.
    $DB->delete_records('event', array('courseid' => $course->id));
    $fs->delete_area_files($coursecontext->id, 'calendar');
    // Delete all related records in other core tables that may have a courseid
    // This array stores the tables that need to be cleared, as
    // table_name => column_name that contains the course id.
    $tablestoclear = array('backup_courses' => 'courseid', 'user_lastaccess' => 'courseid');
    foreach ($tablestoclear as $table => $col) {
        $DB->delete_records($table, array($col => $course->id));
    }
    // Delete all course backup files.
    $fs->delete_area_files($coursecontext->id, 'backup');
    // Cleanup course record - remove links to deleted stuff.
    $oldcourse = new stdClass();
    $oldcourse->id = $course->id;
    $oldcourse->summary = '';
    $oldcourse->cacherev = 0;
    $oldcourse->legacyfiles = 0;
    $oldcourse->enablecompletion = 0;
    if (!empty($options['keep_groups_and_groupings'])) {
        $oldcourse->defaultgroupingid = 0;
    }
    $DB->update_record('course', $oldcourse);
    // Delete course sections.
    $DB->delete_records('course_sections', array('course' => $course->id));
    // Delete legacy, section and any other course files.
    $fs->delete_area_files($coursecontext->id, 'course');
    // Files from summary and section.
    // Delete all remaining stuff linked to context such as files, comments, ratings, etc.
    if (empty($options['keep_roles_and_enrolments']) and empty($options['keep_groups_and_groupings'])) {
        // Easy, do not delete the context itself...
        $coursecontext->delete_content();
    } else {
        // Hack alert!!!!
        // We can not drop all context stuff because it would bork enrolments and roles,
        // there might be also files used by enrol plugins...
    }
    // Delete legacy files - just in case some files are still left there after conversion to new file api,
    // also some non-standard unsupported plugins may try to store something there.
    fulldelete($CFG->dataroot . '/' . $course->id);
    // Delete from cache to reduce the cache size especially makes sense in case of bulk course deletion.
    $cachemodinfo = cache::make('core', 'coursemodinfo');
    $cachemodinfo->delete($courseid);
    // Trigger a course content deleted event.
    $event = \core\event\course_content_deleted::create(array('objectid' => $course->id, 'context' => $coursecontext, 'other' => array('shortname' => $course->shortname, 'fullname' => $course->fullname, 'options' => $options)));
    $event->add_record_snapshot('course', $course);
    $event->trigger();
    return true;
}
Example #8
0
 /**
  * Return activities overview for the given courses.
  *
  * @param array $courseids a list of course ids
  * @return array of warnings and the activities overview
  * @since Moodle 3.2
  * @throws moodle_exception
  */
 public static function get_activities_overview($courseids)
 {
     global $USER;
     // Parameter validation.
     $params = self::validate_parameters(self::get_activities_overview_parameters(), array('courseids' => $courseids));
     $courseoverviews = array();
     list($courses, $warnings) = external_util::validate_courses($params['courseids']);
     if (!empty($courses)) {
         // Add lastaccess to each course (required by print_overview function).
         // We need the complete user data, the ws server does not load a complete one.
         $user = get_complete_user_data('id', $USER->id);
         foreach ($courses as $course) {
             if (isset($user->lastcourseaccess[$course->id])) {
                 $course->lastaccess = $user->lastcourseaccess[$course->id];
             } else {
                 $course->lastaccess = 0;
             }
         }
         $overviews = array();
         if ($modules = get_plugin_list_with_function('mod', 'print_overview')) {
             foreach ($modules as $fname) {
                 $fname($courses, $overviews);
             }
         }
         // Format output.
         foreach ($overviews as $courseid => $modules) {
             $courseoverviews[$courseid]['id'] = $courseid;
             $courseoverviews[$courseid]['overviews'] = array();
             foreach ($modules as $modname => $overviewtext) {
                 $courseoverviews[$courseid]['overviews'][] = array('module' => $modname, 'overviewtext' => $overviewtext);
             }
         }
     }
     $result = array('courses' => $courseoverviews, 'warnings' => $warnings);
     return $result;
 }
Example #9
0
 /**
  * Get a list of reports that support the given store instance.
  *
  * @param string $logstore Name of the store.
  *
  * @return array List of supported reports
  */
 public function get_supported_reports($logstore)
 {
     $allstores = self::get_store_plugins();
     if (empty($allstores[$logstore])) {
         // Store doesn't exist.
         return array();
     }
     $reports = get_plugin_list_with_function('report', 'supports_logstore', 'lib.php');
     $enabled = $this->stores;
     if (empty($enabled[$logstore])) {
         // Store is not enabled, init an instance.
         $classname = '\\' . $logstore . '\\log\\store';
         $instance = new $classname($this);
     } else {
         $instance = $enabled[$logstore];
     }
     $return = array();
     foreach ($reports as $report => $fulldir) {
         if (component_callback($report, 'supports_logstore', array($instance), false)) {
             $return[$report] = get_string('pluginname', $report);
         }
     }
     return $return;
 }
 /**
  * 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;
 }
Example #11
0
/**
 * an adaptation of the standard print_course_overview()
 * @param array $courses a course array to print
 * @param boolean $return if true returns the string
 * @return the rendered view if return is true
 */
function local_print_course_overview($courses, $options = array())
{
    global $PAGE, $OUTPUT;
    $renderer = $PAGE->get_renderer('local_my');
    // Be sure we have something in lastaccess.
    foreach ($courses as $cid => $c) {
        $courses[$cid]->lastaccess = 0 + @$courses[$cid]->lastaccess;
    }
    $overviews = array();
    if ($modules = get_plugin_list_with_function('mod', 'print_overview')) {
        foreach ($modules as $fname) {
            $fname($courses, $overviews);
        }
    }
    $str = '';
    $str .= '<div class="courselist">';
    foreach ($courses as $cid => $c) {
        $str .= '<div>';
        if (empty($options['nocompletion'])) {
            $str .= $renderer->course_completion_gauge($c, 'div', $options['gaugewidth'], $options['gaugeheight']);
        }
        $str .= $renderer->course_simple_div($c);
        $str .= '</div>';
    }
    $str .= '</div>';
    return $str;
}
Example #12
0
 /**
  * Initialize search conditions from plugins
  * local_*_get_question_bank_search_conditions() must return an array of
  * \core_question\bank\search\condition objects.
  */
 protected function init_search_conditions()
 {
     $searchplugins = get_plugin_list_with_function('local', 'get_question_bank_search_conditions');
     foreach ($searchplugins as $component => $function) {
         foreach ($function($this) as $searchobject) {
             $this->add_searchcondition($searchobject);
         }
     }
 }
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * On install, builds the search data for all existing content.
 *
 * @package local_ousearch
 * @copyright 2014 The Open University
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
require __DIR__ . '/../../config.php';
// Check administrator or similar.
require_login();
require_capability('moodle/site:config', context_system::instance());
$url = new moodle_url('/local/ousearch/postinstall.php');
$PAGE->set_url($url);
$PAGE->set_context(context_system::instance());
echo $OUTPUT->header();
if ($_SERVER['REQUEST_METHOD'] === 'POST' && confirm_sesskey()) {
    require_once __DIR__ . '/searchlib.php';
    $plugins = get_plugin_list_with_function('mod', 'ousearch_update_all');
    foreach ($plugins as $plugin => $fn) {
        $fn(true);
    }
} else {
    echo $OUTPUT->box(get_string('postinstall', 'local_ousearch'));
    echo $OUTPUT->single_button($url, get_string('continue'));
}
echo $OUTPUT->footer();
Example #14
0
/**
 * Extend the LTI services through the ltisource plugins
 *
 * @param stdClass $data LTI request data
 * @return bool
 * @throws coding_exception
 */
function lti_extend_lti_services($data)
{
    $plugins = get_plugin_list_with_function('ltisource', $data->messagetype);
    if (!empty($plugins)) {
        // There can only be one.
        if (count($plugins) > 1) {
            throw new coding_exception('More than one ltisource plugin handler found');
        }
        $data->xml = new SimpleXMLElement($data->body);
        $callback = current($plugins);
        call_user_func($callback, $data);
        return true;
    }
    return false;
}
Example #15
0
/**
 * Call a hook present in a subplugin
 *
 * @param  string $hookname The hookname (function without franken style prefix)
 * @param  object $data     Object containing data to be used by the hook function
 * @return bool             Allways false
 */
function local_ltiprovider_call_hook($hookname, $data)
{
    $plugins = get_plugin_list_with_function('ltiproviderextension', $hookname);
    if (!empty($plugins)) {
        foreach ($plugins as $plugin) {
            call_user_func($plugin, $data);
        }
    }
    return false;
}
Example #16
0
 /**
  * This function calls the module function to inject module settings into the
  * settings navigation tree.
  *
  * This only gets called if there is a corrosponding function in the modules
  * lib file.
  *
  * For examples mod/forum/lib.php {@link forum_extend_settings_navigation()}
  *
  * @return navigation_node|false
  */
 protected function load_module_settings()
 {
     global $CFG;
     if (!$this->page->cm && $this->context->contextlevel == CONTEXT_MODULE && $this->context->instanceid) {
         $cm = get_coursemodule_from_id(false, $this->context->instanceid, 0, false, MUST_EXIST);
         $this->page->set_cm($cm, $this->page->course);
     }
     $file = $CFG->dirroot . '/mod/' . $this->page->activityname . '/lib.php';
     if (file_exists($file)) {
         require_once $file;
     }
     $modulenode = $this->add(get_string('pluginadministration', $this->page->activityname));
     $modulenode->force_open();
     // Settings for the module
     if (has_capability('moodle/course:manageactivities', $this->page->cm->context)) {
         $url = new moodle_url('/course/modedit.php', array('update' => $this->page->cm->id, 'return' => true, 'sesskey' => sesskey()));
         $modulenode->add(get_string('editsettings'), $url, navigation_node::TYPE_SETTING, null, 'modedit');
     }
     // Assign local roles
     if (count(get_assignable_roles($this->page->cm->context)) > 0) {
         $url = new moodle_url('/' . $CFG->admin . '/roles/assign.php', array('contextid' => $this->page->cm->context->id));
         $modulenode->add(get_string('localroles', 'role'), $url, self::TYPE_SETTING, null, 'roleassign');
     }
     // Override roles
     if (has_capability('moodle/role:review', $this->page->cm->context) or count(get_overridable_roles($this->page->cm->context)) > 0) {
         $url = new moodle_url('/' . $CFG->admin . '/roles/permissions.php', array('contextid' => $this->page->cm->context->id));
         $modulenode->add(get_string('permissions', 'role'), $url, self::TYPE_SETTING, null, 'roleoverride');
     }
     // Check role permissions
     if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:assign'), $this->page->cm->context)) {
         $url = new moodle_url('/' . $CFG->admin . '/roles/check.php', array('contextid' => $this->page->cm->context->id));
         $modulenode->add(get_string('checkpermissions', 'role'), $url, self::TYPE_SETTING, null, 'rolecheck');
     }
     // Manage filters
     if (has_capability('moodle/filter:manage', $this->page->cm->context) && count(filter_get_available_in_context($this->page->cm->context)) > 0) {
         $url = new moodle_url('/filter/manage.php', array('contextid' => $this->page->cm->context->id));
         $modulenode->add(get_string('filters', 'admin'), $url, self::TYPE_SETTING, null, 'filtermanage');
     }
     // Add reports
     $reports = get_plugin_list_with_function('report', 'extend_navigation_module', 'lib.php');
     foreach ($reports as $reportfunction) {
         $reportfunction($modulenode, $this->page->cm);
     }
     // Add a backup link
     $featuresfunc = $this->page->activityname . '_supports';
     if (function_exists($featuresfunc) && $featuresfunc(FEATURE_BACKUP_MOODLE2) && has_capability('moodle/backup:backupactivity', $this->page->cm->context)) {
         $url = new moodle_url('/backup/backup.php', array('id' => $this->page->cm->course, 'cm' => $this->page->cm->id));
         $modulenode->add(get_string('backup'), $url, self::TYPE_SETTING, null, 'backup');
     }
     // Restore this activity
     $featuresfunc = $this->page->activityname . '_supports';
     if (function_exists($featuresfunc) && $featuresfunc(FEATURE_BACKUP_MOODLE2) && has_capability('moodle/restore:restoreactivity', $this->page->cm->context)) {
         $url = new moodle_url('/backup/restorefile.php', array('contextid' => $this->page->cm->context->id));
         $modulenode->add(get_string('restore'), $url, self::TYPE_SETTING, null, 'restore');
     }
     // Allow the active advanced grading method plugin to append its settings
     $featuresfunc = $this->page->activityname . '_supports';
     if (function_exists($featuresfunc) && $featuresfunc(FEATURE_ADVANCED_GRADING) && has_capability('moodle/grade:managegradingforms', $this->page->cm->context)) {
         require_once $CFG->dirroot . '/grade/grading/lib.php';
         $gradingman = get_grading_manager($this->page->cm->context, $this->page->activityname);
         $gradingman->extend_settings_navigation($this, $modulenode);
     }
     $function = $this->page->activityname . '_extend_settings_navigation';
     if (!function_exists($function)) {
         return $modulenode;
     }
     $function($this, $modulenode);
     // Remove the module node if there are no children
     if (empty($modulenode->children)) {
         $modulenode->remove();
     }
     return $modulenode;
 }
Example #17
0
/**
 * Executes cron functions for a specific type of plugin.
 *
 * @param string $plugintype Plugin type (e.g. 'report')
 * @param string $description If specified, will display 'Starting (whatever)'
 *   and 'Finished (whatever)' lines, otherwise does not display
 */
function cron_execute_plugin_type($plugintype, $description = null)
{
    global $DB;
    // Get list from plugin => function for all plugins
    $plugins = get_plugin_list_with_function($plugintype, 'cron');
    // Modify list for backward compatibility (different files/names)
    $plugins = cron_bc_hack_plugin_functions($plugintype, $plugins);
    // Return if no plugins with cron function to process
    if (!$plugins) {
        return;
    }
    if ($description) {
        mtrace('Starting ' . $description);
    }
    foreach ($plugins as $component => $cronfunction) {
        $dir = core_component::get_component_directory($component);
        // Get cron period if specified in version.php, otherwise assume every cron
        $cronperiod = 0;
        if (file_exists("{$dir}/version.php")) {
            $plugin = new stdClass();
            include "{$dir}/version.php";
            if (isset($plugin->cron)) {
                $cronperiod = $plugin->cron;
            }
        }
        // Using last cron and cron period, don't run if it already ran recently
        $lastcron = get_config($component, 'lastcron');
        if ($cronperiod && $lastcron) {
            if ($lastcron + $cronperiod > time()) {
                // do not execute cron yet
                continue;
            }
        }
        mtrace('Processing cron function for ' . $component . '...');
        cron_trace_time_and_memory();
        $pre_dbqueries = $DB->perf_get_queries();
        $pre_time = microtime(true);
        $cronfunction();
        mtrace("done. (" . ($DB->perf_get_queries() - $pre_dbqueries) . " dbqueries, " . round(microtime(true) - $pre_time, 2) . " seconds)");
        set_config('lastcron', time(), $component);
        @set_time_limit(0);
    }
    if ($description) {
        mtrace('Finished ' . $description);
    }
}
Example #18
0
/**
 * Extend the LTI services through the ltisource plugins
 *
 * @param stdClass $data LTI request data
 * @return bool
 * @throws coding_exception
 */
function lti_extend_lti_services($data)
{
    $plugins = get_plugin_list_with_function('ltisource', $data->messagetype);
    if (!empty($plugins)) {
        try {
            // There can only be one
            if (count($plugins) > 1) {
                throw new coding_exception('More than one ltisource plugin handler found');
            }
            $callback = current($plugins);
            call_user_func($callback, $data);
        } catch (moodle_exception $e) {
            $error = $e->getMessage();
            if (debugging('', DEBUG_DEVELOPER)) {
                $error .= ' ' . format_backtrace(get_exception_info($e)->backtrace);
            }
            $responsexml = lti_get_response_xml('failure', $error, $data->messageid, $data->messagetype);
            header('HTTP/1.0 400 bad request');
            echo $responsexml->asXML();
        }
        return true;
    }
    return false;
}
 /**
  * This function gives local plugins an opportunity to modify the settings navigation.
  */
 protected function load_local_plugin_settings()
 {
     // Get all local plugins with an extend_settings_navigation function in their lib.php file
     foreach (get_plugin_list_with_function('local', 'extends_settings_navigation') as $function) {
         // Call each function providing this (the settings navigation) and the current context.
         $function($this, $this->context);
     }
 }
Example #20
0
/**
 * Check for course updates in the given context level instances (only modules supported right Now)
 *
 * @param  stdClass $course  course object
 * @param  array $tocheck    instances to check for updates
 * @param  array $filter check only for updates in these areas
 * @return array list of warnings and instances with updates information
 * @since  Moodle 3.2
 */
function course_check_updates($course, $tocheck, $filter = array())
{
    global $CFG, $DB;
    $instances = array();
    $warnings = array();
    $modulescallbacksupport = array();
    $modinfo = get_fast_modinfo($course);
    $supportedplugins = get_plugin_list_with_function('mod', 'check_updates_since');
    // Check instances.
    foreach ($tocheck as $instance) {
        if ($instance['contextlevel'] == 'module') {
            // Check module visibility.
            try {
                $cm = $modinfo->get_cm($instance['id']);
            } catch (Exception $e) {
                $warnings[] = array('item' => 'module', 'itemid' => $instance['id'], 'warningcode' => 'cmidnotincourse', 'message' => 'This module id does not belong to this course.');
                continue;
            }
            if (!$cm->uservisible) {
                $warnings[] = array('item' => 'module', 'itemid' => $instance['id'], 'warningcode' => 'nonuservisible', 'message' => 'You don\'t have access to this module.');
                continue;
            }
            if (empty($supportedplugins['mod_' . $cm->modname])) {
                $warnings[] = array('item' => 'module', 'itemid' => $instance['id'], 'warningcode' => 'missingcallback', 'message' => 'This module does not implement the check_updates_since callback: ' . $instance['contextlevel']);
                continue;
            }
            // Retrieve the module instance.
            $instances[] = array('contextlevel' => $instance['contextlevel'], 'id' => $instance['id'], 'updates' => call_user_func($cm->modname . '_check_updates_since', $cm, $instance['since'], $filter));
        } else {
            $warnings[] = array('item' => 'contextlevel', 'itemid' => $instance['id'], 'warningcode' => 'contextlevelnotsupported', 'message' => 'Context level not yet supported ' . $instance['contextlevel']);
        }
    }
    return array($instances, $warnings);
}