示例#1
0
/**
 * Checks whether the current user is permitted (using the normal UI) to
 * remove a specific group member, assuming that they have access to remove
 * group members in general.
 *
 * For automatically-created group member entries, this checks with the
 * relevant plugin to see whether it is permitted. The default, if the plugin
 * doesn't provide a function, is true.
 *
 * For other entries (and any which have already been deleted/don't exist) it
 * just returns true.
 *
 * @param mixed $grouporid The group id or group object
 * @param mixed $userorid The user id or user object
 * @return bool True if permitted, false otherwise
 */
function groups_remove_member_allowed($grouporid, $userorid)
{
    global $DB;
    if (is_object($userorid)) {
        $userid = $userorid->id;
    } else {
        $userid = $userorid;
    }
    if (is_object($grouporid)) {
        $groupid = $grouporid->id;
    } else {
        $groupid = $grouporid;
    }
    // Get entry
    if (!($entry = $DB->get_record('groups_members', array('groupid' => $groupid, 'userid' => $userid), '*', IGNORE_MISSING))) {
        // If the entry does not exist, they are allowed to remove it (this
        // is consistent with groups_remove_member below).
        return true;
    }
    // If the entry does not have a component value, they can remove it
    if (empty($entry->component)) {
        return true;
    }
    // It has a component value, so we need to call a plugin function (if it
    // exists); the default is to allow removal
    return component_callback($entry->component, 'allow_group_member_remove', array($entry->itemid, $entry->groupid, $entry->userid), true);
}
示例#2
0
function lti_get_types()
{
    global $OUTPUT;
    $subtypes = array();
    foreach (get_plugin_list('ltisource') as $name => $dir) {
        if ($moretypes = component_callback("ltisource_{$name}", 'get_types')) {
            $subtypes = array_merge($subtypes, $moretypes);
        }
    }
    if (empty($subtypes)) {
        return MOD_SUBTYPE_NO_CHILDREN;
    }
    $types = array();
    $type = new stdClass();
    $type->modclass = MOD_CLASS_ACTIVITY;
    $type->type = 'lti_group_start';
    $type->typestr = '--' . get_string('modulenameplural', 'mod_lti');
    $types[] = $type;
    $link = get_string('modulename_link', 'mod_lti');
    $linktext = get_string('morehelp');
    $help = get_string('modulename_help', 'mod_lti');
    $help .= html_writer::tag('div', $OUTPUT->doc_link($link, $linktext, true), array('class' => 'helpdoclink'));
    $type = new stdClass();
    $type->modclass = MOD_CLASS_ACTIVITY;
    $type->type = '';
    $type->typestr = get_string('generaltool', 'mod_lti');
    $type->help = $help;
    $types[] = $type;
    $types = array_merge($types, $subtypes);
    $type = new stdClass();
    $type->modclass = MOD_CLASS_ACTIVITY;
    $type->type = 'lti_group_end';
    $type->typestr = '--';
    $types[] = $type;
    return $types;
}
示例#3
0
文件: index.php 项目: evltuma/moodle
list($context, $course, $cm) = get_context_info_array($contextid);
require_login($course, false, $cm);
$url = new moodle_url('/rating/index.php', array('contextid' => $contextid, 'component' => $component, 'ratingarea' => $ratingarea, 'itemid' => $itemid, 'scaleid' => $scaleid));
if (!empty($sort)) {
    $url->param('sort', $sort);
}
if (!empty($popup)) {
    $url->param('popup', $popup);
}
$PAGE->set_url($url);
$PAGE->set_context($context);
if ($popup) {
    $PAGE->set_pagelayout('popup');
}
$params = array('contextid' => $contextid, 'component' => $component, 'ratingarea' => $ratingarea, 'itemid' => $itemid, 'scaleid' => $scaleid);
if (!has_capability('moodle/rating:view', $context) || !component_callback($component, 'rating_can_see_item_ratings', array($params), true)) {
    print_error('noviewrate', 'rating');
}
$canviewallratings = has_capability('moodle/rating:viewall', $context);
switch ($sort) {
    case 'firstname':
        $sqlsort = "u.firstname ASC";
        break;
    case 'rating':
        $sqlsort = "r.rating ASC";
        break;
    default:
        $sqlsort = "r.timemodified ASC";
}
$scalemenu = make_grades_menu($scaleid);
$strrating = get_string('rating', 'rating');
示例#4
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;
 }
示例#5
0
/**
 * Set the visibility of a module and inherent properties.
 *
 * Note: Do not forget to trigger the event \core\event\course_module_updated as it needs
 * to be triggered manually, refer to {@link \core\event\course_module_updated::create_from_cm()}.
 *
 * From 2.4 the parameter $prevstateoverrides has been removed, the logic it triggered
 * has been moved to {@link set_section_visible()} which was the only place from which
 * the parameter was used.
 *
 * @param int $id of the module
 * @param int $visible state of the module
 * @return bool false when the module was not found, true otherwise
 */
