Пример #1
0
 /**
  * Loads all of the course sections into the navigation
  *
  * @param global_navigation $navigation
  * @param navigation_node $node The course node within the navigation
  */
 public function extend_course_navigation($navigation, navigation_node $node)
 {
     // Display orphaned activities for the users who can see them.
     $context = context_course::instance($this->courseid);
     if (has_all_capabilities(array('moodle/course:viewhiddensections', 'moodle/course:viewhiddenactivities'), $context)) {
         $modinfo = get_fast_modinfo($this->courseid);
         if (!empty($modinfo->sections[1])) {
             $section1 = $modinfo->get_section_info(1);
             // Show orphaned activities.
             $orphanednode = $node->add(get_string('orphaned', 'format_singleactivity'), $this->get_view_url(1), navigation_node::TYPE_SECTION, null, $section1->id);
             $orphanednode->nodetype = navigation_node::NODETYPE_BRANCH;
             $orphanednode->add_class('orphaned');
             foreach ($modinfo->sections[1] as $cmid) {
                 $this->navigation_add_activity($orphanednode, $modinfo->cms[$cmid]);
             }
         }
     }
 }
Пример #2
0
/**
 * Returns the list of all editing actions that current user can perform on the module
 *
 * @param cm_info $mod The module to produce editing buttons for
 * @param int $indent The current indenting (default -1 means no move left-right actions)
 * @param int $sr The section to link back to (used for creating the links)
 * @return array array of action_link or pix_icon objects
 */
function course_get_cm_edit_actions_reduced(cm_info $mod, $indent = -1, $sr = null)
{
    global $COURSE, $SITE;
    static $str;
    $coursecontext = context_course::instance($mod->course);
    $modcontext = context_module::instance($mod->id);
    $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign');
    $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
    //No permission to edit anything.
    if (!has_any_capability($editcaps, $modcontext) and !has_all_capabilities($dupecaps, $coursecontext)) {
        return array();
    }
    $hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
    if (!isset($str)) {
        $str = get_strings(array('delete', 'move', 'moveright', 'moveleft', 'editsettings', 'duplicate', 'hide', 'show'), 'moodle');
        $str->assign = get_string('assignroles', 'role');
        $str->groupsnone = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone"));
        $str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->groupsvisible = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible"));
    }
    $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
    if ($sr !== null) {
        $baseurl->param('sr', $sr);
    }
    $actions = array();
    // Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php)
    // Note that restoring on front page is never allowed.
    if ($mod->course != SITEID && has_all_capabilities($dupecaps, $coursecontext) && plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2)) {
        $actions['duplicate'] = new action_menu_link_secondary(new moodle_url($baseurl, array('duplicate' => $mod->id)), new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->duplicate, array('class' => 'editing_duplicate', 'data-action' => 'duplicate', 'data-sr' => $sr));
    }
    // Delete.
    if ($hasmanageactivities) {
        $actions['delete'] = new action_menu_link_secondary(new moodle_url($baseurl, array('delete' => $mod->id)), new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->delete, array('class' => 'editing_delete', 'data-action' => 'delete'));
    }
    return $actions;
}
Пример #3
0
 /**
  * This function returns a nice list representing category tree
  * for display or to use in a form <select> element
  *
  * List is cached for 10 minutes
  *
  * For example, if you have a tree of categories like:
  *   Miscellaneous (id = 1)
  *      Subcategory (id = 2)
  *         Sub-subcategory (id = 4)
  *   Other category (id = 3)
  * Then after calling this function you will have
  * array(1 => 'Miscellaneous',
  *       2 => 'Miscellaneous / Subcategory',
  *       4 => 'Miscellaneous / Subcategory / Sub-subcategory',
  *       3 => 'Other category');
  *
  * If you specify $requiredcapability, then only categories where the current
  * user has that capability will be added to $list.
  * If you only have $requiredcapability in a child category, not the parent,
  * then the child catgegory will still be included.
  *
  * If you specify the option $excludeid, then that category, and all its children,
  * are omitted from the tree. This is useful when you are doing something like
  * moving categories, where you do not want to allow people to move a category
  * to be the child of itself.
  *
  * See also {@link make_categories_options()}
  *
  * @param string/array $requiredcapability if given, only categories where the current
  *      user has this capability will be returned. Can also be an array of capabilities,
  *      in which case they are all required.
  * @param integer $excludeid Exclude this category and its children from the lists built.
  * @param string $separator string to use as a separator between parent and child category. Default ' / '
  * @return array of strings
  */
 public static function make_categories_list($requiredcapability = '', $excludeid = 0, $separator = ' / ')
 {
     global $DB;
     $coursecatcache = cache::make('core', 'coursecat');
     // Check if we cached the complete list of user-accessible category names ($baselist) or list of ids with requried cap ($thislist).
     $basecachekey = 'catlist';
     $baselist = $coursecatcache->get($basecachekey);
     if ($baselist !== false) {
         $baselist = false;
     }
     $thislist = false;
     if (!empty($requiredcapability)) {
         $requiredcapability = (array) $requiredcapability;
         $thiscachekey = 'catlist:' . serialize($requiredcapability);
         if ($baselist !== false && ($thislist = $coursecatcache->get($thiscachekey)) !== false) {
             $thislist = preg_split('|,|', $thislist, -1, PREG_SPLIT_NO_EMPTY);
         }
     } else {
         if ($baselist !== false) {
             $thislist = array_keys($baselist);
         }
     }
     if ($baselist === false) {
         // We don't have $baselist cached, retrieve it. Retrieve $thislist again in any case.
         $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
         $sql = "SELECT cc.id, cc.sortorder, cc.name, cc.visible, cc.parent, cc.path, {$ctxselect}\n                    FROM {course_categories} cc\n                    JOIN {context} ctx ON cc.id = ctx.instanceid AND ctx.contextlevel = :contextcoursecat\n                    ORDER BY cc.sortorder";
         $rs = $DB->get_recordset_sql($sql, array('contextcoursecat' => CONTEXT_COURSECAT));
         $baselist = array();
         $thislist = array();
         foreach ($rs as $record) {
             // If the category's parent is not visible to the user, it is not visible as well.
             if (!$record->parent || isset($baselist[$record->parent])) {
                 $context = context_coursecat::instance($record->id);
                 if (!$record->visible && !has_capability('moodle/category:viewhiddencategories', $context)) {
                     // No cap to view category, added to neither $baselist nor $thislist
                     continue;
                 }
                 $baselist[$record->id] = array('name' => format_string($record->name, true, array('context' => $context)), 'path' => $record->path);
                 if (!empty($requiredcapability) && !has_all_capabilities($requiredcapability, $context)) {
                     // No required capability, added to $baselist but not to $thislist.
                     continue;
                 }
                 $thislist[] = $record->id;
             }
         }
         $rs->close();
         $coursecatcache->set($basecachekey, $baselist);
         if (!empty($requiredcapability)) {
             $coursecatcache->set($thiscachekey, join(',', $thislist));
         }
     } else {
         if ($thislist === false) {
             // We have $baselist cached but not $thislist. Simplier query is used to retrieve.
             $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
             $sql = "SELECT ctx.instanceid id, {$ctxselect}\n                    FROM {context} ctx WHERE ctx.contextlevel = :contextcoursecat";
             $contexts = $DB->get_records_sql($sql, array('contextcoursecat' => CONTEXT_COURSECAT));
             $thislist = array();
             foreach (array_keys($baselist) as $id) {
                 context_helper::preload_from_record($contexts[$id]);
                 if (has_all_capabilities($requiredcapability, context_coursecat::instance($id))) {
                     $thislist[] = $id;
                 }
             }
             $coursecatcache->set($thiscachekey, join(',', $thislist));
         }
     }
     // Now build the array of strings to return, mind $separator and $excludeid.
     $names = array();
     foreach ($thislist as $id) {
         $path = preg_split('|/|', $baselist[$id]['path'], -1, PREG_SPLIT_NO_EMPTY);
         if (!$excludeid || !in_array($excludeid, $path)) {
             $namechunks = array();
             foreach ($path as $parentid) {
                 $namechunks[] = $baselist[$parentid]['name'];
             }
             $names[$id] = join($separator, $namechunks);
         }
     }
     return $names;
 }
Пример #4
0
/**
 * @param $list
 * @param $parents
 * @param string $requiredcapability
 * @param int $excludeid
 * @param null $category
 * @param string $path
 * @return mixed
 */
function make_categories_manager_list(&$list, &$parents, $requiredcapability = '', $excludeid = 0, $category = null, $path = "")
{
    $requiredcapability = '';
    // Initialize the arrays if needed.
    if (!is_array($list)) {
        $list = array();
    }
    if (!is_array($parents)) {
        $parents = array();
    }
    if (empty($category)) {
        // Start at the top level.
        $category = new stdClass();
        $category->id = 0;
    } else {
        // This is the excluded category, don't include it.
        if ($excludeid > 0 && $excludeid == $category->id) {
            return;
        }
        $context = context_coursecat::instance($category->id);
        $categoryname = format_string($category->name, true, array('context' => $context));
        // Update $path.
        if ($path) {
            $path = $path . ' / ' . $categoryname;
        } else {
            $path = $categoryname;
        }
        // Add this category to $list, if the permissions check out.
        if (empty($requiredcapability)) {
            $list[$category->id] = $path;
        } else {
            $requiredcapability = (array) $requiredcapability;
            if (has_all_capabilities($requiredcapability, $context)) {
                $list[$category->id] = $path;
            }
        }
    }
    // Add all the children recursively, while updating the parents array.
    if ($categories = get_child_manager_categories($category->id)) {
        foreach ($categories as $cat) {
            if (!empty($category->id)) {
                if (isset($parents[$category->id])) {
                    $parents[$cat->id] = $parents[$category->id];
                }
                $parents[$cat->id][] = $category->id;
            }
            make_categories_manager_list($list, $parents, $requiredcapability, $excludeid, $cat, $path);
        }
    }
}
Пример #5
0
    /**
     * Executes the search
     *
     * @global moodle_database $DB
     * @return int The number of results
     */
    final public function search() {
        global $DB;
        if (!is_null($this->results)) {
            return $this->results;
        }

        $this->results = array();
        $this->totalcount = 0;
        $contextlevel = $this->get_itemcontextlevel();
        list($sql, $params) = $this->get_searchsql();
        $blocksz = 5000;
        $offs = 0;
        // Get total number, to avoid some incorrect iterations
        $countsql = preg_replace('/ORDER BY.*/', '', $sql);
        $totalcourses = $DB->count_records_sql("SELECT COUNT(*) FROM ($countsql) sel", $params);
        // User to be checked is always the same (usually null, get it form first element)
        $firstcap = reset($this->requiredcapabilities);
        $userid = isset($firstcap['user']) ? $firstcap['user'] : null;
        // Extract caps to check, this saves us a bunch of iterations
        $requiredcaps = array();
        foreach ($this->requiredcapabilities as $cap) {
            $requiredcaps[] = $cap['capability'];
        }
        // Iterate while we have records and haven't reached $this->maxresults.
        while ($totalcourses > $offs and $this->totalcount < self::$MAXRESULTS) {
            $resultset = $DB->get_records_sql($sql, $params, $offs, $blocksz);
            foreach ($resultset as $result) {
                context_instance_preload($result);
                $context = get_context_instance($contextlevel, $result->id);
                if (count($requiredcaps) > 0) {
                    if (!has_all_capabilities($requiredcaps, $context, $userid)) {
                        continue;
                    }
                }
                // Check if we are over the limit.
                if ($this->totalcount+1 > self::$MAXRESULTS) {
                    $this->hasmoreresults = true;
                    break;
                }
                // If not, then continue.
                $this->totalcount++;
                $this->results[$result->id] = $result;
            }
            $offs += $blocksz;
        }

        return $this->totalcount;
    }
Пример #6
0
/**
 * Produces the editing buttons for a module
 *
 * @global core_renderer $OUTPUT
 * @staticvar type $str
 * @param stdClass $mod The module to produce editing buttons for
 * @param bool $absolute_ignored ignored - all links are absolute
 * @param bool $moveselect If true a move seleciton process is used (default true)
 * @param int $indent The current indenting
 * @param int $section The section to link back to
 * @return string XHTML for the editing buttons
 */
