Пример #1
0
 /**
  * Constructs navigational breadcrumbs
  */
 function build_navbar_default($who = null)
 {
     $id = $this->required_param('id', PARAM_INT);
     $classpage = new pmclasspage(array('id' => $id));
     $classpage->build_navbar_view();
     $this->_navbar = $classpage->navbar;
 }
Пример #2
0
 function can_do_default()
 {
     global $USER;
     $id = $this->required_param('id', PARAM_INT);
     // TODO: Ugly, this needs to be overhauled
     $cpage = new pmclasspage();
     return $cpage->_has_capability('local/elisreports:view', $id) || instructor::user_is_instructor_of_class(cm_get_crlmuserid($USER->id), $id);
 }
Пример #3
0
 public function definition()
 {
     $mform =& $this->_form;
     // ensure the user is allowed to view the classes being listed
     $user_classes = pmclass_get_listing('crsname', 'ASC', 0, 11, '', '', 0, false, pmclasspage::get_contexts('local/elisprogram:class_view'));
     if (empty($user_classes)) {
         // show a default label
         $mform->addElement('static', 'static_name', get_string('no_courses', 'block_courserequest'));
     } else {
         // we have classes to list
         $mform->addElement('static', 'static_title', get_string('current_classes', 'block_courserequest'));
         foreach ($user_classes as $uc) {
             $context = \local_elisprogram\context\pmclass::instance($uc->id);
             // this points to the page that displays the specific class
             $target = new pmclasspage(array('id' => $uc->id, 'action' => 'view'));
             $mform->addElement('static', 'course' . $uc->id, '', "<a href=\"{$target->url}\">{$uc->idnumber}</a>");
         }
         // use a "More" link if there are more than ten classes
         if (count($user_classes) > 10) {
             $target = new pmclasspage(array());
             // TBV
             $more = "<a href=\"{$target->url}\">" . get_string('moreclasses', 'block_courserequest') . '</a>';
             $mform->addElement('static', '' . $uc->id, '', $more);
         }
     }
     // button for creating a new request
     $mform->addElement('submit', 'add', get_string('request', 'block_courserequest'));
 }