function set_coursemodule_visible($id, $visible)
{
    global $DB, $CFG;
    require_once $CFG->libdir . '/gradelib.php';
    require_once $CFG->dirroot . '/calendar/lib.php';
    // Trigger developer's attention when using the previously removed argument.
    if (func_num_args() > 2) {
        debugging('Wrong number of arguments passed to set_coursemodule_visible(), $prevstateoverrides
            has been removed.', DEBUG_DEVELOPER);
    }
    if (!($cm = $DB->get_record('course_modules', array('id' => $id)))) {
        return false;
    }
    // Create events and propagate visibility to associated grade items if the value has changed.
    // Only do this if it's changed to avoid accidently overwriting manual showing/hiding of student grades.
    if ($cm->visible == $visible) {
        return true;
    }
    if (!($modulename = $DB->get_field('modules', 'name', array('id' => $cm->module)))) {
        return false;
    }
    if ($events = $DB->get_records('event', array('instance' => $cm->instance, 'modulename' => $modulename))) {
        foreach ($events as $event) {
            if ($visible) {
                $event = new calendar_event($event);
                $event->toggle_visibility(true);
            } else {
                $event = new calendar_event($event);
                $event->toggle_visibility(false);
            }
        }
    }
    // Updating visible and visibleold to keep them in sync. Only changing a section visibility will
    // affect visibleold to allow for an original visibility restore. See set_section_visible().
    $cminfo = new stdClass();
    $cminfo->id = $id;
    $cminfo->visible = $visible;
    $cminfo->visibleold = $visible;
    $DB->update_record('course_modules', $cminfo);
    // Hide the associated grade items so the teacher doesn't also have to go to the gradebook and hide them there.
    // Note that this must be done after updating the row in course_modules, in case
    // the modules grade_item_update function needs to access $cm->visible.
    if (plugin_supports('mod', $modulename, FEATURE_CONTROLS_GRADE_VISIBILITY) && component_callback_exists('mod_' . $modulename, 'grade_item_update')) {
        $instance = $DB->get_record($modulename, array('id' => $cm->instance), '*', MUST_EXIST);
        component_callback('mod_' . $modulename, 'grade_item_update', array($instance));
    } else {
        $grade_items = grade_item::fetch_all(array('itemtype' => 'mod', 'itemmodule' => $modulename, 'iteminstance' => $cm->instance, 'courseid' => $cm->course));
        if ($grade_items) {
            foreach ($grade_items as $grade_item) {
                $grade_item->set_hidden(!$visible);
            }
        }
    }
    rebuild_course_cache($cm->course, true);
    return true;
}
 public function get_mod_recent_activity($context)
 {
     global $COURSE, $OUTPUT;
     $viewfullnames = has_capability('moodle/site:viewfullnames', $context);
     $recentactivity = array();
     $timestart = time() - 86400 * 7;
     // 7 days ago.
     if (optional_param('testing', false, PARAM_BOOL)) {
         $timestart = time() - 86400 * 700;
         // 700 days ago for testing purposes.
     }
     $modinfo = get_fast_modinfo($COURSE);
     $usedmodules = $modinfo->get_used_module_names();
     if (empty($usedmodules)) {
         // No used modules so return null string.
         return '';
     }
     foreach ($usedmodules as $modname => $modfullname) {
         // Each module gets it's own logs and prints them.
         ob_start();
         $hascontent = component_callback('mod_' . $modname, 'print_recent_activity', array($COURSE, $viewfullnames, $timestart), false);
         if ($hascontent) {
             $content = ob_get_contents();
             if (!empty($content)) {
                 $recentactivity[$modname] = $content;
             }
         }
         ob_end_clean();
     }
     $output = '';
     if (!empty($recentactivity)) {
         foreach ($recentactivity as $modname => $moduleactivity) {
             // Get mod icon, empty alt as title already there.
             $img = html_writer::tag('img', '', array('src' => $OUTPUT->pix_url('icon', $modname), 'alt' => ''));
             // Create media object for module activity.
             $output .= "<div class='snap-media-object course-footer-update-{$modname}'>{$img}" . "<div class=snap-media-body>{$moduleactivity}</div></div>";
         }
     }
     return $output;
 }
示例#7
0
文件: mod_form.php 项目: dg711/moodle
 public function definition()
 {
     global $PAGE, $OUTPUT, $COURSE;
     if ($type = optional_param('type', false, PARAM_ALPHA)) {
         component_callback("ltisource_{$type}", 'add_instance_hook');
     }
     $this->typeid = 0;
     $mform =& $this->_form;
     // Adding the "general" fieldset, where all the common settings are shown.
     $mform->addElement('header', 'general', get_string('general', 'form'));
     // Adding the standard "name" field.
     $mform->addElement('text', 'name', get_string('basicltiname', 'lti'), array('size' => '64'));
     $mform->setType('name', PARAM_TEXT);
     $mform->addRule('name', null, 'required', null, 'client');
     $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
     // Adding the optional "intro" and "introformat" pair of fields.
     $this->standard_intro_elements(get_string('basicltiintro', 'lti'));
     $mform->setAdvanced('introeditor');
     // Display the label to the right of the checkbox so it looks better & matches rest of the form.
     if ($mform->elementExists('showdescription')) {
         $coursedesc = $mform->getElement('showdescription');
         if (!empty($coursedesc)) {
             $coursedesc->setText(' ' . $coursedesc->getLabel());
             $coursedesc->setLabel('&nbsp');
         }
     }
     $mform->setAdvanced('showdescription');
     $mform->addElement('checkbox', 'showtitlelaunch', '&nbsp;', ' ' . get_string('display_name', 'lti'));
     $mform->setAdvanced('showtitlelaunch');
     $mform->setDefault('showtitlelaunch', true);
     $mform->addHelpButton('showtitlelaunch', 'display_name', 'lti');
     $mform->addElement('checkbox', 'showdescriptionlaunch', '&nbsp;', ' ' . get_string('display_description', 'lti'));
     $mform->setAdvanced('showdescriptionlaunch');
     $mform->addHelpButton('showdescriptionlaunch', 'display_description', 'lti');
     // Tool settings.
     $attributes = array();
     if ($update = optional_param('update', false, PARAM_INT)) {
         $attributes['disabled'] = 'disabled';
     }
     $attributes['class'] = 'lti_contentitem';
     $tooltypes = $mform->addElement('select', 'typeid', get_string('external_tool_type', 'lti'), array(), $attributes);
     $typeid = optional_param('typeid', false, PARAM_INT);
     $mform->getElement('typeid')->setValue($typeid);
     $mform->addHelpButton('typeid', 'external_tool_type', 'lti');
     $toolproxy = array();
     // Array of tool type IDs that don't support ContentItemSelectionRequest.
     $noncontentitemtypes = [];
     foreach (lti_get_types_for_add_instance() as $id => $type) {
         if (!empty($type->toolproxyid)) {
             $toolproxy[] = $type->id;
             $attributes = array('globalTool' => 1, 'toolproxy' => 1);
             $enabledcapabilities = explode("\n", $type->enabledcapability);
             if (!in_array('Result.autocreate', $enabledcapabilities)) {
                 $attributes['nogrades'] = 1;
             }
             if (!in_array('Person.name.full', $enabledcapabilities) && !in_array('Person.name.family', $enabledcapabilities) && !in_array('Person.name.given', $enabledcapabilities)) {
                 $attributes['noname'] = 1;
             }
             if (!in_array('Person.email.primary', $enabledcapabilities)) {
                 $attributes['noemail'] = 1;
             }
         } else {
             if ($type->course == $COURSE->id) {
                 $attributes = array('editable' => 1, 'courseTool' => 1, 'domain' => $type->tooldomain);
             } else {
                 if ($id != 0) {
                     $attributes = array('globalTool' => 1, 'domain' => $type->tooldomain);
                 } else {
                     $attributes = array();
                 }
             }
         }
         if (!$update && $id) {
             $config = lti_get_type_config($id);
             if (!empty($config['contentitem'])) {
                 $attributes['data-contentitem'] = 1;
                 $attributes['data-id'] = $id;
             } else {
                 $noncontentitemtypes[] = $id;
             }
         }
         $tooltypes->addOption($type->name, $id, $attributes);
     }
     // Add button that launches the content-item selection dialogue.
     // Set contentitem URL.
     $contentitemurl = new moodle_url('/mod/lti/contentitem.php');
     $contentbuttonattributes['data-contentitemurl'] = $contentitemurl->out(false);
     $mform->addElement('button', 'selectcontent', get_string('selectcontent', 'lti'), $contentbuttonattributes);
     if ($update) {
         $mform->disabledIf('selectcontent', 'typeid', 'neq', 0);
     } else {
         // Disable select content button if the selected tool doesn't support content item or it's set to Automatic.
         $allnoncontentitemtypes = $noncontentitemtypes;
         $allnoncontentitemtypes[] = '0';
         // Add option value for "Automatic, based on launch URL".
         $mform->disabledIf('selectcontent', 'typeid', 'in', $allnoncontentitemtypes);
     }
     $mform->addElement('text', 'toolurl', get_string('launch_url', 'lti'), array('size' => '64'));
     $mform->setType('toolurl', PARAM_URL);
     $mform->addHelpButton('toolurl', 'launch_url', 'lti');
     if ($update) {
         $mform->disabledIf('toolurl', 'typeid', 'neq', 0);
     } else {
         $mform->disabledIf('toolurl', 'typeid', 'in', $noncontentitemtypes);
     }
     $mform->addElement('text', 'securetoolurl', get_string('secure_launch_url', 'lti'), array('size' => '64'));
     $mform->setType('securetoolurl', PARAM_URL);
     $mform->setAdvanced('securetoolurl');
     $mform->addHelpButton('securetoolurl', 'secure_launch_url', 'lti');
     if ($update) {
         $mform->disabledIf('securetoolurl', 'typeid', 'neq', 0);
     } else {
         $mform->disabledIf('securetoolurl', 'typeid', 'in', $noncontentitemtypes);
     }
     $mform->addElement('hidden', 'urlmatchedtypeid', '', array('id' => 'id_urlmatchedtypeid'));
     $mform->setType('urlmatchedtypeid', PARAM_INT);
     $launchoptions = array();
     $launchoptions[LTI_LAUNCH_CONTAINER_DEFAULT] = get_string('default', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_EMBED] = get_string('embed', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS] = get_string('embed_no_blocks', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_REPLACE_MOODLE_WINDOW] = get_string('existing_window', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_WINDOW] = get_string('new_window', 'lti');
     $mform->addElement('select', 'launchcontainer', get_string('launchinpopup', 'lti'), $launchoptions);
     $mform->setDefault('launchcontainer', LTI_LAUNCH_CONTAINER_DEFAULT);
     $mform->addHelpButton('launchcontainer', 'launchinpopup', 'lti');
     $mform->setAdvanced('launchcontainer');
     $mform->addElement('text', 'resourcekey', get_string('resourcekey', 'lti'));
     $mform->setType('resourcekey', PARAM_TEXT);
     $mform->setAdvanced('resourcekey');
     $mform->addHelpButton('resourcekey', 'resourcekey', 'lti');
     if ($update) {
         $mform->disabledIf('resourcekey', 'typeid', 'neq', 0);
     } else {
         $mform->disabledIf('resourcekey', 'typeid', 'in', $noncontentitemtypes);
     }
     $mform->setForceLtr('resourcekey');
     $mform->addElement('passwordunmask', 'password', get_string('password', 'lti'));
     $mform->setType('password', PARAM_TEXT);
     $mform->setAdvanced('password');
     $mform->addHelpButton('password', 'password', 'lti');
     if ($update) {
         $mform->disabledIf('password', 'typeid', 'neq', 0);
     } else {
         $mform->disabledIf('password', 'typeid', 'in', $noncontentitemtypes);
     }
     $mform->addElement('textarea', 'instructorcustomparameters', get_string('custom', 'lti'), array('rows' => 4, 'cols' => 60));
     $mform->setType('instructorcustomparameters', PARAM_TEXT);
     $mform->setAdvanced('instructorcustomparameters');
     $mform->addHelpButton('instructorcustomparameters', 'custom', 'lti');
     $mform->setForceLtr('instructorcustomparameters');
     $mform->addElement('text', 'icon', get_string('icon_url', 'lti'), array('size' => '64'));
     $mform->setType('icon', PARAM_URL);
     $mform->setAdvanced('icon');
     $mform->addHelpButton('icon', 'icon_url', 'lti');
     if ($update) {
         $mform->disabledIf('icon', 'typeid', 'neq', 0);
     } else {
         $mform->disabledIf('icon', 'typeid', 'in', $noncontentitemtypes);
     }
     $mform->addElement('text', 'secureicon', get_string('secure_icon_url', 'lti'), array('size' => '64'));
     $mform->setType('secureicon', PARAM_URL);
     $mform->setAdvanced('secureicon');
     $mform->addHelpButton('secureicon', 'secure_icon_url', 'lti');
     if ($update) {
         $mform->disabledIf('secureicon', 'typeid', 'neq', 0);
     } else {
         $mform->disabledIf('secureicon', 'typeid', 'in', $noncontentitemtypes);
     }
     // Add privacy preferences fieldset where users choose whether to send their data.
     $mform->addElement('header', 'privacy', get_string('privacy', 'lti'));
     $mform->addElement('advcheckbox', 'instructorchoicesendname', '&nbsp;', ' ' . get_string('share_name', 'lti'));
     $mform->setDefault('instructorchoicesendname', '1');
     $mform->addHelpButton('instructorchoicesendname', 'share_name', 'lti');
     $mform->disabledIf('instructorchoicesendname', 'typeid', 'in', $toolproxy);
     $mform->addElement('advcheckbox', 'instructorchoicesendemailaddr', '&nbsp;', ' ' . get_string('share_email', 'lti'));
     $mform->setDefault('instructorchoicesendemailaddr', '1');
     $mform->addHelpButton('instructorchoicesendemailaddr', 'share_email', 'lti');
     $mform->disabledIf('instructorchoicesendemailaddr', 'typeid', 'in', $toolproxy);
     $mform->addElement('advcheckbox', 'instructorchoiceacceptgrades', '&nbsp;', ' ' . get_string('accept_grades', 'lti'));
     $mform->setDefault('instructorchoiceacceptgrades', '1');
     $mform->addHelpButton('instructorchoiceacceptgrades', 'accept_grades', 'lti');
     $mform->disabledIf('instructorchoiceacceptgrades', 'typeid', 'in', $toolproxy);
     // Add standard course module grading elements.
     $this->standard_grading_coursemodule_elements();
     // Add standard elements, common to all modules.
     $this->standard_coursemodule_elements();
     $mform->setAdvanced('cmidnumber');
     // Add standard buttons, common to all modules.
     $this->add_action_buttons();
     $editurl = new moodle_url('/mod/lti/instructor_edit_tool_type.php', array('sesskey' => sesskey(), 'course' => $COURSE->id));
     $ajaxurl = new moodle_url('/mod/lti/ajax.php');
     $jsinfo = (object) array('edit_icon_url' => (string) $OUTPUT->pix_url('t/edit'), 'add_icon_url' => (string) $OUTPUT->pix_url('t/add'), 'delete_icon_url' => (string) $OUTPUT->pix_url('t/delete'), 'green_check_icon_url' => (string) $OUTPUT->pix_url('i/valid'), 'warning_icon_url' => (string) $OUTPUT->pix_url('warning', 'lti'), 'instructor_tool_type_edit_url' => $editurl->out(false), 'ajax_url' => $ajaxurl->out(true), 'courseId' => $COURSE->id);
     $module = array('name' => 'mod_lti_edit', 'fullpath' => '/mod/lti/mod_form.js', 'requires' => array('base', 'io', 'querystring-stringify-simple', 'node', 'event', 'json-parse'), 'strings' => array(array('addtype', 'lti'), array('edittype', 'lti'), array('deletetype', 'lti'), array('delete_confirmation', 'lti'), array('cannot_edit', 'lti'), array('cannot_delete', 'lti'), array('global_tool_types', 'lti'), array('course_tool_types', 'lti'), array('using_tool_configuration', 'lti'), array('using_tool_cartridge', 'lti'), array('domain_mismatch', 'lti'), array('custom_config', 'lti'), array('tool_config_not_found', 'lti'), array('tooltypeadded', 'lti'), array('tooltypedeleted', 'lti'), array('tooltypenotdeleted', 'lti'), array('tooltypeupdated', 'lti'), array('forced_help', 'lti')));
     if (!empty($typeid)) {
         $mform->setAdvanced('typeid');
         $mform->setAdvanced('toolurl');
     }
     $PAGE->requires->js_init_call('M.mod_lti.editor.init', array(json_encode($jsinfo)), true, $module);
 }
示例#8
0
/**
 * @param stdClass $comment
 * @param stdClass $options
 * @throws comment_exception
 */
function mod_hsuforum_comment_message(stdClass $comment, stdClass $options)
{
    global $DB;
    if ($options->commentarea != 'userposts_comments') {
        throw new comment_exception('invalidcommentarea');
    }
    if (!($user = $DB->get_record('user', array('id' => $options->itemid)))) {
        throw new comment_exception('invalidcommentitemid');
    }
    /** @var context $context */
    $context = $options->context;
    if (!($cm = get_coursemodule_from_id('hsuforum', $context->instanceid))) {
        throw new comment_exception('invalidcontext');
    }
    // Get all the users with the ability to rate.
    $recipients = get_users_by_capability($context, 'mod/hsuforum:rate');
    // Add the item user if they are different from commenter.
    if ($comment->userid != $user->id and has_capability('mod/hsuforum:replypost', $context, $user)) {
        $recipients[$user->id] = $user;
    }
    // Sender is the author of the comment.
    $sender = $DB->get_record('user', array('id' => $comment->userid));
    // Make sure that the commenter is not getting the message.
    unset($recipients[$comment->userid]);
    if (\core_component::get_plugin_directory('local', 'joulegrader') !== null) {
        // Joule Grader is installed and control panel enabled.
        $gareaid = component_callback('local_joulegrader', 'area_from_context', array($context, 'hsuforum'));
        $contexturl = new moodle_url('/local/joulegrader/view.php', array('courseid' => $cm->course, 'garea' => $gareaid, 'guser' => $user->id));
    } else {
        $contexturl = $context->get_url();
    }
    $params = array($comment, $recipients, $sender, $cm->name, $contexturl);
    component_callback('local_mrooms', 'comment_send_messages', $params);
}
示例#9
0
文件: lib.php 项目: IFPBMoodle/moodle
/**
 * Return aliases of this activity. LTI should have an alias for each configured tool type
 * This is so you can add an external tool types directly to the activity chooser
 *
 * @param stdClass $defaultitem default item that would be added to the activity chooser if this callback was not present.
 *     It has properties: archetype, name, title, help, icon, link
 * @return array An array of aliases for this activity. Each element is an object with same list of properties as $defaultitem,
 *     plus an additional property, helplink.
 *     Properties title and link are required
 **/
function lti_get_shortcuts($defaultitem)
{
    global $CFG, $COURSE;
    require_once $CFG->dirroot . '/mod/lti/locallib.php';
    $types = lti_get_configured_types($COURSE->id, $defaultitem->link->param('sr'));
    $types[] = $defaultitem;
    // Add items defined in ltisource plugins.
    foreach (core_component::get_plugin_list('ltisource') as $pluginname => $dir) {
        if ($moretypes = component_callback("ltisource_{$pluginname}", 'get_types')) {
            // Callback 'get_types()' in 'ltisource' plugins is deprecated in 3.1 and will be removed in 3.5, TODO MDL-53697.
            debugging('Deprecated callback get_types() is found in ltisource_' . $pluginname . ', use get_shortcuts() instead', DEBUG_DEVELOPER);
            $grouptitle = get_string('modulenameplural', 'mod_lti');
            foreach ($moretypes as $subtype) {
                // Instead of adding subitems combine the name of the group with the name of the subtype.
                $subtype->title = get_string('activitytypetitle', '', (object) ['activity' => $grouptitle, 'type' => $subtype->typestr]);
                // Re-implement the logic of get_module_metadata() in Moodle 3.0 and below for converting
                // subtypes into items in activity chooser.
                $subtype->type = str_replace('&amp;', '&', $subtype->type);
                $subtype->name = preg_replace('/.*type=/', '', $subtype->type);
                $subtype->link = new moodle_url($defaultitem->link, array('type' => $subtype->name));
                if (empty($subtype->help) && !empty($subtype->name) && get_string_manager()->string_exists('help' . $subtype->name, $pluginname)) {
                    $subtype->help = get_string('help' . $subtype->name, $pluginname);
                }
                unset($subtype->typestr);
                $types[] = $subtype;
            }
        }
        // LTISOURCE plugins can also implement callback get_shortcuts() to add items to the activity chooser.
        // The return values are the same as of the 'mod' callbacks except that $defaultitem is only passed for reference and
        // should not be added to the return value.
        if ($moretypes = component_callback("ltisource_{$pluginname}", 'get_shortcuts', array($defaultitem))) {
            $types = array_merge($types, $moretypes);
        }
    }
    return $types;
}
示例#10
0
 /**
  * Retrieve a list of ratings for a given item (forum post etc)
  *
  * @param string $contextlevel course, module, user...
  * @param int $instanceid the instance if for the context element
  * @param string $component the name of the component
  * @param string $ratingarea rating area
  * @param int $itemid the item id
  * @param int $scaleid the scale id
  * @param string $sort sql order (firstname, rating or timemodified)
  * @return array Result and possible warnings
  * @throws moodle_exception
  * @since Moodle 2.9
  */
 public static function get_item_ratings($contextlevel, $instanceid, $component, $ratingarea, $itemid, $scaleid, $sort)
 {
     global $USER, $PAGE;
     $warnings = array();
     $arrayparams = array('contextlevel' => $contextlevel, 'instanceid' => $instanceid, 'component' => $component, 'ratingarea' => $ratingarea, 'itemid' => $itemid, 'scaleid' => $scaleid, 'sort' => $sort);
     // Validate and normalize parameters.
     $params = self::validate_parameters(self::get_item_ratings_parameters(), $arrayparams);
     $context = self::get_context_from_params($params);
     self::validate_context($context);
     // Minimal capability required.
     $callbackparams = array('contextid' => $context->id, 'component' => $component, 'ratingarea' => $ratingarea, 'itemid' => $itemid, 'scaleid' => $scaleid);
     if (!has_capability('moodle/rating:view', $context) || !component_callback($component, 'rating_can_see_item_ratings', array($callbackparams), true)) {
         throw new moodle_exception('noviewrate', 'rating');
     }
     list($context, $course, $cm) = get_context_info_array($context->id);
     // Can we see all ratings?
     $canviewallratings = has_capability('moodle/rating:viewall', $context);
     // Create the Sql sort order string.
     switch ($params['sort']) {
         case 'firstname':
             $sqlsort = "u.firstname ASC";
             break;
         case 'rating':
             $sqlsort = "r.rating ASC";
             break;
         default:
             $sqlsort = "r.timemodified ASC";
     }
     $ratingoptions = new stdClass();
     $ratingoptions->context = $context;
     $ratingoptions->component = $params['component'];
     $ratingoptions->ratingarea = $params['ratingarea'];
     $ratingoptions->itemid = $params['itemid'];
     $ratingoptions->sort = $sqlsort;
     $rm = new rating_manager();
     $ratings = $rm->get_all_ratings_for_item($ratingoptions);
     $scalemenu = make_grades_menu($params['scaleid']);
     // If the scale was changed after ratings were submitted some ratings may have a value above the current maximum.
     // We can't just do count($scalemenu) - 1 as custom scales start at index 1, not 0.
     $maxrating = max(array_keys($scalemenu));
     $results = array();
     foreach ($ratings as $rating) {
         if ($canviewallratings || $USER->id == $rating->userid) {
             if ($rating->rating > $maxrating) {
                 $rating->rating = $maxrating;
             }
             // The rating object has all the required fields for generating the picture url.
             $userpicture = new user_picture($rating);
             $userpicture->size = 1;
             // Size f1.
             $profileimageurl = $userpicture->get_url($PAGE)->out(false);
             $result = array();
             $result['id'] = $rating->id;
             $result['userid'] = $rating->userid;
             $result['userpictureurl'] = $profileimageurl;
             $result['userfullname'] = fullname($rating);
             $result['rating'] = $scalemenu[$rating->rating];
             $result['timemodified'] = $rating->timemodified;
             $results[] = $result;
         }
     }
     return array('ratings' => $results, 'warnings' => $warnings);
 }
示例#11
0
 /**
  * Checks if the activity type requires subtypes.
  *
  * @return bool|null (null if the check is not possible)
  */
 public function activity_has_subtypes()
 {
     if (!($modname = $this->get_activitytype())) {
         return null;
     }
     return component_callback('mod_' . $modname, 'get_types', array(), MOD_SUBTYPE_NO_CHILDREN) !== MOD_SUBTYPE_NO_CHILDREN;
 }
示例#12
0
 public function definition()
 {
     global $DB, $PAGE, $OUTPUT, $USER, $COURSE;
     if ($type = optional_param('type', false, PARAM_ALPHA)) {
         component_callback("ltisource_{$type}", 'add_instance_hook');
     }
     $this->typeid = 0;
     $mform =& $this->_form;
     //-------------------------------------------------------------------------------
     // Adding the "general" fieldset, where all the common settings are shown
     $mform->addElement('header', 'general', get_string('general', 'form'));
     // Adding the standard "name" field
     $mform->addElement('text', 'name', get_string('basicltiname', 'lti'), array('size' => '64'));
     $mform->setType('name', PARAM_TEXT);
     $mform->addRule('name', null, 'required', null, 'client');
     $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
     // Adding the optional "intro" and "introformat" pair of fields
     $this->add_intro_editor(false, get_string('basicltiintro', 'lti'));
     $mform->setAdvanced('introeditor');
     // Display the label to the right of the checkbox so it looks better & matches rest of the form
     $coursedesc = $mform->getElement('showdescription');
     if (!empty($coursedesc)) {
         $coursedesc->setText(' ' . $coursedesc->getLabel());
         $coursedesc->setLabel('&nbsp');
     }
     $mform->setAdvanced('showdescription');
     $mform->addElement('checkbox', 'showtitlelaunch', '&nbsp;', ' ' . get_string('display_name', 'lti'));
     $mform->setAdvanced('showtitlelaunch');
     $mform->setDefault('showtitlelaunch', true);
     $mform->addHelpButton('showtitlelaunch', 'display_name', 'lti');
     $mform->addElement('checkbox', 'showdescriptionlaunch', '&nbsp;', ' ' . get_string('display_description', 'lti'));
     $mform->setAdvanced('showdescriptionlaunch');
     $mform->addHelpButton('showdescriptionlaunch', 'display_description', 'lti');
     // Tool settings
     $tooltypes = $mform->addElement('select', 'typeid', get_string('external_tool_type', 'lti'), array());
     $mform->addHelpButton('typeid', 'external_tool_type', 'lti');
     foreach (lti_get_types_for_add_instance() as $id => $type) {
         if ($type->course == $COURSE->id) {
             $attributes = array('editable' => 1, 'courseTool' => 1, 'domain' => $type->tooldomain);
         } else {
             if ($id != 0) {
                 $attributes = array('globalTool' => 1, 'domain' => $type->tooldomain);
             } else {
                 $attributes = array();
             }
         }
         $tooltypes->addOption($type->name, $id, $attributes);
     }
     $mform->addElement('text', 'toolurl', get_string('launch_url', 'lti'), array('size' => '64'));
     $mform->setType('toolurl', PARAM_TEXT);
     $mform->addHelpButton('toolurl', 'launch_url', 'lti');
     $mform->addElement('text', 'securetoolurl', get_string('secure_launch_url', 'lti'), array('size' => '64'));
     $mform->setType('securetoolurl', PARAM_TEXT);
     $mform->setAdvanced('securetoolurl');
     $mform->addHelpButton('securetoolurl', 'secure_launch_url', 'lti');
     $mform->addElement('hidden', 'urlmatchedtypeid', '', array('id' => 'id_urlmatchedtypeid'));
     $mform->setType('urlmatchedtypeid', PARAM_INT);
     $launchoptions = array();
     $launchoptions[LTI_LAUNCH_CONTAINER_DEFAULT] = get_string('default', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_EMBED] = get_string('embed', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS] = get_string('embed_no_blocks', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_REPLACE_MOODLE_WINDOW] = get_string('existing_window', 'lti');
     $launchoptions[LTI_LAUNCH_CONTAINER_WINDOW] = get_string('new_window', 'lti');
     $mform->addElement('select', 'launchcontainer', get_string('launchinpopup', 'lti'), $launchoptions);
     $mform->setDefault('launchcontainer', LTI_LAUNCH_CONTAINER_DEFAULT);
     $mform->addHelpButton('launchcontainer', 'launchinpopup', 'lti');
     $mform->addElement('text', 'resourcekey', get_string('resourcekey', 'lti'));
     $mform->setType('resourcekey', PARAM_TEXT);
     $mform->setAdvanced('resourcekey');
     $mform->addHelpButton('resourcekey', 'resourcekey', 'lti');
     $mform->addElement('passwordunmask', 'password', get_string('password', 'lti'));
     $mform->setType('password', PARAM_TEXT);
     $mform->setAdvanced('password');
     $mform->addHelpButton('password', 'password', 'lti');
     $mform->addElement('textarea', 'instructorcustomparameters', get_string('custom', 'lti'), array('rows' => 4, 'cols' => 60));
     $mform->setType('instructorcustomparameters', PARAM_TEXT);
     $mform->setAdvanced('instructorcustomparameters');
     $mform->addHelpButton('instructorcustomparameters', 'custom', 'lti');
     $mform->addElement('text', 'icon', get_string('icon_url', 'lti'), array('size' => '64'));
     $mform->setType('icon', PARAM_TEXT);
     $mform->setAdvanced('icon');
     $mform->addHelpButton('icon', 'icon_url', 'lti');
     $mform->addElement('text', 'secureicon', get_string('secure_icon_url', 'lti'), array('size' => '64'));
     $mform->setType('secureicon', PARAM_TEXT);
     $mform->setAdvanced('secureicon');
     $mform->addHelpButton('secureicon', 'secure_icon_url', 'lti');
     //-------------------------------------------------------------------------------
     // Add privacy preferences fieldset where users choose whether to send their data
     $mform->addElement('header', 'privacy', get_string('privacy', 'lti'));
     $mform->addElement('advcheckbox', 'instructorchoicesendname', '&nbsp;', ' ' . get_string('share_name', 'lti'));
     $mform->setDefault('instructorchoicesendname', '1');
     $mform->addHelpButton('instructorchoicesendname', 'share_name', 'lti');
     $mform->addElement('advcheckbox', 'instructorchoicesendemailaddr', '&nbsp;', ' ' . get_string('share_email', 'lti'));
     $mform->setDefault('instructorchoicesendemailaddr', '1');
     $mform->addHelpButton('instructorchoicesendemailaddr', 'share_email', 'lti');
     $mform->addElement('advcheckbox', 'instructorchoiceacceptgrades', '&nbsp;', ' ' . get_string('accept_grades', 'lti'));
     $mform->setDefault('instructorchoiceacceptgrades', '1');
     $mform->addHelpButton('instructorchoiceacceptgrades', 'accept_grades', 'lti');
     //$mform->addElement('checkbox', 'instructorchoiceallowroster', '&nbsp;', ' ' . get_string('share_roster', 'lti'));
     //$mform->setDefault('instructorchoiceallowroster', '1');
     //$mform->addHelpButton('instructorchoiceallowroster', 'share_roster', 'lti');
     //-------------------------------------------------------------------------------
     /**
     $debugoptions=array();
     $debugoptions[0] = get_string('debuglaunchoff', 'lti');
     $debugoptions[1] = get_string('debuglaunchon', 'lti');
     
     $mform->addElement('select', 'debuglaunch', get_string('debuglaunch', 'lti'), $debugoptions);
     
     if (isset($this->typeconfig['debuglaunch'])) {
         if ($this->typeconfig['debuglaunch'] == 0) {
             $mform->setDefault('debuglaunch', '0');
         } else if ($this->typeconfig['debuglaunch'] == 1) {
             $mform->setDefault('debuglaunch', '1');
         }
     }
     */
     // Add standard course module grading elements.
     $this->standard_grading_coursemodule_elements();
     //-------------------------------------------------------------------------------
     // add standard elements, common to all modules
     $this->standard_coursemodule_elements();
     $mform->setAdvanced('cmidnumber');
     //-------------------------------------------------------------------------------
     // add standard buttons, common to all modules
     $this->add_action_buttons();
     $editurl = new moodle_url('/mod/lti/instructor_edit_tool_type.php', array('sesskey' => sesskey(), 'course' => $COURSE->id));
     $ajaxurl = new moodle_url('/mod/lti/ajax.php');
     $jsinfo = (object) array('edit_icon_url' => (string) $OUTPUT->pix_url('t/edit'), 'add_icon_url' => (string) $OUTPUT->pix_url('t/add'), 'delete_icon_url' => (string) $OUTPUT->pix_url('t/delete'), 'green_check_icon_url' => (string) $OUTPUT->pix_url('i/valid'), 'warning_icon_url' => (string) $OUTPUT->pix_url('warning', 'lti'), 'instructor_tool_type_edit_url' => $editurl->out(false), 'ajax_url' => $ajaxurl->out(true), 'courseId' => $COURSE->id);
     $module = array('name' => 'mod_lti_edit', 'fullpath' => '/mod/lti/mod_form.js', 'requires' => array('base', 'io', 'querystring-stringify-simple', 'node', 'event', 'json-parse'), 'strings' => array(array('addtype', 'lti'), array('edittype', 'lti'), array('deletetype', 'lti'), array('delete_confirmation', 'lti'), array('cannot_edit', 'lti'), array('cannot_delete', 'lti'), array('global_tool_types', 'lti'), array('course_tool_types', 'lti'), array('using_tool_configuration', 'lti'), array('domain_mismatch', 'lti'), array('custom_config', 'lti'), array('tool_config_not_found', 'lti'), array('forced_help', 'lti')));
     $PAGE->requires->js_init_call('M.mod_lti.editor.init', array(json_encode($jsinfo)), true, $module);
 }
示例#13
0
 /**
  * Test update_inplace_editable()
  */
 public function test_update_inplace_editable()
 {
     global $CFG, $DB, $PAGE;
     require_once $CFG->dirroot . '/lib/external/externallib.php';
     $this->resetAfterTest(true);
     $tag = $this->getDataGenerator()->create_tag();
     $this->setUser($this->getDataGenerator()->create_user());
     // Call service for core_tag component without necessary permissions.
     try {
         core_external::update_inplace_editable('core_tag', 'tagname', $tag->id, 'new tag name');
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertEquals('Sorry, but you do not currently have permissions to do that (Manage all tags)', $e->getMessage());
     }
     // Change to admin user and make sure that tag name can be updated using web service update_inplace_editable().
     $this->setAdminUser();
     $res = core_external::update_inplace_editable('core_tag', 'tagname', $tag->id, 'New tag name');
     $res = external_api::clean_returnvalue(core_external::update_inplace_editable_returns(), $res);
     $this->assertEquals('New tag name', $res['value']);
     $this->assertEquals('New tag name', $DB->get_field('tag', 'rawname', array('id' => $tag->id)));
     // Call callback core_tag_inplace_editable() directly.
     $tmpl = component_callback('core_tag', 'inplace_editable', array('tagname', $tag->id, 'Rename me again'));
     $this->assertInstanceOf('core\\output\\inplace_editable', $tmpl);
     $res = $tmpl->export_for_template($PAGE->get_renderer('core'));
     $this->assertEquals('Rename me again', $res['value']);
     $this->assertEquals('Rename me again', $DB->get_field('tag', 'rawname', array('id' => $tag->id)));
 }
示例#14
0
 /**
  * Is the gradebook accessible - i.e. are there any reports accessible to this user
  * @return bool
  */
 public static function gradebook_accessible($context)
 {
     global $COURSE;
     // Ask if user has not capabilities and if course is set to not to show the grades to students.
     if (!has_capability('gradereport/grader:view', $context) && $COURSE->showgrades == 0) {
         return false;
     }
     // Find all enabled reports.
     $reports = core_component::get_plugin_list('gradereport');
     foreach (array_keys($reports) as $report) {
         if (!component_callback('gradereport_' . $report, 'is_enabled', array(), true)) {
             unset($reports[$report]);
         }
     }
     // Reduce reports list down to just those accessible to user.
     foreach ($reports as $plugin => $plugindir) {
         // Remove ones we can't see.
         if (!has_capability('gradereport/' . $plugin . ':view', $context)) {
             unset($reports[$plugin]);
         }
     }
     return !empty($reports);
 }
示例#15
0
 /**
  * Get a HTML fragment for inserting into something. Initial use is for inserting mforms into
  * a page using AJAX.
  * This web service is designed to be called only via AJAX and not directly.
  * Callbacks that are called by this web service are responsible for doing the appropriate security checks
  * to access the information returned. This only does minimal validation on the context.
  *
  * @param string $component Name of the component.
  * @param string $callback Function callback name.
  * @param int $contextid Context ID this fragment is in.
  * @param array $args optional arguments for the callback.
  * @return array HTML and JavaScript fragments for insertion into stuff.
  * @since Moodle 3.1
  */
 public static function get_fragment($component, $callback, $contextid, $args = null)
 {
     global $OUTPUT, $PAGE;
     $params = self::validate_parameters(self::get_fragment_parameters(), array('component' => $component, 'callback' => $callback, 'contextid' => $contextid, 'args' => $args));
     // Reformat arguments into something less unwieldy.
     $arguments = array();
     foreach ($params['args'] as $paramargument) {
         $arguments[$paramargument['name']] = $paramargument['value'];
     }
     $context = context::instance_by_id($contextid);
     self::validate_context($context);
     // Hack alert: Forcing bootstrap_renderer to initiate moodle page.
     $OUTPUT->header();
     // Overwriting page_requirements_manager with the fragment one so only JS included from
     // this point is returned to the user.
     $PAGE->start_collecting_javascript_requirements();
     $data = component_callback($params['component'], 'output_fragment_' . $params['callback'], $arguments);
     $jsfooter = $PAGE->requires->get_end_code();
     $output = array('html' => $data, 'javascript' => $jsfooter);
     return $output;
 }
示例#16
0
 /**
  * Is the gradebook accessible - i.e. are there any reports accessible to this user
  * @return bool
  */
 public static function gradebook_accessible($context)
 {
     // Find all enabled reports.
     $reports = core_component::get_plugin_list('gradereport');
     foreach (array_keys($reports) as $report) {
         if (!component_callback('gradereport_' . $report, 'is_enabled', array(), true)) {
             unset($reports[$report]);
         }
     }
     // Reduce reports list down to just those accessible to user.
     foreach ($reports as $plugin => $plugindir) {
         // Remove ones we can't see.
         if (!has_capability('gradereport/' . $plugin . ':view', $context)) {
             unset($reports[$plugin]);
         }
     }
     return !empty($reports);
 }
示例#17
0
 /**
  * Test callback updating section name
  */
 public function test_inplace_editable()
 {
     global $CFG, $DB, $PAGE;
     $this->resetAfterTest();
     $user = $this->getDataGenerator()->create_user();
     $course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'weeks'), array('createsections' => true));
     $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
     $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
     $this->setUser($user);
     $section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
     // Call callback format_weeks_inplace_editable() directly.
     $tmpl = component_callback('format_weeks', 'inplace_editable', array('sectionname', $section->id, 'Rename me again'));
     $this->assertInstanceOf('core\\output\\inplace_editable', $tmpl);
     $res = $tmpl->export_for_template($PAGE->get_renderer('core'));
     $this->assertEquals('Rename me again', $res['value']);
     $this->assertEquals('Rename me again', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
     // Try updating using callback from mismatching course format.
     try {
         $tmpl = component_callback('format_topics', 'inplace_editable', array('sectionname', $section->id, 'New name'));
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertEquals(1, preg_match('/^Can not find data record in database/', $e->getMessage()));
     }
 }