function make_editing_buttons(stdClass $mod, $absolute_ignored = true, $moveselect = true, $indent = -1, $section = -1)
{
    global $CFG, $OUTPUT;
    static $str;
    $coursecontext = get_context_instance(CONTEXT_COURSE, $mod->course);
    $modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
    $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign');
    $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
    // no permission to edit anything
    if (!has_any_capability($editcaps, $modcontext) and !has_all_capabilities($dupecaps, $coursecontext)) {
        return false;
    }
    $hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
    if (!isset($str)) {
        $str = new stdClass();
        $str->assign = get_string("assignroles", 'role');
        $str->delete = get_string("delete");
        $str->move = get_string("move");
        $str->moveup = get_string("moveup");
        $str->movedown = get_string("movedown");
        $str->moveright = get_string("moveright");
        $str->moveleft = get_string("moveleft");
        $str->update = get_string("update");
        $str->duplicate = get_string("duplicate");
        $str->hide = get_string("hide");
        $str->show = get_string("show");
        $str->groupsnone = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone"));
        $str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->groupsvisible = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible"));
        $str->forcedgroupsnone = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsnone"));
        $str->forcedgroupsseparate = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->forcedgroupsvisible = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsvisible"));
    }
    $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
    if ($section >= 0) {
        $baseurl->param('sr', $section);
    }
    $actions = array();
    // leftright
    if ($hasmanageactivities) {
        if (right_to_left()) {
            // Exchange arrows on RTL
            $rightarrow = 't/left';
            $leftarrow = 't/right';
        } else {
            $rightarrow = 't/right';
            $leftarrow = 't/left';
        }
        if ($indent > 0) {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')), new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_moveleft', 'title' => $str->moveleft));
        }
        if ($indent >= 0) {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '1')), new pix_icon($rightarrow, $str->moveright, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_moveright', 'title' => $str->moveright));
        }
    }
    // move
    if ($hasmanageactivities) {
        if ($moveselect) {
            $actions[] = new action_link(new moodle_url($baseurl, array('copy' => $mod->id)), new pix_icon('t/move', $str->move, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_move', 'title' => $str->move));
        } else {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'move' => '-1')), new pix_icon('t/up', $str->moveup, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_moveup', 'title' => $str->moveup));
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'move' => '1')), new pix_icon('t/down', $str->movedown, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_movedown', 'title' => $str->movedown));
        }
    }
    // Update
    if ($hasmanageactivities) {
        $actions[] = new action_link(new moodle_url($baseurl, array('update' => $mod->id)), new pix_icon('t/edit', $str->update, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_update', 'title' => $str->update));
    }
    // Duplicate (require both target import caps to be able to duplicate, see modduplicate.php)
    if (has_all_capabilities($dupecaps, $coursecontext)) {
        $actions[] = new action_link(new moodle_url($baseurl, array('duplicate' => $mod->id)), new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_duplicate', 'title' => $str->duplicate));
    }
    // Delete
    if ($hasmanageactivities) {
        $actions[] = new action_link(new moodle_url($baseurl, array('delete' => $mod->id)), new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_delete', 'title' => $str->delete));
    }
    // hideshow
    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
        if ($mod->visible) {
            $actions[] = new action_link(new moodle_url($baseurl, array('hide' => $mod->id)), new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_hide', 'title' => $str->hide));
        } else {
            $actions[] = new action_link(new moodle_url($baseurl, array('show' => $mod->id)), new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_show', 'title' => $str->show));
        }
    }
    // groupmode
    if ($hasmanageactivities and $mod->groupmode !== false) {
        if ($mod->groupmode == SEPARATEGROUPS) {
            $groupmode = 0;
            $grouptitle = $str->groupsseparate;
            $forcedgrouptitle = $str->forcedgroupsseparate;
            $groupclass = 'editing_groupsseparate';
            $groupimage = 't/groups';
        } else {
            if ($mod->groupmode == VISIBLEGROUPS) {
                $groupmode = 1;
                $grouptitle = $str->groupsvisible;
                $forcedgrouptitle = $str->forcedgroupsvisible;
                $groupclass = 'editing_groupsvisible';
                $groupimage = 't/groupv';
            } else {
                $groupmode = 2;
                $grouptitle = $str->groupsnone;
                $forcedgrouptitle = $str->forcedgroupsnone;
                $groupclass = 'editing_groupsnone';
                $groupimage = 't/groupn';
            }
        }
        if ($mod->groupmodelink) {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $groupmode)), new pix_icon($groupimage, $grouptitle, 'moodle', array('class' => 'iconsmall')), null, array('class' => $groupclass, 'title' => $grouptitle));
        } else {
            $actions[] = new pix_icon($groupimage, $forcedgrouptitle, 'moodle', array('title' => $forcedgrouptitle, 'class' => 'iconsmall'));
        }
    }
    // Assign
    if (has_capability('moodle/role:assign', $modcontext)) {
        $actions[] = new action_link(new moodle_url('/' . $CFG->admin . '/roles/assign.php', array('contextid' => $modcontext->id)), new pix_icon('i/roles', $str->assign, 'moodle', array('class' => 'iconsmall')), null, array('class' => 'editing_assign', 'title' => $str->assign));
    }
    $output = html_writer::start_tag('span', array('class' => 'commands'));
    foreach ($actions as $action) {
        if ($action instanceof renderable) {
            $output .= $OUTPUT->render($action);
        } else {
            $output .= $action;
        }
    }
    $output .= html_writer::end_tag('span');
    return $output;
}
Пример #7
0
 /**
  * Add elements to grade form.
  *
  * @param MoodleQuickForm $mform
  * @param stdClass $data
  * @param array $params
  * @return void
  */
 public function add_grade_form_elements(MoodleQuickForm $mform, stdClass $data, $params)
 {
     global $USER, $CFG;
     $settings = $this->get_instance();
     $rownum = $params['rownum'];
     $last = $params['last'];
     $useridlistid = $params['useridlistid'];
     $userid = $params['userid'];
     $attemptnumber = $params['attemptnumber'];
     if (!$userid) {
         $cache = cache::make_from_params(cache_store::MODE_SESSION, 'mod_assign', 'useridlist');
         if (!($useridlist = $cache->get($this->get_course_module()->id . '_' . $useridlistid))) {
             $useridlist = $this->get_grading_userid_list();
             $cache->set($this->get_course_module()->id . '_' . $useridlistid, $useridlist);
         }
     } else {
         $useridlist = array($userid);
         $rownum = 0;
         $useridlistid = '';
     }
     $userid = $useridlist[$rownum];
     $grade = $this->get_user_grade($userid, false, $attemptnumber);
     $submission = null;
     if ($this->get_instance()->teamsubmission) {
         $submission = $this->get_group_submission($userid, 0, false, $attemptnumber);
     } else {
         $submission = $this->get_user_submission($userid, false, $attemptnumber);
     }
     // Add advanced grading.
     $gradingdisabled = $this->grading_disabled($userid);
     $gradinginstance = $this->get_grading_instance($userid, $grade, $gradingdisabled);
     $mform->addElement('header', 'gradeheader', get_string('grade'));
     if ($gradinginstance) {
         $gradingelement = $mform->addElement('grading', 'advancedgrading', get_string('grade') . ':', array('gradinginstance' => $gradinginstance));
         if ($gradingdisabled) {
             $gradingelement->freeze();
         } else {
             $mform->addElement('hidden', 'advancedgradinginstanceid', $gradinginstance->get_id());
             $mform->setType('advancedgradinginstanceid', PARAM_INT);
         }
     } else {
         // Use simple direct grading.
         if ($this->get_instance()->grade > 0) {
             $name = get_string('gradeoutof', 'assign', $this->get_instance()->grade);
             if (!$gradingdisabled) {
                 $gradingelement = $mform->addElement('text', 'grade', $name);
                 $mform->addHelpButton('grade', 'gradeoutofhelp', 'assign');
                 $mform->setType('grade', PARAM_RAW);
             } else {
                 $mform->addElement('hidden', 'grade', $name);
                 $mform->hardFreeze('grade');
                 $mform->setType('grade', PARAM_RAW);
                 $strgradelocked = get_string('gradelocked', 'assign');
                 $mform->addElement('static', 'gradedisabled', $name, $strgradelocked);
                 $mform->addHelpButton('gradedisabled', 'gradeoutofhelp', 'assign');
             }
         } else {
             $grademenu = array(-1 => get_string("nograde")) + make_grades_menu($this->get_instance()->grade);
             if (count($grademenu) > 1) {
                 $gradingelement = $mform->addElement('select', 'grade', get_string('grade') . ':', $grademenu);
                 // The grade is already formatted with format_float so it needs to be converted back to an integer.
                 if (!empty($data->grade)) {
                     $data->grade = (int) unformat_float($data->grade);
                 }
                 $mform->setType('grade', PARAM_INT);
                 if ($gradingdisabled) {
                     $gradingelement->freeze();
                 }
             }
         }
     }
     $gradinginfo = grade_get_grades($this->get_course()->id, 'mod', 'assign', $this->get_instance()->id, $userid);
     if (!empty($CFG->enableoutcomes)) {
         foreach ($gradinginfo->outcomes as $index => $outcome) {
             $options = make_grades_menu(-$outcome->scaleid);
             if ($outcome->grades[$userid]->locked) {
                 $options[0] = get_string('nooutcome', 'grades');
                 $mform->addElement('static', 'outcome_' . $index . '[' . $userid . ']', $outcome->name . ':', $options[$outcome->grades[$userid]->grade]);
             } else {
                 $options[''] = get_string('nooutcome', 'grades');
                 $attributes = array('id' => 'menuoutcome_' . $index);
                 $mform->addElement('select', 'outcome_' . $index . '[' . $userid . ']', $outcome->name . ':', $options, $attributes);
                 $mform->setType('outcome_' . $index . '[' . $userid . ']', PARAM_INT);
                 $mform->setDefault('outcome_' . $index . '[' . $userid . ']', $outcome->grades[$userid]->grade);
             }
         }
     }
     $capabilitylist = array('gradereport/grader:view', 'moodle/grade:viewall');
     if (has_all_capabilities($capabilitylist, $this->get_course_context())) {
         $urlparams = array('id' => $this->get_course()->id);
         $url = new moodle_url('/grade/report/grader/index.php', $urlparams);
         $usergrade = '-';
         if (isset($gradinginfo->items[0]->grades[$userid]->str_grade)) {
             $usergrade = $gradinginfo->items[0]->grades[$userid]->str_grade;
         }
         $gradestring = $this->get_renderer()->action_link($url, $usergrade);
     } else {
         $usergrade = '-';
         if (isset($gradinginfo->items[0]->grades[$userid]) && !$gradinginfo->items[0]->grades[$userid]->hidden) {
             $usergrade = $gradinginfo->items[0]->grades[$userid]->str_grade;
         }
         $gradestring = $usergrade;
     }
     if ($this->get_instance()->markingworkflow) {
         $states = $this->get_marking_workflow_states_for_current_user();
         $options = array('' => get_string('markingworkflowstatenotmarked', 'assign')) + $states;
         $mform->addElement('select', 'workflowstate', get_string('markingworkflowstate', 'assign'), $options);
         $mform->addHelpButton('workflowstate', 'markingworkflowstate', 'assign');
     }
     if ($this->get_instance()->markingallocation && has_capability('mod/assign:manageallocations', $this->context)) {
         $markers = get_users_by_capability($this->context, 'mod/assign:grade');
         $markerlist = array('' => get_string('choosemarker', 'assign'));
         foreach ($markers as $marker) {
             $markerlist[$marker->id] = fullname($marker);
         }
         $mform->addElement('select', 'allocatedmarker', get_string('allocatedmarker', 'assign'), $markerlist);
         $mform->addHelpButton('allocatedmarker', 'allocatedmarker', 'assign');
         $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_READYFORREVIEW);
         $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_INREVIEW);
         $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_READYFORRELEASE);
         $mform->disabledIf('allocatedmarker', 'workflowstate', 'eq', ASSIGN_MARKING_WORKFLOW_STATE_RELEASED);
     }
     $mform->addElement('static', 'currentgrade', get_string('currentgrade', 'assign'), $gradestring);
     if (count($useridlist) > 1) {
         $strparams = array('current' => $rownum + 1, 'total' => count($useridlist));
         $name = get_string('outof', 'assign', $strparams);
         $mform->addElement('static', 'gradingstudent', get_string('gradingstudent', 'assign'), $name);
     }
     // Let feedback plugins add elements to the grading form.
     $this->add_plugin_grade_elements($grade, $mform, $data, $userid);
     // Hidden params.
     $mform->addElement('hidden', 'id', $this->get_course_module()->id);
     $mform->setType('id', PARAM_INT);
     $mform->addElement('hidden', 'rownum', $rownum);
     $mform->setType('rownum', PARAM_INT);
     $mform->setConstant('rownum', $rownum);
     $mform->addElement('hidden', 'useridlistid', $useridlistid);
     $mform->setType('useridlistid', PARAM_INT);
     $mform->addElement('hidden', 'attemptnumber', $attemptnumber);
     $mform->setType('attemptnumber', PARAM_INT);
     $mform->addElement('hidden', 'ajax', optional_param('ajax', 0, PARAM_INT));
     $mform->setType('ajax', PARAM_INT);
     if ($this->get_instance()->teamsubmission) {
         $mform->addElement('header', 'groupsubmissionsettings', get_string('groupsubmissionsettings', 'assign'));
         $mform->addElement('selectyesno', 'applytoall', get_string('applytoteam', 'assign'));
         $mform->setDefault('applytoall', 1);
     }
     // Do not show if we are editing a previous attempt.
     if ($attemptnumber == -1 && $this->get_instance()->attemptreopenmethod != ASSIGN_ATTEMPT_REOPEN_METHOD_NONE) {
         $mform->addElement('header', 'attemptsettings', get_string('attemptsettings', 'assign'));
         $attemptreopenmethod = get_string('attemptreopenmethod_' . $this->get_instance()->attemptreopenmethod, 'assign');
         $mform->addElement('static', 'attemptreopenmethod', get_string('attemptreopenmethod', 'assign'), $attemptreopenmethod);
         $attemptnumber = 0;
         if ($submission) {
             $attemptnumber = $submission->attemptnumber;
         }
         $maxattempts = $this->get_instance()->maxattempts;
         if ($maxattempts == ASSIGN_UNLIMITED_ATTEMPTS) {
             $maxattempts = get_string('unlimitedattempts', 'assign');
         }
         $mform->addelement('static', 'maxattemptslabel', get_string('maxattempts', 'assign'), $maxattempts);
         $mform->addelement('static', 'attemptnumberlabel', get_string('attemptnumber', 'assign'), $attemptnumber + 1);
         $ismanual = $this->get_instance()->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL;
         $issubmission = !empty($submission);
         $isunlimited = $this->get_instance()->maxattempts == ASSIGN_UNLIMITED_ATTEMPTS;
         $islessthanmaxattempts = $issubmission && $submission->attemptnumber < $this->get_instance()->maxattempts - 1;
         if ($ismanual && (!$issubmission || $isunlimited || $islessthanmaxattempts)) {
             $mform->addElement('selectyesno', 'addattempt', get_string('addattempt', 'assign'));
             $mform->setDefault('addattempt', 0);
         }
     }
     $mform->addElement('hidden', 'action', 'submitgrade');
     $mform->setType('action', PARAM_ALPHA);
     $buttonarray = array();
     $name = get_string('savechanges', 'assign');
     $buttonarray[] = $mform->createElement('submit', 'savegrade', $name);
     if (!$last) {
         $name = get_string('savenext', 'assign');
         $buttonarray[] = $mform->createElement('submit', 'saveandshownext', $name);
     }
     $buttonarray[] = $mform->createElement('cancel', 'cancelbutton', get_string('cancel'));
     $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
     $mform->closeHeaderBefore('buttonar');
     $buttonarray = array();
     if ($rownum > 0) {
         $name = get_string('previous', 'assign');
         $buttonarray[] = $mform->createElement('submit', 'nosaveandprevious', $name);
     }
     if (!$last) {
         $name = get_string('nosavebutnext', 'assign');
         $buttonarray[] = $mform->createElement('submit', 'nosaveandnext', $name);
     }
     if (!empty($buttonarray)) {
         $mform->addGroup($buttonarray, 'navar', '', array(' '), false);
     }
     // The grading form does not work well with shortforms.
     $mform->setDisableShortforms();
 }
Пример #8
0
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// 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/>.
/**
 * Link to user roles management.
 *
 * @package    tool_cohortroles
 * @copyright  2015 Damyon Wiese
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
defined('MOODLE_INTERNAL') || die;
// This tool's required capabilities.
$capabilities = ['moodle/cohort:view', 'moodle/role:manage'];
// Check if the user has all of the required capabilities.
$context = context_system::instance();
$hasaccess = has_all_capabilities($capabilities, $context);
// Add this admin page only if the user has all of the required capabilities.
if ($hasaccess) {
    $str = get_string('managecohortroles', 'tool_cohortroles');
    $url = new moodle_url('/admin/tool/cohortroles/index.php');
    $ADMIN->add('roles', new admin_externalpage('toolcohortroles', $str, $url, $capabilities));
}
Пример #9
0
/**
 * Returns the list of all editing actions that current user can perform on the module
 *
 * @param cm_info $mod The module to produce editing buttons for
 * @param int $indent The current indenting (default -1 means no move left-right actions)
 * @param int $sr The section to link back to (used for creating the links)
 * @return array array of action_link or pix_icon objects
 */