Пример #4
0
/**
 * Dynamically loads child menu items for a course 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_course($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();
    /*****************************************
     * Course - Class Associations
     *****************************************/
    $class_css_class = block_elisadmin_get_item_css_class('class_instance');
    //permissions filter
    $class_contexts = pmclasspage::get_contexts('local/elisprogram:class_view');
    $listing = pmclass_get_listing('crsname', 'asc', 0, $num_block_icons, '', '', $id, false, $class_contexts, $parent_cluster_id);
    foreach ($listing as $item) {
        $item->clsname = $item->idnumber;
        $params = array('id' => $item->id, 'action' => 'view');
        $result_items[] = block_elisadmin_get_menu_item('pmclass', $item, 'root', $class_css_class, $parent_cluster_id, $parent_curriculum_id, $params, false, $parent_path);
    }
    unset($listing);
    //summary item
    $num_records = pmclass_count_records('', '', $id, false, $class_contexts, $parent_cluster_id);
    if ($num_block_icons < $num_records) {
        $params = array('action' => 'default', '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('pmclass', $class_css_class, $num_records - $num_block_icons, $params, '', $parent_path);
    }
    return $result_items;
}
Пример #5
0
 /**
  * Determines whether the current user is allowed to create, edit, and delete associations
  * between a user and a class
  *
  * @param    int      $userid    The id of the user being associated to the class
  * @param    int      $classid   The id of the class we are associating the user to
  * @uses     $DB
  * @uses     $USER;
  * @return   boolean             True if the current user has the required permissions, otherwise false
  */
 public static function can_manage_assoc($userid, $classid)
 {
     global $DB, $USER;
     // TODO: Ugly, this needs to be overhauled
     $cpage = new pmclasspage();
     if (!pmclasspage::can_enrol_into_class($classid)) {
         //the users who satisfty this condition are a superset of those who can manage associations
         return false;
     } else {
         if ($cpage->_has_capability('local/elisprogram:class_enrol', $classid)) {
             //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:class_enrol_userset_user', $USER->id);
     $allowed_clusters = array();
     $allowed_clusters = pmclass::get_allowed_clusters($classid);
     //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 = ? AND {$cluster_select}";
     //user just needs to be in one of the possible clusters
     if ($DB->record_exists_select(clusterassignment::TABLE, $select, array($userid))) {
         return true;
     }
     return false;
 }
Пример #6
0
 /**
  * Determine whether the current user can enrol students into the class.
  *
  * @return bool Whether the user can enrol users into the class or not.
  */
 public function can_do_add()
 {
     $id = $this->required_param('id');
     return pmclasspage::can_enrol_into_class($id);
 }
Пример #7
0
 /**
  * Returns an array of cluster ids that are associated to the supplied class through tracks and
  * the current user has access to enrol users into
  *
  * @param   int        $clsid  The class whose association ids we care about
  * @return  int array          The array of accessible cluster ids
  */
 public static function get_allowed_clusters($clsid)
 {
     global $USER;
     $context = pm_context_set::for_user_with_capability('cluster', 'local/elisprogram:assign_userset_user_class_instructor', $USER->id);
     $allowed_clusters = array();
     // TODO: Ugly, this needs to be overhauled
     $cpage = new pmclasspage();
     if ($cpage->_has_capability('local/elisprogram:assign_userset_user_class_instructor', $clsid)) {
         require_once elispm::lib('data/clusterassignment.class.php');
         $cmuserid = pm_get_crlmuserid($USER->id);
         $userclusters = clusterassignment::find(new field_filter('userid', $cmuserid));
         foreach ($userclusters as $usercluster) {
             $allowed_clusters[] = $usercluster->clusterid;
         }
     }
     //we first need to go through tracks to get to clusters
     $track_listing = new trackassignment(array('classid' => $clsid));
     $tracks = $track_listing->get_assigned_tracks();
     //iterate over the track ides, which are the keys of the array
     if (!empty($tracks)) {
         foreach (array_keys($tracks) as $track) {
             //get the clusters and check the context against them
             $clusters = clustertrack::get_clusters($track);
             $allowed_track_clusters = $context->get_allowed_instances($clusters, 'cluster', 'clusterid');
             //append all clusters that are allowed by the available clusters contexts
             foreach ($allowed_track_clusters as $allowed_track_cluster) {
                 $allowed_clusters[] = $allowed_track_cluster;
             }
         }
     }
     return $allowed_clusters;
 }
Пример #8
0
 /**
  * Gets filter sql for permissions.
  * @return array An array consisting of additional WHERE conditions, and parameters.
  */
 protected function get_filter_sql_permissions()
 {
     global $DB;
     $additionalfilters = array();
     $additionalfiltersparams = array();
     // If appropriate limit selection to users belonging to clusters for which the user can manage instructor assignments.
     // TODO: Ugly, this needs to be overhauled.
     $cpage = new pmclasspage();
     if (!$cpage->_has_capability('local/elisprogram:assign_class_instructor', $this->classid)) {
         // Perform SQL filtering for the more "conditional" capability.
         $allowedclusters = instructor::get_allowed_clusters($this->classid);
         if (empty($allowedclusters)) {
             $additionalfilters[] = 'FALSE';
         } else {
             list($usersetinoreq, $usersetinoreqparams) = $DB->get_in_or_equal($allowedclusters);
             $clusterfilter = 'SELECT userid FROM {' . clusterassignment::TABLE . '} WHERE clusterid ' . $usersetinoreq;
             $additionalfilters[] = 'element.id IN (' . $clusterfilter . ')';
             $additionalfiltersparams = array_merge($additionalfiltersparams, $usersetinoreqparams);
         }
     }
     return array($additionalfilters, $additionalfiltersparams);
 }
Пример #9
0
 /**
  * Test creating a new class entity with a default role assignment defined.
  */
 public function test_createclasswithdefaultroleassignment()
 {
     global $USER, $DB;
     list($rcid, $reid) = $this->create_roles('class');
     // Setup the editor role to be the default role for the class context.
     elis::$config->local_elisprogram->default_class_role_id = $reid;
     $sysctx = context_system::instance();
     // Assign the test user the creator role.
     role_assign($rcid, $USER->id, $sysctx->id);
     // Create a new class entity.
     $data = array('courseid' => 100, 'idnumber' => 'program100', 'name' => 'program100', 'description' => 'program100');
     $obj = new pmclass($data);
     $obj->save();
     // Initialize a new class management page and invoke the code that handles default role assignments.
     $page = new pmclasspage();
     $sink = $this->redirectMessages();
     $page->after_cm_entity_add($obj);
     $classctx = \local_elisprogram\context\pmclass::instance($obj->id);
     $params = array('roleid' => $reid, 'userid' => $USER->id, 'contextid' => $classctx->id);
     $this->assertTrue($DB->record_exists('role_assignments', $params));
 }
 /**
  * Takes a record and transforms it into an appropriate format
  * This method is set up as a hook to be implented by actual report class
  *
  * @param   stdClass  $record         The current report record
  * @param   string    $export_format  The format being used to render the report
  * @uses $CFG
  * @return stdClass  The reformatted record
  */
 function transform_record($record, $export_format)
 {
     //add entity links
     if ($export_format == table_report::$EXPORT_FORMAT_HTML) {
         //link curriculum name to its "view" page if the the current record has a curriculum
         if (!empty($record->curid) && isset($record->curriculumname)) {
             $page = new curriculumpage(array('id' => $record->curid, 'action' => 'view'));
             if ($page->can_do()) {
                 $record->curriculumname = '<span class="external_report_link"><a href="' . $page->url . '" target="_blank">' . $record->curriculumname . '</a></span>';
             }
         } else {
             //non-curriculum course, so use status string with no link
             $record->curriculumname = get_string('noncurriculumcourse', $this->languagefile);
         }
         //link course name to its "view" page
         $page = new coursepage(array('id' => $record->courseid, 'action' => 'view'));
         if ($page->can_do()) {
             $record->coursename = '<span class="external_report_link"><a href="' . $page->url . '" target="_blank">' . $record->coursename . '</a></span>';
         }
         //link class name to its "view" page
         $page = new pmclasspage(array('id' => $record->classid, 'action' => 'view'));
         if ($page->can_do()) {
             $record->classidnumber = '<span class="external_report_link"><a href="' . $page->url . '" target="_blank">' . $record->classidnumber . '</a></span>';
         }
     }
     //show environment as N/A if not set
     if (empty($record->envname)) {
         $record->envname = get_string('na', $this->languagefile);
     }
     //format the start date
     $record->startdate = $this->format_date($record->startdate);
     //show number of passed and total number of completion elements
     $record->elementsdisplayed = get_string('compelements_passed', $this->languagefile, $record);
     //convert status id to a display string
     if ($record->completestatusid == STUSTATUS_PASSED) {
         $record->completionstatus = get_string('status_passed', $this->languagefile);
     } else {
         if ($record->completestatusid == STUSTATUS_FAILED) {
             $record->completionstatus = get_string('status_failed', $this->languagefile);
         } else {
             if ($record->completestatusid == STUSTATUS_NOTCOMPLETE) {
                 $record->completionstatus = get_string('status_notcomplete', $this->languagefile);
             } else {
                 $record->completionstatus = get_string('status_notstarted', $this->languagefile);
             }
         }
     }
     //if not passed, shouldn't have any credits
     if ($record->completestatusid != STUSTATUS_PASSED) {
         $record->credits = 0;
     }
     //copy result of complex sub-query into simple field
     $record->creditsdisplayed = $this->format_credits($record->credits);
     //format the completion time
     if ($record->completestatusid == STUSTATUS_NOTCOMPLETE) {
         //not complete, so don't show a completion time
         $record->completetime = '0';
     }
     //only show a completion time if passed
     if ($record->completestatusid == STUSTATUS_PASSED || $record->completestatusid == STUSTATUS_FAILED) {
         $record->completetime = $this->format_date($record->completetime);
     } else {
         $record->completetime = get_string('na', $this->languagefile);
     }
     //display whether the current record is a student or an instructor assignment
     if ($record->isinstructor) {
         $record->classrole = get_string('instructor', $this->languagefile);
     } else {
         $record->classrole = get_string('student', $this->languagefile);
     }
     //handle custom field default values and display logic
     $this->transform_custom_field_data($record);
     return $record;
 }
Пример #11
0
 public function __construct(array $params = null)
 {
     // Check the course certificate global settings value
     $showcoursecerttab = isset(elis::$config->local_elisprogram->disablecoursecertificates);
     $showcoursecerttab = $showcoursecerttab && empty(elis::$config->local_elisprogram->disablecoursecertificates);
     $numclasses = 1;
     if (($id = $this->optional_param('id', 0, PARAM_INT)) > 0 && !$this->_has_capability('local/elisprogram:class_create', $id)) {
         $parentclusterid = $this->optional_param('parent_clusterid', 0, PARAM_INT);
         $numclasses = pmclass_count_records('', '', $id, false, pmclasspage::get_contexts('local/elisprogram:class_view'), $parentclusterid);
     }
     $this->tabs = array(array('tab_id' => 'view', 'page' => get_class($this), 'params' => array('action' => 'view'), 'name' => get_string('detail', 'local_elisprogram'), 'showtab' => true), array('tab_id' => 'edit', 'page' => get_class($this), 'params' => array('action' => 'edit'), 'name' => get_string('edit', 'local_elisprogram'), 'showtab' => true, 'showbutton' => true, 'image' => 'edit'), array('tab_id' => 'pmclasspage', 'page' => 'pmclasspage', 'params' => array('action' => 'default'), 'name' => get_string('course_classes', 'local_elisprogram'), 'showtab' => $numclasses > 0, 'showbutton' => $numclasses > 0, 'image' => 'class'), array('tab_id' => 'elem', 'page' => get_class($this), 'params' => array('action' => 'lelem'), 'name' => get_string('completion_elements', 'local_elisprogram'), 'showtab' => true, 'showbutton' => true, 'image' => 'grades'), array('tab_id' => 'coursecurriculumpage', 'page' => 'coursecurriculumpage', 'name' => get_string('course_curricula', 'local_elisprogram'), 'showtab' => true, 'showbutton' => true, 'image' => 'curriculum'), array('tab_id' => 'course_rolepage', 'page' => 'course_rolepage', 'name' => get_string('roles', 'role'), 'showtab' => true, 'showbutton' => false, 'image' => 'tag'), array('tab_id' => 'course_enginepage', 'page' => 'course_enginepage', 'name' => get_string('results_engine', 'local_elisprogram'), 'showtab' => true, 'showbutton' => true, 'image' => 'calculator'), array('tab_id' => 'course_enginestatuspage', 'page' => 'course_enginestatuspage', 'name' => get_string('status_report', 'local_elisprogram'), 'showtab' => false, 'showbutton' => false), array('tab_id' => 'course_certificatepage', 'page' => 'course_certificatepage', 'name' => get_string('certificate_settings', 'local_elisprogram'), 'showtab' => $showcoursecerttab, 'showbutton' => $showcoursecerttab, 'image' => 'certificate'), array('tab_id' => 'delete', 'page' => get_class($this), 'params' => array('action' => 'delete'), 'name' => get_string('delete_label', 'local_elisprogram'), 'showbutton' => true, 'image' => 'delete'));
     parent::__construct($params);
 }
Пример #12
0
 function display_default()
 {
     // Get parameters
     $sort = optional_param('sort', 'crsname', PARAM_ALPHA);
     $dir = optional_param('dir', 'ASC', PARAM_ALPHA);
     $page = optional_param('page', 0, PARAM_INT);
     $perpage = optional_param('perpage', 30, PARAM_INT);
     // how many per page
     $namesearch = trim(optional_param('search', '', PARAM_TEXT));
     $alpha = optional_param('alpha', '', PARAM_ALPHA);
     $id = $this->get_cm_id();
     //this parameter signifies a required relationship between a class and a track
     //through a cluster
     $parent_clusterid = $this->optional_param('parent_clusterid', 0, PARAM_INT);
     // Define columns
     $columns = array('crsname' => array('header' => get_string('class_course', 'local_elisprogram')), 'idnumber' => array('header' => get_string('class_idnumber', 'local_elisprogram')), 'moodlecourse' => array('header' => get_string('class_moodle_course', 'local_elisprogram')), 'startdate' => array('header' => get_string('class_startdate', 'local_elisprogram')), 'enddate' => array('header' => get_string('class_enddate', 'local_elisprogram')), 'starttime' => array('header' => get_string('class_starttime', 'local_elisprogram')), 'endtime' => array('header' => get_string('class_endtime', 'local_elisprogram')), 'maxstudents' => array('header' => get_string('class_maxstudents', 'local_elisprogram')));
     //set the column data needed to maintain and display current sort
     if ($dir !== 'DESC') {
         $dir = 'ASC';
     }
     if (isset($columns[$sort])) {
         $columns[$sort]['sortable'] = $dir;
     }
     $contexts = pmclasspage::get_contexts('local/elisprogram:class_view');
     $items = pmclass_get_listing($sort, $dir, $page * $perpage, $perpage, $namesearch, $alpha, $id, false, $contexts, $parent_clusterid);
     $numitems = pmclass_count_records($namesearch, $alpha, $id, false, $contexts, $parent_clusterid);
     pmclasspage::get_contexts('local/elisprogram:class_edit');
     pmclasspage::get_contexts('local/elisprogram:class_delete');
     if (!empty($id)) {
         $coursepage = new coursepage(array('id' => $id));
         $coursepage->print_tabs('pmclasspage', array('id' => $id));
     }
     $this->print_list_view($items, $numitems, $columns, $filter = null, $alphaflag = true, $searchflag = true);
     unset($items);
 }
 /**
  * Test perms.
  * @dataProvider dataprovider_available_table_obeys_perms
  * @param array $associations An array of arrays of parameters to construct student associations.
  * @param int $tableclassid The ID of the class we're managing.
  * @param array $expectedresults The expected page of results.
  */
 public function test_available_table_obeys_perms($perms, $classtracks, $trackclusters, $userclusters, $tableclassid, $expectedresults)
 {
     global $USER, $DB, $CFG;
     $userbackup = $USER;
     // Set up permissions.
     $USER = $this->setup_permissions_test();
     // Set up permissions.
     foreach ($perms as $perm => $contexts) {
         foreach ($contexts as $level => $ids) {
             if ($level === 'system') {
                 $this->give_permission_for_context($USER->id, $perm, context_system::instance());
             } else {
                 foreach ($ids as $id) {
                     $ctxclass = '\\local_elisprogram\\context\\' . $level;
                     $ctx = $ctxclass::instance($id);
                     $this->give_permission_for_context($USER->id, $perm, $ctx);
                 }
             }
         }
     }
     pmclasspage::$contexts = array();
     accesslib_clear_all_caches(true);
     // Create associations.
     $assocarrays = array('classtracks' => 'trackassignment', 'trackclusters' => 'clustertrack', 'userclusters' => 'clusterassignment');
     foreach ($assocarrays as $arrayname => $assocclass) {
         foreach (${$arrayname} as $association) {
             $association = new $assocclass($association);
             $association->save();
         }
     }
     $table = new deepsight_datatable_instructor_available_mock($DB, 'test', 'http://localhost', 'testuniqid');
     $table->set_classid($tableclassid);
     $actualresults = $table->get_search_results(array(), array(), 0, 20);
     $this->assert_search_results($expectedresults, count($expectedresults), $actualresults);
     // Restore user.
     $USER = $userbackup;
 }
Пример #14
0
 /**
  * Determines whether the current user is allowed to enrol users into the provided class.
  * @param int $classid The id of the class we are checking permissions on
  * @return boolean Whether the user is allowed to enrol users into the class
  *
  */
 public static function can_enrol_into_class($classid)
 {
     global $USER;
     $directperm = 'local/elisprogram:assign_class_instructor';
     $indirectperm = 'local/elisprogram:assign_userset_user_class_instructor';
     // Check the standard capability.
     // TODO: Ugly, this needs to be overhauled.
     $cpage = new pmclasspage();
     if ($cpage->_has_capability($directperm, $classid) || $cpage->_has_capability($indirectperm, $classid)) {
         return true;
     }
     // Get the context for the "indirect" capability.
     $context = pm_context_set::for_user_with_capability('cluster', $indirectperm, $USER->id);
     // We first need to go through tracks to get to clusters.
     $tracklisting = new trackassignment(array('classid' => $classid));
     $tracks = $tracklisting->get_assigned_tracks();
     // Iterate over the track ides, which are the keys of the array.
     if (!empty($tracks)) {
         foreach (array_keys($tracks) as $track) {
             // Get the clusters and check the context against them.
             $clusters = clustertrack::get_clusters($track);
             if (!empty($clusters)) {
                 foreach ($clusters as $cluster) {
                     if ($context->context_allowed($cluster->clusterid, 'cluster')) {
                         return true;
                     }
                 }
             }
         }
     }
     return false;
 }
Пример #15
0
 /**
  * Method to return sql filter for table
  * @return array the filter sql and sql parameters
  */
 public function table_filter()
 {
     $contexts = pmclasspage::get_contexts('local/elisprogram:class_view');
     if ($contexts != null) {
         $filterobj = $contexts->get_filter('id', 'class');
         return $filterobj->get_sql(false, 'cc');
     }
     return array('FALSE', array());
 }
Пример #16
0
 /**
  * Do copy curriculum.
  */
 public function do_copycurr()
 {
     global $CFG;
     // TODO: replace print_object messages with notice messages.
     $sesskey = required_param('sesskey', PARAM_TEXT);
     if (!confirm_sesskey($sesskey)) {
         print_error('invalidsesskey', 'error', 'index.php');
     }
     $data = (array) data_submitted();
     $clusterid = $this->required_param('id', PARAM_INT);
     if (empty($data)) {
         notify(get_string('nodatasubmit', 'local_elisprogram'), 'red');
     }
     $targetcluster = new userset($clusterid);
     // Retrieve all of the curriculums that need to be copied and assigned.
     $prefixlen = strlen(self::CPY_CURR_PREFIX);
     foreach ($data as $datakey => $datavalue) {
         if (0 === strncmp($datakey, self::CPY_CURR_PREFIX, $prefixlen)) {
             $currid = (int) substr($datakey, $prefixlen);
             if (!$currid) {
                 continue;
             }
             $curr = new curriculum($currid);
             $options = array('targetcluster' => $targetcluster);
             if ($this->optional_param(self::CPY_CURR_TRK_PREFIX . $currid, 0, PARAM_INT)) {
                 $options['tracks'] = true;
             }
             if ($this->optional_param(self::CPY_CURR_CRS_PREFIX . $currid, 0, PARAM_INT)) {
                 $options['courses'] = true;
             }
             if ($this->optional_param(self::CPY_CURR_CLS_PREFIX . $currid, 0, PARAM_INT)) {
                 $options['classes'] = true;
             }
             $options['moodlecourses'] = $this->optional_param(self::CPY_CURR_MDLCRS_PREFIX . $currid, 'copyalways', PARAM_ALPHA);
             $rv = $curr->duplicate($options);
             if (!empty($rv['errors'])) {
                 foreach ($rv['errors'] as $error) {
                     notify($error);
                 }
             }
             /*
              * The following block of code performs any necessary post-processing,
              * primarily used for copying role assignments
              */
             // We need to handle curricula first in case role assignments at lower levels become redundant.
             if (!empty($rv['curricula'])) {
                 $curriculum = new stdClass();
                 $curriculum->id = $rv['curricula'][$curr->id];
                 curriculumpage::after_cm_entity_add($curriculum);
             }
             if (!empty($rv['tracks'])) {
                 foreach ($rv['tracks'] as $trackid) {
                     $track = new stdClass();
                     $track->id = $trackid;
                     trackpage::after_cm_entity_add($track);
                 }
             }
             if (!empty($rv['courses'])) {
                 foreach ($rv['courses'] as $courseid) {
                     $course = new stdClass();
                     $course->id = $courseid;
                     coursepage::after_cm_entity_add($course);
                 }
             }
             if (!empty($rv['classes'])) {
                 foreach ($rv['classes'] as $classid) {
                     $class = new stdClass();
                     $class->id = $classid;
                     pmclasspage::after_cm_entity_add($class);
                 }
             }
             if (!empty($rv['curricula'])) {
                 $newcurr = new curriculum($rv['curricula'][$curr->id]);
                 $tempcurr = new stdClass();
                 $tempcurr->name = $curr->name;
                 $tempcurr->newname = $newcurr->name;
                 notify(get_string('clustcpycurr', 'local_elisprogram', $tempcurr), 'notifysuccess');
             }
         }
     }
     $tmppage = new clustercurriculumpage(array('id' => $data['id']));
     redirect($tmppage->url, '', 2);
 }