示例#18
0
/**
 * Builds a standard LTI Content-Item selection request.
 *
 * @param int $id The tool type ID.
 * @param stdClass $course The course object.
 * @param moodle_url $returnurl The return URL in the tool consumer (TC) that the tool provider (TP)
 *                              will use to return the Content-Item message.
 * @param string $title The tool's title, if available.
 * @param string $text The text to display to represent the content item. This value may be a long description of the content item.
 * @param array $mediatypes Array of MIME types types supported by the TC. If empty, the TC will support ltilink by default.
 * @param array $presentationtargets Array of ways in which the selected content item(s) can be requested to be opened
 *                                   (via the presentationDocumentTarget element for a returned content item).
 *                                   If empty, "frame", "iframe", and "window" will be supported by default.
 * @param bool $autocreate Indicates whether any content items returned by the TP would be automatically persisted without
 * @param bool $multiple Indicates whether the user should be permitted to select more than one item. False by default.
 *                         any option for the user to cancel the operation. False by default.
 * @param bool $unsigned Indicates whether the TC is willing to accept an unsigned return message, or not.
 *                       A signed message should always be required when the content item is being created automatically in the
 *                       TC without further interaction from the user. False by default.
 * @param bool $canconfirm Flag for can_confirm parameter. False by default.
 * @param bool $copyadvice Indicates whether the TC is able and willing to make a local copy of a content item. False by default.
 * @return stdClass The object containing the signed request parameters and the URL to the TP's Content-Item selection interface.
 * @throws moodle_exception When the LTI tool type does not exist.`
 * @throws coding_exception For invalid media type and presentation target parameters.
 */