function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null)
{
    global $COURSE, $SITE;
    static $str;
    $coursecontext = context_course::instance($mod->course);
    $modcontext = context_module::instance($mod->id);
    $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign');
    $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
    // No permission to edit anything.
    if (!has_any_capability($editcaps, $modcontext) and !has_all_capabilities($dupecaps, $coursecontext)) {
        return array();
    }
    $hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
    if (!isset($str)) {
        $str = get_strings(array('delete', 'move', 'moveright', 'moveleft', 'editsettings', 'duplicate', 'hide', 'show'), 'moodle');
        $str->assign = get_string('assignroles', 'role');
        $str->groupsnone = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone"));
        $str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->groupsvisible = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible"));
    }
    $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
    if ($sr !== null) {
        $baseurl->param('sr', $sr);
    }
    $actions = array();
    // Update.
    if ($hasmanageactivities) {
        $actions['update'] = new action_menu_link_secondary(new moodle_url($baseurl, array('update' => $mod->id)), new pix_icon('t/edit', $str->editsettings, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->editsettings, array('class' => 'editing_update', 'data-action' => 'update'));
    }
    // Indent.
    if ($hasmanageactivities && $indent >= 0) {
        $indentlimits = new stdClass();
        $indentlimits->min = 0;
        $indentlimits->max = 16;
        if (right_to_left()) {
            // Exchange arrows on RTL
            $rightarrow = 't/left';
            $leftarrow = 't/right';
        } else {
            $rightarrow = 't/right';
            $leftarrow = 't/left';
        }
        if ($indent >= $indentlimits->max) {
            $enabledclass = 'hidden';
        } else {
            $enabledclass = '';
        }
        $actions['moveright'] = new action_menu_link_secondary(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '1')), new pix_icon($rightarrow, $str->moveright, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->moveright, array('class' => 'editing_moveright ' . $enabledclass, 'data-action' => 'moveright', 'data-keepopen' => true));
        if ($indent <= $indentlimits->min) {
            $enabledclass = 'hidden';
        } else {
            $enabledclass = '';
        }
        $actions['moveleft'] = new action_menu_link_secondary(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')), new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->moveleft, array('class' => 'editing_moveleft ' . $enabledclass, 'data-action' => 'moveleft', 'data-keepopen' => true));
    }
    // Hide/Show.
    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
        if ($mod->visible) {
            $actions['hide'] = new action_menu_link_secondary(new moodle_url($baseurl, array('hide' => $mod->id)), new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->hide, array('class' => 'editing_hide', 'data-action' => 'hide'));
        } else {
            $actions['show'] = new action_menu_link_secondary(new moodle_url($baseurl, array('show' => $mod->id)), new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->show, array('class' => 'editing_show', 'data-action' => 'show'));
        }
    }
    // Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php)
    // Note that restoring on front page is never allowed.
    if ($mod->course != SITEID && has_all_capabilities($dupecaps, $coursecontext) && plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2)) {
        $actions['duplicate'] = new action_menu_link_secondary(new moodle_url($baseurl, array('duplicate' => $mod->id)), new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->duplicate, array('class' => 'editing_duplicate', 'data-action' => 'duplicate', 'data-sr' => $sr));
    }
    // Groupmode.
    if ($hasmanageactivities && !$mod->coursegroupmodeforce) {
        if (plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
            if ($mod->effectivegroupmode == SEPARATEGROUPS) {
                $nextgroupmode = VISIBLEGROUPS;
                $grouptitle = $str->groupsseparate;
                $actionname = 'groupsseparate';
                $groupimage = 'i/groups';
            } else {
                if ($mod->effectivegroupmode == VISIBLEGROUPS) {
                    $nextgroupmode = NOGROUPS;
                    $grouptitle = $str->groupsvisible;
                    $actionname = 'groupsvisible';
                    $groupimage = 'i/groupv';
                } else {
                    $nextgroupmode = SEPARATEGROUPS;
                    $grouptitle = $str->groupsnone;
                    $actionname = 'groupsnone';
                    $groupimage = 'i/groupn';
                }
            }
            $actions[$actionname] = new action_menu_link_primary(new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $nextgroupmode)), new pix_icon($groupimage, null, 'moodle', array('class' => 'iconsmall')), $grouptitle, array('class' => 'editing_' . $actionname, 'data-action' => $actionname, 'data-nextgroupmode' => $nextgroupmode, 'aria-live' => 'assertive'));
        } else {
            $actions['nogroupsupport'] = new action_menu_filler();
        }
    }
    // Assign.
    if (has_capability('moodle/role:assign', $modcontext)) {
        $actions['assign'] = new action_menu_link_secondary(new moodle_url('/admin/roles/assign.php', array('contextid' => $modcontext->id)), new pix_icon('t/assignroles', $str->assign, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->assign, array('class' => 'editing_assign', 'data-action' => 'assignroles'));
    }
    // Delete.
    if ($hasmanageactivities) {
        $actions['delete'] = new action_menu_link_secondary(new moodle_url($baseurl, array('delete' => $mod->id)), new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall', 'title' => '')), $str->delete, array('class' => 'editing_delete', 'data-action' => 'delete'));
    }
    return $actions;
}
Пример #10
0
 /**
  * Returns an array of courses the user is enrolled in, and for each course all of the assignments that the user can
  * view within that course.
  *
  * @param array $courseids An optional array of course ids. If provided only assignments within the given course
  * will be returned. If the user is not enrolled in a given course a warning will be generated and returned.
  * @param array $capabilities An array of additional capability checks you wish to be made on the course context.
  * @return An array of courses and warnings.
  * @since  Moodle 2.4
  */
 public static function get_assignments($courseids = array(), $capabilities = array())
 {
     global $USER, $DB;
     $params = self::validate_parameters(self::get_assignments_parameters(), array('courseids' => $courseids, 'capabilities' => $capabilities));
     $warnings = array();
     $fields = 'sortorder,shortname,fullname,timemodified';
     $courses = enrol_get_users_courses($USER->id, true, $fields);
     // Used to test for ids that have been requested but can't be returned.
     if (count($params['courseids']) > 0) {
         foreach ($params['courseids'] as $courseid) {
             if (!in_array($courseid, array_keys($courses))) {
                 unset($courses[$courseid]);
                 $warnings[] = array('item' => 'course', 'itemid' => $courseid, 'warningcode' => '2', 'message' => 'User is not enrolled or does not have requested capability');
             }
         }
     }
     foreach ($courses as $id => $course) {
         if (count($params['courseids']) > 0 && !in_array($id, $params['courseids'])) {
             unset($courses[$id]);
         }
         $context = context_course::instance($id);
         try {
             self::validate_context($context);
         } catch (Exception $e) {
             unset($courses[$id]);
             $warnings[] = array('item' => 'course', 'itemid' => $id, 'warningcode' => '1', 'message' => 'No access rights in course context ' . $e->getMessage() . $e->getTraceAsString());
             continue;
         }
         if (count($params['capabilities']) > 0 && !has_all_capabilities($params['capabilities'], $context)) {
             unset($courses[$id]);
         }
     }
     $extrafields = 'm.id as assignmentid, ' . 'm.course, ' . 'm.nosubmissions, ' . 'm.submissiondrafts, ' . 'm.sendnotifications, ' . 'm.sendlatenotifications, ' . 'm.sendstudentnotifications, ' . 'm.duedate, ' . 'm.allowsubmissionsfromdate, ' . 'm.grade, ' . 'm.timemodified, ' . 'm.completionsubmit, ' . 'm.cutoffdate, ' . 'm.teamsubmission, ' . 'm.requireallteammemberssubmit, ' . 'm.teamsubmissiongroupingid, ' . 'm.blindmarking, ' . 'm.revealidentities, ' . 'm.attemptreopenmethod, ' . 'm.maxattempts, ' . 'm.markingworkflow, ' . 'm.markingallocation, ' . 'm.requiresubmissionstatement';
     $coursearray = array();
     foreach ($courses as $id => $course) {
         $assignmentarray = array();
         // Get a list of assignments for the course.
         if ($modules = get_coursemodules_in_course('assign', $courses[$id]->id, $extrafields)) {
             foreach ($modules as $module) {
                 $context = context_module::instance($module->id);
                 try {
                     self::validate_context($context);
                     require_capability('mod/assign:view', $context);
                 } catch (Exception $e) {
                     $warnings[] = array('item' => 'module', 'itemid' => $module->id, 'warningcode' => '1', 'message' => 'No access rights in module context');
                     continue;
                 }
                 $configrecords = $DB->get_recordset('assign_plugin_config', array('assignment' => $module->assignmentid));
                 $configarray = array();
                 foreach ($configrecords as $configrecord) {
                     $configarray[] = array('id' => $configrecord->id, 'assignment' => $configrecord->assignment, 'plugin' => $configrecord->plugin, 'subtype' => $configrecord->subtype, 'name' => $configrecord->name, 'value' => $configrecord->value);
                 }
                 $configrecords->close();
                 $assignmentarray[] = array('id' => $module->assignmentid, 'cmid' => $module->id, 'course' => $module->course, 'name' => $module->name, 'nosubmissions' => $module->nosubmissions, 'submissiondrafts' => $module->submissiondrafts, 'sendnotifications' => $module->sendnotifications, 'sendlatenotifications' => $module->sendlatenotifications, 'sendstudentnotifications' => $module->sendstudentnotifications, 'duedate' => $module->duedate, 'allowsubmissionsfromdate' => $module->allowsubmissionsfromdate, 'grade' => $module->grade, 'timemodified' => $module->timemodified, 'completionsubmit' => $module->completionsubmit, 'cutoffdate' => $module->cutoffdate, 'teamsubmission' => $module->teamsubmission, 'requireallteammemberssubmit' => $module->requireallteammemberssubmit, 'teamsubmissiongroupingid' => $module->teamsubmissiongroupingid, 'blindmarking' => $module->blindmarking, 'revealidentities' => $module->revealidentities, 'attemptreopenmethod' => $module->attemptreopenmethod, 'maxattempts' => $module->maxattempts, 'markingworkflow' => $module->markingworkflow, 'markingallocation' => $module->markingallocation, 'requiresubmissionstatement' => $module->requiresubmissionstatement, 'configs' => $configarray);
             }
         }
         $coursearray[] = array('id' => $courses[$id]->id, 'fullname' => $courses[$id]->fullname, 'shortname' => $courses[$id]->shortname, 'timemodified' => $courses[$id]->timemodified, 'assignments' => $assignmentarray);
     }
     $result = array('courses' => $coursearray, 'warnings' => $warnings);
     return $result;
 }
Пример #11
0
 /**
  * Returns an array of courses the user is enrolled, and for each course all of the assignments that the user can
  * view within that course.
  *
  * @param array $courseids An optional array of course ids. If provided only assignments within the given course
  * will be returned. If the user is not enrolled in or can't view a given course a warning will be generated and returned.
  * @param array $capabilities An array of additional capability checks you wish to be made on the course context.
  * @param bool $includenotenrolledcourses Wheter to return courses that the user can see even if is not enroled in.
  * This requires the parameter $courseids to not be empty.
  * @return An array of courses and warnings.
  * @since  Moodle 2.4
  */
 public static function get_assignments($courseids = array(), $capabilities = array(), $includenotenrolledcourses = false)
 {
     global $USER, $DB, $CFG;
     $params = self::validate_parameters(self::get_assignments_parameters(), array('courseids' => $courseids, 'capabilities' => $capabilities, 'includenotenrolledcourses' => $includenotenrolledcourses));
     $warnings = array();
     $courses = array();
     $fields = 'sortorder,shortname,fullname,timemodified';
     // If the courseids list is empty, we return only the courses where the user is enrolled in.
     if (empty($params['courseids'])) {
         $courses = enrol_get_users_courses($USER->id, true, $fields);
         $courseids = array_keys($courses);
     } else {
         if ($includenotenrolledcourses) {
             // In this case, we don't have to check here for enrolmnents. Maybe the user can see the course even if is not enrolled.
             $courseids = $params['courseids'];
         } else {
             // We need to check for enrolments.
             $mycourses = enrol_get_users_courses($USER->id, true, $fields);
             $mycourseids = array_keys($mycourses);
             foreach ($params['courseids'] as $courseid) {
                 if (!in_array($courseid, $mycourseids)) {
                     unset($courses[$courseid]);
                     $warnings[] = array('item' => 'course', 'itemid' => $courseid, 'warningcode' => '2', 'message' => 'User is not enrolled or does not have requested capability');
                 } else {
                     $courses[$courseid] = $mycourses[$courseid];
                 }
             }
             $courseids = array_keys($courses);
         }
     }
     foreach ($courseids as $cid) {
         try {
             $context = context_course::instance($cid);
             self::validate_context($context);
             // Check if this course was already loaded (by enrol_get_users_courses).
             if (!isset($courses[$cid])) {
                 $courses[$cid] = get_course($cid);
             }
             $courses[$cid]->contextid = $context->id;
         } catch (Exception $e) {
             unset($courses[$cid]);
             $warnings[] = array('item' => 'course', 'itemid' => $cid, 'warningcode' => '1', 'message' => 'No access rights in course context ' . $e->getMessage());
             continue;
         }
         if (count($params['capabilities']) > 0 && !has_all_capabilities($params['capabilities'], $context)) {
             unset($courses[$cid]);
         }
     }
     $extrafields = 'm.id as assignmentid, ' . 'm.course, ' . 'm.nosubmissions, ' . 'm.submissiondrafts, ' . 'm.sendnotifications, ' . 'm.sendlatenotifications, ' . 'm.sendstudentnotifications, ' . 'm.duedate, ' . 'm.allowsubmissionsfromdate, ' . 'm.grade, ' . 'm.timemodified, ' . 'm.completionsubmit, ' . 'm.cutoffdate, ' . 'm.teamsubmission, ' . 'm.requireallteammemberssubmit, ' . 'm.teamsubmissiongroupingid, ' . 'm.blindmarking, ' . 'm.revealidentities, ' . 'm.attemptreopenmethod, ' . 'm.maxattempts, ' . 'm.markingworkflow, ' . 'm.markingallocation, ' . 'm.requiresubmissionstatement, ' . 'm.preventsubmissionnotingroup, ' . 'm.intro, ' . 'm.introformat';
     $coursearray = array();
     foreach ($courses as $id => $course) {
         $assignmentarray = array();
         // Get a list of assignments for the course.
         if ($modules = get_coursemodules_in_course('assign', $courses[$id]->id, $extrafields)) {
             foreach ($modules as $module) {
                 $context = context_module::instance($module->id);
                 try {
                     self::validate_context($context);
                     require_capability('mod/assign:view', $context);
                 } catch (Exception $e) {
                     $warnings[] = array('item' => 'module', 'itemid' => $module->id, 'warningcode' => '1', 'message' => 'No access rights in module context');
                     continue;
                 }
                 $assign = new assign($context, null, null);
                 // Get configurations for only enabled plugins.
                 $plugins = $assign->get_submission_plugins();
                 $plugins = array_merge($plugins, $assign->get_feedback_plugins());
                 $configarray = array();
                 foreach ($plugins as $plugin) {
                     if ($plugin->is_enabled() && $plugin->is_visible()) {
                         $configrecords = $plugin->get_config_for_external();
                         foreach ($configrecords as $name => $value) {
                             $configarray[] = array('plugin' => $plugin->get_type(), 'subtype' => $plugin->get_subtype(), 'name' => $name, 'value' => $value);
                         }
                     }
                 }
                 $assignment = array('id' => $module->assignmentid, 'cmid' => $module->id, 'course' => $module->course, 'name' => $module->name, 'nosubmissions' => $module->nosubmissions, 'submissiondrafts' => $module->submissiondrafts, 'sendnotifications' => $module->sendnotifications, 'sendlatenotifications' => $module->sendlatenotifications, 'sendstudentnotifications' => $module->sendstudentnotifications, 'duedate' => $module->duedate, 'allowsubmissionsfromdate' => $module->allowsubmissionsfromdate, 'grade' => $module->grade, 'timemodified' => $module->timemodified, 'completionsubmit' => $module->completionsubmit, 'cutoffdate' => $module->cutoffdate, 'teamsubmission' => $module->teamsubmission, 'requireallteammemberssubmit' => $module->requireallteammemberssubmit, 'teamsubmissiongroupingid' => $module->teamsubmissiongroupingid, 'blindmarking' => $module->blindmarking, 'revealidentities' => $module->revealidentities, 'attemptreopenmethod' => $module->attemptreopenmethod, 'maxattempts' => $module->maxattempts, 'markingworkflow' => $module->markingworkflow, 'markingallocation' => $module->markingallocation, 'requiresubmissionstatement' => $module->requiresubmissionstatement, 'preventsubmissionnotingroup' => $module->preventsubmissionnotingroup, 'configs' => $configarray);
                 // Return or not intro and file attachments depending on the plugin settings.
                 if ($assign->show_intro()) {
                     list($assignment['intro'], $assignment['introformat']) = external_format_text($module->intro, $module->introformat, $context->id, 'mod_assign', 'intro', null);
                     $assignment['introfiles'] = external_util::get_area_files($context->id, 'mod_assign', 'intro', false, false);
                     $assignment['introattachments'] = external_util::get_area_files($context->id, 'mod_assign', ASSIGN_INTROATTACHMENT_FILEAREA, 0);
                 }
                 if ($module->requiresubmissionstatement) {
                     // Submission statement is required, return the submission statement value.
                     $adminconfig = get_config('assign');
                     list($assignment['submissionstatement'], $assignment['submissionstatementformat']) = external_format_text($adminconfig->submissionstatement, FORMAT_MOODLE, $context->id, 'mod_assign', '', 0);
                 }
                 $assignmentarray[] = $assignment;
             }
         }
         $coursearray[] = array('id' => $courses[$id]->id, 'fullname' => external_format_string($courses[$id]->fullname, $course->contextid), 'shortname' => external_format_string($courses[$id]->shortname, $course->contextid), 'timemodified' => $courses[$id]->timemodified, 'assignments' => $assignmentarray);
     }
     $result = array('courses' => $coursearray, 'warnings' => $warnings);
     return $result;
 }
 /**
  * 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;
 }
Пример #13
0
 /**
  * Executes the search
  *
  * @global moodle_database $DB
  * @return int The number of results
  */
 public final function search()
 {
     global $DB;
     if (!is_null($this->results)) {
         return $this->results;
     }
     $this->results = array();
     $this->totalcount = 0;
     $contextlevel = $this->get_itemcontextlevel();
     list($sql, $params) = $this->get_searchsql();
     // Get total number, to avoid some incorrect iterations.
     $countsql = preg_replace('/ORDER BY.*/', '', $sql);
     $totalcourses = $DB->count_records_sql("SELECT COUNT(*) FROM ({$countsql}) sel", $params);
     if ($totalcourses > 0) {
         // User to be checked is always the same (usually null, get it from first element).
         $firstcap = reset($this->requiredcapabilities);
         $userid = isset($firstcap['user']) ? $firstcap['user'] : null;
         // Extract caps to check, this saves us a bunch of iterations.
         $requiredcaps = array();
         foreach ($this->requiredcapabilities as $cap) {
             $requiredcaps[] = $cap['capability'];
         }
         // Iterate while we have records and haven't reached $this->maxresults.
         $resultset = $DB->get_recordset_sql($sql, $params);
         foreach ($resultset as $result) {
             context_helper::preload_from_record($result);
             $classname = context_helper::get_class_for_level($contextlevel);
             $context = $classname::instance($result->id);
             if (count($requiredcaps) > 0) {
                 if (!has_all_capabilities($requiredcaps, $context, $userid)) {
                     continue;
                 }
             }
             // Check if we are over the limit.
             if ($this->totalcount + 1 > $this->maxresults) {
                 $this->hasmoreresults = true;
                 break;
             }
             // If not, then continue.
             $this->totalcount++;
             $this->results[$result->id] = $result;
         }
         $resultset->close();
     }
     return $this->totalcount;
 }
Пример #14
0
function make_editing_buttons($mod, $absolute = false, $moveselect = true, $indent = -1, $section = -1)
{
    global $CFG, $USER, $DB, $OUTPUT;
    static $str;
    static $sesskey;
    $modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
    // no permission to edit
    if (!has_capability('moodle/course:manageactivities', $modcontext)) {
        return false;
    }
    if (!isset($str)) {
        $str->assign = get_string("assignroles", 'role');
        $str->delete = get_string("delete");
        $str->move = get_string("move");
        $str->moveup = get_string("moveup");
        $str->movedown = get_string("movedown");
        $str->moveright = get_string("moveright");
        $str->moveleft = get_string("moveleft");
        $str->update = get_string("update");
        $str->duplicate = get_string("duplicate");
        $str->hide = get_string("hide");
        $str->show = get_string("show");
        $str->clicktochange = get_string("clicktochange");
        $str->forcedmode = get_string("forcedmode");
        $str->groupsnone = get_string("groupsnone");
        $str->groupsseparate = get_string("groupsseparate");
        $str->groupsvisible = get_string("groupsvisible");
        $sesskey = sesskey();
    }
    if ($section >= 0) {
        $section = '&amp;sr=' . $section;
        // Section return
    } else {
        $section = '';
    }
    if ($absolute) {
        $path = $CFG->wwwroot . '/course';
    } else {
        $path = '.';
    }
    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
        if ($mod->visible) {
            $hideshow = '<a class="editing_hide" title="' . $str->hide . '" href="' . $path . '/mod.php?hide=' . $mod->id . '&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/hide') . '" class="iconsmall" ' . ' alt="' . $str->hide . '" /></a>' . "\n";
        } else {
            $hideshow = '<a class="editing_show" title="' . $str->show . '" href="' . $path . '/mod.php?show=' . $mod->id . '&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/show') . '" class="iconsmall" ' . ' alt="' . $str->show . '" /></a>' . "\n";
        }
    } else {
        $hideshow = '';
    }
    if ($mod->groupmode !== false) {
        if ($mod->groupmode == SEPARATEGROUPS) {
            $grouptitle = $str->groupsseparate;
            $groupclass = 'editing_groupsseparate';
            $groupimage = $OUTPUT->pix_url('t/groups') . '';
            $grouplink = $path . '/mod.php?id=' . $mod->id . '&amp;groupmode=0&amp;sesskey=' . $sesskey;
        } else {
            if ($mod->groupmode == VISIBLEGROUPS) {
                $grouptitle = $str->groupsvisible;
                $groupclass = 'editing_groupsvisible';
                $groupimage = $OUTPUT->pix_url('t/groupv') . '';
                $grouplink = $path . '/mod.php?id=' . $mod->id . '&amp;groupmode=1&amp;sesskey=' . $sesskey;
            } else {
                $grouptitle = $str->groupsnone;
                $groupclass = 'editing_groupsnone';
                $groupimage = $OUTPUT->pix_url('t/groupn') . '';
                $grouplink = $path . '/mod.php?id=' . $mod->id . '&amp;groupmode=2&amp;sesskey=' . $sesskey;
            }
        }
        if ($mod->groupmodelink) {
            $groupmode = '<a class="' . $groupclass . '" title="' . $grouptitle . ' (' . $str->clicktochange . ')" href="' . $grouplink . '">' . '<img src="' . $groupimage . '" class="iconsmall" ' . 'alt="' . $grouptitle . '" /></a>';
        } else {
            $groupmode = '<img title="' . $grouptitle . ' (' . $str->forcedmode . ')" ' . ' src="' . $groupimage . '" class="iconsmall" ' . 'alt="' . $grouptitle . '" />';
        }
    } else {
        $groupmode = "";
    }
    if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
        if ($moveselect) {
            $move = '<a class="editing_move" title="' . $str->move . '" href="' . $path . '/mod.php?copy=' . $mod->id . '&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/move') . '" class="iconsmall" ' . ' alt="' . $str->move . '" /></a>' . "\n";
        } else {
            $move = '<a class="editing_moveup" title="' . $str->moveup . '" href="' . $path . '/mod.php?id=' . $mod->id . '&amp;move=-1&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/up') . '" class="iconsmall" ' . ' alt="' . $str->moveup . '" /></a>' . "\n" . '<a class="editing_movedown" title="' . $str->movedown . '" href="' . $path . '/mod.php?id=' . $mod->id . '&amp;move=1&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/down') . '" class="iconsmall" ' . ' alt="' . $str->movedown . '" /></a>' . "\n";
        }
    } else {
        $move = '';
    }
    $leftright = '';
    if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
        if (right_to_left()) {
            // Exchange arrows on RTL
            $rightarrow = 't/left';
            $leftarrow = 't/right';
        } else {
            $rightarrow = 't/right';
            $leftarrow = 't/left';
        }
        if ($indent > 0) {
            $leftright .= '<a class="editing_moveleft" title="' . $str->moveleft . '" href="' . $path . '/mod.php?id=' . $mod->id . '&amp;indent=-1&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url($leftarrow) . '" class="iconsmall" ' . ' alt="' . $str->moveleft . '" /></a>' . "\n";
        }
        if ($indent >= 0) {
            $leftright .= '<a class="editing_moveright" title="' . $str->moveright . '" href="' . $path . '/mod.php?id=' . $mod->id . '&amp;indent=1&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url($rightarrow) . '" class="iconsmall" ' . ' alt="' . $str->moveright . '" /></a>' . "\n";
        }
    }
    if (has_capability('moodle/course:managegroups', $modcontext)) {
        $context = get_context_instance(CONTEXT_MODULE, $mod->id);
        $assign = '<a class="editing_assign" title="' . $str->assign . '" href="' . $CFG->wwwroot . '/' . $CFG->admin . '/roles/assign.php?contextid=' . $context->id . '"><img src="' . $OUTPUT->pix_url('i/roles') . '" alt="' . $str->assign . '" class="iconsmall"/></a>';
    } else {
        $assign = '';
    }
    // Duplicate (require both target import caps to be able to duplicate, see modduplicate.php)
    $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
    if (has_all_capabilities($dupecaps, get_context_instance(CONTEXT_COURSE, $mod->course))) {
        $duplicatemodule = '<a class="editing_duplicate" title="' . $str->duplicate . '" href="' . $path . '/mod.php?duplicate=' . $mod->id . '&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/copy') . '" class="iconsmall" ' . ' alt="' . $str->duplicate . '" /></a>' . "\n";
    } else {
        $duplicatemodule = '';
    }
    return '<span class="commands">' . "\n" . $leftright . $move . '<a class="editing_update" title="' . $str->update . '" href="' . $path . '/mod.php?update=' . $mod->id . '&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/edit') . '" class="iconsmall" ' . ' alt="' . $str->update . '" /></a>' . "\n" . $duplicatemodule . '<a class="editing_delete" title="' . $str->delete . '" href="' . $path . '/mod.php?delete=' . $mod->id . '&amp;sesskey=' . $sesskey . $section . '"><img' . ' src="' . $OUTPUT->pix_url('t/delete') . '" class="iconsmall" ' . ' alt="' . $str->delete . '" /></a>' . "\n" . $hideshow . $groupmode . "\n" . $assign . '</span>';
}
Пример #15
0
/**
 * Produces the editing buttons for a module
 *
 * @global core_renderer $OUTPUT
 * @staticvar type $str
 * @param stdClass $mod The module to produce editing buttons for
 * @param bool $absolute_ignored ignored - all links are absolute
 * @param bool $moveselect If true a move seleciton process is used (default true)
 * @param int $indent The current indenting
 * @param int $section The section to link back to
 * @return string XHTML for the editing buttons
 */
