/** * Associates a cluster with a curriculum. */ public static function associate($cluster, $curriculum, $autoenrol = true) { global $DB; // make sure we don't double-associate if ($DB->record_exists(self::TABLE, array('clusterid' => $cluster, 'curriculumid' => $curriculum))) { return; } // ELIS-7582 @set_time_limit(0); $record = new clustercurriculum(); $record->clusterid = $cluster; $record->autoenrol = !empty($autoenrol) ? 1 : 0; $record->curriculumid = $curriculum; $record->save(); /** * Assign all users in the cluster with curriculum. Don't assign users * if already assigned */ /** * @todo we may need to change this if associating a user with a * curriculum does anything more complicated */ // assign cluster members as students in the newly-associated curriculum if the // association has autoenrol set and the users are not already in the curriculum if (!empty($autoenrol)) { $timenow = time(); $sql = 'INSERT INTO {' . curriculumstudent::TABLE . '} ' . '(userid, curriculumid, timecreated, timemodified) ' . 'SELECT DISTINCT u.id, ' . $curriculum . ', ' . $timenow . ', ' . $timenow . ' ' . 'FROM {' . clusterassignment::TABLE . '} clu ' . 'INNER JOIN {' . user::TABLE . '} u ON u.id = clu.userid ' . 'LEFT OUTER JOIN {' . curriculumstudent::TABLE . '} ca ON ca.userid = u.id AND ca.curriculumid = \'' . $curriculum . '\' ' . 'WHERE clu.clusterid = ? AND ca.curriculumid IS NULL'; $params = array($cluster); $DB->execute($sql, $params); } // events_trigger('pm_userset_program_associated', $record); }
/** * Test that a user without program_view permissions does not get any data returned */ public function test_nocurriculumpermission() { $this->load_csv_data(); $this->setGuestUser(); $curriculumfilter = array('contexts' => curriculumpage::get_contexts('local/elisprogram:program_view')); $curricula = clustercurriculum::get_curricula(1, 0, 5, 'cur.priority ASC, cur.name ASC', $curriculumfilter); $this->assertInternalType('array', $curricula); $this->assertEmpty($curricula); }
/** * Determines whether the current user is allowed to enrol users into the provided curriculum * * @param int $curriculumid The id of the curriculum we are checking permissions on * * @return boolean Whether the user is allowed to enrol users into the curriculum * */ static function can_enrol_into_curriculum($curriculumid) { global $USER; //check the standard capability if (curriculumpage::_has_capability('block/curr_admin:curriculum:enrol', $curriculumid)) { return true; } //get the context for the "indirect" capability $context = cm_context_set::for_user_with_capability('cluster', 'block/curr_admin:curriculum:enrol_cluster_user', $USER->id); //get the clusters and check the context against them $clusters = clustercurriculum::get_clusters($curriculumid); if (!empty($clusters)) { foreach ($clusters as $cluster) { if ($context->context_allowed($cluster->clusterid, 'cluster')) { return true; } } } return false; }
/** * Determines whether the current user is allowed to enrol users into the provided curriculum * * @param int $curriculumid The id of the curriculum we are checking permissions on * * @return boolean Whether the user is allowed to enrol users into the curriculum * */ static function can_enrol_into_curriculum($curriculumid) { global $USER; //check the standard capability // TODO: Ugly, this needs to be overhauled $cpage = new curriculumpage(); if ($cpage->_has_capability('local/elisprogram:program_enrol', $curriculumid)) { return true; } //get the context for the "indirect" capability $context = pm_context_set::for_user_with_capability('cluster', 'local/elisprogram:program_enrol_userset_user', $USER->id); //get the clusters and check the context against them $clusters = clustercurriculum::get_clusters($curriculumid); if (!empty($clusters)) { foreach ($clusters as $cluster) { if ($context->context_allowed($cluster->clusterid, 'cluster')) { return true; } } } return false; }
/** * Perform the necessary actions required to "delete" a cluster from the system. * * @uses CURMAN * @uses CFG * @param none * @return bool True on success, False otherwise. */ function delete($deletesubs = 0) { global $CURMAN, $CFG; require_once CURMAN_DIRLOCATION . '/cluster/profile/lib.php'; $result = true; $delete_ids = array(); $promote_ids = array(); $cluster_context_level = context_level_base::get_custom_context_level('cluster', 'block_curr_admin'); if ($deletesubs > 0) { /// Figure out all the sub-cluster ids and whether to delete or promote them $LIKE = $CURMAN->db->sql_compare(); $cluster_context_instance = get_context_instance($cluster_context_level, $this->id); $instance_id = $cluster_context_instance->id; $instance_path = $cluster_context_instance->path; $sql = "SELECT instanceid FROM {$CFG->prefix}context\n WHERE path {$LIKE} '{$instance_path}/%' ORDER BY instanceid DESC"; $clusters = get_records_sql($sql); foreach ($clusters as $cluster) { if ($deletesubs == 1) { // This sub-cluster will be deleted $delete_ids[] = $cluster->instanceid; } else { // This sub-cluster will be promoted $promote_ids[] = $cluster->instanceid; } } } $delete_ids[] = $this->id; // The specified cluster always gets deleted foreach ($delete_ids as $delete_id) { // Cascade to regular datarecords $result = $result && clustercurriculum::delete_for_cluster($delete_id); // in clustercurriculum $result = $result && clustertrack::delete_for_cluster($delete_id); // in clustercurriculum $result = $result && clusterassignment::delete_for_cluster($delete_id); $result = $result && usercluster::delete_for_cluster($delete_id); $result = $result && delete_context($cluster_context_level, $delete_id); // Cascade to all plugins $plugins = $this->get_plugins(); foreach ($plugins as $plugin) { require_once CURMAN_DIRLOCATION . '/cluster/' . $plugin . '/lib.php'; $result = $result && call_user_func('cluster_' . $plugin . '_delete_for_cluster', $delete_id); } $result = $result && datarecord::data_delete_record($delete_id); // this record } if (count($promote_ids) > 0) { foreach ($promote_ids as $promote_id) { $cluster_data = get_record(CLSTTABLE, 'id', $promote_id); $lower_depth = $cluster_data->depth - 1; $select = "id='{$cluster_data->parent}'"; $parent_cnt = $CURMAN->db->count_records_select(CLSTTABLE, $select); $newclusterdata = new stdClass(); $newclusterdata->id = $promote_id; if ($parent_cnt < 1) { /// Parent not found so this cluster will be top-level $newclusterdata->parent = 0; $newclusterdata->depth = 1; } else { /// A child cluster found so lets lower the depth $newclusterdata->depth = $lower_depth; } $result = update_record(CLSTTABLE, $newclusterdata); $cluster_context_level = context_level_base::get_custom_context_level('cluster', 'block_curr_admin'); $sql = "UPDATE {$CFG->prefix}context\n SET depth=0, path=NULL\n WHERE contextlevel='{$cluster_context_level}' AND instanceid='{$promote_id}'"; $feedback = ""; execute_sql($sql, $feedback); } build_context_path(); // Re-build the context table for all sub-clusters } return $result; }
/** * Clone a curriculum. * @param array $options options for cloning. Valid options are: * - 'tracks': whether or not to clone tracks (default: false) * - 'courses': whether or not to clone courses (default: false) * - 'classes': whether or not to clone classes (default: false) * - 'moodlecourses': whether or not to clone Moodle courses (if they were * autocreated). Values can be (default: "copyalways"): * - "copyalways": always copy course * - "copyautocreated": only copy autocreated courses * - "autocreatenew": autocreate new courses from course template * - "link": link to existing course * - 'targetcluster': the cluster id or cluster object (if any) to * associate the clones with (default: none) * @return array array of array of object IDs created. Key in outer array * is type of object (plural). Key in inner array is original object ID, * value is new object ID. Outer array also has an entry called 'errors', * which is an array of any errors encountered when duplicating the * object. */ function duplicate($options = array()) { require_once CURMAN_DIRLOCATION . '/lib/track.class.php'; $objs = array('errors' => array()); if (isset($options['targetcluster'])) { $cluster = $options['targetcluster']; if (!is_object($cluster) || !is_a($cluster, 'cluster')) { $options['targetcluster'] = $cluster = new cluster($cluster); } } // clone main curriculum object $clone = new curriculum($this); unset($clone->id); if (isset($cluster)) { // if cluster specified, append cluster's name to curriculum $clone->name = $clone->name . ' - ' . $cluster->name; $clone->idnumber = $clone->idnumber . ' - ' . $cluster->name; } $clone = new curriculum(addslashes_recursive($clone)); if (!$clone->add()) { $objs['errors'][] = get_string('failclustcpycurr', 'block_curr_admin', $this); return $objs; } $objs['curricula'] = array($this->id => $clone->id); $options['targetcurriculum'] = $clone->id; // associate with target cluster (if any) if (isset($cluster)) { clustercurriculum::associate($cluster->id, $clone->id); } if (!empty($options['courses'])) { // copy courses $currcrs = curriculumcourse_get_list_by_curr($this->id); if (!empty($currcrs)) { $objs['courses'] = array(); $objs['classes'] = array(); foreach ($currcrs as $currcrsdata) { $course = new course($currcrsdata->courseid); $rv = $course->duplicate($options); if (isset($rv['errors']) && !empty($rv['errors'])) { $objs['errors'] = array_merge($objs['errors'], $rv['errors']); } if (isset($rv['courses'])) { $objs['courses'] = $objs['courses'] + $rv['courses']; } if (isset($rv['classes'])) { $objs['classes'] = $objs['classes'] + $rv['classes']; } // associate with curriculum if (isset($rv['courses'][$course->id])) { $curcrs = new curriculumcourse($currcrsdata); unset($curcrs->id); $curcrs->courseid = $rv['courses'][$course->id]; $curcrs->curriculumid = $clone->id; $curcrs->add(); } } } } if (!empty($objs['errors'])) { return $objs; } if (!empty($options['tracks'])) { // copy tracks $tracks = track_get_listing('name', 'ASC', 0, 0, '', '', $this->id); if (isset($objs['courses'])) { $options['coursemap'] = $objs['courses']; } if (!empty($tracks)) { $objs['tracks'] = array(); if (isset($objs['courses'])) { $options['coursemap'] = $objs['courses']; } if (!isset($objs['classes'])) { $objs['classes'] = array(); } foreach ($tracks as $track) { $track = new track($track); $options['classmap'] = $objs['classes']; $rv = $track->duplicate($options); if (isset($rv['errors']) && !empty($rv['errors'])) { $objs['errors'] = array_merge($objs['errors'], $rv['errors']); } if (isset($rv['tracks'])) { $objs['tracks'] = $objs['tracks'] + $rv['tracks']; } if (isset($rv['classes'])) { $objs['classes'] = $objs['classes'] + $rv['classes']; } } } } return $objs; }
/** * Dynamically loads child menu items for a curriculum entity * * @param int $id The entity id * @param int $parent_cluster_id The last cluster passed going down the elisadmin tree, or 0 if none * @param int $parent_curriculum_id The last curriculum passed going down the elisadmin tree, or 0 if none * @param int $num_block_icons Max number of entries to display * @param string $parent_path Path of parent curriculum elements in the tree * @return menuitem array The appropriate child items */ function block_elisadmin_load_menu_children_curriculum($id, $parent_cluster_id, $parent_curriculum_id, $num_block_icons, $parent_path = '') { global $CFG; //page dependencies require_once elispm::file('pmclasspage.class.php'); $result_items = array(); /***************************************** * Curriculum - Course Associations *****************************************/ $course_css_class = block_elisadmin_get_item_css_class('course_instance'); //permissions filter $course_filter = array('contexts' => coursepage::get_contexts('local/elisprogram:course_view')); $listing = curriculumcourse_get_listing($id, 'position', 'ASC', 0, $num_block_icons, '', '', $course_filter); foreach ($listing as $item) { $item->id = $item->courseid; $params = array('id' => $item->id, 'action' => 'view'); //count associated classes $class_contexts = pmclasspage::get_contexts('local/elisprogram:class_view'); $class_count = pmclass_count_records('', '', $item->id, false, $class_contexts, $parent_cluster_id); $isLeaf = empty($class_count); $result_items[] = block_elisadmin_get_menu_item('course', $item, 'root', $course_css_class, $parent_cluster_id, $parent_curriculum_id, $params, $isLeaf, $parent_path); } unset($listing); //summary item $num_records = curriculumcourse_count_records($id, '', '', $course_filter); if ($num_block_icons < $num_records) { $params = array('id' => $id); $result_items[] = block_elisadmin_get_menu_summary_item('curriculumcourse', $course_css_class, $num_records - $num_block_icons, $params, '', $parent_path); } /***************************************** * Curriculum - Track Associations *****************************************/ $track_css_class = block_elisadmin_get_item_css_class('track_instance'); //permissions filter $track_contexts = trackpage::get_contexts('local/elisprogram:track_view'); if ($track_records = track_get_listing('name', 'ASC', 0, $num_block_icons, '', '', $id, $parent_cluster_id, $track_contexts)) { foreach ($track_records as $track_record) { $params = array('id' => $track_record->id, 'action' => 'view'); //count associated classes $class_contexts = array('contexts' => pmclasspage::get_contexts('local/elisprogram:class_view')); $class_count = track_assignment_count_records($track_record->id, '', '', $class_contexts); //count associated clusters $cluster_filter = array('contexts' => usersetpage::get_contexts('local/elisprogram:userset_view')); $cluster_count = clustertrack::count_clusters($track_record->id, $parent_cluster_id, $cluster_filter); $isLeaf = empty($class_count) && empty($cluster_count); $result_items[] = block_elisadmin_get_menu_item('track', $track_record, 'root', $track_css_class, $parent_cluster_id, $parent_curriculum_id, $params, $isLeaf, $parent_path); } } //summary item $num_records = track_count_records('', '', $id, $parent_cluster_id, $track_contexts); if ($num_block_icons < $num_records) { $params = array('id' => $id); //add extra param if appropriate if (!empty($parent_cluster_id)) { $params['parent_clusterid'] = $parent_cluster_id; } $result_items[] = block_elisadmin_get_menu_summary_item('track', $track_css_class, $num_records - $num_block_icons, $params, '', $parent_path); } /***************************************** * Curriculum - Cluster Associations *****************************************/ $cluster_css_class = block_elisadmin_get_item_css_class('cluster_instance'); //permissions filter $cluster_filter = array('contexts' => usersetpage::get_contexts('local/elisprogram:userset_view')); $clusters = clustercurriculum::get_clusters($id, $parent_cluster_id, 'name', 'ASC', 0, $num_block_icons, $cluster_filter); //$clusters = clustercurriculum::get_clusters($id, $parent_cluster_id, 'priority, name', 'ASC', 0, $num_block_icons); if (!empty($clusters)) { foreach ($clusters as $cluster) { $cluster->id = $cluster->clusterid; $params = array('id' => $cluster->id, 'action' => 'view'); $result_items[] = block_elisadmin_get_menu_item('userset', $cluster, 'root', $cluster_css_class, $cluster->id, $parent_curriculum_id, $params, false, $parent_path); } } //summary item $num_records = clustercurriculum::count_clusters($id, $parent_cluster_id, $cluster_filter); if ($num_block_icons < $num_records) { $params = array('id' => $id); //add extra param if appropriate if (!empty($parent_cluster_id)) { $params['parent_clusterid'] = $parent_cluster_id; } $result_items[] = block_elisadmin_get_menu_summary_item('curriculumcluster', $cluster_css_class, $num_records - $num_block_icons, $params, 'clustercurriculumpage.class.php', $parent_path); } return $result_items; }
function get_content() { global $CFG, $ADMIN, $USER, $CURMAN, $HTTPSPAGEREQUIRED; require_once $CFG->libdir . '/adminlib.php'; require_once $CFG->dirroot . '/my/pagelib.php'; // dependencies on page classes require_once $CFG->dirroot . '/curriculum/clusterpage.class.php'; require_once $CFG->dirroot . '/curriculum/curriculumpage.class.php'; require_once $CFG->dirroot . '/curriculum/coursepage.class.php'; require_once $CFG->dirroot . '/curriculum/trackpage.class.php'; // ELIS-1251 - Don't display a useless message if in the center column // if ($this->instance->position == BLOCK_POS_CENTRE) { // $this->content = new stdClass; // $output = "This is content to display if in the middle..."; // $this->content->text = $output; // $this->content->footer = ''; // return $this->content; // } /// Display a link to the admin interface if on the main site index page and the current user has /// admin or developer access. // if ($this->instance->pageid == SITEID && // has_capability('block/curr_admin:config', get_context_instance(CONTEXT_SYSTEM, SITEID))) { // // $this->content = new stdClass; // $this->content->text = '<a href="' . $CFG->wwwroot . '/curriculum/index.php">' . // get_string('accesscurriculumadmin', 'block_curr_admin') . '</a>'; // $this->content->footer = ''; // } /// Determine the users CM access level. $access = cm_determine_access($USER->id); $this->title = get_string("blocktitle{$access}", 'block_curr_admin'); if (empty($access) || $this->content !== NULL) { return $this->content; } //if we are not on a CM "newpage", disable the expansion of //entities in the curr admin tree (logic in curriculum/index.php) if (!isset($CURMAN->page)) { unset($USER->currentitypath); } //include the necessary javascript libraries for the YUI TreeView require_js(array('yui_yahoo', 'yui_dom', 'yui_event', 'yui_treeview')); //for converting tree representation require_js('yui_json'); //for asynch request dynamic loading require_js('yui_connection'); //include our custom code that handles the YUI Treeview menu if (!empty($HTTPSPAGEREQUIRED)) { $wwwroot = $CFG->httpswwwroot; } else { $wwwroot = $CFG->wwwroot; } require_js($wwwroot . '/curriculum/js/menuitem.js'); //CM entities for placement at the top of the menu $cm_entity_pages = array(); $cm_entity_pages[] = new menuitem('root'); $num_block_icons = isset($CURMAN->config->num_block_icons) ? $CURMAN->config->num_block_icons : 5; /***************************************** * Clusters *****************************************/ if (!isset($CURMAN->config->display_clusters_at_top_level) || !empty($CURMAN->config->display_clusters_at_top_level)) { $manageclusters_css_class = block_curr_admin_get_item_css_class('manageclusters'); $cluster_css_class = block_curr_admin_get_item_css_class('cluster_instance'); require_once CURMAN_DIRLOCATION . '/lib/contexts.php'; $context_result = cm_context_set::for_user_with_capability('cluster', 'block/curr_admin:cluster:view', $USER->id); $extrafilters = array('contexts' => $context_result, 'parent' => 0); $num_records = cluster_count_records('', '', $extrafilters); if ($clusters = cluster_get_listing('priority, name', 'ASC', 0, $num_block_icons, '', '', $extrafilters)) { foreach ($clusters as $cluster) { $params = array('id' => $cluster->id, 'action' => 'view'); // count sub-clusters $cluster_filter = array('contexts' => clusterpage::get_contexts('block/curr_admin:cluster:view'), 'parent' => $cluster->id); $cluster_count = cluster_count_records('', '', $cluster_filter); // count associated curricula $curriculum_filter = array('contexts' => curriculumpage::get_contexts('block/curr_admin:curriculum:view')); $curriculum_count = clustercurriculum::count_curricula($cluster->id, $curriculum_filter); $isLeaf = empty($cluster_count) && empty($curriculum_count); $cm_entity_pages[] = block_curr_admin_get_menu_item('cluster', $cluster, 'root', $manageclusters_css_class, $cluster->id, 0, $params, $isLeaf); } } if ($num_block_icons < $num_records) { $cm_entity_pages[] = block_curr_admin_get_menu_summary_item('cluster', $cluster_css_class, $num_records - $num_block_icons); } } /***************************************** * Curricula *****************************************/ if (!empty($CURMAN->config->display_curricula_at_top_level)) { $managecurricula_css_class = block_curr_admin_get_item_css_class('managecurricula'); $curriculum_css_class = block_curr_admin_get_item_css_class('curriculum_instance'); require_once CURMAN_DIRLOCATION . '/curriculumpage.class.php'; $num_records = curriculum_count_records('', '', curriculumpage::get_contexts('block/curr_admin:curriculum:view')); if ($curricula = get_records(CURTABLE, '', '', 'priority ASC, name ASC', '*', 0, $num_block_icons)) { foreach ($curricula as $curriculum) { $params = array('id' => $curriculum->id, 'action' => 'view'); // count associated courses $course_filter = array('contexts' => coursepage::get_contexts('block/curr_admin:course:view')); $course_count = curriculumcourse_count_records($curriculum->id, '', '', $course_filter); // count associated tracks $track_contexts = trackpage::get_contexts('block/curr_admin:track:view'); $track_count = track_count_records('', '', $curriculum->id, 0, $track_contexts); // count associated clusters $cluster_filter = array('contexts' => clusterpage::get_contexts('block/curr_admin:cluster:view')); $cluster_count = clustercurriculum::count_clusters($curriculum->id, 0, $cluster_filter); $isLeaf = empty($course_count) && empty($track_count) && empty($cluster_count); $cm_entity_pages[] = block_curr_admin_get_menu_item('curriculum', $curriculum, 'root', $managecurricula_css_class, 0, $curriculum->id, $params, $isLeaf); } } if ($num_block_icons < $num_records) { $cm_entity_pages[] = block_curr_admin_get_menu_summary_item('curriculum', $curriculum_css_class, $num_records - $num_block_icons); } } global $SITE; //general cm pages $pages = array(new menuitem('dashboard', new menuitempage('dashboardpage'), 'root', '', block_curr_admin_get_item_css_class('dashboard')), new menuitem('admn', null, 'root', get_string('admin'), block_curr_admin_get_item_css_class('admn', true)), new menuitem('bulkuser', new menuitempage('bulkuserpage'), null, get_string('userbulk', 'admin'), block_curr_admin_get_item_css_class('bulkuser'))); //show the Jasper report server link if applicable if (cm_jasper_link_enabled()) { //page action $jasper_link_params = array('action' => 'reportslist'); //page instance $jasper_link_page = new menuitempage('jasperreportpage', '', $jasper_link_params); //styling for the link $jasper_link_css = block_curr_admin_get_item_css_class('reportslist'); $pages[] = new menuitem('reportslist', $jasper_link_page, null, '', $jasper_link_css); } $pages = array_merge($pages, array(new menuitem('customfields', new menuitempage('customfieldpage', '', array('level' => 'user')), null, '', block_curr_admin_get_item_css_class('customfields')), new menuitem('clusterclassification', new menuitempage('clusterclassificationpage', 'plugins/cluster_classification/clusterclassificationpage.class.php'), null, get_string('cluster_classification', 'crlm_cluster_classification'), block_curr_admin_get_item_css_class('clusterclassification')), new menuitem('info', null, 'root', get_string('informationalelements', 'block_curr_admin'), block_curr_admin_get_item_css_class('info', true)), new menuitem('managetags', new menuitempage('tagpage'), null, '', block_curr_admin_get_item_css_class('managetags')), new menuitem('manageenvironments', new menuitempage('envpage'), null, '', block_curr_admin_get_item_css_class('manageenvironments')), new menuitem('users', null, 'root', '', block_curr_admin_get_item_css_class('users', true)), new menuitem('manageusers', new menuitempage('usermanagementpage'), null, '', block_curr_admin_get_item_css_class('manageusers')), new menuitem('manageclusters', new menuitempage('clusterpage'), null, '', block_curr_admin_get_item_css_class('manageclusters')), new menuitem('curr', null, 'root', get_string('curriculum', 'block_curr_admin'), block_curr_admin_get_item_css_class('curr', true)), new menuitem('certificatelist', new menuitempage('certificatelistpage'), null, '', block_curr_admin_get_item_css_class('certificatelist')), new menuitem('managecurricula', new menuitempage('curriculumpage'), null, '', block_curr_admin_get_item_css_class('managecurricula')), new menuitem('managecourses', new menuitempage('coursepage'), null, '', block_curr_admin_get_item_css_class('managecourses')), new menuitem('manageclasses', new menuitempage('cmclasspage'), null, '', block_curr_admin_get_item_css_class('manageclasses')), new menuitem('crscat', null, 'root', get_string('learningplan', 'block_curr_admin'), block_curr_admin_get_item_css_class('crscat', true)), new menuitem('currentcourses', new menuitempage('coursecatalogpage', '', array('action' => 'current')), null, '', block_curr_admin_get_item_css_class('currentcourses')), new menuitem('availablecourses', new menuitempage('coursecatalogpage', '', array('action' => 'available')), null, '', block_curr_admin_get_item_css_class('availablecourses')), new menuitem('waitlist', new menuitempage('coursecatalogpage', '', array('action' => 'waitlist')), null, get_string('waitlistcourses', 'block_curr_admin'), block_curr_admin_get_item_css_class('waitlist')), new menuitem('rept', null, 'root', get_string('reports', 'block_curr_admin'), block_curr_admin_get_item_css_class('rept', true)))); if (has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $SITE->id))) { if ($CURMAN->config->site_course_cluster_groups) { $pages[] = new menuitem('frontpagegroups', new menuitempage('url_page', 'lib/menuitem.class.php', "{$CFG->wwwroot}/group/index.php?id={$SITE->id}"), 'admn', get_string('frontpagegroups', 'crlm_cluster_groups'), block_curr_admin_get_item_css_class('manageclusters')); } if ($CURMAN->config->cluster_groupings) { $pages[] = new menuitem('frontpagegroupings', new menuitempage('url_page', 'lib/menuitem.class.php', "{$CFG->wwwroot}/group/groupings.php?id={$SITE->id}"), 'admn', get_string('frontpagegroupings', 'crlm_cluster_groups'), block_curr_admin_get_item_css_class('manageclusters')); } } /** * This section adds all the necessary PHP reports to the menu */ //get all report pages, including categories but not including the //topmost report element $report_pages = block_curr_admin_get_report_tree_items(); //merge in the reporting page links $pages = array_merge($pages, $report_pages); if (empty($CURMAN->config->userdefinedtrack)) { $pages[] = new menuitem('managetracks', new menuitempage('trackpage'), null, '', block_curr_admin_get_item_css_class('managetracks')); } $access = cm_determine_access($USER->id); switch ($access) { case 'admin': case 'developer': $pages[] = new menuitem('configmanager', new menuitempage('configpage', '', array('section' => 'admn')), null, get_string('configuration'), block_curr_admin_get_item_css_class('configuration')); $pages[] = new menuitem('notifications', new menuitempage('notifications', 'notificationspage.class.php', array('section' => 'admn')), null, '', block_curr_admin_get_item_css_class('notifications')); $pages[] = new menuitem('dataimport', new menuitempage('dataimportpage', 'elis_ip/elis_ip_page.php', array('section' => 'admn')), null, '', block_curr_admin_get_item_css_class('integrationpoint')); $pages[] = new menuitem('defaultcls', new menuitempage('configclsdefaultpage', '', array('section' => 'admn')), null, '', block_curr_admin_get_item_css_class('defaultcls')); $pages[] = new menuitem('defaultcrs', new menuitempage('configcrsdefaultpage', '', array('section' => 'admn')), null, '', block_curr_admin_get_item_css_class('defaultcrs')); break; default: break; } //turn all pages that have no children into leaf nodes menuitemlisting::flag_leaf_nodes($pages); //combine the specific entity page listing with the general CM listing $menuitemlisting = new menuitemlisting(array_merge($cm_entity_pages, $pages)); $tree = new treerepresentation($menuitemlisting); $this->content = new stdClass(); $this->content->text = $tree->convert_to_markup(); $this->content->footer = ''; return $this->content; }
function __construct(&$items, $columns, $pageurl, $decorators = array()) { global $CURMAN, $USER; parent::__construct($items, $columns, $pageurl, $decorators); $id = required_param('id', PARAM_INT); if (!curriculumpage::_has_capability('block/curr_admin:curriculum:enrol', $id)) { $context = cm_context_set::for_user_with_capability('cluster', 'block/curr_admin:curriculum:enrol_cluster_user', $USER->id); $allowed_clusters = array(); //get the clusters assigned to this curriculum $clusters = clustercurriculum::get_clusters($id); if (!empty($clusters)) { foreach ($clusters as $cluster) { if ($context->context_allowed($cluster->clusterid, 'cluster')) { $allowed_clusters[] = $cluster->id; } } } $this->allowed_clusters = $allowed_clusters; } }
/** * Perform the necessary actions required to "delete" a cluster from the system. * * @param none * @return bool True on success, False otherwise. */ function delete() { require_once elis::lib('data/data_filter.class.php'); if ($this->deletesimple) { //core delete method, not including recursion (entered once for each //individual userset being delete) //clean make the delete cascade into association records $filter = new field_filter('clusterid', $this->id); clustercurriculum::delete_records($filter, $this->_db); clustertrack::delete_records($filter, $this->_db); clusterassignment::delete_records($filter, $this->_db); //cluster plugin cleanup $plugins = get_plugin_list(self::ENROL_PLUGIN_TYPE); foreach ($plugins as $plugin => $plugindir) { require_once elis::plugin_file(self::ENROL_PLUGIN_TYPE . '_' . $plugin, 'lib.php'); call_user_func('cluster_' . $plugin . '_delete_for_cluster', $this->id); } //delete the userset record parent::delete(); //delete this cluster's context //get a new context instance, $contextclass = \local_eliscore\context\helper::get_class_for_level(CONTEXT_ELIS_USERSET); $userset_context = $contextclass::instance($this->id); $userset_context->delete(); events_trigger('cluster_deleted', $this->id); return; } $result = true; $children = array(); $delete_ids = array(); $promote_ids = array(); /// Figure out all the sub-clusters $cluster_context_instance = \local_elisprogram\context\userset::instance($this->id); $instance_id = $cluster_context_instance->id; $instance_path = $cluster_context_instance->path; $children = userset::find(new join_filter('id', 'context', 'instanceid', new AND_filter(array(new field_filter('path', "{$instance_path}/%", field_filter::LIKE), new field_filter('contextlevel', CONTEXT_ELIS_USERSET)))), array('depth' => 'ASC'), 0, 0, $this->_db); $children = $children->to_array(); if ($this->deletesubs) { $todelete = $children; $todelete[] = $this; // The specified cluster always gets deleted } else { $todelete = array($this); } foreach ($todelete as $userset) { //delete without recursion $userset->deletesimple = true; $userset->delete(); } if (!$this->deletesubs && !empty($children)) { foreach ($children as $child) { $lower_depth = $child->depth - 1; if (userset::exists(new field_filter('id', $child->parent))) { /// A parent found so lets lower the depth $child->depth = 0; } else { /// Parent not found so this cluster will be top-level $child->parent = 0; $child->depth = 1; } $child->save(); $sql = "UPDATE {context}\n SET depth=0, path=NULL\n WHERE contextlevel=? AND instanceid=?"; $this->_db->execute($sql, array(CONTEXT_ELIS_USERSET, $child->id)); } \local_eliscore\context\helper::build_all_paths(false, array(CONTEXT_ELIS_USERSET)); // Re-build the context table for all sub-clusters } return $result; }
function action_default() { $id = $this->required_param('id', PARAM_INT); $sort = $this->optional_param('sort', 'name', PARAM_CLEAN); $dir = $this->optional_param('dir', 'ASC', PARAM_CLEAN); //this extra parameter signals a dependency on a parent cluster $parent_clusterid = $this->optional_param('parent_clusterid', 0, PARAM_INT); $columns = array('name' => 'Name', 'display' => 'Display', 'autoenrol' => get_string('auto_enrol', 'block_curr_admin'), 'buttons' => ''); $items = clustercurriculum::get_clusters($id, $parent_clusterid, $sort, $dir); $formatters = $this->create_link_formatters(array('name'), 'clusterpage', 'clusterid'); $this->print_list_view($items, $columns, $formatters, 'clusters'); $contexts = clusterpage::get_contexts('block/curr_admin:associate'); $clusters = cluster_get_listing('name', 'ASC', 0, 0, '', '', array('contexts' => $contexts)); if (empty($clusters)) { $num_clusters = cluster_count_records(); if (!empty($num_clusters)) { // some clusters exist, but don't have associate capability on // any of them echo '<div align="center"><br />'; print_string('no_associate_caps_cluster', 'block_curr_admin'); echo '</div>'; } else { // no clusters at all echo '<div align="center"><br />'; print_string('all_items_assigned', 'block_curr_admin'); echo '</div>'; } } else { $this->print_dropdown($clusters, $items, 'curriculumid', 'clusterid'); } }
/** * Associates a cluster with a curriculum. */ static function associate($cluster, $curriculum, $autoenrol = true) { global $CURMAN; $db = $CURMAN->db; // make sure we don't double-associate if ($db->record_exists(CLSTCURTABLE, 'clusterid', $cluster, 'curriculumid', $curriculum)) { return; } $record = new clustercurriculum(); $record->clusterid = $cluster; $record->autoenrol = !empty($autoenrol) ? 1 : 0; $record->curriculumid = $curriculum; $record->data_insert_record(); /* Assign all users in the cluster with curriculum. Don't assign users * if already assigned */ /** * @todo we may need to change this if associating a user with a * curriculum does anything more complicated */ //only insert users if we are auto-enrolling if (!empty($autoenrol)) { $timenow = time(); $sql = 'INSERT INTO ' . $db->prefix_table(CURASSTABLE) . ' ' . '(userid, curriculumid, timecreated, timemodified) ' . 'SELECT DISTINCT u.id, ' . $curriculum . ', ' . $timenow . ', ' . $timenow . ' ' . 'FROM ' . $db->prefix_table(CLSTUSERTABLE) . ' clu ' . 'INNER JOIN ' . $db->prefix_table(USRTABLE) . ' u ON u.id = clu.userid ' . 'LEFT OUTER JOIN ' . $db->prefix_table(CURASSTABLE) . ' ca ON ca.userid = u.id AND ca.curriculumid = \'' . $curriculum . '\' ' . 'WHERE clu.clusterid = \'' . $cluster . '\' AND ca.curriculumid IS NULL'; $db->execute_sql($sql, false); } events_trigger('crlm_cluster_curriculum_associated', $record); }
/** * Validate that deleting a userset deletes all appropriate associations */ public function test_delete_elis_userset_deletes_associations() { global $CFG, $DB; // Entities. require_once $CFG->dirroot . '/local/elisprogram/lib/setup.php'; require_once elispm::lib('data/userset.class.php'); require_once elispm::lib('data/user.class.php'); require_once elispm::lib('data/curriculum.class.php'); require_once elispm::lib('data/track.class.php'); require_once elis::lib('data/customfield.class.php'); // Associations. require_once elispm::lib('data/clusterassignment.class.php'); require_once elispm::lib('data/clustercurriculum.class.php'); require_once elispm::lib('data/clustertrack.class.php'); require_once elispm::file('enrol/userset/moodleprofile/userset_profile.class.php'); // For context level access. require_once elispm::file('accesslib.php'); $origfieldcount = $DB->count_records(field::TABLE); // Set up user set. $userset = new userset(array('name' => 'testusersetname')); $userset->save(); // Set up other entities and associations. // Cluster enrolment. $user = new user(array('idnumber' => 'testuseridnumber', 'username' => 'testuserusername', 'firstname' => 'testuserfirstname', 'lastname' => 'testuserlastname', 'email' => '*****@*****.**', 'country' => 'CA')); $user->save(); $clusterassignment = new clusterassignment(array('clusterid' => $userset->id, 'userid' => $user->id)); $clusterassignment->save(); // Cluster-curriculum assignment. $curriculum = new curriculum(array('idnumber' => 'testcurriculumidnumber')); $curriculum->save(); $clustercurriculum = new clustercurriculum(array('clusterid' => $userset->id, 'curriculumid' => $curriculum->id)); $clustercurriculum->save(); // Cluster-track assignment. $track = new track(array('curid' => $curriculum->id, 'idnumber' => 'testtrackidnumber')); $track->save(); $clustertrack = new clustertrack(array('clusterid' => $userset->id, 'trackid' => $track->id)); $clustertrack->save(); // Custom field. $field = new field(array('name' => 'testfieldname', 'categoryid' => 9999)); $field->save(); $context = \local_elisprogram\context\userset::instance($userset->id); $data = new field_data_int(array('contextid' => $context->id, 'fieldid' => $field->id, 'data' => 1)); $data->save(); // Cluster profile criteria. $clusterprofile = new userset_profile(array('clusterid' => $userset->id, 'fieldid' => $field->id, 'value' => 0)); $clusterprofile->save(); // Validate setup. $this->assertEquals(1, $DB->count_records(userset::TABLE)); $this->assertEquals(1, $DB->count_records(user::TABLE)); $this->assertEquals(1, $DB->count_records(clusterassignment::TABLE)); $this->assertEquals(1, $DB->count_records(curriculum::TABLE)); $this->assertEquals(1, $DB->count_records(clustercurriculum::TABLE)); $this->assertEquals(1, $DB->count_records(track::TABLE)); $this->assertEquals(1, $DB->count_records(clustertrack::TABLE)); $this->assertEquals(1 + $origfieldcount, $DB->count_records(field::TABLE)); $this->assertEquals(1, $DB->count_records(field_data_int::TABLE)); $this->assertEquals(1, $DB->count_records(userset_profile::TABLE)); // Run the import. $data = array('action' => 'delete'); $this->run_core_userset_import($data, true); // Validation. $this->assertEquals(0, $DB->count_records(userset::TABLE)); $this->assertEquals(1, $DB->count_records(user::TABLE)); $this->assertEquals(0, $DB->count_records(clusterassignment::TABLE)); $this->assertEquals(1, $DB->count_records(curriculum::TABLE)); $this->assertEquals(0, $DB->count_records(clustercurriculum::TABLE)); $this->assertEquals(1, $DB->count_records(track::TABLE)); $this->assertEquals(0, $DB->count_records(clustertrack::TABLE)); $this->assertEquals(1 + $origfieldcount, $DB->count_records(field::TABLE)); $this->assertEquals(0, $DB->count_records(field_data_int::TABLE)); $this->assertEquals(0, $DB->count_records(userset_profile::TABLE)); }
/** * Test validation of duplicates * @expectedException data_object_validation_exception */ public function test_clustercurriculum_validationpreventsduplicates() { $this->load_csv_data(); $clustercurriculum = new clustercurriculum(array('clusterid' => 1, 'curriculumid' => 1)); $clustercurriculum->save(); }
/** * Determines whether the current user is allowed to create, edit, and delete associations * between a user and a curriculum * * @param int $userid The id of the user being associated to the curricula * @param int $curid The id of the curricula we are associating the user to * * @return boolean True if the current user has the required permissions, otherwise false */ public static function can_manage_assoc($userid, $curid) { global $USER, $DB; // TODO: Ugly, this needs to be overhauled $cpage = new curriculumpage(); if (!curriculumpage::can_enrol_into_curriculum($curid)) { //the users who satisfty this condition are a superset of those who can manage associations return false; } else { if ($cpage->_has_capability('local/elisprogram:program_enrol', $curid)) { //current user has the direct capability return true; } } //get the context for the "indirect" capability $context = pm_context_set::for_user_with_capability('cluster', 'local/elisprogram:program_enrol_userset_user', $USER->id); $allowedclusters = array(); // Get the clusters and check the context against them. $clusters = clustercurriculum::get_clusters($curid); $allowedclusters = $context->get_allowed_instances($clusters, 'cluster', 'clusterid'); // Query to get users associated to at least one enabling cluster. $clusterselect = ''; if (empty($allowedclusters)) { $clusterselect = '0=1'; } else { $clusterselect = 'clusterid IN (' . implode(',', $allowedclusters) . ')'; } $select = "userid = {$userid} AND {$clusterselect}"; //user just needs to be in one of the possible clusters if ($DB->record_exists_select(clusterassignment::TABLE, $select)) { return true; } return false; }
/** * Test available table doesn't show assigned usersets. * @dataProvider dataprovider_available_doesnt_show_assigned_usersets * @param array $associations An array of arrays of parameters to construct clustercurriculum associations. * @param int $tableprogramid The ID of the program we're going to manage. * @param array $expectedresults The expected page of results. * @param int $expectedtotal The expected number of total results. */ public function test_available_doesnt_show_assigned_usersets($associations, $tableprogramid, $expectedresults, $expectedtotal) { global $USER, $DB, $CFG; $userbackup = $USER; // Set up permissions. $USER = $this->setup_permissions_test(); $this->give_permission_for_context($USER->id, 'local/elisprogram:associate', context_system::instance()); foreach ($associations as $association) { $clustercurriculum = new clustercurriculum($association); $clustercurriculum->save(); } // Construct test table. $table = new deepsight_datatable_programuserset_available_mock($DB, 'test', 'http://localhost', 'testuniqid'); $table->set_programid($tableprogramid); // Perform test. $actualresults = $table->get_search_results(array(), array(), 0, 20); // Verify result. $this->assert_search_results($expectedresults, $expectedtotal, $actualresults); // Restore user. $USER = $userbackup; }
function get_content() { global $CFG, $ADMIN, $USER, $HTTPSPAGEREQUIRED, $PAGE, $DB, $SITE; require_once $CFG->libdir . '/adminlib.php'; //dependencies on page classes require_once elispm::file('usersetpage.class.php'); require_once elispm::file('curriculumpage.class.php'); require_once elispm::file('coursepage.class.php'); require_once elispm::file('trackpage.class.php'); //require_once($CFG->dirroot . '/my/pagelib.php'); /// Determine the users CM access level. $access = cm_determine_access($USER->id); //make sure local_elisprogram / custom contexts set up correctly //to prevent error before the upgrade to ELIS 2 if (empty($access) || $this->content !== NULL || !defined('CONTEXT_ELIS_PROGRAM')) { return $this->content; } //if we are not on a PM page, disable the expansion of //entities in the curr admin tree (logic in curriculum/index.php) if (!is_a($PAGE, 'pm_page') && $PAGE->pagetype != 'admin-setting-local_elisprogram_settings') { unset($USER->currentitypath); } // Include Icon CSS. $PAGE->requires->css('/local/elisprogram/icons.css'); //CM entities for placement at the top of the menu $cm_entity_pages = array(); $cm_entity_pages[] = new menuitem('root'); $num_block_icons = isset(elis::$config->local_elisprogram->num_block_icons) ? elis::$config->local_elisprogram->num_block_icons : 5; /***************************************** * Clusters *****************************************/ if (!isset(elis::$config->local_elisprogram->display_clusters_at_top_level) || !empty(elis::$config->local_elisprogram->display_clusters_at_top_level)) { $manageclusters_css_class = block_elisadmin_get_item_css_class('manageclusters'); $cluster_css_class = block_elisadmin_get_item_css_class('cluster_instance'); require_once elispm::lib('contexts.php'); $context_result = pm_context_set::for_user_with_capability('cluster', 'local/elisprogram:userset_view', $USER->id); $extrafilters = array('contexts' => $context_result, 'parent' => 0); $num_records = cluster_count_records('', '', $extrafilters); if ($clusters = cluster_get_listing('priority, name', 'ASC', 0, $num_block_icons, '', '', $extrafilters)) { foreach ($clusters as $cluster) { $params = array('id' => $cluster->id, 'action' => 'view'); //count sub-clusters $cluster_filter = array('contexts' => usersetpage::get_contexts('local/elisprogram:userset_view')); $cluster_count = cluster_count_records('', '', array('parent' => $cluster->id), $cluster_filter); //count associated curricula $curriculum_filter = array('contexts' => curriculumpage::get_contexts('local/elisprogram:program_view')); $curriculum_count = clustercurriculum::count_curricula($cluster->id, $curriculum_filter); $isLeaf = empty($cluster_count) && empty($curriculum_count); $cm_entity_pages[] = block_elisadmin_get_menu_item('userset', $cluster, 'root', $manageclusters_css_class, $cluster->id, 0, $params, $isLeaf); } } if ($num_block_icons < $num_records) { $cm_entity_pages[] = block_elisadmin_get_menu_summary_item('userset', $cluster_css_class, $num_records - $num_block_icons); } } /***************************************** * Curricula *****************************************/ if (!empty(elis::$config->local_elisprogram->display_curricula_at_top_level)) { $managecurricula_css_class = block_elisadmin_get_item_css_class('managecurricula'); $curriculum_css_class = block_elisadmin_get_item_css_class('curriculum_instance'); require_once elispm::file('curriculumpage.class.php'); $num_records = curriculum_count_records('', '', curriculumpage::get_contexts('local/elisprogram:program_view')); $curricula = $DB->get_recordset(curriculum::TABLE, null, 'priority ASC, name ASC', '*', 0, $num_block_icons); foreach ($curricula as $curriculum) { $params = array('id' => $curriculum->id, 'action' => 'view'); //count associated courses $course_filter = array('contexts' => coursepage::get_contexts('local/elisprogram:course_view')); $course_count = curriculumcourse_count_records($curriculum->id, '', '', $course_filter); //count associated tracks $track_contexts = trackpage::get_contexts('local/elisprogram:track_view'); $track_count = track_count_records('', '', $curriculum->id, 0, $track_contexts); //count associated clusters $cluster_filter = array('contexts' => usersetpage::get_contexts('local/elisprogram:userset_view')); $cluster_count = clustercurriculum::count_clusters($curriculum->id, 0, $cluster_filter); $isLeaf = empty($course_count) && empty($track_count) && empty($cluster_count); $cm_entity_pages[] = block_elisadmin_get_menu_item('curriculum', $curriculum, 'root', $managecurricula_css_class, 0, $curriculum->id, $params, $isLeaf); } unset($curricula); if ($num_block_icons < $num_records) { $cm_entity_pages[] = block_elisadmin_get_menu_summary_item('curriculum', $curriculum_css_class, $num_records - $num_block_icons); } } //general cm pages $pages = array(new menuitem('dashboard', new menuitempage('dashboardpage'), 'root', '', block_elisadmin_get_item_css_class('dashboard')), new menuitem('admn', null, 'root', get_string('admin'), block_elisadmin_get_item_css_class('admn', true)), new menuitem('bulkuser', new menuitempage('bulkuserpage'), null, get_string('userbulk', 'admin'), block_elisadmin_get_item_css_class('bulkuser')), new menuitem('resultsconfig', new menuitempage('resultsconfigpage'), null, 'Default Results Engine Score Settings', block_elisadmin_get_item_css_class('resultsconfig'))); // ELIS-3208 - commented out this code as the Jasper reports no longer work in ELIS 2 /* //show the Jasper report server link if applicable if (cm_jasper_link_enabled()) { //page action $jasper_link_params = array('action' => 'reportslist'); //page instance $jasper_link_page = new menuitempage('jasperreportpage', '', $jasper_link_params); //styling for the link $jasper_link_css = block_elisadmin_get_item_css_class('reportslist'); $pages[] = new menuitem('reportslist', $jasper_link_page, null, '', $jasper_link_css); } */ $pages = array_merge($pages, array(new menuitem('customfields', new menuitempage('customfieldpage', '', array('level' => 'user')), null, '', block_elisadmin_get_item_css_class('customfields')), new menuitem('clusterclassification', new menuitempage('usersetclassificationpage', 'plugins/usetclassify/usersetclassificationpage.class.php'), null, get_string('userset_classification', 'elisprogram_usetclassify'), block_elisadmin_get_item_css_class('clusterclassification')), new menuitem('users', null, 'root', '', block_elisadmin_get_item_css_class('users', true)), new menuitem('manageusers', new menuitempage('userpage'), null, '', block_elisadmin_get_item_css_class('manageusers')), new menuitem('manageclusters', new menuitempage('usersetpage'), null, '', block_elisadmin_get_item_css_class('manageclusters')), new menuitem('curr', null, 'root', get_string('curriculum', 'local_elisprogram'), block_elisadmin_get_item_css_class('curr', true)), new menuitem('certificatelist', new menuitempage('certificatelistpage'), null, '', block_elisadmin_get_item_css_class('certificatelist')), new menuitem('managecurricula', new menuitempage('curriculumpage'), null, '', block_elisadmin_get_item_css_class('managecurricula')), new menuitem('managecourses', new menuitempage('coursepage'), null, '', block_elisadmin_get_item_css_class('managecourses')), new menuitem('manageclasses', new menuitempage('pmclasspage'), null, '', block_elisadmin_get_item_css_class('manageclasses')), new menuitem('crscat', null, 'root', get_string('learningplan', 'local_elisprogram'), block_elisadmin_get_item_css_class('crscat', true)), new menuitem('currentcourses', new menuitempage('coursecatalogpage', '', array('action' => 'current')), null, '', block_elisadmin_get_item_css_class('currentcourses')), new menuitem('availablecourses', new menuitempage('coursecatalogpage', '', array('action' => 'available')), null, '', block_elisadmin_get_item_css_class('availablecourses')), new menuitem('waitlist', new menuitempage('coursecatalogpage', '', array('action' => 'waitlist')), null, get_string('waitlistcourses', 'local_elisprogram'), block_elisadmin_get_item_css_class('waitlist')), new menuitem('rept', null, 'root', get_string('reports', 'local_elisprogram'), block_elisadmin_get_item_css_class('rept', true)))); if (has_capability('moodle/course:managegroups', context_course::instance($SITE->id))) { if (elis::$config->elisprogram_usetgroups->site_course_userset_groups) { $pages[] = new menuitem('frontpagegroups', new menuitempage('url_page', 'lib/menuitem.class.php', "{$CFG->wwwroot}/group/index.php?id={$SITE->id}"), 'admn', get_string('frontpagegroups', 'elisprogram_usetgroups'), block_elisadmin_get_item_css_class('manageclusters')); } if (elis::$config->elisprogram_usetgroups->userset_groupings) { $pages[] = new menuitem('frontpagegroupings', new menuitempage('url_page', 'lib/menuitem.class.php', "{$CFG->wwwroot}/group/groupings.php?id={$SITE->id}"), 'admn', get_string('frontpagegroupings', 'elisprogram_usetgroups'), block_elisadmin_get_item_css_class('manageclusters')); } } /** * This section adds all the necessary PHP reports to the menu */ //get all report pages, including categories but not including the //topmost report element $report_pages = block_elisadmin_get_report_tree_items(); //merge in the reporting page links $pages = array_merge($pages, $report_pages); if (empty(elis::$config->local_elisprogram->userdefinedtrack)) { $pages[] = new menuitem('managetracks', new menuitempage('trackpage'), null, '', block_elisadmin_get_item_css_class('managetracks')); } $syscontext = context_system::instance(); if (has_capability('local/elisprogram:config', $syscontext)) { $pages[] = new menuitem('configmanager', new menuitempage('url_page', 'lib/menuitem.class.php', "{$CFG->wwwroot}/admin/settings.php?section=local_elisprogram_settings"), 'admn', get_string('configuration'), block_elisadmin_get_item_css_class('configuration')); } $pages[] = new menuitem('notifications', new menuitempage('notifications', 'notificationspage.class.php', array('section' => 'admn')), null, '', block_elisadmin_get_item_css_class('notifications')); //$pages[] = new menuitem('dataimport', new menuitempage('dataimportpage', 'elis_ip/elis_ip_page.php', array('section' => 'admn')), null, '', block_elisadmin_get_item_css_class('integrationpoint')); $pages[] = new menuitem('defaultcls', new menuitempage('configclsdefaultpage', '', array('section' => 'admn')), null, '', block_elisadmin_get_item_css_class('defaultcls')); $pages[] = new menuitem('defaultcrs', new menuitempage('configcrsdefaultpage', '', array('section' => 'admn')), null, '', block_elisadmin_get_item_css_class('defaultcrs')); //turn all pages that have no children into leaf nodes menuitemlisting::flag_leaf_nodes($pages); //combine the specific entity page listing with the general CM listing $menuitemlisting = new menuitemlisting(array_merge($cm_entity_pages, $pages)); $tree = new treerepresentation($menuitemlisting); $this->content = new stdClass(); $this->content->text = $tree->convert_to_markup(); $this->content->footer = ''; $PAGE->requires->yui_module('moodle-local_elisprogram-menuitem', 'M.local_elisprogram.init_menuitem', array($tree->get_js_object(), $CFG->httpswwwroot), null, true); return $this->content; }
/** * Clone a curriculum. * @param array $options options for cloning. Valid options are: * - 'tracks': whether or not to clone tracks (default: false) * - 'courses': whether or not to clone courses (default: false) * - 'classes': whether or not to clone classes (default: false) * - 'moodlecourses': whether or not to clone Moodle courses (if they were * autocreated). Values can be (default: "copyalways"): * - "copyalways": always copy course * - "copyautocreated": only copy autocreated courses * - "autocreatenew": autocreate new courses from course template * - "link": link to existing course * - 'targetcluster': the cluster id or cluster object (if any) to * associate the clones with (default: none) * @return array array of array of object IDs created. Key in outer array * is type of object (plural). Key in inner array is original object ID, * value is new object ID. Outer array also has an entry called 'errors', * which is an array of any errors encountered when duplicating the * object. */ function duplicate(array $options = array()) { require_once elispm::lib('data/track.class.php'); $objs = array('errors' => array()); if (isset($options['targetcluster'])) { $userset = $options['targetcluster']; if (!is_object($userset) || !is_a($userset, 'userset')) { $options['targetcluster'] = $userset = new userset($userset); } } // Due to lazy loading, we need to pre-load this object $this->load(); // clone main curriculum object $clone = new curriculum($this); unset($clone->id); $idnumber = $clone->idnumber; $name = $clone->name; if (isset($userset)) { $to_append = ' - ' . $userset->name; // if cluster specified, append cluster's name to curriculum $idnumber = append_once($idnumber, $to_append, array('maxlength' => 95)); $name = append_once($name, $to_append, array('maxlength' => 59)); } //get a unique idnumber $clone->idnumber = generate_unique_identifier(curriculum::TABLE, 'idnumber', $idnumber, array('idnumber' => $idnumber)); if ($clone->idnumber != $idnumber) { //get the suffix appended and add it to the name $parts = explode('.', $clone->idnumber); $suffix = end($parts); $clone->name = $name . '.' . $suffix; } else { $clone->name = $name; } $clone = new curriculum($clone); $clone->save(); $objs['curricula'] = array($this->id => $clone->id); $options['targetcurriculum'] = $clone->id; // associate with target cluster (if any) if (isset($userset)) { clustercurriculum::associate($userset->id, $clone->id); } if (!empty($options['courses'])) { // copy courses $currcrs = curriculumcourse_get_list_by_curr($this->id); if ($currcrs->valid()) { $objs['courses'] = array(); $objs['classes'] = array(); foreach ($currcrs as $currcrsdata) { $course = new course($currcrsdata->courseid); $rv = $course->duplicate($options); if (isset($rv['errors']) && !empty($rv['errors'])) { $objs['errors'] = array_merge($objs['errors'], $rv['errors']); } if (isset($rv['courses'])) { $objs['courses'] = $objs['courses'] + $rv['courses']; } if (isset($rv['classes'])) { $objs['classes'] = $objs['classes'] + $rv['classes']; } // associate with curriculum if (isset($rv['courses'][$course->id])) { $curcrs = new curriculumcourse($currcrsdata); unset($curcrs->id); $curcrs->courseid = $rv['courses'][$course->id]; $curcrs->curriculumid = $clone->id; $curcrs->save(); } } } unset($currcrs); } if (!empty($objs['errors'])) { return $objs; } if (!empty($options['tracks'])) { // copy tracks $tracks = track_get_listing('name', 'ASC', 0, 0, '', '', $this->id); if (isset($objs['courses'])) { $options['coursemap'] = $objs['courses']; } if (!empty($tracks)) { $objs['tracks'] = array(); if (isset($objs['courses'])) { $options['coursemap'] = $objs['courses']; } if (!isset($objs['classes'])) { $objs['classes'] = array(); } foreach ($tracks as $track) { $track = new track($track); $options['classmap'] = $objs['classes']; $rv = $track->duplicate($options); if (isset($rv['errors']) && !empty($rv['errors'])) { $objs['errors'] = array_merge($objs['errors'], $rv['errors']); } if (isset($rv['tracks'])) { $objs['tracks'] = $objs['tracks'] + $rv['tracks']; } if (isset($rv['classes'])) { $objs['classes'] = $objs['classes'] + $rv['classes']; } } } } return $objs; }
/** * Test available table shows only programs the user has permission to enrol into based on * local/elisprogram:program_enrol_userset_user permission on a parent userset. * * @dataProvider dataprovider_available_permissions_program_enrol_userset_user * @param array $usersetidsforperm An array of userset IDs to assign the local/elisprogram:program_enrol_userset_user on. * @param array $clusterassignments An array of arrays of parameters to construct clusterassignments with. * @param array $clustercurriculums An array of arrays of parameters to construct clustercurriculums with. * @param int $tableuserid The id of the user to manage associations for. * @param array $expectedresults The expected page of results. * @param int $expectedtotal The expected number of total results. */ public function test_available_permissions_program_enrol_userset_user($usersetidsforperm, $clusterassignments, $clustercurriculums, $tableuserid, $expectedresults, $expectedtotal) { global $USER, $DB, $CFG; $userbackup = $USER; // Import usersets. $dataset = $this->createCsvDataSet(array(userset::TABLE => elispm::file('tests/fixtures/deepsight_userset.csv'))); $this->loadDataSet($dataset); // Set up permissions. $USER = $this->setup_permissions_test(); // Initialize userset contexts. for ($i = 1; $i <= 5; $i++) { $ctx = \local_elisprogram\context\userset::instance($i); } accesslib_clear_all_caches(true); // Set up capabilities. $capability = 'local/elisprogram:program_enrol_userset_user'; foreach ($usersetidsforperm as $usersetid) { $this->give_permission_for_context($USER->id, $capability, \local_elisprogram\context\userset::instance($usersetid)); } // Create clusterassignments. foreach ($clusterassignments as $clusterassignment) { $clusterassignment = new clusterassignment($clusterassignment); $clusterassignment->save(); } // Create clustercurriculums. foreach ($clustercurriculums as $clustercurriculum) { $clustercurriculum = new clustercurriculum($clustercurriculum); $clustercurriculum->save(); } // Construct test table. $table = new deepsight_datatable_userprogram_available_mock($DB, 'test', 'http://localhost', 'testuniqid'); $table->set_userid($tableuserid); // Perform test. $actualresults = $table->get_search_results(array(), array(), 0, 20); // Verify. $this->assert_search_results($expectedresults, $expectedtotal, $actualresults); }
/** * Unassign the usersets from the program. * @param array $elements An array of userset information to unassign from the program. * @param bool $bulkaction Whether this is a bulk-action or not. * @return array An array to format as JSON and return to the Javascript. */ protected function _respond_to_js(array $elements, $bulkaction) { global $DB; $programid = required_param('id', PARAM_INT); foreach ($elements as $usersetid => $label) { if ($this->can_unassign($programid, $usersetid) === true) { $assignrecfilters = array('clusterid' => $usersetid, 'curriculumid' => $programid); $assignrec = $DB->get_record(clustercurriculum::TABLE, $assignrecfilters); $clustercurriculum = new clustercurriculum($assignrec); $clustercurriculum->delete(); } } return array('result' => 'success', 'msg' => 'Success'); }
/** * Determines whether the current user is allowed to create, edit, and delete associations * between a user and a curriculum * * @param int $userid The id of the user being associated to the curricula * @param int $curid The id of the curricula we are associating the user to * * @return boolean True if the current user has the required permissions, otherwise false */ public static function can_manage_assoc($userid, $curid) { global $USER; if (!curriculumpage::can_enrol_into_curriculum($curid)) { //the users who satisfty this condition are a superset of those who can manage associations return false; } else { if (curriculumpage::_has_capability('block/curr_admin:curriculum:enrol', $curid)) { //current user has the direct capability return true; } } //get the context for the "indirect" capability $context = cm_context_set::for_user_with_capability('cluster', 'block/curr_admin:curriculum:enrol_cluster_user', $USER->id); $allowed_clusters = array(); //get the clusters and check the context against them $clusters = clustercurriculum::get_clusters($curid); $allowed_clusters = $context->get_allowed_instances($clusters, 'cluster', 'id'); //query to get users associated to at least one enabling cluster $cluster_select = ''; if (empty($allowed_clusters)) { $cluster_select = '0=1'; } else { $cluster_select = 'clusterid IN (' . implode(',', $allowed_clusters) . ')'; } $select = "userid = {$userid} AND {$cluster_select}"; //user just needs to be in one of the possible clusters if (record_exists_select(CLSTUSERTABLE, $select)) { return true; } return false; }
/** * Display copy curriculum action. */ public function display_copycurredit() { global $CFG, $USER, $PAGE, $DB, $OUTPUT; $PAGE->requires->js('/local/elisprogram/js/clustercurriculumpage.js'); $id = $this->required_param('id', PARAM_INT); // Create a list of curricula to be excluded. $curriculumshown = array(); $table = new html_table(); $table->head = array(get_string('userset_cpyclustname', 'local_elisprogram'), get_string('userset_cpycurname', 'local_elisprogram'), get_string('userset_cpyadd', 'local_elisprogram'), get_string('userset_cpytrkcpy', 'local_elisprogram'), get_string('userset_cpycrscpy', 'local_elisprogram'), get_string('userset_cpyclscpy', 'local_elisprogram'), get_string('userset_cpymdlclscpy', 'local_elisprogram')); $table->class = 'cluster_copy_curriculum'; // Get all clusters. $sort = 'name'; $dir = 'ASC'; $clusters = cluster_get_listing($sort, $dir, 0); $clusterlist = array(); $sql = 'SELECT * from {' . userset::TABLE . '}'; // Exclude clusters the user does not have the capability to manage/see. $context = get_contexts_by_capability_for_user('cluster', 'local/elisprogram:userset_view', $USER->id); echo '<form action="index.php" method="post">'; $mdlcrsoptions = array('copyalways' => get_string('program_copy_mdlcrs_copyalways', 'local_elisprogram'), 'copyautocreated' => get_string('program_copy_mdlcrs_copyautocreated', 'local_elisprogram'), 'autocreatenew' => get_string('program_copy_mdlcrs_autocreatenew', 'local_elisprogram'), 'link' => get_string('program_copy_mdlcrs_link', 'local_elisprogram')); $contexts = curriculumpage::get_contexts('local/elisprogram:associate'); foreach ($clusters as $clusid => $clusdata) { if (!$context->context_allowed($clusid, 'cluster')) { continue; } $assocurr = clustercurriculum::get_curricula($clusid); if (!empty($assocurr)) { $first = true; foreach ($assocurr as $assocurrrec) { // Add to list of curricula to exclude. $curriculumshown[] = $assocurrrec->curriculumid; // Skip over this clusters associated curricula. if ($clusid == $id) { continue; } // Skip over curricula that user cannot associate. if (!$contexts->context_allowed($assocurrrec->curriculumid, 'curriculum')) { continue; } if ($first) { $curname = format_string($clusdata->name); $first = false; } else { $curname = ''; } // Disable the last 3 options unless the first is checked. $checkboxids = "'" . self::CPY_CURR_PREFIX . $assocurrrec->curriculumid . "',\n '" . self::CPY_CURR_TRK_PREFIX . $assocurrrec->curriculumid . "',\n '" . self::CPY_CURR_CRS_PREFIX . $assocurrrec->curriculumid . "',\n '" . self::CPY_CURR_CLS_PREFIX . $assocurrrec->curriculumid . "'"; $togglecheckboxes = "cluster_copy_checkbox_changed(" . $checkboxids . ");"; $table->data[] = array($curname, format_string($assocurrrec->name), html_writer::checkbox(self::CPY_CURR_PREFIX . $assocurrrec->curriculumid, 1, false, '', array('id' => self::CPY_CURR_PREFIX . $assocurrrec->curriculumid, 'onclick' => $togglecheckboxes)), html_writer::checkbox(self::CPY_CURR_TRK_PREFIX . $assocurrrec->curriculumid, 1, false, '', array('disabled' => true, 'id' => self::CPY_CURR_TRK_PREFIX . $assocurrrec->curriculumid)), html_writer::checkbox(self::CPY_CURR_CRS_PREFIX . $assocurrrec->curriculumid, 1, false, '', array('disabled' => true, 'id' => self::CPY_CURR_CRS_PREFIX . $assocurrrec->curriculumid)), html_writer::checkbox(self::CPY_CURR_CLS_PREFIX . $assocurrrec->curriculumid, 1, false, '', array('disabled' => true, 'id' => self::CPY_CURR_CLS_PREFIX . $assocurrrec->curriculumid)), html_writer::select($mdlcrsoptions, self::CPY_CURR_MDLCRS_PREFIX . $assocurrrec->curriculumid)); $table->rowclass[] = 'clus_cpy_row'; } } } // Add unassociated row to table. $table->data[] = array(get_string('usersetprogram_unassociated', 'local_elisprogram'), '', '', '', '', '', ''); $table->rowclass[] = 'clus_cpy_row unassigned'; // Get all curriculums, removing curricula that have already been listed. $curriculums = curriculum_get_listing($sort, $dir, 0, 0, '', '', $contexts); foreach ($curriculums as $curriculumid => $curriculumdata) { if (false === array_search($curriculumid, $curriculumshown)) { $checkboxids = "'" . self::CPY_CURR_PREFIX . $curriculumid . "',\n '" . self::CPY_CURR_TRK_PREFIX . $curriculumid . "',\n '" . self::CPY_CURR_CRS_PREFIX . $curriculumid . "',\n '" . self::CPY_CURR_CLS_PREFIX . $curriculumid . "'"; $togglecheckboxes = "cluster_copy_checkbox_changed(" . $checkboxids . ");"; $table->data[] = array('', format_string($curriculumdata->name), html_writer::checkbox(self::CPY_CURR_PREFIX . $curriculumid, 1, false, '', array('id' => self::CPY_CURR_PREFIX . $curriculumid, 'onclick' => $togglecheckboxes)), html_writer::checkbox(self::CPY_CURR_TRK_PREFIX . $curriculumid, 1, false, '', array('disabled' => true, 'id' => self::CPY_CURR_TRK_PREFIX . $curriculumid)), html_writer::checkbox(self::CPY_CURR_CRS_PREFIX . $curriculumid, 1, false, '', array('disabled' => true, 'id' => self::CPY_CURR_CRS_PREFIX . $curriculumid)), html_writer::checkbox(self::CPY_CURR_CLS_PREFIX . $curriculumid, 1, false, '', array('disabled' => true, 'id' => self::CPY_CURR_CLS_PREFIX . $curriculumid)), html_writer::select($mdlcrsoptions, self::CPY_CURR_MDLCRS_PREFIX . $curriculumid)); $table->rowclass[] = 'clus_cpy_row'; } } $currselectall = '<div class="currselectall">'; $currselectall .= '<a id="clus_currcpy_select_all" onclick="cluster_copycurriculum_set_all_selected()">'; $currselectall .= get_string('selectall') . '</a></div>'; $trkselectall = '<div class="trkselectall"><a id="clus_trkcpy_select_all" onclick="cluster_copytrack_set_all_selected()">'; $trkselectall .= get_string('selectall') . '</a></div>'; $crsselectall = '<div class="crsselectall"><a id="clus_crscpy_select_all" onclick="cluster_copycourse_set_all_selected()">'; $crsselectall .= get_string('selectall') . '</a></div>'; $clsselectall = '<div class="clsselectall"><a id="clus_crscpy_select_all" onclick="cluster_copyclass_set_all_selected()">'; $clsselectall .= get_string('selectall') . '</a></div>'; $table->data[] = array('', '', $currselectall, $trkselectall, $crsselectall, $clsselectall); $table->rowclass[] = 'clus_cpy_row select_all_row'; echo html_writer::table($table); echo '<div class="clus_curr_cpy_save_exit">'; echo '<input type="submit" name="save" value="' . get_string('userset_saveexit', 'local_elisprogram') . '">'; echo '<div class="hidden">'; echo '<input type="hidden" name="id" value="' . $id . '">'; echo '<input type="hidden" name="s" value="clstcur">'; echo '<input type="hidden" name="action" value="copycurr">'; echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '">'; echo '</div>'; echo '</div>'; echo '</form>'; }