function lti_build_content_item_selection_request($id, $course, moodle_url $returnurl, $title = '', $text = '', $mediatypes = [], $presentationtargets = [], $autocreate = false, $multiple = false, $unsigned = false, $canconfirm = false, $copyadvice = false)
{
    $tool = lti_get_type($id);
    // Validate parameters.
    if (!$tool) {
        throw new moodle_exception('errortooltypenotfound', 'mod_lti');
    }
    if (!is_array($mediatypes)) {
        throw new coding_exception('The list of accepted media types should be in an array');
    }
    if (!is_array($presentationtargets)) {
        throw new coding_exception('The list of accepted presentation targets should be in an array');
    }
    // Check title. If empty, use the tool's name.
    if (empty($title)) {
        $title = $tool->name;
    }
    $typeconfig = lti_get_type_config($id);
    $key = '';
    $secret = '';
    $islti2 = false;
    if (isset($tool->toolproxyid)) {
        $islti2 = true;
        $toolproxy = lti_get_tool_proxy($tool->toolproxyid);
        $key = $toolproxy->guid;
        $secret = $toolproxy->secret;
    } else {
        $toolproxy = null;
        if (!empty($typeconfig['resourcekey'])) {
            $key = $typeconfig['resourcekey'];
        }
        if (!empty($typeconfig['password'])) {
            $secret = $typeconfig['password'];
        }
    }
    $tool->enabledcapability = '';
    if (!empty($typeconfig['enabledcapability_ContentItemSelectionRequest'])) {
        $tool->enabledcapability = $typeconfig['enabledcapability_ContentItemSelectionRequest'];
    }
    $tool->parameter = '';
    if (!empty($typeconfig['parameter_ContentItemSelectionRequest'])) {
        $tool->parameter = $typeconfig['parameter_ContentItemSelectionRequest'];
    }
    // Set the tool URL.
    if (!empty($typeconfig['toolurl_ContentItemSelectionRequest'])) {
        $toolurl = new moodle_url($typeconfig['toolurl_ContentItemSelectionRequest']);
    } else {
        $toolurl = new moodle_url($typeconfig['toolurl']);
    }
    // Check if SSL is forced.
    if (!empty($typeconfig['forcessl'])) {
        // Make sure the tool URL is set to https.
        if (strtolower($toolurl->get_scheme()) === 'http') {
            $toolurl->set_scheme('https');
        }
        // Make sure the return URL is set to https.
        if (strtolower($returnurl->get_scheme()) === 'http') {
            $returnurl->set_scheme('https');
        }
    }
    $toolurlout = $toolurl->out(false);
    // Get base request parameters.
    $instance = new stdClass();
    $instance->course = $course->id;
    $requestparams = lti_build_request($instance, $typeconfig, $course, $id, $islti2);
    // Get LTI2-specific request parameters and merge to the request parameters if applicable.
    if ($islti2) {
        $lti2params = lti_build_request_lti2($tool, $requestparams);
        $requestparams = array_merge($requestparams, $lti2params);
    }
    // Get standard request parameters and merge to the request parameters.
    $orgid = !empty($typeconfig['organizationid']) ? $typeconfig['organizationid'] : '';
    $standardparams = lti_build_standard_request(null, $orgid, $islti2, 'ContentItemSelectionRequest');
    $requestparams = array_merge($requestparams, $standardparams);
    // Get custom request parameters and merge to the request parameters.
    $customstr = '';
    if (!empty($typeconfig['customparameters'])) {
        $customstr = $typeconfig['customparameters'];
    }
    $customparams = lti_build_custom_parameters($toolproxy, $tool, $instance, $requestparams, $customstr, '', $islti2);
    $requestparams = array_merge($requestparams, $customparams);
    // Allow request params to be updated by sub-plugins.
    $plugins = core_component::get_plugin_list('ltisource');
    foreach (array_keys($plugins) as $plugin) {
        $pluginparams = component_callback('ltisource_' . $plugin, 'before_launch', [$instance, $toolurlout, $requestparams], []);
        if (!empty($pluginparams) && is_array($pluginparams)) {
            $requestparams = array_merge($requestparams, $pluginparams);
        }
    }
    // Media types. Set to ltilink by default if empty.
    if (empty($mediatypes)) {
        $mediatypes = ['application/vnd.ims.lti.v1.ltilink'];
    }
    $requestparams['accept_media_types'] = implode(',', $mediatypes);
    // Presentation targets. Supports frame, iframe, window by default if empty.
    if (empty($presentationtargets)) {
        $presentationtargets = ['frame', 'iframe', 'window'];
    }
    $requestparams['accept_presentation_document_targets'] = implode(',', $presentationtargets);
    // Other request parameters.
    $requestparams['accept_copy_advice'] = $copyadvice === true ? 'true' : 'false';
    $requestparams['accept_multiple'] = $multiple === true ? 'true' : 'false';
    $requestparams['accept_unsigned'] = $unsigned === true ? 'true' : 'false';
    $requestparams['auto_create'] = $autocreate === true ? 'true' : 'false';
    $requestparams['can_confirm'] = $canconfirm === true ? 'true' : 'false';
    $requestparams['content_item_return_url'] = $returnurl->out(false);
    $requestparams['title'] = $title;
    $requestparams['text'] = $text;
    $signedparams = lti_sign_parameters($requestparams, $toolurlout, 'POST', $key, $secret);
    $toolurlparams = $toolurl->params();
    // Strip querystring params in endpoint url from $signedparams to avoid duplication.
    if (!empty($toolurlparams) && !empty($signedparams)) {
        foreach (array_keys($toolurlparams) as $paramname) {
            if (isset($signedparams[$paramname])) {
                unset($signedparams[$paramname]);
            }
        }
    }
    // Check for params that should not be passed. Unset if they are set.
    $unwantedparams = ['resource_link_id', 'resource_link_title', 'resource_link_description', 'launch_presentation_return_url', 'lis_result_sourcedid'];
    foreach ($unwantedparams as $param) {
        if (isset($signedparams[$param])) {
            unset($signedparams[$param]);
        }
    }
    // Prepare result object.
    $result = new stdClass();
    $result->params = $signedparams;
    $result->url = $toolurlout;
    return $result;
}
示例#19
0
 /**
  * Returns list of recent activity within modules
  *
  * For each used module type executes callback MODULE_print_recent_activity()
  *
  * @return array array of pairs moduletype => content
  */
 protected function get_modules_recent_activity()
 {
     $context = context_course::instance($this->page->course->id);
     $viewfullnames = has_capability('moodle/site:viewfullnames', $context);
     $hascontent = false;
     $modinfo = get_fast_modinfo($this->page->course);
     $usedmodules = $modinfo->get_used_module_names();
     $recentactivity = array();
     foreach ($usedmodules as $modname => $modfullname) {
         // Each module gets it's own logs and prints them
         ob_start();
         $hascontent = component_callback('mod_' . $modname, 'print_recent_activity', array($this->page->course, $viewfullnames, $this->get_timestart()), false);
         if ($hascontent) {
             $recentactivity[$modname] = ob_get_contents();
         }
         ob_end_clean();
     }
     return $recentactivity;
 }