function make_editing_buttons(stdClass $mod, $absolute_ignored = true, $moveselect = true, $indent = -1, $section = null)
{
    global $CFG, $OUTPUT, $COURSE;
    static $str;
    $coursecontext = context_course::instance($mod->course);
    $modcontext = context_module::instance($mod->id);
    $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign');
    $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
    // no permission to edit anything
    if (!has_any_capability($editcaps, $modcontext) and !has_all_capabilities($dupecaps, $coursecontext)) {
        return false;
    }
    $hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
    if (!isset($str)) {
        $str = new stdClass();
        $str->assign = get_string("assignroles", 'role');
        $str->delete = get_string("delete");
        $str->move = get_string("move");
        $str->moveup = get_string("moveup");
        $str->movedown = get_string("movedown");
        $str->moveright = get_string("moveright");
        $str->moveleft = get_string("moveleft");
        $str->update = get_string("update");
        $str->duplicate = get_string("duplicate");
        $str->hide = get_string("hide");
        $str->show = get_string("show");
        $str->groupsnone = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone"));
        $str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->groupsvisible = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible"));
        $str->forcedgroupsnone = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsnone"));
        $str->forcedgroupsseparate = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->forcedgroupsvisible = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsvisible"));
        $str->edittitle = get_string('edittitle', 'moodle');
    }
    $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
    if ($section !== null) {
        $baseurl->param('sr', $section);
    }
    $actions = array();
    // AJAX edit title
    if ($mod->modname !== 'label' && $hasmanageactivities && course_ajax_enabled($COURSE)) {
        $actions[] = new action_link(new moodle_url($baseurl, array('update' => $mod->id)), new pix_icon('t/editstring', $str->edittitle, 'moodle', array('class' => 'iconsmall visibleifjs', 'title' => '')), null, array('class' => 'editing_title', 'title' => $str->edittitle));
    }
    // leftright
    if ($hasmanageactivities) {
        if (right_to_left()) {
            // Exchange arrows on RTL
            $rightarrow = 't/left';
            $leftarrow = 't/right';
        } else {
            $rightarrow = 't/right';
            $leftarrow = 't/left';
        }
        if ($indent > 0) {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')), new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_moveleft', 'title' => $str->moveleft));
        }
        if ($indent >= 0) {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '1')), new pix_icon($rightarrow, $str->moveright, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_moveright', 'title' => $str->moveright));
        }
    }
    // move
    if ($hasmanageactivities) {
        if ($moveselect) {
            $actions[] = new action_link(new moodle_url($baseurl, array('copy' => $mod->id)), new pix_icon('t/move', $str->move, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_move', 'title' => $str->move));
        } else {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'move' => '-1')), new pix_icon('t/up', $str->moveup, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_moveup', 'title' => $str->moveup));
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'move' => '1')), new pix_icon('t/down', $str->movedown, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_movedown', 'title' => $str->movedown));
        }
    }
    // Update
    if ($hasmanageactivities) {
        $actions[] = new action_link(new moodle_url($baseurl, array('update' => $mod->id)), new pix_icon('t/edit', $str->update, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_update', 'title' => $str->update));
    }
    // Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php)
    if (has_all_capabilities($dupecaps, $coursecontext) && plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2)) {
        $actions[] = new action_link(new moodle_url($baseurl, array('duplicate' => $mod->id)), new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_duplicate', 'title' => $str->duplicate));
    }
    // Delete
    if ($hasmanageactivities) {
        $actions[] = new action_link(new moodle_url($baseurl, array('delete' => $mod->id)), new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_delete', 'title' => $str->delete));
    }
    // hideshow
    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
        if ($mod->visible) {
            $actions[] = new action_link(new moodle_url($baseurl, array('hide' => $mod->id)), new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_hide', 'title' => $str->hide));
        } else {
            $actions[] = new action_link(new moodle_url($baseurl, array('show' => $mod->id)), new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_show', 'title' => $str->show));
        }
    }
    // groupmode
    if ($hasmanageactivities and $mod->groupmode !== false) {
        if ($mod->groupmode == SEPARATEGROUPS) {
            $groupmode = 0;
            $grouptitle = $str->groupsseparate;
            $forcedgrouptitle = $str->forcedgroupsseparate;
            $groupclass = 'editing_groupsseparate';
            $groupimage = 't/groups';
        } else {
            if ($mod->groupmode == VISIBLEGROUPS) {
                $groupmode = 1;
                $grouptitle = $str->groupsvisible;
                $forcedgrouptitle = $str->forcedgroupsvisible;
                $groupclass = 'editing_groupsvisible';
                $groupimage = 't/groupv';
            } else {
                $groupmode = 2;
                $grouptitle = $str->groupsnone;
                $forcedgrouptitle = $str->forcedgroupsnone;
                $groupclass = 'editing_groupsnone';
                $groupimage = 't/groupn';
            }
        }
        if ($mod->groupmodelink) {
            $actions[] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $groupmode)), new pix_icon($groupimage, $grouptitle, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => $groupclass, 'title' => $grouptitle));
        } else {
            $actions[] = new pix_icon($groupimage, $forcedgrouptitle, 'moodle', array('title' => $forcedgrouptitle, 'class' => 'iconsmall'));
        }
    }
    // Assign
    if (has_capability('moodle/role:assign', $modcontext)) {
        $actions[] = new action_link(new moodle_url('/' . $CFG->admin . '/roles/assign.php', array('contextid' => $modcontext->id)), new pix_icon('t/assignroles', $str->assign, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_assign', 'title' => $str->assign));
    }
    // The space added before the <span> is a ugly hack but required to set the CSS property white-space: nowrap
    // and having it to work without attaching the preceding text along with it. Hopefully the refactoring of
    // the course page HTML will allow this to be removed.
    $output = ' ' . html_writer::start_tag('span', array('class' => 'commands'));
    foreach ($actions as $action) {
        if ($action instanceof renderable) {
            $output .= $OUTPUT->render($action);
        } else {
            $output .= $action;
        }
    }
    $output .= html_writer::end_tag('span');
    return $output;
}
 static function add($modulename, $courseid, $atstart = 0, $ifexists = 0, $moduleparams = null, $section = 0, $visible = 0, $permissionsoverrides = array())
 {
     global $DB, $CFG;
     // Check module type exists
     if (!($module = $DB->get_record('modules', array('name' => $modulename), '*'))) {
         return array(false, 'Module type not found');
     }
     // Check course exists
     if (!($course = $DB->get_record('course', array('id' => $courseid), '*'))) {
         return array(false, 'Course not found');
     }
     // Check course is correct format
     if ($course->format == 'site' || $course->format == 'social' || $course->format == 'scorm') {
         return array(false, 'Course is not a weekly or topic type, skipping');
     }
     // Check user has required permissions to add course module
     $requiredcapabilities = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:override');
     if (!has_all_capabilities($requiredcapabilities, context_course::instance($courseid))) {
         return array(false, 'Insufficient permissions to add course module');
     }
     // Set course module initial data
     $newcm = new stdClass();
     $newcm->course = $course->id;
     $newcm->module = $module->id;
     $newcm->modulename = $module->name;
     $newcm->section = 0;
     $newcm->instance = 0;
     $newcm->visible = $visible;
     $newcm->groupmode = 0;
     // No groups
     $newcm->groupingid = 0;
     $newcm->groupmembersonly = 0;
     $newcm->showdescription = 0;
     $newcm->cmidnumber = '';
     // Check whether module plugin class exists for selected module otherwise use generic module plugin
     $modulepluginclass = 'module_plugin_' . $modulename;
     $modulepluginfilename = 'moduleplugins/' . $modulepluginclass . '.php';
     if (file_exists($modulepluginfilename)) {
         include_once $modulepluginfilename;
         $moduleplugin = new $modulepluginclass($moduleparams, $newcm);
     } else {
         include_once 'moduleplugins/module_plugin_generic.php';
         $moduleplugin = new module_plugin_generic($moduleparams, $newcm, $modulename);
         $modulepluginclass = 'module_plugin_generic';
     }
     // Check that module params XML is valid
     if (!$modulepluginclass::check_params_xml($moduleparams)) {
         return array(false, 'Module parameters not valid');
     }
     $newcm->name = (string) $moduleparams->title;
     $newcm->intro = (string) $moduleparams->description;
     $newcm->introformat = 1;
     // Check whether module instance with title already exists
     $sql = 'SELECT COUNT(*) AS count FROM {course_sections} AS cs JOIN {course_modules} AS cm ON cm.section = cs.id JOIN {modules} AS ms ON ms.id = cm.module JOIN {' . $module->name . '} AS m ON m.id = cm.instance WHERE cs.course = ? AND cs.section = ? AND m.name = ? AND ms.name = ?';
     $instances = $DB->get_record_sql($sql, array($course->id, $section, $newcm->name, $module->name));
     if ($instances->count > 0) {
         if ($ifexists == 0) {
             return array(false, 'Already exists, skipping');
         } else {
             if ($ifexists == 2) {
                 if (!self::delete($modulename, $course, $newcm->name, $section)) {
                     return array(false, 'Error removing existing module instance(s), could not replace');
                 }
             }
         }
     }
     // Create course module
     if (!($newcm->coursemodule = add_course_module($newcm))) {
         return array(false, 'Could not create course module');
     }
     // Create module instance
     $ret = $moduleplugin->create_instance();
     if (!$ret[0]) {
         return $ret;
     }
     // Update course_modules DB row to reference new module instance
     $DB->set_field('course_modules', 'instance', $newcm->instance, array('id' => $newcm->coursemodule));
     // course_modules and course_sections each contain a reference
     // to each other, so we have to update one of them twice.
     if ($atstart) {
         if (!($section = $DB->get_record('course_sections', array('course' => $newcm->course, 'section' => $newcm->section)))) {
             // Section doesn't already exist so create it in normal manner
             // $sectionid = add_mod_to_section($newcm); JAC change 20160809
             // requires course_add_cm_to_section($courseorid, $cmid, $sectionnum, $beforemod = null)
             $sectionid = course_add_cm_to_section($newcm->course, $newcm->coursemodule, $newcm->section);
         } else {
             // Moodle's add_mod_to_section add before functionality is broken so we have to do this here
             $section->sequence = trim($section->sequence);
             if (empty($section->sequence)) {
                 $newsequence = "{$newcm->coursemodule}";
             } else {
                 $newsequence = "{$newcm->coursemodule},{$section->sequence}";
             }
             $DB->set_field("course_sections", "sequence", $newsequence, array("id" => $section->id));
             $sectionid = $section->id;
         }
     } else {
         // $sectionid = add_mod_to_section($newcm); JAC change 20160809
         $sectionid = course_add_cm_to_section($newcm->course, $newcm->coursemodule, $newcm->section);
     }
     $DB->set_field('course_modules', 'section', $sectionid, array('id' => $newcm->coursemodule));
     // Trigger post create actions
     $ret = $moduleplugin->post_create_setup();
     if (!$ret[0]) {
         self::delete($modulename, $course, $newcm->name, $section);
         return array(false, 'Error carrying out post creation setup. Error was: ' . $ret[1]);
     }
     // If $permissionsoverrides is not empty, override permissions of specified role capabilites
     if (count($permissionsoverrides) > 0) {
         $modcontext = context_module::instance($newcm->coursemodule);
         foreach ($permissionsoverrides as $permissionoverride) {
             $permission = $permissionoverride[2] == 'allow' ? CAP_ALLOW : CAP_PREVENT;
             role_change_permission($permissionoverride[0], $modcontext, $permissionoverride[1], $permission);
         }
     }
     // Trigger mod_created event with information about this module.
     $eventname = 'mod_created';
     $eventdata = new stdClass();
     $eventdata->modulename = $module->name;
     $eventdata->name = $newcm->name;
     $eventdata->cmid = $newcm->coursemodule;
     $eventdata->courseid = $course->id;
     $eventdata->userid = 0;
     events_trigger($eventname, $eventdata);
     // Rebuild course cache
     rebuild_course_cache($course->id);
     return array(true, '');
 }
Пример #17
0
    // May as well just bail aggressively here.
    print_error('invaliduserid');
}
// Make sure the user has not been deleted
if ($user->deleted) {
    $PAGE->set_title(get_string('userdeleted'));
    $PAGE->set_context(get_system_context());
    echo $OUTPUT->header();
    echo $OUTPUT->heading($PAGE->title);
    echo $OUTPUT->footer();
    die;
}
$isloggedin = isloggedin();
$isguestuser = $isloggedin && isguestuser();
$isparent = !$iscurrentuser && $DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id));
$hasparentaccess = $isparent && has_all_capabilities(array('moodle/user:viewdetails', 'moodle/user:readuserposts'), $usercontext);
// Check whether a specific course has been requested
if ($isspecificcourse) {
    // Get the requested course and its context
    $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
    $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid, MUST_EXIST);
    // We have a specific course to search, which we will also assume we are within.
    if ($hasparentaccess) {
        // A `parent` role won't likely have access to the course so we won't attempt
        // to enter it. We will however still make them jump through the normal
        // login hoops
        require_login();
        $PAGE->set_context($coursecontext);
        $PAGE->set_course($course);
    } else {
        // Enter the course we are searching
Пример #18
0
 /**
  * Returns an array of courses the user is enrolled in, and for each course all of the seplments that the user can
  * view within that course.
  *
  * @param array $courseids An optional array of course ids. If provided only seplments within the given course
  * will be returned. If the user is not enrolled in a given course a warning will be generated and returned.
  * @param array $capabilities An array of additional capability checks you wish to be made on the course context.
  * @return An array of courses and warnings.
  * @since  Moodle 2.4
  */
 public static function get_seplments($courseids = array(), $capabilities = array())
 {
     global $USER, $DB, $CFG;
     require_once "{$CFG->dirroot}/mod/sepl/locallib.php";
     $params = self::validate_parameters(self::get_seplments_parameters(), array('courseids' => $courseids, 'capabilities' => $capabilities));
     $warnings = array();
     $fields = 'sortorder,shortname,fullname,timemodified';
     $courses = enrol_get_users_courses($USER->id, true, $fields);
     // Used to test for ids that have been requested but can't be returned.
     if (count($params['courseids']) > 0) {
         foreach ($params['courseids'] as $courseid) {
             if (!in_array($courseid, array_keys($courses))) {
                 unset($courses[$courseid]);
                 $warnings[] = array('item' => 'course', 'itemid' => $courseid, 'warningcode' => '2', 'message' => 'User is not enrolled or does not have requested capability');
             }
         }
     }
     foreach ($courses as $id => $course) {
         if (count($params['courseids']) > 0 && !in_array($id, $params['courseids'])) {
             unset($courses[$id]);
         }
         $context = context_course::instance($id);
         try {
             self::validate_context($context);
         } catch (Exception $e) {
             unset($courses[$id]);
             $warnings[] = array('item' => 'course', 'itemid' => $id, 'warningcode' => '1', 'message' => 'No access rights in course context ' . $e->getMessage() . $e->getTraceAsString());
             continue;
         }
         if (count($params['capabilities']) > 0 && !has_all_capabilities($params['capabilities'], $context)) {
             unset($courses[$id]);
         }
     }
     $extrafields = 'm.id as seplmentid, ' . 'm.course, ' . 'm.nosubmissions, ' . 'm.submissiondrafts, ' . 'm.sendnotifications, ' . 'm.sendlatenotifications, ' . 'm.sendstudentnotifications, ' . 'm.duedate, ' . 'm.allowsubmissionsfromdate, ' . 'm.grade, ' . 'm.timemodified, ' . 'm.completionsubmit, ' . 'm.cutoffdate, ' . 'm.teamsubmission, ' . 'm.requireallteammemberssubmit, ' . 'm.teamsubmissiongroupingid, ' . 'm.blindmarking, ' . 'm.revealidentities, ' . 'm.attemptreopenmethod, ' . 'm.maxattempts, ' . 'm.markingworkflow, ' . 'm.markingallocation, ' . 'm.requiresubmissionstatement, ' . 'm.intro, ' . 'm.introformat';
     $coursearray = array();
     foreach ($courses as $id => $course) {
         $seplmentarray = array();
         // Get a list of seplments for the course.
         if ($modules = get_coursemodules_in_course('sepl', $courses[$id]->id, $extrafields)) {
             foreach ($modules as $module) {
                 $context = context_module::instance($module->id);
                 try {
                     self::validate_context($context);
                     require_capability('mod/sepl:view', $context);
                 } catch (Exception $e) {
                     $warnings[] = array('item' => 'module', 'itemid' => $module->id, 'warningcode' => '1', 'message' => 'No access rights in module context');
                     continue;
                 }
                 $configrecords = $DB->get_recordset('sepl_plugin_config', array('seplment' => $module->seplmentid));
                 $configarray = array();
                 foreach ($configrecords as $configrecord) {
                     $configarray[] = array('id' => $configrecord->id, 'seplment' => $configrecord->seplment, 'plugin' => $configrecord->plugin, 'subtype' => $configrecord->subtype, 'name' => $configrecord->name, 'value' => $configrecord->value);
                 }
                 $configrecords->close();
                 $seplment = array('id' => $module->seplmentid, 'cmid' => $module->id, 'course' => $module->course, 'name' => $module->name, 'nosubmissions' => $module->nosubmissions, 'submissiondrafts' => $module->submissiondrafts, 'sendnotifications' => $module->sendnotifications, 'sendlatenotifications' => $module->sendlatenotifications, 'sendstudentnotifications' => $module->sendstudentnotifications, 'duedate' => $module->duedate, 'allowsubmissionsfromdate' => $module->allowsubmissionsfromdate, 'grade' => $module->grade, 'timemodified' => $module->timemodified, 'completionsubmit' => $module->completionsubmit, 'cutoffdate' => $module->cutoffdate, 'teamsubmission' => $module->teamsubmission, 'requireallteammemberssubmit' => $module->requireallteammemberssubmit, 'teamsubmissiongroupingid' => $module->teamsubmissiongroupingid, 'blindmarking' => $module->blindmarking, 'revealidentities' => $module->revealidentities, 'attemptreopenmethod' => $module->attemptreopenmethod, 'maxattempts' => $module->maxattempts, 'markingworkflow' => $module->markingworkflow, 'markingallocation' => $module->markingallocation, 'requiresubmissionstatement' => $module->requiresubmissionstatement, 'configs' => $configarray);
                 // Return or not intro and file attachments depending on the plugin settings.
                 $sepl = new sepl($context, null, null);
                 if ($sepl->show_intro()) {
                     list($seplment['intro'], $seplment['introformat']) = external_format_text($module->intro, $module->introformat, $context->id, 'mod_sepl', ASSIGN_INTROATTACHMENT_FILEAREA, 0);
                     $fs = get_file_storage();
                     if ($files = $fs->get_area_files($context->id, 'mod_sepl', ASSIGN_INTROATTACHMENT_FILEAREA, 0, 'timemodified', false)) {
                         $seplment['introattachments'] = array();
                         foreach ($files as $file) {
                             $filename = $file->get_filename();
                             $seplment['introattachments'][] = array('filename' => $filename, 'mimetype' => $file->get_mimetype(), 'fileurl' => moodle_url::make_webservice_pluginfile_url($context->id, 'mod_sepl', ASSIGN_INTROATTACHMENT_FILEAREA, 0, '/', $filename)->out(false));
                         }
                     }
                 }
                 $seplmentarray[] = $seplment;
             }
         }
         $coursearray[] = array('id' => $courses[$id]->id, 'fullname' => $courses[$id]->fullname, 'shortname' => $courses[$id]->shortname, 'timemodified' => $courses[$id]->timemodified, 'seplments' => $seplmentarray);
     }
     $result = array('courses' => $coursearray, 'warnings' => $warnings);
     return $result;
 }
Пример #19
0
 /**
  * Test has_capability(), has_any_capability() and has_all_capabilities().
  */
 public function test_has_capability_and_friends()
 {
     global $DB;
     $this->resetAfterTest();
     $course = $this->getDataGenerator()->create_course();
     $coursecontext = context_course::instance($course->id);
     $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'), '*', MUST_EXIST);
     $teacher = $this->getDataGenerator()->create_user();
     role_assign($teacherrole->id, $teacher->id, $coursecontext);
     $admin = $DB->get_record('user', array('username' => 'admin'));
     // Note: Here are used default capabilities, the full test is in permission evaluation bellow,
     // use two capabilities that teacher has and one does not, none of them should be allowed for not-logged-in user.
     $this->assertTrue($DB->record_exists('capabilities', array('name' => 'moodle/backup:backupsection')));
     $this->assertTrue($DB->record_exists('capabilities', array('name' => 'moodle/backup:backupcourse')));
     $this->assertTrue($DB->record_exists('capabilities', array('name' => 'moodle/site:approvecourse')));
     $sca = array('moodle/backup:backupsection', 'moodle/backup:backupcourse', 'moodle/site:approvecourse');
     $sc = array('moodle/backup:backupsection', 'moodle/backup:backupcourse');
     $this->setUser(0);
     $this->assertFalse(has_capability('moodle/backup:backupsection', $coursecontext));
     $this->assertFalse(has_capability('moodle/backup:backupcourse', $coursecontext));
     $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext));
     $this->assertFalse(has_any_capability($sca, $coursecontext));
     $this->assertFalse(has_all_capabilities($sca, $coursecontext));
     $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext, $teacher));
     $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext, $teacher));
     $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext, $teacher));
     $this->assertTrue(has_any_capability($sca, $coursecontext, $teacher));
     $this->assertTrue(has_all_capabilities($sc, $coursecontext, $teacher));
     $this->assertFalse(has_all_capabilities($sca, $coursecontext, $teacher));
     $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext, $admin));
     $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext, $admin));
     $this->assertTrue(has_capability('moodle/site:approvecourse', $coursecontext, $admin));
     $this->assertTrue(has_any_capability($sca, $coursecontext, $admin));
     $this->assertTrue(has_all_capabilities($sc, $coursecontext, $admin));
     $this->assertTrue(has_all_capabilities($sca, $coursecontext, $admin));
     $this->assertFalse(has_capability('moodle/backup:backupsection', $coursecontext, $admin, false));
     $this->assertFalse(has_capability('moodle/backup:backupcourse', $coursecontext, $admin, false));
     $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext, $admin, false));
     $this->assertFalse(has_any_capability($sca, $coursecontext, $admin, false));
     $this->assertFalse(has_all_capabilities($sc, $coursecontext, $admin, false));
     $this->assertFalse(has_all_capabilities($sca, $coursecontext, $admin, false));
     $this->setUser($teacher);
     $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext));
     $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext));
     $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext));
     $this->assertTrue(has_any_capability($sca, $coursecontext));
     $this->assertTrue(has_all_capabilities($sc, $coursecontext));
     $this->assertFalse(has_all_capabilities($sca, $coursecontext));
     $this->setAdminUser();
     $this->assertTrue(has_capability('moodle/backup:backupsection', $coursecontext));
     $this->assertTrue(has_capability('moodle/backup:backupcourse', $coursecontext));
     $this->assertTrue(has_capability('moodle/site:approvecourse', $coursecontext));
     $this->assertTrue(has_any_capability($sca, $coursecontext));
     $this->assertTrue(has_all_capabilities($sc, $coursecontext));
     $this->assertTrue(has_all_capabilities($sca, $coursecontext));
     $this->assertFalse(has_capability('moodle/backup:backupsection', $coursecontext, 0));
     $this->assertFalse(has_capability('moodle/backup:backupcourse', $coursecontext, 0));
     $this->assertFalse(has_capability('moodle/site:approvecourse', $coursecontext, 0));
     $this->assertFalse(has_any_capability($sca, $coursecontext, 0));
     $this->assertFalse(has_all_capabilities($sca, $coursecontext, 0));
 }
Пример #20
0
/**
 * Used to add options to the Settings menu for the subpage
 * @param unknown_type $settings Don't know what this parameter is
 * @param navigation_node $subpagenode Navigation node object for subpage
 */
function subpage_extend_settings_navigation($settings, navigation_node $subpagenode)
{
    global $PAGE;
    if ($PAGE->user_allowed_editing()) {
        $url = new moodle_url('/mod/subpage/view.php', array('id' => $PAGE->cm->id));
        $url->param('sesskey', sesskey());
        if ($PAGE->user_is_editing()) {
            $url->param('edit', 'off');
            $editstring = get_string('turneditingoff');
        } else {
            $url->param('edit', 'on');
            $editstring = get_string('turneditingon');
        }
        $node = navigation_node::create($editstring, $url, navigation_node::TYPE_SETTING, null, 'subpageeditingtoggle');
        $subpagenode->add_node($node, 'modedit');
    }
    if (has_all_capabilities(array('moodle/backup:backupsection', 'moodle/backup:backupactivity'), $PAGE->context)) {
        $url = new moodle_url('/mod/subpage/copy.php', array('id' => $PAGE->cm->id));
        $node = navigation_node::create(get_string('copy', 'subpage'), $url, navigation_node::TYPE_SETTING, null, 'subpagecopy');
        $subpagenode->add_node($node);
    }
}
Пример #21
0
 /**
  * Returns an array of plugin reports as grade_plugin_info objects
  *
  * @param int $courseid
  * @return array
  */
 public static function get_plugins_reports($courseid)
 {
     global $SITE;
     if (self::$gradereports !== null) {
         return self::$gradereports;
     }
     $context = context_course::instance($courseid);
     $gradereports = array();
     $gradepreferences = array();
     foreach (core_component::get_plugin_list('gradereport') as $plugin => $plugindir) {
         //some reports make no sense if we're not within a course
         if ($courseid == $SITE->id && ($plugin == 'grader' || $plugin == 'user')) {
             continue;
         }
         // Remove ones we can't see
         if (!has_capability('gradereport/' . $plugin . ':view', $context)) {
             continue;
         }
         // Singleview doesn't doesn't accomodate for all cap combos yet, so this is hardcoded..
         if ($plugin === 'singleview' && !has_all_capabilities(array('moodle/grade:viewall', 'moodle/grade:edit'), $context)) {
             continue;
         }
         $pluginstr = get_string('pluginname', 'gradereport_' . $plugin);
         $url = new moodle_url('/grade/report/' . $plugin . '/index.php', array('id' => $courseid));
         $gradereports[$plugin] = new grade_plugin_info($plugin, $url, $pluginstr);
         // Add link to preferences tab if such a page exists
         if (file_exists($plugindir . '/preferences.php')) {
             $url = new moodle_url('/grade/report/' . $plugin . '/preferences.php', array('id' => $courseid));
             $gradepreferences[$plugin] = new grade_plugin_info($plugin, $url, get_string('preferences', 'grades') . ': ' . $pluginstr);
         }
     }
     if (count($gradereports) == 0) {
         $gradereports = false;
         $gradepreferences = false;
     } else {
         if (count($gradepreferences) == 0) {
             $gradepreferences = false;
             asort($gradereports);
         } else {
             asort($gradereports);
             asort($gradepreferences);
         }
     }
     self::$gradereports = $gradereports;
     self::$gradereportpreferences = $gradepreferences;
     return self::$gradereports;
 }
Пример #22
0
/**
 * This function recursively travels the categories, building up a nice list
 * for display. It also makes an array that list all the parents for each
 * category.
 *
 * For example, if you have a tree of categories like:
 *   Miscellaneous (id = 1)
 *      Subcategory (id = 2)
 *         Sub-subcategory (id = 4)
 *   Other category (id = 3)
 * Then after calling this function you will have
 * $list = array(1 => 'Miscellaneous', 2 => 'Miscellaneous / Subcategory',
 *      4 => 'Miscellaneous / Subcategory / Sub-subcategory',
 *      3 => 'Other category');
 * $parents = array(2 => array(1), 4 => array(1, 2));
 *
 * If you specify $requiredcapability, then only categories where the current
 * user has that capability will be added to $list, although all categories
 * will still be added to $parents, and if you only have $requiredcapability
 * in a child category, not the parent, then the child catgegory will still be
 * included.
 *
 * If you specify the option $excluded, then that category, and all its children,
 * are omitted from the tree. This is useful when you are doing something like
 * moving categories, where you do not want to allow people to move a category
 * to be the child of itself.
 *
 * @param array $list For output, accumulates an array categoryid => full category path name
 * @param array $parents For output, accumulates an array categoryid => list of parent category ids.
 * @param string/array $requiredcapability if given, only categories where the current
 *      user has this capability will be added to $list. Can also be an array of capabilities,
 *      in which case they are all required.
 * @param integer $excludeid Omit this category and its children from the lists built.
 * @param object $category Build the tree starting at this category - otherwise starts at the top level.
 * @param string $path For internal use, as part of recursive calls.
 */