示例#20
0
文件: modlib.php 项目: evltuma/moodle
/**
 * Update the module info.
 * This function doesn't check the user capabilities. It updates the course module and the module instance.
 * Then execute common action to create/update module process (trigger event, rebuild cache, save plagiarism settings...).
 *
 * @param object $cm course module
 * @param object $moduleinfo module info
 * @param object $course course of the module
 * @param object $mform - the mform is required by some specific module in the function MODULE_update_instance(). This is due to a hack in this function.
 * @return array list of course module and module info.
 */
function update_moduleinfo($cm, $moduleinfo, $course, $mform = null)
{
    global $DB, $CFG;
    $data = new stdClass();
    if ($mform) {
        $data = $mform->get_data();
    }
    // Attempt to include module library before we make any changes to DB.
    include_modulelib($moduleinfo->modulename);
    $moduleinfo->course = $course->id;
    $moduleinfo = set_moduleinfo_defaults($moduleinfo);
    if (!empty($course->groupmodeforce) or !isset($moduleinfo->groupmode)) {
        $moduleinfo->groupmode = $cm->groupmode;
        // Keep original.
    }
    // Update course module first.
    $cm->groupmode = $moduleinfo->groupmode;
    if (isset($moduleinfo->groupingid)) {
        $cm->groupingid = $moduleinfo->groupingid;
    }
    $completion = new completion_info($course);
    if ($completion->is_enabled()) {
        // Completion settings that would affect users who have already completed
        // the activity may be locked; if so, these should not be updated.
        if (!empty($moduleinfo->completionunlocked)) {
            $cm->completion = $moduleinfo->completion;
            $cm->completiongradeitemnumber = $moduleinfo->completiongradeitemnumber;
            $cm->completionview = $moduleinfo->completionview;
        }
        // The expected date does not affect users who have completed the activity,
        // so it is safe to update it regardless of the lock status.
        $cm->completionexpected = $moduleinfo->completionexpected;
    }
    if (!empty($CFG->enableavailability)) {
        // This code is used both when submitting the form, which uses a long
        // name to avoid clashes, and by unit test code which uses the real
        // name in the table.
        if (property_exists($moduleinfo, 'availabilityconditionsjson')) {
            if ($moduleinfo->availabilityconditionsjson !== '') {
                $cm->availability = $moduleinfo->availabilityconditionsjson;
            } else {
                $cm->availability = null;
            }
        } else {
            if (property_exists($moduleinfo, 'availability')) {
                $cm->availability = $moduleinfo->availability;
            }
        }
        // If there is any availability data, verify it.
        if ($cm->availability) {
            $tree = new \core_availability\tree(json_decode($cm->availability));
            // Save time and database space by setting null if the only data
            // is an empty tree.
            if ($tree->is_empty()) {
                $cm->availability = null;
            }
        }
    }
    if (isset($moduleinfo->showdescription)) {
        $cm->showdescription = $moduleinfo->showdescription;
    } else {
        $cm->showdescription = 0;
    }
    $DB->update_record('course_modules', $cm);
    $modcontext = context_module::instance($moduleinfo->coursemodule);
    // Update embedded links and save files.
    if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) {
        $moduleinfo->intro = file_save_draft_area_files($moduleinfo->introeditor['itemid'], $modcontext->id, 'mod_' . $moduleinfo->modulename, 'intro', 0, array('subdirs' => true), $moduleinfo->introeditor['text']);
        $moduleinfo->introformat = $moduleinfo->introeditor['format'];
        unset($moduleinfo->introeditor);
    }
    // Get the a copy of the grade_item before it is modified incase we need to scale the grades.
    $oldgradeitem = null;
    $newgradeitem = null;
    if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') {
        // Fetch the grade item before it is updated.
        $oldgradeitem = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => $moduleinfo->modulename, 'iteminstance' => $moduleinfo->instance, 'itemnumber' => 0, 'courseid' => $moduleinfo->course));
    }
    $updateinstancefunction = $moduleinfo->modulename . "_update_instance";
    if (!$updateinstancefunction($moduleinfo, $mform)) {
        print_error('cannotupdatemod', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
    }
    // This needs to happen AFTER the grademin/grademax have already been updated.
    if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') {
        // Get the grade_item after the update call the activity to scale the grades.
        $newgradeitem = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => $moduleinfo->modulename, 'iteminstance' => $moduleinfo->instance, 'itemnumber' => 0, 'courseid' => $moduleinfo->course));
        if ($newgradeitem && $oldgradeitem->gradetype == GRADE_TYPE_VALUE && $newgradeitem->gradetype == GRADE_TYPE_VALUE) {
            $params = array($course, $cm, $oldgradeitem->grademin, $oldgradeitem->grademax, $newgradeitem->grademin, $newgradeitem->grademax);
            if (!component_callback('mod_' . $moduleinfo->modulename, 'rescale_activity_grades', $params)) {
                print_error('cannotreprocessgrades', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
            }
        }
    }
    // Make sure visibility is set correctly (in particular in calendar).
    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
        set_coursemodule_visible($moduleinfo->coursemodule, $moduleinfo->visible);
    }
    if (isset($moduleinfo->cmidnumber)) {
        // Label.
        // Set cm idnumber - uniqueness is already verified by form validation.
        set_coursemodule_idnumber($moduleinfo->coursemodule, $moduleinfo->cmidnumber);
    }
    // Update module tags.
    if (core_tag_tag::is_enabled('core', 'course_modules') && isset($moduleinfo->tags)) {
        core_tag_tag::set_item_tags('core', 'course_modules', $moduleinfo->coursemodule, $modcontext, $moduleinfo->tags);
    }
    // Now that module is fully updated, also update completion data if required.
    // (this will wipe all user completion data and recalculate it)
    if ($completion->is_enabled() && !empty($moduleinfo->completionunlocked)) {
        $completion->reset_all_state($cm);
    }
    $cm->name = $moduleinfo->name;
    \core\event\course_module_updated::create_from_cm($cm, $modcontext)->trigger();
    $moduleinfo = edit_module_post_actions($moduleinfo, $course);
    return array($cm, $moduleinfo);
}
示例#21
0
 /**
  * Use this editor for given element.
  *
  * @param string $elementid
  * @param array $options
  * @param null $fpoptions
  */
 public function use_editor($elementid, array $options = null, $fpoptions = null)
 {
     global $PAGE;
     $configstr = get_config('editor_atto', 'toolbar');
     $grouplines = explode("\n", $configstr);
     $groups = array();
     foreach ($grouplines as $groupline) {
         $line = explode('=', $groupline);
         if (count($line) > 1) {
             $group = trim(array_shift($line));
             $plugins = array_map('trim', explode(',', array_shift($line)));
             $groups[$group] = $plugins;
         }
     }
     $modules = array('moodle-editor_atto-editor');
     $options['context'] = empty($options['context']) ? context_system::instance() : $options['context'];
     $jsplugins = array();
     foreach ($groups as $group => $plugins) {
         $groupplugins = array();
         foreach ($plugins as $plugin) {
             // Do not die on missing plugin.
             if (!core_component::get_component_directory('atto_' . $plugin)) {
                 continue;
             }
             $jsplugin = array();
             $jsplugin['name'] = $plugin;
             $jsplugin['params'] = array();
             $modules[] = 'moodle-atto_' . $plugin . '-button';
             component_callback('atto_' . $plugin, 'strings_for_js');
             $extra = component_callback('atto_' . $plugin, 'params_for_js', array($elementid, $options, $fpoptions));
             if ($extra) {
                 $jsplugin = array_merge($jsplugin, $extra);
             }
             // We always need the plugin name.
             $PAGE->requires->string_for_js('pluginname', 'atto_' . $plugin);
             $groupplugins[] = $jsplugin;
         }
         $jsplugins[] = array('group' => $group, 'plugins' => $groupplugins);
     }
     $PAGE->requires->strings_for_js(array('editor_command_keycode', 'editor_control_keycode', 'plugin_title_shortcut', 'textrecovered', 'autosavefailed', 'autosavesucceeded', 'errortextrecovery'), 'editor_atto');
     $PAGE->requires->strings_for_js(array('warning', 'info'), 'moodle');
     $PAGE->requires->yui_module($modules, 'Y.M.editor_atto.Editor.init', array($this->get_init_params($elementid, $options, $fpoptions, $jsplugins)));
 }
示例#22
0
 /**
  * Update any component's editable value assuming that component implements necessary callback
  *
  * @since Moodle 3.1
  * @param string $component
  * @param string $itemtype
  * @param string $itemid
  * @param string $value
  */
 public static function update_inplace_editable($component, $itemtype, $itemid, $value)
 {
     global $PAGE;
     // Validate and normalize parameters.
     $params = self::validate_parameters(self::update_inplace_editable_parameters(), array('component' => $component, 'itemtype' => $itemtype, 'itemid' => $itemid, 'value' => $value));
     if (!($functionname = component_callback_exists($component, 'inplace_editable'))) {
         throw new \moodle_exception('inplaceeditableerror');
     }
     $tmpl = component_callback($params['component'], 'inplace_editable', array($params['itemtype'], $params['itemid'], $params['value']));
     if (!$tmpl || !$tmpl instanceof \core\output\inplace_editable) {
         throw new \moodle_exception('inplaceeditableerror');
     }
     $PAGE->set_context(null);
     // To prevent warning if context was not set in the callback.
     return $tmpl->export_for_template($PAGE->get_renderer('core'));
 }
示例#23
0
/**
 * Called by pluginfile.php to serve files related to the 'question' core
 * component and for files belonging to qtypes.
 *
 * For files that relate to questions in a question_attempt, then we delegate to
 * a function in the component that owns the attempt (for example in the quiz,
 * or in core question preview) to get necessary inforation.
 *
 * (Note that, at the moment, all question file areas relate to questions in
 * attempts, so the If at the start of the last paragraph is always true.)
 *
 * Does not return, either calls send_file_not_found(); or serves the file.
 *
 * @package  core_question
 * @category files
 * @param stdClass $course course settings object
 * @param stdClass $context context object
 * @param string $component the name of the component we are serving files for.
 * @param string $filearea the name of the file area.
 * @param array $args the remaining bits of the file path.
 * @param bool $forcedownload whether the user must be forced to download the file.
 * @param array $options additional options affecting the file serving
 */