function make_categories_list(&$list, &$parents, $requiredcapability = '', $excludeid = 0, $category = NULL, $path = "")
{
    // initialize the arrays if needed
    if (!is_array($list)) {
        $list = array();
    }
    if (!is_array($parents)) {
        $parents = array();
    }
    if (empty($category)) {
        // Start at the top level.
        $category = new stdClass();
        $category->id = 0;
    } else {
        // This is the excluded category, don't include it.
        if ($excludeid > 0 && $excludeid == $category->id) {
            return;
        }
        // Update $path.
        if ($path) {
            $path = $path . ' / ' . format_string($category->name);
        } else {
            $path = format_string($category->name);
        }
        // Add this category to $list, if the permissions check out.
        if (empty($requiredcapability)) {
            $list[$category->id] = $path;
        } else {
            ensure_context_subobj_present($category, CONTEXT_COURSECAT);
            $requiredcapability = (array) $requiredcapability;
            if (has_all_capabilities($requiredcapability, $category->context)) {
                $list[$category->id] = $path;
            }
        }
    }
    // Add all the children recursively, while updating the parents array.
    if ($categories = get_child_categories($category->id)) {
        foreach ($categories as $cat) {
            if (!empty($category->id)) {
                if (isset($parents[$category->id])) {
                    $parents[$cat->id] = $parents[$category->id];
                }
                $parents[$cat->id][] = $category->id;
            }
            make_categories_list($list, $parents, $requiredcapability, $excludeid, $cat, $path);
        }
    }
}
Пример #23
0
    /**
     * add elements to grade form
     *
     * @param MoodleQuickForm $mform
     * @param stdClass $data
     * @param array $params
     * @return void
     */
    public function add_grade_form_elements(MoodleQuickForm $mform, stdClass $data, $params) {
        global $USER, $CFG;
        $settings = $this->get_instance();

        $rownum = $params['rownum'];
        $last = $params['last'];
        $useridlist = $params['useridlist'];
        $userid = $useridlist[$rownum];
        $grade = $this->get_user_grade($userid, false);

        // add advanced grading
        $gradingdisabled = $this->grading_disabled($userid);
        $gradinginstance = $this->get_grading_instance($userid, $gradingdisabled);

        if ($gradinginstance) {
            $gradingelement = $mform->addElement('grading', 'advancedgrading', get_string('grade').':', array('gradinginstance' => $gradinginstance));
            if ($gradingdisabled) {
                $gradingelement->freeze();
            } else {
                $mform->addElement('hidden', 'advancedgradinginstanceid', $gradinginstance->get_id());
            }
        } else {
            // use simple direct grading
            if ($this->get_instance()->grade > 0) {
                $gradingelement = $mform->addElement('text', 'grade', get_string('gradeoutof', 'assign',$this->get_instance()->grade));
                $mform->addHelpButton('grade', 'gradeoutofhelp', 'assign');
                $mform->setType('grade', PARAM_TEXT);
                if ($gradingdisabled) {
                    $gradingelement->freeze();
                }
            } else {
                $grademenu = make_grades_menu($this->get_instance()->grade);
                if (count($grademenu) > 0) {
                    $gradingelement = $mform->addElement('select', 'grade', get_string('grade').':', $grademenu);
                    $mform->setType('grade', PARAM_INT);
                    if ($gradingdisabled) {
                        $gradingelement->freeze();
                    }
                }
            }
        }

        $gradinginfo = grade_get_grades($this->get_course()->id,
                                        'mod',
                                        'assign',
                                        $this->get_instance()->id,
                                        $userid);
        if (!empty($CFG->enableoutcomes)) {
            foreach($gradinginfo->outcomes as $index=>$outcome) {
                $options = make_grades_menu(-$outcome->scaleid);
                if ($outcome->grades[$userid]->locked) {
                    $options[0] = get_string('nooutcome', 'grades');
                    $mform->addElement('static', 'outcome_'.$index.'['.$userid.']', $outcome->name.':',
                            $options[$outcome->grades[$userid]->grade]);
                } else {
                    $options[''] = get_string('nooutcome', 'grades');
                    $attributes = array('id' => 'menuoutcome_'.$index );
                    $mform->addElement('select', 'outcome_'.$index.'['.$userid.']', $outcome->name.':', $options, $attributes );
                    $mform->setType('outcome_'.$index.'['.$userid.']', PARAM_INT);
                    $mform->setDefault('outcome_'.$index.'['.$userid.']', $outcome->grades[$userid]->grade );
                }
            }
        }

        if (has_all_capabilities(array('gradereport/grader:view', 'moodle/grade:viewall'), $this->get_course_context())) {
            $gradestring = $this->output->action_link(new moodle_url('/grade/report/grader/index.php',
                                                              array('id'=>$this->get_course()->id)),
                                                $gradinginfo->items[0]->grades[$userid]->str_grade);
        } else {
            $gradestring = $gradinginfo->items[0]->grades[$userid]->str_grade;
        }
        $mform->addElement('static', 'finalgrade', get_string('currentgrade', 'assign').':', $gradestring);


        $mform->addElement('static', 'progress', '', get_string('gradingstudentprogress', 'assign', array('index'=>$rownum+1, 'count'=>count($useridlist))));

        // plugins
        $this->add_plugin_grade_elements($grade, $mform, $data);

        // hidden params
        $mform->addElement('hidden', 'id', $this->get_course_module()->id);
        $mform->setType('id', PARAM_INT);
        $mform->addElement('hidden', 'rownum', $rownum);
        $mform->setType('rownum', PARAM_INT);
        $mform->addElement('hidden', 'useridlist', implode(',', $useridlist));
        $mform->setType('useridlist', PARAM_TEXT);
        $mform->addElement('hidden', 'ajax', optional_param('ajax', 0, PARAM_INT));
        $mform->setType('ajax', PARAM_INT);

        if ($this->get_instance()->teamsubmission) {
            $mform->addElement('selectyesno', 'applytoall', get_string('applytoteam', 'assign'));
            $mform->setDefault('applytoall', 1);
        }

        $mform->addElement('hidden', 'action', 'submitgrade');
        $mform->setType('action', PARAM_ALPHA);


        $buttonarray=array();
        $buttonarray[] = $mform->createElement('submit', 'savegrade', get_string('savechanges', 'assign'));
        if (!$last) {
            $buttonarray[] = $mform->createElement('submit', 'saveandshownext', get_string('savenext','assign'));
        }
        $buttonarray[] = $mform->createElement('cancel', 'cancelbutton', get_string('cancel'));
        $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
        $mform->closeHeaderBefore('buttonar');
        $buttonarray=array();

        if ($rownum > 0) {
            $buttonarray[] = $mform->createElement('submit', 'nosaveandprevious', get_string('previous','assign'));
        }

        if (!$last) {
            $buttonarray[] = $mform->createElement('submit', 'nosaveandnext', get_string('nosavebutnext', 'assign'));
        }
        $mform->addGroup($buttonarray, 'navar', '', array(' '), false);
    }
Пример #24
0
/**
 * Returns the list of all editing actions that current user can perform on the module
 *
 * @param cm_info $mod The module to produce editing buttons for
 * @param int $indent The current indenting (default -1 means no move left-right actions)
 * @param int $sr The section to link back to (used for creating the links)
 * @return array array of action_link or pix_icon objects
 */