function question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload, array $options = array())
{
    global $DB, $CFG;
    // Special case, sending a question bank export.
    if ($filearea === 'export') {
        list($context, $course, $cm) = get_context_info_array($context->id);
        require_login($course, false, $cm);
        require_once $CFG->dirroot . '/question/editlib.php';
        $contexts = new question_edit_contexts($context);
        // check export capability
        $contexts->require_one_edit_tab_cap('export');
        $category_id = (int) array_shift($args);
        $format = array_shift($args);
        $cattofile = array_shift($args);
        $contexttofile = array_shift($args);
        $filename = array_shift($args);
        // load parent class for import/export
        require_once $CFG->dirroot . '/question/format.php';
        require_once $CFG->dirroot . '/question/editlib.php';
        require_once $CFG->dirroot . '/question/format/' . $format . '/format.php';
        $classname = 'qformat_' . $format;
        if (!class_exists($classname)) {
            send_file_not_found();
        }
        $qformat = new $classname();
        if (!($category = $DB->get_record('question_categories', array('id' => $category_id)))) {
            send_file_not_found();
        }
        $qformat->setCategory($category);
        $qformat->setContexts($contexts->having_one_edit_tab_cap('export'));
        $qformat->setCourse($course);
        if ($cattofile == 'withcategories') {
            $qformat->setCattofile(true);
        } else {
            $qformat->setCattofile(false);
        }
        if ($contexttofile == 'withcontexts') {
            $qformat->setContexttofile(true);
        } else {
            $qformat->setContexttofile(false);
        }
        if (!$qformat->exportpreprocess()) {
            send_file_not_found();
            print_error('exporterror', 'question', $thispageurl->out());
        }
        // export data to moodle file pool
        if (!($content = $qformat->exportprocess(true))) {
            send_file_not_found();
        }
        send_file($content, $filename, 0, 0, true, true, $qformat->mime_type());
    }
    // Normal case, a file belonging to a question.
    $qubaidorpreview = array_shift($args);
    // Two sub-cases: 1. A question being previewed outside an attempt/usage.
    if ($qubaidorpreview === 'preview') {
        $previewcontextid = (int) array_shift($args);
        $previewcomponent = array_shift($args);
        $questionid = (int) array_shift($args);
        $previewcontext = context_helper::instance_by_id($previewcontextid);
        $result = component_callback($previewcomponent, 'question_preview_pluginfile', array($previewcontext, $questionid, $context, $component, $filearea, $args, $forcedownload, $options), 'newcallbackmissing');
        if ($result === 'newcallbackmissing' && ($filearea = 'questiontext')) {
            // Fall back to the legacy callback for backwards compatibility.
            debugging("Component {$previewcomponent} does not define the expected " . "{$previewcomponent}_question_preview_pluginfile callback. Falling back to the deprecated " . "{$previewcomponent}_questiontext_preview_pluginfile callback.", DEBUG_DEVELOPER);
            component_callback($previewcomponent, 'questiontext_preview_pluginfile', array($previewcontext, $questionid, $args, $forcedownload, $options));
        }
        send_file_not_found();
    }
    // 2. A question being attempted in the normal way.
    $qubaid = (int) $qubaidorpreview;
    $slot = (int) array_shift($args);
    $module = $DB->get_field('question_usages', 'component', array('id' => $qubaid));
    if ($module === 'core_question_preview') {
        require_once $CFG->dirroot . '/question/previewlib.php';
        return question_preview_question_pluginfile($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
    } else {
        $dir = core_component::get_component_directory($module);
        if (!file_exists("{$dir}/lib.php")) {
            send_file_not_found();
        }
        include_once "{$dir}/lib.php";
        $filefunction = $module . '_question_pluginfile';
        if (function_exists($filefunction)) {
            $filefunction($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
        }
        // Okay, we're here so lets check for function without 'mod_'.
        if (strpos($module, 'mod_') === 0) {
            $filefunctionold = substr($module, 4) . '_question_pluginfile';
            if (function_exists($filefunctionold)) {
                $filefunctionold($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
            }
        }
        send_file_not_found();
    }
}
示例#24
0
/**
 * Return the launch data required for opening the external tool.
 *
 * @param  stdClass $instance the external tool activity settings
 * @return array the endpoint URL and parameters (including the signature)
 * @since  Moodle 3.0
 */
function lti_get_launch_data($instance)
{
    global $PAGE, $CFG;
    if (empty($instance->typeid)) {
        $tool = lti_get_tool_by_url_match($instance->toolurl, $instance->course);
        if ($tool) {
            $typeid = $tool->id;
        } else {
            $typeid = null;
        }
    } else {
        $typeid = $instance->typeid;
        $tool = lti_get_type($typeid);
    }
    if ($typeid) {
        $typeconfig = lti_get_type_config($typeid);
    } else {
        // There is no admin configuration for this tool. Use configuration in the lti instance record plus some defaults.
        $typeconfig = (array) $instance;
        $typeconfig['sendname'] = $instance->instructorchoicesendname;
        $typeconfig['sendemailaddr'] = $instance->instructorchoicesendemailaddr;
        $typeconfig['customparameters'] = $instance->instructorcustomparameters;
        $typeconfig['acceptgrades'] = $instance->instructorchoiceacceptgrades;
        $typeconfig['allowroster'] = $instance->instructorchoiceallowroster;
        $typeconfig['forcessl'] = '0';
    }
    // Default the organizationid if not specified.
    if (empty($typeconfig['organizationid'])) {
        $urlparts = parse_url($CFG->wwwroot);
        $typeconfig['organizationid'] = $urlparts['host'];
    }
    if (isset($tool->toolproxyid)) {
        $toolproxy = lti_get_tool_proxy($tool->toolproxyid);
        $key = $toolproxy->guid;
        $secret = $toolproxy->secret;
    } else {
        $toolproxy = null;
        if (!empty($instance->resourcekey)) {
            $key = $instance->resourcekey;
        } else {
            if (!empty($typeconfig['resourcekey'])) {
                $key = $typeconfig['resourcekey'];
            } else {
                $key = '';
            }
        }
        if (!empty($instance->password)) {
            $secret = $instance->password;
        } else {
            if (!empty($typeconfig['password'])) {
                $secret = $typeconfig['password'];
            } else {
                $secret = '';
            }
        }
    }
    $endpoint = !empty($instance->toolurl) ? $instance->toolurl : $typeconfig['toolurl'];
    $endpoint = trim($endpoint);
    // If the current request is using SSL and a secure tool URL is specified, use it.
    if (lti_request_is_using_ssl() && !empty($instance->securetoolurl)) {
        $endpoint = trim($instance->securetoolurl);
    }
    // If SSL is forced, use the secure tool url if specified. Otherwise, make sure https is on the normal launch URL.
    if (isset($typeconfig['forcessl']) && $typeconfig['forcessl'] == '1') {
        if (!empty($instance->securetoolurl)) {
            $endpoint = trim($instance->securetoolurl);
        }
        $endpoint = lti_ensure_url_is_https($endpoint);
    } else {
        if (!strstr($endpoint, '://')) {
            $endpoint = 'http://' . $endpoint;
        }
    }
    $orgid = $typeconfig['organizationid'];
    $course = $PAGE->course;
    $islti2 = isset($tool->toolproxyid);
    $allparams = lti_build_request($instance, $typeconfig, $course, $typeid, $islti2);
    if ($islti2) {
        $requestparams = lti_build_request_lti2($tool, $allparams);
    } else {
        $requestparams = $allparams;
    }
    $requestparams = array_merge($requestparams, lti_build_standard_request($instance, $orgid, $islti2));
    $customstr = '';
    if (isset($typeconfig['customparameters'])) {
        $customstr = $typeconfig['customparameters'];
    }
    $requestparams = array_merge($requestparams, lti_build_custom_parameters($toolproxy, $tool, $instance, $allparams, $customstr, $instance->instructorcustomparameters, $islti2));
    $launchcontainer = lti_get_launch_container($instance, $typeconfig);
    $returnurlparams = array('course' => $course->id, 'launch_container' => $launchcontainer, 'instanceid' => $instance->id, 'sesskey' => sesskey());
    // Add the return URL. We send the launch container along to help us avoid frames-within-frames when the user returns.
    $url = new \moodle_url('/mod/lti/return.php', $returnurlparams);
    $returnurl = $url->out(false);
    if (isset($typeconfig['forcessl']) && $typeconfig['forcessl'] == '1') {
        $returnurl = lti_ensure_url_is_https($returnurl);
    }
    $target = '';
    switch ($launchcontainer) {
        case LTI_LAUNCH_CONTAINER_EMBED:
        case LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS:
            $target = 'iframe';
            break;
        case LTI_LAUNCH_CONTAINER_REPLACE_MOODLE_WINDOW:
            $target = 'frame';
            break;
        case LTI_LAUNCH_CONTAINER_WINDOW:
            $target = 'window';
            break;
    }
    if (!empty($target)) {
        $requestparams['launch_presentation_document_target'] = $target;
    }
    $requestparams['launch_presentation_return_url'] = $returnurl;
    // Allow request params to be updated by sub-plugins.
    $plugins = core_component::get_plugin_list('ltisource');
    foreach (array_keys($plugins) as $plugin) {
        $pluginparams = component_callback('ltisource_' . $plugin, 'before_launch', array($instance, $endpoint, $requestparams), array());
        if (!empty($pluginparams) && is_array($pluginparams)) {
            $requestparams = array_merge($requestparams, $pluginparams);
        }
    }
    if (!empty($key) && !empty($secret)) {
        $parms = lti_sign_parameters($requestparams, $endpoint, "POST", $key, $secret);
        $endpointurl = new \moodle_url($endpoint);
        $endpointparams = $endpointurl->params();
        // Strip querystring params in endpoint url from $parms to avoid duplication.
        if (!empty($endpointparams) && !empty($parms)) {
            foreach (array_keys($endpointparams) as $paramname) {
                if (isset($parms[$paramname])) {
                    unset($parms[$paramname]);
                }
            }
        }
    } else {
        // If no key and secret, do the launch unsigned.
        $returnurlparams['unsigned'] = '1';
        $parms = $requestparams;
    }
    return array($endpoint, $parms);
}
示例#25
0
/**
 * Invoke plugin's callback functions
 *
 * @param string $type plugin type e.g. 'mod'
 * @param string $name plugin name
 * @param string $feature feature name
 * @param string $action feature's action
 * @param array $params parameters of callback function, should be an array
 * @param mixed $default default value if callback function hasn't been defined, or if it retursn null.
 * @return mixed
 *
 * @todo Decide about to deprecate and drop plugin_callback() - MDL-30743
 */
function plugin_callback($type, $name, $feature, $action, $params = null, $default = null)
{
    return component_callback($type . '_' . $name, $feature . '_' . $action, (array) $params, $default);
}
示例#26
0
/**
 * Called by pluginfile.php to serve files related to the 'question' core
 * component and for files belonging to qtypes.
 *
 * For files that relate to questions in a question_attempt, then we delegate to
 * a function in the component that owns the attempt (for example in the quiz,
 * or in core question preview) to get necessary inforation.
 *
 * (Note that, at the moment, all question file areas relate to questions in
 * attempts, so the If at the start of the last paragraph is always true.)
 *
 * Does not return, either calls send_file_not_found(); or serves the file.
 *
 * @package  core_question
 * @category files
 * @param stdClass $course course settings object
 * @param stdClass $context context object
 * @param string $component the name of the component we are serving files for.
 * @param string $filearea the name of the file area.
 * @param array $args the remaining bits of the file path.
 * @param bool $forcedownload whether the user must be forced to download the file.
 */
function question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload)
{
    global $DB, $CFG;
    if ($filearea === 'questiontext_preview') {
        $component = array_shift($args);
        $questionid = array_shift($args);
        component_callback($component, 'questiontext_preview_pluginfile', array($context, $questionid, $args, $forcedownload));
        send_file_not_found();
    }
    list($context, $course, $cm) = get_context_info_array($context->id);
    require_login($course, false, $cm);
    if ($filearea === 'export') {
        require_once $CFG->dirroot . '/question/editlib.php';
        $contexts = new question_edit_contexts($context);
        // check export capability
        $contexts->require_one_edit_tab_cap('export');
        $category_id = (int) array_shift($args);
        $format = array_shift($args);
        $cattofile = array_shift($args);
        $contexttofile = array_shift($args);
        $filename = array_shift($args);
        // load parent class for import/export
        require_once $CFG->dirroot . '/question/format.php';
        require_once $CFG->dirroot . '/question/editlib.php';
        require_once $CFG->dirroot . '/question/format/' . $format . '/format.php';
        $classname = 'qformat_' . $format;
        if (!class_exists($classname)) {
            send_file_not_found();
        }
        $qformat = new $classname();
        if (!($category = $DB->get_record('question_categories', array('id' => $category_id)))) {
            send_file_not_found();
        }
        $qformat->setCategory($category);
        $qformat->setContexts($contexts->having_one_edit_tab_cap('export'));
        $qformat->setCourse($course);
        if ($cattofile == 'withcategories') {
            $qformat->setCattofile(true);
        } else {
            $qformat->setCattofile(false);
        }
        if ($contexttofile == 'withcontexts') {
            $qformat->setContexttofile(true);
        } else {
            $qformat->setContexttofile(false);
        }
        if (!$qformat->exportpreprocess()) {
            send_file_not_found();
            print_error('exporterror', 'question', $thispageurl->out());
        }
        // export data to moodle file pool
        if (!($content = $qformat->exportprocess(true))) {
            send_file_not_found();
        }
        send_file($content, $filename, 0, 0, true, true, $qformat->mime_type());
    }
    $qubaid = (int) array_shift($args);
    $slot = (int) array_shift($args);
    $module = $DB->get_field('question_usages', 'component', array('id' => $qubaid));
    if ($module === 'core_question_preview') {
        require_once $CFG->dirroot . '/question/previewlib.php';
        return question_preview_question_pluginfile($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload);
    } else {
        $dir = get_component_directory($module);
        if (!file_exists("{$dir}/lib.php")) {
            send_file_not_found();
        }
        include_once "{$dir}/lib.php";
        $filefunction = $module . '_question_pluginfile';
        if (!function_exists($filefunction)) {
            send_file_not_found();
        }
        $filefunction($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload);
        send_file_not_found();
    }
}
示例#27
0
 /**
  * Assign roles
  *
  * This has to be called after enrolments processing.
  *
  * @param mixed $data
  * @return void
  */
 public function process_assignment($data)
 {
     global $DB;
     $data = (object) $data;
     // Check roleid, userid are one of the mapped ones
     if (!($newroleid = $this->get_mappingid('role', $data->roleid))) {
         return;
     }
     if (!($newuserid = $this->get_mappingid('user', $data->userid))) {
         return;
     }
     if (!$DB->record_exists('user', array('id' => $newuserid, 'deleted' => 0))) {
         // Only assign roles to not deleted users
         return;
     }
     if (!($contextid = $this->task->get_contextid())) {
         return;
     }
     if (empty($data->component)) {
         // assign standard manual roles
         // TODO: role_assign() needs one userid param to be able to specify our restore userid
         role_assign($newroleid, $newuserid, $contextid);
     } else {
         if (strpos($data->component, 'enrol_') === 0) {
             // Deal with enrolment roles - ignore the component and just find out the instance via new id,
             // it is possible that enrolment was restored using different plugin type.
             if (!isset($this->plugins)) {
                 $this->plugins = enrol_get_plugins(true);
             }
             if ($enrolid = $this->get_mappingid('enrol', $data->itemid)) {
                 if ($instance = $DB->get_record('enrol', array('id' => $enrolid))) {
                     if (isset($this->plugins[$instance->enrol])) {
                         $this->plugins[$instance->enrol]->restore_role_assignment($instance, $newroleid, $newuserid, $contextid);
                     }
                 }
             }
         } else {
             $data->roleid = $newroleid;
             $data->userid = $newuserid;
             $data->contextid = $contextid;
             $dir = core_component::get_component_directory($data->component);
             if ($dir and is_dir($dir)) {
                 if (component_callback($data->component, 'restore_role_assignment', array($this, $data), true)) {
                     return;
                 }
             }
             // Bad luck, plugin could not restore the data, let's add normal membership.
             role_assign($data->roleid, $data->userid, $data->contextid);
             $message = "Restore of '{$data->component}/{$data->itemid}' role assignments is not supported, using manual role assignments instead.";
             $this->log($message, backup::LOG_WARNING);
         }
     }
 }
示例#28
0
    $url->param('popup', $popup);
}
$PAGE->set_url($url);
$PAGE->set_context($context);

if ($popup) {
    $PAGE->set_pagelayout('popup');
}

$params = array('contextid' => $contextid,
                'component' => $component,
                'ratingarea' => $ratingarea,
                'itemid' => $itemid,
                'scaleid' => $scaleid);
if (!has_capability('moodle/rating:view', $context) ||
        !component_callback($component, 'rating_can_see_item_ratings', array($params), true)) {
    print_error('noviewrate', 'rating');
}

$canviewallratings = has_capability('moodle/rating:viewall', $context);

switch ($sort) {
    case 'firstname': $sqlsort = "u.firstname ASC"; break;
    case 'rating':    $sqlsort = "r.rating ASC"; break;
    default:          $sqlsort = "r.timemodified ASC";
}

$scalemenu = make_grades_menu($scaleid);

$strrating  = get_string('rating', 'rating');
$strname    = get_string('name');