function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null)
{
    global $COURSE, $SITE;
    static $str;
    $coursecontext = context_course::instance($mod->course);
    $modcontext = context_module::instance($mod->id);
    $editcaps = array('moodle/course:manageactivities', 'moodle/course:activityvisibility', 'moodle/role:assign');
    $dupecaps = array('moodle/backup:backuptargetimport', 'moodle/restore:restoretargetimport');
    // no permission to edit anything
    if (!has_any_capability($editcaps, $modcontext) and !has_all_capabilities($dupecaps, $coursecontext)) {
        return array();
    }
    $hasmanageactivities = has_capability('moodle/course:manageactivities', $modcontext);
    if (!isset($str)) {
        $str = get_strings(array('delete', 'move', 'moveright', 'moveleft', 'update', 'duplicate', 'hide', 'show', 'edittitle'), 'moodle');
        $str->assign = get_string('assignroles', 'role');
        $str->groupsnone = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsnone"));
        $str->groupsseparate = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->groupsvisible = get_string('clicktochangeinbrackets', 'moodle', get_string("groupsvisible"));
        $str->forcedgroupsnone = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsnone"));
        $str->forcedgroupsseparate = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsseparate"));
        $str->forcedgroupsvisible = get_string('forcedmodeinbrackets', 'moodle', get_string("groupsvisible"));
    }
    $baseurl = new moodle_url('/course/mod.php', array('sesskey' => sesskey()));
    if ($sr !== null) {
        $baseurl->param('sr', $sr);
    }
    $actions = array();
    // AJAX edit title
    if ($mod->has_view() && $hasmanageactivities && ($mod->course == $COURSE->id && course_ajax_enabled($COURSE) || $mod->course == SITEID && course_ajax_enabled($SITE))) {
        // we will not display link if we are on some other-course page (where we should not see this module anyway)
        $actions['title'] = new action_link(new moodle_url($baseurl, array('update' => $mod->id)), new pix_icon('t/editstring', $str->edittitle, 'moodle', array('class' => 'iconsmall visibleifjs', 'title' => '')), null, array('class' => 'editing_title', 'title' => $str->edittitle));
    }
    // leftright
    if ($hasmanageactivities) {
        if (right_to_left()) {
            // Exchange arrows on RTL
            $rightarrow = 't/left';
            $leftarrow = 't/right';
        } else {
            $rightarrow = 't/right';
            $leftarrow = 't/left';
        }
        if ($indent > 0) {
            $actions['moveleft'] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '-1')), new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_moveleft', 'title' => $str->moveleft));
        }
        if ($indent >= 0) {
            $actions['moveright'] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'indent' => '1')), new pix_icon($rightarrow, $str->moveright, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_moveright', 'title' => $str->moveright));
        }
    }
    // move
    if ($hasmanageactivities) {
        $actions['move'] = new action_link(new moodle_url($baseurl, array('copy' => $mod->id)), new pix_icon('t/move', $str->move, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_move', 'title' => $str->move));
    }
    // Update
    if ($hasmanageactivities) {
        $actions['update'] = new action_link(new moodle_url($baseurl, array('update' => $mod->id)), new pix_icon('t/edit', $str->update, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_update', 'title' => $str->update));
    }
    // Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php)
    // note that restoring on front page is never allowed
    if ($mod->course != SITEID && has_all_capabilities($dupecaps, $coursecontext) && plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2)) {
        $actions['duplicate'] = new action_link(new moodle_url($baseurl, array('duplicate' => $mod->id)), new pix_icon('t/copy', $str->duplicate, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_duplicate', 'title' => $str->duplicate));
    }
    // Delete
    if ($hasmanageactivities) {
        $actions['delete'] = new action_link(new moodle_url($baseurl, array('delete' => $mod->id)), new pix_icon('t/delete', $str->delete, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_delete', 'title' => $str->delete));
    }
    // hideshow
    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
        if ($mod->visible) {
            $actions['hide'] = new action_link(new moodle_url($baseurl, array('hide' => $mod->id)), new pix_icon('t/hide', $str->hide, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_hide', 'title' => $str->hide));
        } else {
            $actions['show'] = new action_link(new moodle_url($baseurl, array('show' => $mod->id)), new pix_icon('t/show', $str->show, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_show', 'title' => $str->show));
        }
    }
    // groupmode
    if ($hasmanageactivities and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
        if ($mod->coursegroupmodeforce) {
            $modgroupmode = $mod->coursegroupmode;
        } else {
            $modgroupmode = $mod->groupmode;
        }
        if ($modgroupmode == SEPARATEGROUPS) {
            $groupmode = NOGROUPS;
            $grouptitle = $str->groupsseparate;
            $forcedgrouptitle = $str->forcedgroupsseparate;
            $actionname = 'groupsseparate';
            $groupimage = 't/groups';
        } else {
            if ($modgroupmode == VISIBLEGROUPS) {
                $groupmode = SEPARATEGROUPS;
                $grouptitle = $str->groupsvisible;
                $forcedgrouptitle = $str->forcedgroupsvisible;
                $actionname = 'groupsvisible';
                $groupimage = 't/groupv';
            } else {
                $groupmode = VISIBLEGROUPS;
                $grouptitle = $str->groupsnone;
                $forcedgrouptitle = $str->forcedgroupsnone;
                $actionname = 'groupsnone';
                $groupimage = 't/groupn';
            }
        }
        if (!$mod->coursegroupmodeforce) {
            $actions[$actionname] = new action_link(new moodle_url($baseurl, array('id' => $mod->id, 'groupmode' => $groupmode)), new pix_icon($groupimage, $grouptitle, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_' . $actionname, 'title' => $grouptitle));
        } else {
            $actions[$actionname] = new pix_icon($groupimage, $forcedgrouptitle, 'moodle', array('title' => $forcedgrouptitle, 'class' => 'iconsmall'));
        }
    }
    // Assign
    if (has_capability('moodle/role:assign', $modcontext)) {
        $actions['assign'] = new action_link(new moodle_url('/admin/roles/assign.php', array('contextid' => $modcontext->id)), new pix_icon('t/assignroles', $str->assign, 'moodle', array('class' => 'iconsmall', 'title' => '')), null, array('class' => 'editing_assign', 'title' => $str->assign));
    }
    return $actions;
}
 /**
  * Returns true if the user can change the visibility of this course.
  *
  * Note: this function does not check that the current user can access the course.
  * To do that please call require_login with the course, or if not possible call {@see course_in_list::can_access()}
  *
  * @return bool
  */
 public function can_change_visibility()
 {
     // You must be able to both hide a course and view the hidden course.
     return has_all_capabilities(array('moodle/course:visibility', 'moodle/course:viewhiddencourses'), $this->get_context());
 }
Пример #26
0
 /**
  * Builds and returns the rows that will make up the right part of the grader report
  * @param boolean $displayaverages whether to display average rows in the table
  * @return array Array of html_table_row objects
  */
 public function get_right_rows($displayaverages)
 {
     global $CFG, $USER, $OUTPUT, $DB, $PAGE;
     $rows = array();
     $this->rowcount = 0;
     $numrows = count($this->gtree->get_levels());
     $numusers = count($this->users);
     $gradetabindex = 1;
     $columnstounset = array();
     $strgrade = $this->get_lang_string('grade');
     $strfeedback = $this->get_lang_string("feedback");
     $arrows = $this->get_sort_arrows();
     $jsarguments = array('cfg' => array('ajaxenabled' => false), 'items' => array(), 'users' => array(), 'feedback' => array());
     $jsscales = array();
     // Get preferences once.
     $showactivityicons = $this->get_pref('showactivityicons');
     $quickgrading = $this->get_pref('quickgrading');
     $showquickfeedback = $this->get_pref('showquickfeedback');
     $enableajax = $this->get_pref('enableajax');
     $showanalysisicon = $this->get_pref('showanalysisicon');
     // Get strings which are re-used inside the loop.
     $strftimedatetimeshort = get_string('strftimedatetimeshort');
     $strexcludedgrades = get_string('excluded', 'grades');
     $strerror = get_string('error');
     foreach ($this->gtree->get_levels() as $key => $row) {
         $headingrow = new html_table_row();
         $headingrow->attributes['class'] = 'heading_name_row';
         foreach ($row as $columnkey => $element) {
             $sortlink = clone $this->baseurl;
             if (isset($element['object']->id)) {
                 $sortlink->param('sortitemid', $element['object']->id);
             }
             $eid = $element['eid'];
             $object = $element['object'];
             $type = $element['type'];
             $categorystate = @$element['categorystate'];
             if (!empty($element['colspan'])) {
                 $colspan = $element['colspan'];
             } else {
                 $colspan = 1;
             }
             if (!empty($element['depth'])) {
                 $catlevel = 'catlevel' . $element['depth'];
             } else {
                 $catlevel = '';
             }
             // Element is a filler
             if ($type == 'filler' or $type == 'fillerfirst' or $type == 'fillerlast') {
                 $fillercell = new html_table_cell();
                 $fillercell->attributes['class'] = $type . ' ' . $catlevel;
                 $fillercell->colspan = $colspan;
                 $fillercell->text = '&nbsp;';
                 // This is a filler cell; don't use a <th>, it'll confuse screen readers.
                 $fillercell->header = false;
                 $headingrow->cells[] = $fillercell;
             } else {
                 if ($type == 'category') {
                     // Element is a category
                     $categorycell = new html_table_cell();
                     $categorycell->attributes['class'] = 'category ' . $catlevel;
                     $categorycell->colspan = $colspan;
                     $categorycell->text = $this->get_course_header($element);
                     $categorycell->header = true;
                     $categorycell->scope = 'col';
                     // Print icons
                     if ($USER->gradeediting[$this->courseid]) {
                         $categorycell->text .= $this->get_icons($element);
                     }
                     $headingrow->cells[] = $categorycell;
                 } else {
                     // Element is a grade_item
                     if ($element['object']->id == $this->sortitemid) {
                         if ($this->sortorder == 'ASC') {
                             $arrow = $this->get_sort_arrow('up', $sortlink);
                         } else {
                             $arrow = $this->get_sort_arrow('down', $sortlink);
                         }
                     } else {
                         $arrow = $this->get_sort_arrow('move', $sortlink);
                     }
                     $headerlink = $this->gtree->get_element_header($element, true, $showactivityicons, false, false, true);
                     $itemcell = new html_table_cell();
                     $itemcell->attributes['class'] = $type . ' ' . $catlevel . ' highlightable' . ' i' . $element['object']->id;
                     $itemcell->attributes['data-itemid'] = $element['object']->id;
                     if ($element['object']->is_hidden()) {
                         $itemcell->attributes['class'] .= ' dimmed_text';
                     }
                     $singleview = '';
                     if (has_all_capabilities(array('gradereport/singleview:view', 'moodle/grade:viewall', 'moodle/grade:edit'), $this->context)) {
                         $url = new moodle_url('/grade/report/singleview/index.php', array('id' => $this->course->id, 'item' => 'grade', 'itemid' => $element['object']->id));
                         $singleview = $OUTPUT->action_icon($url, new pix_icon('t/editstring', get_string('singleview', 'grades', $element['object']->get_name())));
                     }
                     $itemcell->colspan = $colspan;
                     $itemcell->text = shorten_text($headerlink) . $arrow . $singleview;
                     $itemcell->header = true;
                     $itemcell->scope = 'col';
                     $headingrow->cells[] = $itemcell;
                 }
             }
         }
         $rows[] = $headingrow;
     }
     $rows = $this->get_right_icons_row($rows);
     // Preload scale objects for items with a scaleid and initialize tab indices
     $scaleslist = array();
     $tabindices = array();
     foreach ($this->gtree->get_items() as $itemid => $item) {
         $scale = null;
         if (!empty($item->scaleid)) {
             $scaleslist[] = $item->scaleid;
             $jsarguments['items'][$itemid] = array('id' => $itemid, 'name' => $item->get_name(true), 'type' => 'scale', 'scale' => $item->scaleid, 'decimals' => $item->get_decimals());
         } else {
             $jsarguments['items'][$itemid] = array('id' => $itemid, 'name' => $item->get_name(true), 'type' => 'value', 'scale' => false, 'decimals' => $item->get_decimals());
         }
         $tabindices[$item->id]['grade'] = $gradetabindex;
         $tabindices[$item->id]['feedback'] = $gradetabindex + $numusers;
         $gradetabindex += $numusers * 2;
     }
     $scalesarray = array();
     if (!empty($scaleslist)) {
         $scalesarray = $DB->get_records_list('scale', 'id', $scaleslist);
     }
     $jsscales = $scalesarray;
     foreach ($this->users as $userid => $user) {
         if ($this->canviewhidden) {
             $altered = array();
             $unknown = array();
         } else {
             $hidingaffected = grade_grade::get_hiding_affected($this->grades[$userid], $this->gtree->get_items());
             $altered = $hidingaffected['altered'];
             $unknown = $hidingaffected['unknown'];
             unset($hidingaffected);
         }
         $itemrow = new html_table_row();
         $itemrow->id = 'user_' . $userid;
         $fullname = fullname($user);
         $jsarguments['users'][$userid] = $fullname;
         foreach ($this->gtree->items as $itemid => $unused) {
             $item =& $this->gtree->items[$itemid];
             $grade = $this->grades[$userid][$item->id];
             $itemcell = new html_table_cell();
             $itemcell->id = 'u' . $userid . 'i' . $itemid;
             $itemcell->attributes['data-itemid'] = $itemid;
             // Get the decimal points preference for this item
             $decimalpoints = $item->get_decimals();
             if (in_array($itemid, $unknown)) {
                 $gradeval = null;
             } else {
                 if (array_key_exists($itemid, $altered)) {
                     $gradeval = $altered[$itemid];
                 } else {
                     $gradeval = $grade->finalgrade;
                 }
             }
             if (!empty($grade->finalgrade)) {
                 $gradevalforjs = null;
                 if ($item->scaleid && !empty($scalesarray[$item->scaleid])) {
                     $gradevalforjs = (int) $gradeval;
                 } else {
                     $gradevalforjs = format_float($gradeval, $decimalpoints);
                 }
                 $jsarguments['grades'][] = array('user' => $userid, 'item' => $itemid, 'grade' => $gradevalforjs);
             }
             // MDL-11274
             // Hide grades in the grader report if the current grader doesn't have 'moodle/grade:viewhidden'
             if (!$this->canviewhidden and $grade->is_hidden()) {
                 if (!empty($CFG->grade_hiddenasdate) and $grade->get_datesubmitted() and !$item->is_category_item() and !$item->is_course_item()) {
                     // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
                     $itemcell->text = "<span class='datesubmitted'>" . userdate($grade->get_datesubmitted(), $strftimedatetimeshort) . "</span>";
                 } else {
                     $itemcell->text = '-';
                 }
                 $itemrow->cells[] = $itemcell;
                 continue;
             }
             // emulate grade element
             $eid = $this->gtree->get_grade_eid($grade);
             $element = array('eid' => $eid, 'object' => $grade, 'type' => 'grade');
             $itemcell->attributes['class'] .= ' grade i' . $itemid;
             if ($item->is_category_item()) {
                 $itemcell->attributes['class'] .= ' cat';
             }
             if ($item->is_course_item()) {
                 $itemcell->attributes['class'] .= ' course';
             }
             if ($grade->is_overridden()) {
                 $itemcell->attributes['class'] .= ' overridden';
                 $itemcell->attributes['aria-label'] = get_string('overriddengrade', 'gradereport_grader');
             }
             if (!empty($grade->feedback)) {
                 $feedback = wordwrap(trim(format_string($grade->feedback, $grade->feedbackformat)), 34, '<br>');
                 $itemcell->attributes['data-feedback'] = $feedback;
                 $jsarguments['feedback'][] = array('user' => $userid, 'item' => $itemid, 'content' => $feedback);
             }
             if ($grade->is_excluded()) {
                 // Adding white spaces before and after to prevent a screenreader from
                 // thinking that the words are attached to the next/previous <span> or text.
                 $itemcell->text .= " <span class='excludedfloater'>" . $strexcludedgrades . "</span> ";
             }
             // Do not show any icons if no grade (no record in DB to match)
             if (!$item->needsupdate and $USER->gradeediting[$this->courseid]) {
                 $itemcell->text .= $this->get_icons($element);
             }
             $hidden = '';
             if ($grade->is_hidden()) {
                 $hidden = ' dimmed_text ';
             }
             $gradepass = '******';
             if ($grade->is_passed($item)) {
                 $gradepass = '******';
             } else {
                 if (is_null($grade->is_passed($item))) {
                     $gradepass = '';
                 }
             }
             // if in editing mode, we need to print either a text box
             // or a drop down (for scales)
             // grades in item of type grade category or course are not directly editable
             if ($item->needsupdate) {
                 $itemcell->text .= "<span class='gradingerror{$hidden}'>" . $strerror . "</span>";
             } else {
                 if ($USER->gradeediting[$this->courseid]) {
                     if ($item->scaleid && !empty($scalesarray[$item->scaleid])) {
                         $scale = $scalesarray[$item->scaleid];
                         $gradeval = (int) $gradeval;
                         // scales use only integers
                         $scales = explode(",", $scale->scale);
                         // reindex because scale is off 1
                         // MDL-12104 some previous scales might have taken up part of the array
                         // so this needs to be reset
                         $scaleopt = array();
                         $i = 0;
                         foreach ($scales as $scaleoption) {
                             $i++;
                             $scaleopt[$i] = $scaleoption;
                         }
                         if ($quickgrading and $grade->is_editable()) {
                             $oldval = empty($gradeval) ? -1 : $gradeval;
                             if (empty($item->outcomeid)) {
                                 $nogradestr = $this->get_lang_string('nograde');
                             } else {
                                 $nogradestr = $this->get_lang_string('nooutcome', 'grades');
                             }
                             $attributes = array('tabindex' => $tabindices[$item->id]['grade'], 'id' => 'grade_' . $userid . '_' . $item->id);
                             $gradelabel = $fullname . ' ' . $item->itemname;
                             $itemcell->text .= html_writer::label(get_string('useractivitygrade', 'gradereport_grader', $gradelabel), $attributes['id'], false, array('class' => 'accesshide'));
                             $itemcell->text .= html_writer::select($scaleopt, 'grade[' . $userid . '][' . $item->id . ']', $gradeval, array(-1 => $nogradestr), $attributes);
                         } else {
                             if (!empty($scale)) {
                                 $scales = explode(",", $scale->scale);
                                 // invalid grade if gradeval < 1
                                 if ($gradeval < 1) {
                                     $itemcell->text .= "<span class='gradevalue{$hidden}{$gradepass}'>-</span>";
                                 } else {
                                     $gradeval = $grade->grade_item->bounded_grade($gradeval);
                                     //just in case somebody changes scale
                                     $itemcell->text .= "<span class='gradevalue{$hidden}{$gradepass}'>{$scales[$gradeval - 1]}</span>";
                                 }
                             }
                         }
                     } else {
                         if ($item->gradetype != GRADE_TYPE_TEXT) {
                             // Value type
                             if ($quickgrading and $grade->is_editable()) {
                                 $value = format_float($gradeval, $decimalpoints);
                                 $gradelabel = $fullname . ' ' . $item->itemname;
                                 $itemcell->text .= '<label class="accesshide" for="grade_' . $userid . '_' . $item->id . '">' . get_string('useractivitygrade', 'gradereport_grader', $gradelabel) . '</label>';
                                 $itemcell->text .= '<input size="6" tabindex="' . $tabindices[$item->id]['grade'] . '" type="text" class="text" title="' . $strgrade . '" name="grade[' . $userid . '][' . $item->id . ']" id="grade_' . $userid . '_' . $item->id . '" value="' . $value . '" />';
                             } else {
                                 $itemcell->text .= "<span class='gradevalue{$hidden}{$gradepass}'>" . format_float($gradeval, $decimalpoints) . "</span>";
                             }
                         }
                     }
                     // If quickfeedback is on, print an input element
                     if ($showquickfeedback and $grade->is_editable()) {
                         $feedbacklabel = $fullname . ' ' . $item->itemname;
                         $itemcell->text .= '<label class="accesshide" for="feedback_' . $userid . '_' . $item->id . '">' . get_string('useractivityfeedback', 'gradereport_grader', $feedbacklabel) . '</label>';
                         $itemcell->text .= '<input class="quickfeedback" tabindex="' . $tabindices[$item->id]['feedback'] . '" id="feedback_' . $userid . '_' . $item->id . '" size="6" title="' . $strfeedback . '" type="text" name="feedback[' . $userid . '][' . $item->id . ']" value="' . s($grade->feedback) . '" />';
                     }
                 } else {
                     // Not editing
                     $gradedisplaytype = $item->get_displaytype();
                     if ($item->scaleid && !empty($scalesarray[$item->scaleid])) {
                         $itemcell->attributes['class'] .= ' grade_type_scale';
                     } else {
                         if ($item->gradetype != GRADE_TYPE_TEXT) {
                             $itemcell->attributes['class'] .= ' grade_type_text';
                         }
                     }
                     if ($enableajax) {
                         $canoverride = true;
                         if ($item->is_category_item() || $item->is_course_item()) {
                             $canoverride = (bool) get_config('moodle', 'grade_overridecat');
                         }
                         if ($canoverride) {
                             $itemcell->attributes['class'] .= ' clickable';
                         }
                     }
                     if ($item->needsupdate) {
                         $itemcell->text .= "<span class='gradingerror{$hidden}{$gradepass}'>" . $error . "</span>";
                     } else {
                         // The max and min for an aggregation may be different to the grade_item.
                         if (!is_null($gradeval)) {
                             $item->grademax = $grade->get_grade_max();
                             $item->grademin = $grade->get_grade_min();
                         }
                         $itemcell->text .= "<span class='gradevalue{$hidden}{$gradepass}'>" . grade_format_gradevalue($gradeval, $item, true, $gradedisplaytype, null) . "</span>";
                         if ($showanalysisicon) {
                             $itemcell->text .= $this->gtree->get_grade_analysis_icon($grade);
                         }
                     }
                 }
             }
             if (!empty($this->gradeserror[$item->id][$userid])) {
                 $itemcell->text .= $this->gradeserror[$item->id][$userid];
             }
             $itemrow->cells[] = $itemcell;
         }
         $rows[] = $itemrow;
     }
     if ($enableajax) {
         $jsarguments['cfg']['ajaxenabled'] = true;
         $jsarguments['cfg']['scales'] = array();
         foreach ($jsscales as $scale) {
             $jsarguments['cfg']['scales'][$scale->id] = explode(',', $scale->scale);
         }
         $jsarguments['cfg']['feedbacktrunclength'] = $this->feedback_trunc_length;
         // Student grades and feedback are already at $jsarguments['feedback'] and $jsarguments['grades']
     }
     $jsarguments['cfg']['isediting'] = (bool) $USER->gradeediting[$this->courseid];
     $jsarguments['cfg']['courseid'] = $this->courseid;
     $jsarguments['cfg']['studentsperpage'] = $this->get_students_per_page();
     $jsarguments['cfg']['showquickfeedback'] = (bool) $showquickfeedback;
     $module = array('name' => 'gradereport_grader', 'fullpath' => '/grade/report/grader/module.js', 'requires' => array('base', 'dom', 'event', 'event-mouseenter', 'event-key', 'io-queue', 'json-parse', 'overlay'));
     $PAGE->requires->js_init_call('M.gradereport_grader.init_report', $jsarguments, false, $module);
     $PAGE->requires->strings_for_js(array('addfeedback', 'feedback', 'grade'), 'grades');
     $PAGE->requires->strings_for_js(array('ajaxchoosescale', 'ajaxclicktoclose', 'ajaxerror', 'ajaxfailedupdate', 'ajaxfieldchanged'), 'gradereport_grader');
     if (!$enableajax && $USER->gradeediting[$this->courseid]) {
         $PAGE->requires->yui_module('moodle-core-formchangechecker', 'M.core_formchangechecker.init', array(array('formid' => 'gradereport_grader')));
         $PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle');
     }
     $rows = $this->get_right_range_row($rows);
     if ($displayaverages) {
         $rows = $this->get_right_avg_row($rows, true);
         $rows = $this->get_right_avg_row($rows);
     }
     return $rows;
 }
Пример #27
0
/**
 * A list of courses that match a search
 *
 * @global object
 * @global object
 * @param array $searchterms An array of search criteria
 * @param string $sort A field and direction to sort by
 * @param int $page The page number to get
 * @param int $recordsperpage The number of records per page
 * @param int $totalcount Passed in by reference.
 * @param array $requiredcapabilities Extra list of capabilities used to filter courses
 * @return object {@link $COURSE} records
 */
function get_courses_search($searchterms, $sort, $page, $recordsperpage, &$totalcount, $requiredcapabilities = array())
{
    global $CFG, $DB;
    if ($DB->sql_regex_supported()) {
        $REGEXP = $DB->sql_regex(true);
        $NOTREGEXP = $DB->sql_regex(false);
    }
    $searchcond = array();
    $params = array();
    $i = 0;
    // Thanks Oracle for your non-ansi concat and type limits in coalesce. MDL-29912
    if ($DB->get_dbfamily() == 'oracle') {
        $concat = "(c.summary|| ' ' || c.fullname || ' ' || c.idnumber || ' ' || c.shortname)";
    } else {
        $concat = $DB->sql_concat("COALESCE(c.summary, '')", "' '", 'c.fullname', "' '", 'c.idnumber', "' '", 'c.shortname');
    }
    foreach ($searchterms as $searchterm) {
        $i++;
        $NOT = false;
        /// Initially we aren't going to perform NOT LIKE searches, only MSSQL and Oracle
        /// will use it to simulate the "-" operator with LIKE clause
        /// Under Oracle and MSSQL, trim the + and - operators and perform
        /// simpler LIKE (or NOT LIKE) queries
        if (!$DB->sql_regex_supported()) {
            if (substr($searchterm, 0, 1) == '-') {
                $NOT = true;
            }
            $searchterm = trim($searchterm, '+-');
        }
        // TODO: +- may not work for non latin languages
        if (substr($searchterm, 0, 1) == '+') {
            $searchterm = trim($searchterm, '+-');
            $searchterm = preg_quote($searchterm, '|');
            $searchcond[] = "{$concat} {$REGEXP} :ss{$i}";
            $params['ss' . $i] = "(^|[^a-zA-Z0-9]){$searchterm}([^a-zA-Z0-9]|\$)";
        } else {
            if (substr($searchterm, 0, 1) == "-") {
                $searchterm = trim($searchterm, '+-');
                $searchterm = preg_quote($searchterm, '|');
                $searchcond[] = "{$concat} {$NOTREGEXP} :ss{$i}";
                $params['ss' . $i] = "(^|[^a-zA-Z0-9]){$searchterm}([^a-zA-Z0-9]|\$)";
            } else {
                $searchcond[] = $DB->sql_like($concat, ":ss{$i}", false, true, $NOT);
                $params['ss' . $i] = "%{$searchterm}%";
            }
        }
    }
    if (empty($searchcond)) {
        $searchcond = array('1 = 1');
    }
    $searchcond = implode(" AND ", $searchcond);
    $courses = array();
    $c = 0;
    // counts how many visible courses we've seen
    // Tiki pagination
    $limitfrom = $page * $recordsperpage;
    $limitto = $limitfrom + $recordsperpage;
    $ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
    $ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
    $params['contextlevel'] = CONTEXT_COURSE;
    $sql = "SELECT c.* {$ccselect}\n              FROM {course} c\n           {$ccjoin}\n             WHERE {$searchcond} AND c.id <> " . SITEID . "\n          ORDER BY {$sort}";
    $rs = $DB->get_recordset_sql($sql, $params);
    foreach ($rs as $course) {
        // Preload contexts only for hidden courses or courses we need to return.
        context_helper::preload_from_record($course);
        $coursecontext = context_course::instance($course->id);
        if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
            continue;
        }
        if (!empty($requiredcapabilities)) {
            if (!has_all_capabilities($requiredcapabilities, $coursecontext)) {
                continue;
            }
        }
        // Don't exit this loop till the end
        // we need to count all the visible courses
        // to update $totalcount
        if ($c >= $limitfrom && $c < $limitto) {
            $courses[$course->id] = $course;
        }
        $c++;
    }
    $rs->close();
    // our caller expects 2 bits of data - our return
    // array, and an updated $totalcount
    $totalcount = $c;
    return $courses;
}
Пример #28
0
     // can't do anything else with the front page
     echo "  <td>&nbsp;</td>\n";
     // category place
     echo "  <td>&nbsp;</td>\n";
     // select place
     echo "  <td>&nbsp;</td>\n";
     // edit place
     echo "</tr>\n";
     continue;
 }
 echo "<tr>\n";
 echo "<td><a {$linkcss} href=\"view.php?id={$course->id}\">" . highlight($search, $coursecontext->get_context_name(false)) . "</a></td>\n";
 echo "<td>" . $displaylist[$course->category] . "</td>\n";
 echo "<td>\n";
 // If user has all required capabilities to move course then show selectable checkbox
 if (has_all_capabilities($capabilities, $coursecontext)) {
     echo "<input type=\"checkbox\" name=\"c{$course->id}\" />\n";
 } else {
     echo "<input type=\"checkbox\" name=\"c{$course->id}\" disabled=\"disabled\" />\n";
 }
 echo "</td>\n";
 echo "<td>\n";
 // checks whether user can update course settings
 if (has_capability('moodle/course:update', $coursecontext)) {
     echo "<a title=\"" . get_string("settings") . "\" href=\"{$CFG->wwwroot}/course/edit.php?id={$course->id}\">\n<img" . " src=\"" . $OUTPUT->pix_url('t/edit') . "\" class=\"iconsmall\" alt=\"" . get_string("settings") . "\" /></a>\n ";
 }
 // checks whether user can do role assignment
 if (has_capability('moodle/course:enrolreview', $coursecontext)) {
     echo '<a title="' . get_string('enrolledusers', 'enrol') . '" href="' . $CFG->wwwroot . '/enrol/users.php?id=' . $course->id . '">';
     echo '<img src="' . $OUTPUT->pix_url('i/enrolusers') . '" class="iconsmall" alt="' . get_string('enrolledusers', 'enrol') . '" /></a> ' . "\n";
 }
Пример #29
0
/**
 * Returns posts made by the selected user in the requested courses.
 *
 * This method can be used to return all of the posts made by the requested user
 * within the given courses.
 * For each course the access of the current user and requested user is checked
 * and then for each post access to the post and forum is checked as well.
 *
 * This function is safe to use with usercapabilities.
 *
 * @global moodle_database $DB
 * @param stdClass $user The user whose posts we want to get
 * @param array $courses The courses to search
 * @param bool $musthaveaccess If set to true errors will be thrown if the user
 *                             cannot access one or more of the courses to search
 * @param bool $discussionsonly If set to true only discussion starting posts
 *                              will be returned.
 * @param int $limitfrom The offset of records to return
 * @param int $limitnum The number of records to return
 * @return stdClass An object the following properties
 *               ->totalcount: the total number of posts made by the requested user
 *                             that the current user can see.
 *               ->courses: An array of courses the current user can see that the
 *                          requested user has posted in.
 *               ->forums: An array of forums relating to the posts returned in the
 *                         property below.
 *               ->posts: An array containing the posts to show for this request.
 */
function forum_get_posts_by_user($user, array $courses, $musthaveaccess = false, $discussionsonly = false, $limitfrom = 0, $limitnum = 50) {
    global $DB, $USER, $CFG;

    $return = new stdClass;
    $return->totalcount = 0;    // The total number of posts that the current user is able to view
    $return->courses = array(); // The courses the current user can access
    $return->forums = array();  // The forums that the current user can access that contain posts
    $return->posts = array();   // The posts to display

    // First up a small sanity check. If there are no courses to check we can
    // return immediately, there is obviously nothing to search.
    if (empty($courses)) {
        return $return;
    }

    // A couple of quick setups
    $isloggedin = isloggedin();
    $isguestuser = $isloggedin && isguestuser();
    $iscurrentuser = $isloggedin && $USER->id == $user->id;

    // Checkout whether or not the current user has capabilities over the requested
    // user and if so they have the capabilities required to view the requested
    // users content.
    $usercontext = context_user::instance($user->id, MUST_EXIST);
    $hascapsonuser = !$iscurrentuser && $DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id));
    $hascapsonuser = $hascapsonuser && has_all_capabilities(array('moodle/user:viewdetails', 'moodle/user:readuserposts'), $usercontext);

    // Before we actually search each course we need to check the user's access to the
    // course. If the user doesn't have the appropraite access then we either throw an
    // error if a particular course was requested or we just skip over the course.
    foreach ($courses as $course) {
        $coursecontext = context_course::instance($course->id, MUST_EXIST);
        if ($iscurrentuser || $hascapsonuser) {
            // If it is the current user, or the current user has capabilities to the
            // requested user then all we need to do is check the requested users
            // current access to the course.
            // Note: There is no need to check group access or anything of the like
            // as either the current user is the requested user, or has granted
            // capabilities on the requested user. Either way they can see what the
            // requested user posted, although its VERY unlikely in the `parent` situation
            // that the current user will be able to view the posts in context.
            if (!is_viewing($coursecontext, $user) && !is_enrolled($coursecontext, $user)) {
                // Need to have full access to a course to see the rest of own info
                if ($musthaveaccess) {
                    print_error('errorenrolmentrequired', 'forum');
                }
                continue;
            }
        } else {
            // Check whether the current user is enrolled or has access to view the course
            // if they don't we immediately have a problem.
            if (!can_access_course($course)) {
                if ($musthaveaccess) {
                    print_error('errorenrolmentrequired', 'forum');
                }
                continue;
            }

            // Check whether the requested user is enrolled or has access to view the course
            // if they don't we immediately have a problem.
            if (!can_access_course($course, $user)) {
                if ($musthaveaccess) {
                    print_error('notenrolled', 'forum');
                }
                continue;
            }

            // If groups are in use and enforced throughout the course then make sure
            // we can meet in at least one course level group.
            // Note that we check if either the current user or the requested user have
            // the capability to access all groups. This is because with that capability
            // a user in group A could post in the group B forum. Grrrr.
            if (groups_get_course_groupmode($course) == SEPARATEGROUPS && $course->groupmodeforce
              && !has_capability('moodle/site:accessallgroups', $coursecontext) && !has_capability('moodle/site:accessallgroups', $coursecontext, $user->id)) {
                // If its the guest user to bad... the guest user cannot access groups
                if (!$isloggedin or $isguestuser) {
                    // do not use require_login() here because we might have already used require_login($course)
                    if ($musthaveaccess) {
                        redirect(get_login_url());
                    }
                    continue;
                }
                // Get the groups of the current user
                $mygroups = array_keys(groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid, 'g.id, g.name'));
                // Get the groups the requested user is a member of
                $usergroups = array_keys(groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name'));
                // Check whether they are members of the same group. If they are great.
                $intersect = array_intersect($mygroups, $usergroups);
                if (empty($intersect)) {
                    // But they're not... if it was a specific course throw an error otherwise
                    // just skip this course so that it is not searched.
                    if ($musthaveaccess) {
                        print_error("groupnotamember", '', $CFG->wwwroot."/course/view.php?id=$course->id");
                    }
                    continue;
                }
            }
        }
        // Woo hoo we got this far which means the current user can search this
        // this course for the requested user. Although this is only the course accessibility
        // handling that is complete, the forum accessibility tests are yet to come.
        $return->courses[$course->id] = $course;
    }
    // No longer beed $courses array - lose it not it may be big
    unset($courses);

    // Make sure that we have some courses to search
    if (empty($return->courses)) {
        // If we don't have any courses to search then the reality is that the current
        // user doesn't have access to any courses is which the requested user has posted.
        // Although we do know at this point that the requested user has posts.
        if ($musthaveaccess) {
            print_error('permissiondenied');
        } else {
            return $return;
        }
    }

    // Next step: Collect all of the forums that we will want to search.
    // It is important to note that this step isn't actually about searching, it is
    // about determining which forums we can search by testing accessibility.
    $forums = forum_get_forums_user_posted_in($user, array_keys($return->courses), $discussionsonly);

    // Will be used to build the where conditions for the search
    $forumsearchwhere = array();
    // Will be used to store the where condition params for the search
    $forumsearchparams = array();
    // Will record forums where the user can freely access everything
    $forumsearchfullaccess = array();
    // DB caching friendly
    $now = round(time(), -2);
    // For each course to search we want to find the forums the user has posted in
    // and providing the current user can access the forum create a search condition
    // for the forum to get the requested users posts.
    foreach ($return->courses as $course) {
        // Now we need to get the forums
        $modinfo = get_fast_modinfo($course);
        if (empty($modinfo->instances['forum'])) {
            // hmmm, no forums? well at least its easy... skip!
            continue;
        }
        // Iterate
        foreach ($modinfo->get_instances_of('forum') as $forumid => $cm) {
            if (!$cm->uservisible or !isset($forums[$forumid])) {
                continue;
            }
            // Get the forum in question
            $forum = $forums[$forumid];
            // This is needed for functionality later on in the forum code....
            $forum->cm = $cm;

            // Check that either the current user can view the forum, or that the
            // current user has capabilities over the requested user and the requested
            // user can view the discussion
            if (!has_capability('mod/forum:viewdiscussion', $cm->context) && !($hascapsonuser && has_capability('mod/forum:viewdiscussion', $cm->context, $user->id))) {
                continue;
            }

            // This will contain forum specific where clauses
            $forumsearchselect = array();
            if (!$iscurrentuser && !$hascapsonuser) {
                // Make sure we check group access
                if (groups_get_activity_groupmode($cm, $course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $cm->context)) {
                    $groups = $modinfo->get_groups($cm->groupingid);
                    $groups[] = -1;
                    list($groupid_sql, $groupid_params) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED, 'grps'.$forumid.'_');
                    $forumsearchparams = array_merge($forumsearchparams, $groupid_params);
                    $forumsearchselect[] = "d.groupid $groupid_sql";
                }

                // hidden timed discussions
                if (!empty($CFG->forum_enabletimedposts) && !has_capability('mod/forum:viewhiddentimedposts', $cm->context)) {
                    $forumsearchselect[] = "(d.userid = :userid{$forumid} OR (d.timestart < :timestart{$forumid} AND (d.timeend = 0 OR d.timeend > :timeend{$forumid})))";
                    $forumsearchparams['userid'.$forumid] = $user->id;
                    $forumsearchparams['timestart'.$forumid] = $now;
                    $forumsearchparams['timeend'.$forumid] = $now;
                }

                // qanda access
                if ($forum->type == 'qanda' && !has_capability('mod/forum:viewqandawithoutposting', $cm->context)) {
                    // We need to check whether the user has posted in the qanda forum.
                    $discussionspostedin = forum_discussions_user_has_posted_in($forum->id, $user->id);
                    if (!empty($discussionspostedin)) {
                        $forumonlydiscussions = array();  // Holds discussion ids for the discussions the user is allowed to see in this forum.
                        foreach ($discussionspostedin as $d) {
                            $forumonlydiscussions[] = $d->id;
                        }
                        list($discussionid_sql, $discussionid_params) = $DB->get_in_or_equal($forumonlydiscussions, SQL_PARAMS_NAMED, 'qanda'.$forumid.'_');
                        $forumsearchparams = array_merge($forumsearchparams, $discussionid_params);
                        $forumsearchselect[] = "(d.id $discussionid_sql OR p.parent = 0)";
                    } else {
                        $forumsearchselect[] = "p.parent = 0";
                    }

                }

                if (count($forumsearchselect) > 0) {
                    $forumsearchwhere[] = "(d.forum = :forum{$forumid} AND ".implode(" AND ", $forumsearchselect).")";
                    $forumsearchparams['forum'.$forumid] = $forumid;
                } else {
                    $forumsearchfullaccess[] = $forumid;
                }
            } else {
                // The current user/parent can see all of their own posts
                $forumsearchfullaccess[] = $forumid;
            }
        }
    }

    // If we dont have any search conditions, and we don't have any forums where
    // the user has full access then we just return the default.
    if (empty($forumsearchwhere) && empty($forumsearchfullaccess)) {
        return $return;
    }

    // Prepare a where condition for the full access forums.
    if (count($forumsearchfullaccess) > 0) {
        list($fullidsql, $fullidparams) = $DB->get_in_or_equal($forumsearchfullaccess, SQL_PARAMS_NAMED, 'fula');
        $forumsearchparams = array_merge($forumsearchparams, $fullidparams);
        $forumsearchwhere[] = "(d.forum $fullidsql)";
    }

    // Prepare SQL to both count and search.
    // We alias user.id to useridx because we forum_posts already has a userid field and not aliasing this would break
    // oracle and mssql.
    $userfields = user_picture::fields('u', null, 'useridx');
    $countsql = 'SELECT COUNT(*) ';
    $selectsql = 'SELECT p.*, d.forum, d.name AS discussionname, '.$userfields.' ';
    $wheresql = implode(" OR ", $forumsearchwhere);

    if ($discussionsonly) {
        if ($wheresql == '') {
            $wheresql = 'p.parent = 0';
        } else {
            $wheresql = 'p.parent = 0 AND ('.$wheresql.')';
        }
    }

    $sql = "FROM {forum_posts} p
            JOIN {forum_discussions} d ON d.id = p.discussion
            JOIN {user} u ON u.id = p.userid
           WHERE ($wheresql)
             AND p.userid = :userid ";
    $orderby = "ORDER BY p.modified DESC";
    $forumsearchparams['userid'] = $user->id;

    // Set the total number posts made by the requested user that the current user can see
    $return->totalcount = $DB->count_records_sql($countsql.$sql, $forumsearchparams);
    // Set the collection of posts that has been requested
    $return->posts = $DB->get_records_sql($selectsql.$sql.$orderby, $forumsearchparams, $limitfrom, $limitnum);

    // We need to build an array of forums for which posts will be displayed.
    // We do this here to save the caller needing to retrieve them themselves before
    // printing these forums posts. Given we have the forums already there is
    // practically no overhead here.
    foreach ($return->posts as $post) {
        if (!array_key_exists($post->forum, $return->forums)) {
            $return->forums[$post->forum] = $forums[$post->forum];
        }
    }

    return $return;
}
Пример #30
0
 /**
  * @param stdclass $user the owner of the stage
  */
 public function __construct(stdclass $user)
 {
     global $DB;
     $stringstree = array();
     // tree of strings to simulate ORDER BY component, stringid, lang, branch
     $this->strings = array();
     // final list populated from the stringstree
     $stage = mlang_persistent_stage::instance_for_user($user->id, $user->sesskey);
     $needed = array();
     // describes all strings that we will have to load to displaye the stage
     if (has_capability('local/amos:importfile', get_system_context(), $user)) {
         $this->importform = new local_amos_importfile_form(new moodle_url('/local/amos/importfile.php'), local_amos_importfile_options());
     }
     if (has_capability('local/amos:commit', get_system_context(), $user)) {
         $this->mergeform = new local_amos_merge_form(new moodle_url('/local/amos/merge.php'), local_amos_merge_options());
     }
     if (has_capability('local/amos:stage', get_system_context(), $user)) {
         $this->diffform = new local_amos_diff_form(new moodle_url('/local/amos/diff.php'), local_amos_diff_options());
     }
     if (has_all_capabilities(array('local/amos:execute', 'local/amos:stage'), get_system_context(), $user)) {
         $this->executeform = new local_amos_execute_form(new moodle_url('/local/amos/execute.php'), local_amos_execute_options());
     }
     foreach ($stage->get_iterator() as $component) {
         foreach ($component->get_iterator() as $staged) {
             if (!isset($needed[$component->version->code][$component->lang][$component->name])) {
                 $needed[$component->version->code][$component->lang][$component->name] = array();
             }
             $needed[$component->version->code][$component->lang][$component->name][] = $staged->id;
             $needed[$component->version->code]['en'][$component->name][] = $staged->id;
             $string = new stdclass();
             $string->component = $component->name;
             $string->branch = $component->version->code;
             $string->version = $component->version->label;
             $string->language = $component->lang;
             $string->stringid = $staged->id;
             $string->text = $staged->text;
             $string->timemodified = $staged->timemodified;
             $string->deleted = $staged->deleted;
             $string->original = null;
             // is populated in the next step
             $string->current = null;
             // dtto
             $string->new = $staged->text;
             $string->committable = false;
             $stringstree[$string->component][$string->stringid][$string->language][$string->branch] = $string;
         }
     }
     // order by component
     ksort($stringstree);
     foreach ($stringstree as $subtree) {
         // order by stringid
         ksort($subtree);
         foreach ($subtree as $subsubtree) {
             // order by language
             ksort($subsubtree);
             foreach ($subsubtree as $subsubsubtree) {
                 // order by branch
                 ksort($subsubsubtree);
                 foreach ($subsubsubtree as $string) {
                     $this->strings[] = $string;
                 }
             }
         }
     }
     unset($stringstree);
     $fver = array();
     $flng = array();
     $fcmp = array();
     foreach ($needed as $branch => $languages) {
         $fver[$branch] = true;
         foreach ($languages as $language => $components) {
             $flng[$language] = true;
             foreach ($components as $component => $strings) {
                 $fcmp[$component] = true;
                 $needed[$branch][$language][$component] = mlang_component::from_snapshot($component, $language, mlang_version::by_code($branch), null, false, false, $strings);
             }
         }
     }
     $this->filterfields->fver = array_keys($fver);
     $this->filterfields->flng = array_keys($flng);
     $this->filterfields->fcmp = array_keys($fcmp);
     $allowedlangs = mlang_tools::list_allowed_languages($user->id);
     foreach ($this->strings as $string) {
         if (!empty($allowedlangs['X']) or !empty($allowedlangs[$string->language])) {
             $string->committable = true;
         }
         if (!$needed[$string->branch]['en'][$string->component]->has_string($string->stringid)) {
             $string->original = '*DELETED*';
         } else {
             $string->original = $needed[$string->branch]['en'][$string->component]->get_string($string->stringid)->text;
         }
         if ($needed[$string->branch][$string->language][$string->component] instanceof mlang_component) {
             $string->current = $needed[$string->branch][$string->language][$string->component]->get_string($string->stringid);
             if ($string->current instanceof mlang_string) {
                 $string->current = $string->current->text;
             }
         }
         if (empty(mlang_version::by_code($string->branch)->translatable)) {
             $string->committable = false;
         }
     }
 }