controller = new SloodleController(); } /** * Determines whether or not course data has been loaded. * @return bool */ function is_loaded() { if (empty($this->course_object) || empty($this->sloodle_course_data)) return false; return true; } /** * Gets the identifier of the course in the VLE. * @return mixed Course identifier. Type depends on VLE. (In Moodle, it will be an integer). */ function get_course_id() { return (int)$this->course_object->id; } /** * Gets the VLE course object. * WARNING: this should only be used when ABSOLUTELY necessary. * The contents are specific to the VLE. * @return mixed Type and content depends upon VLE. In Moodle, it is an object representing a record from the 'course' table. */ function get_course_object() { return $this->course_object; } /** * Gets the short name of this course in the VLE. * @return string Shortname of this course. */ function get_short_name() { return $this->course_object->shortname; } /** * Gets the full name of this course in the VLE. * @return string Fullname of this course. */ function get_full_name() { return $this->course_object->fullname; } /** * Is auto registration permitted on this site AND course? * Takes into account the site-wide setting as well. * @return bool */ function check_autoreg() { // Check the site *and* the course value return ((bool)sloodle_autoreg_enabled_site() && (bool)$this->get_autoreg()); } /** * Gets the autoregistration value for this course only. * (Ignores the site setting). * @return bool */ function get_autoreg() { return (!empty($this->sloodle_course_data->autoreg)); } /** * Enables auto-registration for this course. * NOTE: it may still be disabled at site-level. * @return void */ function enable_autoreg() { $this->sloodle_course_data->autoreg = 1; } /** * Disables auto-registration for this course. * NOTE: does not affect the site setting. * @return void */ function disable_autoreg() { $this->sloodle_course_data->autoreg = 0; } /** * Is auto enrolment permitted on this site AND course? * Takes into account the site-wide setting as well. * @return bool */ function check_autoenrol() { // Check the site *and* the course value return ((bool)sloodle_autoenrol_enabled_site() && $this->get_autoenrol()); } /** * Gets the auto enrolment value for this course only. * (Ignores the site setting). * @return bool */ function get_autoenrol() { return (!empty($this->sloodle_course_data->autoenrol)); } /** * Enables auto-enrolment for this course. * NOTE: it may still be disabled at site-level. * @return void */ function enable_autoenrol() { $this->sloodle_course_data->autoenrol = 1; } /** * Disables auto-enrolment for this course. * NOTE: does not affect the site setting. * @return void */ function disable_autoenrol() { $this->sloodle_course_data->autoenrol = 0; } /** * Determines whether or not the course is available. * Checks that the course has not been disabled or hidden etc.. * @return bool True if the course is available */ function is_available() { // Check visbility if (empty($this->course_object->visible)) return false; return true; } /** * Gets the position of the loginzone as a string vector * @return string */ function get_loginzone_position() { if (isset($this->sloodle_course_data->loginzonepos)) return $this->sloodle_course_data->loginzonepos; return ''; } /** * Sets the position of the loginzone as a string vector * @param string $pos A string position vector * @return void * @todo Update to handle arrays as well */ function set_loginzone_position($pos) { $this->sloodle_course_data->loginzonepos = $pos; } /** * Sets the position of the loginzone as a set of components * @param float $x * @param float $y * @param float $z * @return void */ function set_loginzone_position_xyz($x, $y, $z) { $this->sloodle_course_data->loginzonepos = "<$x,$y,$z>"; } /** * Gets the size of the loginzone as a string vector * @return string */ function get_loginzone_size() { if (isset($this->sloodle_course_data->loginzonesize)) return $this->sloodle_course_data->loginzonesize; return ''; } /** * Sets the size of the loginzone as a string vector * @param string $size A string size vector * @return void * @todo Update to handle arrays as well */ function set_loginzone_size($size) { $this->sloodle_course_data->loginzonesize = $size; } /** * Sets the size of the loginzone as a set of components * @param float $x * @param float $y * @param float $z * @return void */ function set_loginzone_size_xyz($x, $y, $z) { $this->sloodle_course_data->loginzonesize = "<$x,$y,$z>"; } /** * Gets the region of the loginzone * @return string */ function get_loginzone_region() { if (isset($this->sloodle_course_data->loginzoneregion)) return $this->sloodle_course_data->loginzoneregion; return ''; } /** * Sets the region of the loginzone * @param string $region A string naming a region * @return void */ function set_loginzone_region($region) { $this->sloodle_course_data->loginzoneregion = $region; } /** * Gets the timestamp of the last time the loginzone was updated * @return int */ function get_loginzone_time_updated() { if (isset($this->sloodle_course_data->loginzoneupdated)) return $this->sloodle_course_data->loginzoneupdated; return 0; } /** * Sets the timestamp of the last time the loginzone was updated * @param int $timestamp A unix timestamp. If null, the current timestamp is used * @return void */ function set_loginzone_time_updated($timestamp = null) { if ($timestamp == null) $timestamp = time(); $this->sloodle_course_data->loginzoneupdated = $timestamp; } /** * Generates a new LoginZone allocation for the specified user. * @param SloodleUser $user The user for whom this allocation should be made * @return string|false A SLurl for the allocation, or false if it was unsuccessful */ function generate_loginzone_allocation($user) { // Make sure the necessary data is available if (!(isset($this->sloodle_course_data->loginzonepos) && isset($this->sloodle_course_data->loginzonesize) && isset($this->sloodle_course_data->loginzoneregion))) return false; // Delete any existing LoginZone allocation for this user sloodle_delete_records('sloodle_loginzone_allocation', 'userid', $user->get_user_id()); // We will try up to 10 times to find a new available position $loginzonesize = sloodle_vector_to_array($this->sloodle_course_data->loginzonesize); $maxtries = 10; $success = false; for ($i = 0; $i < $maxtries && $success == false; $i++) { // Generate a new random position $rndpos_arr = sloodle_random_position_in_zone($loginzonesize); // Make sure the Z parameter is even - round it if not if ($rndpos_arr['z'] % 2 != 0) $rndpos_arr['z'] += 1; $rndpos_str = sloodle_array_to_vector($rndpos_arr); // Is the position already taken? if (!sloodle_get_record('sloodle_loginzone_allocation', 'course', $this->get_course_id(), 'position', $rndpos_str)) { // Nobody has the position $success = true; } } // Did we succeed in generating it? if (!$success) return false; // Create a new one $alloc = new stdClass(); $alloc->course = $this->get_course_id(); $alloc->userid = $user->get_user_id(); $alloc->position = $rndpos_str; $alloc->timecreated = time(); // Attempt to insert it into the database if (!sloodle_insert_record('sloodle_loginzone_allocation', $alloc)) return false; return true; } /** * Gets the SLurl for the specified user's loginzone alloation * @param SloodleUser $user The user whose allocation is to be retrieved * @return string|bool The SLurl string if successful, or false if the user has no allocation or the loginzone does not exist */ function get_loginzone_allocation($user) { // Make sure the necessary data is available if (!(isset($this->sloodle_course_data->loginzonepos) && isset($this->sloodle_course_data->loginzonesize) && isset($this->sloodle_course_data->loginzoneregion))) return false; // Attempt to fetch the data $alloc = sloodle_get_record('sloodle_loginzone_allocation', 'course', $this->get_course_id(), 'userid', $user->get_user_id()); if (!$alloc) return false; $relpos = sloodle_vector_to_array($alloc->position); // Calculate the absolute position of the allocation $loginzonepos= sloodle_vector_to_array($this->sloodle_course_data->loginzonepos); $abspos = array('x'=>$loginzonepos['x'] + $relpos['x'], 'y'=>$loginzonepos['y'] + $relpos['y'], 'z'=>$loginzonepos['z'] + $relpos['z']); // Construct and return the SLurl return "secondlife://{$this->sloodle_course_data->loginzoneregion}/{$abspos['x']}/{$abspos['y']}/{$abspos['z']}"; } /** * Finds the user identified by LoginZone allocation, and loads it into the given user object. * Note: does not delete the allocation. * @param string $pos Absolute position vector (relative to sim, not to LoginZone) * @param SloodleUser &$user The user object which will be manipulated (by reference) * @return bool True if successful, or false otherwise */ function load_user_by_loginzone($pos, &$user) { // Calculate the relative position of the allocation $abspos = sloodle_vector_to_array($pos); $loginzonepos= sloodle_vector_to_array($this->sloodle_course_data->loginzonepos); $relpos = array('x'=>$abspos['x'] - $loginzonepos['x'], 'y'=>$abspos['y'] - $loginzonepos['y'], 'z'=>$abspos['z'] - $loginzonepos['z']); $relposstr = sloodle_array_to_vector($relpos); // Generate an alternate LoginZone position 1 unit downwards, in case the SL teleport glitch has happened. // (Note that LoginZone positions are generate on even Z units only, so an offset of 1 shouldn't cause a problem) $altrelpos = array('x'=>$relpos['x'], 'y'=>$relpos['y'], 'z'=>$relpos['z'] - 1); $altrelposstr = sloodle_array_to_vector($altrelpos); // Attempt to find a matching LoginZone position in the database $rec = sloodle_get_record('sloodle_loginzone_allocation', 'course', $this->get_course_id(), 'position', $relposstr); if (!$rec) { $rec = sloodle_get_record('sloodle_loginzone_allocation', 'course', $this->get_course_id(), 'position', $altrelposstr); } if (!$rec) return false; // Load the user return $user->load_user($rec->userid); } /** * Deletes any loginzone allocations for the given user * If there are multiple for the same user (which there should never be) it will delete them all. * @param SloodleUser $user The user whose allocation is to be deleted * @return void */ function delete_loginzone_allocation($user) { sloodle_delete_records('sloodle_loginzone_allocation', 'userid', $user->get_user_id()); } /** * Determines whether or not LoginZone data exists for this course. * @return bool True if there is complete data, or false otherwise */ function has_loginzone_data() { return (!(empty($this->sloodle_course_data->loginzonepos) || empty($this->sloodle_course_data->loginzonesize) || empty($this->sloodle_course_data->loginzoneregion))); } /** * Reads fresh data into the structure from the database. * Fetches Moodle and Sloodle data about the course specified. * If necessary, it creates a new Sloodle entry with default settings. * Returns true if successful, or false on failure. * @param mixed $course Either a unique course ID, or a course data object. If the former, then VLE course data is read from the database. Otherwise, the data object is used as-is. * @return bool */ function load($course) { // Reset everything $this->course_object = null; $this->sloodle_course_data = null; // Check what we are dealing with if (is_int($course)) { // It is a course ID - make sure it's valid if ($course <= 0) return false; // Load the course data $this->course_object = sloodle_get_record('course', 'id', $course); if (!$this->course_object) { $this->course_object = null; return false; } } else if (is_object($course)) { // It is an object - make sure it has an ID if (!isset($course->id)) return false; $this->course_object = $course; } else { // Don't know what it is - do nothing return false; } // Fetch the Sloodle course data $this->sloodle_course_data = sloodle_get_record('sloodle_course', 'course', $this->course_object->id); // Did it fail? if (!$this->sloodle_course_data) { // Create the new entry $this->sloodle_course_data = new stdClass(); $this->sloodle_course_data->course = $this->course_object->id; $this->sloodle_course_data->autoreg = 0; $this->sloodle_course_data->loginzonepos = ''; $this->sloodle_course_data->loginzonesize = ''; $this->sloodle_course_data->loginzoneregion = ''; $this->sloodle_course_data->id = sloodle_insert_record('sloodle_course', $this->sloodle_course_data); // Did something go wrong? if (!$this->sloodle_course_data->id) { $this->course_object = null; $this->sloodle_course_data = null; return false; } } return true; } /** * Loads course and controller data by the unqiue site-wide identifier of a Sloodle controller. * @param mixed $controllerid The unique site-wide identifier for a Sloodle Controller. (For Moodle, an integer cmi) * @return bool True if successful, or false on failure. */ function load_by_controller($controllerid) { // Clear out all our data $this->course_object = null; $this->sloodle_course_data = null; // Construct a new controller object, and attempt to load its data $this->controller = new SloodleController(); if (!$this->controller->load($controllerid)) { sloodle_debug("Failed to load controller.
"); return false; } // Now attempt to load all the course data if (!$this->load($this->controller->get_course_id())) { sloodle_debug("Failed to load course data.
"); return false; } return true; } /** * Writes current Sloodle course data back to the database. * Requires that a course structure has already been retrieved. * @return bool True if successful, or false on failure */ function write() { // Make sure the course data is valid if (empty($this->course_object) || $this->course_object->id <= 0) return false; if (empty($this->sloodle_course_data) || $this->sloodle_course_data->id <= 0) return false; // Update the Sloodle data return sloodle_update_record('sloodle_course', $this->sloodle_course_data); } /** * Gets an array associating layout ID's to names * @return array */ function get_layout_names() { // Fetch the layout records $layouts = sloodle_get_records('sloodle_layout', 'course', $this->course_object->id, 'name'); if (!$layouts) return array(); // Construct the array of names $layout_names = array(); foreach ($layouts as $l) { $layout_names[$l->id] = $l->name; } return $layout_names; } /** * Gets all the entries in the named layout. * @param string $name The name of the layout to query * @return array|bool A numeric array of {@link SloodleLayoutEntry} objects if successful, or false if the layout does not exist */ function get_layout_entries($name) { // Attempt to find the relevant layout $layout = sloodle_get_record('sloodle_layout', 'course', $this->course_object->id, 'name', $name); if (!$layout) return false; return $this->get_layout_entries_for_layout_id($layout->id); } /** * Gets all the entries in the named layout. * @param string $name The name of the layout to query * @return array|bool A numeric array of {@link SloodleLayoutEntry} objects if successful, or false if the layout does not exist */ function get_layout_entries_for_layout_id($id) { // Fetch all entries $recs = sloodle_get_records('sloodle_layout_entry', 'layout', $id); if (!$recs) return array(); // Construct the array of SloodleLayoutEntry objects $entries = array(); foreach ($recs as $r) { $entry = new SloodleLayoutEntry($r); $entries[] = $entry; } return $entries; } /** * Gets SloodleLayout objects for all the layouts in the course. */ function get_layouts($controllerid) { // Fetch the layout records $layoutrecs = sloodle_get_records('sloodle_layout', 'course', $this->course_object->id, 'name'); $layouts = array(); if (!$layoutrecs) return array(); foreach ($layoutrecs as $r) { if ($r->controllerid != $controllerid) { continue; } $layouts[] = new SloodleLayout($r); } return $layouts; } /** * Deletes the named layout. * @param string $name The name of the layout to delete * @return void */ function delete_layout($name) { // Attempt to find the relevant layout $layout = sloodle_get_record('sloodle_layout', 'course', $this->course_object->id, 'name', $name); if (!$layout) return; // Delete all related entries sloodle_delete_records('sloodle_layout_entry', 'layout', $layout->id); // Delete the layout itself sloodle_delete_records('sloodle_layout', 'course', $this->course_object->id, 'name', $name); } /** * Save the given entries in the named profile. * @param string $name The name of the layout to query * @param array $entries A numeric array of {@link SloodleLayoutEntry} objects to store * @param bool $add (Default: false) If true, then the entries will be added to the layout instead of replacing existing entries * @return bool True if successful, or false otherwise */ function save_layout($name, $entries, $add = false) { // Attempt to find the relevant layout $layout = sloodle_get_record('sloodle_layout', 'course', $this->course_object->id, 'name', $name); $lid = 0; if ($layout) { $lid = $layout->id; } return $this->save_layout_by_id($lid, $name, $entries, $add); } /** * Save the given entries in the profile specified by id. * @param string $id The id of the layout to query. 0 to add a new layout. * @param string $name The new name of the layout. * @param array $entries A numeric array of {@link SloodleLayoutEntry} objects to store * @param bool $add (Default: false) If true, then the entries will be added to the layout instead of replacing existing entries * @return bool True if successful, or false otherwise */ function save_layout_by_id($id, $name, $entries, $add = false) { // Attempt to find the relevant layout if ($id > 0) { /* // Delete all existing entries if necessary // This will happen when we save // TODO: make add-only functionality for backwards compatibility if (!$add) { sloodle_delete_records('sloodle_layout_entry', 'layout', $layout->id); } */ $layout = $this->get_layout($id); $layout->name = $name; $layout->timeupdated = time(); $layout->entries = $entries; $layout->populate_entries_from_active_objects(); // where the records have objectuuids set, copy their settings if (!$layout->update()) { return false; } $this->layout = $layout; } else { $layout = new SloodleLayout(); $layout->name = $name; $layout->course = $this->course_object->id; $layout->timeupdated = time(); $layout->entries = $entries; $layout->populate_entries_from_active_objects(); $layout->id = $layout->insert(); #sloodle_insert_record('sloodle_layout', $layout); if (!$layout->id) return false; $this->layout = $layout; } /* // This should have been done by the layout // Insert each new entry $success = true; foreach ($entries as $e) { $rec = new stdClass(); $rec->layout = $layout->id; $rec->name = $e->name; $rec->position = $e->position; $rec->rotation = $e->rotation; // TODO EDE: If there's an objectuuid for the entry, copy the entries from the active object table to the layout config table if ($objectuuid != '') { $rec->copy_active_object_with_uuid($e->objectuuid); } $entry_id = sloodle_insert_record('sloodle_layout_entry', $rec); } */ return $layout->id; } function get_enrolled_users(){ global $CFG; $contextid = get_context_instance(CONTEXT_COURSE,$this->course_object->id); $cid=$contextid->id; $sql= "SELECT distinct sl.*,sl.uuid as avuuid,u.id, u.firstname, u.lastname FROM {$CFG->prefix}user u INNER JOIN {$CFG->prefix}sloodle_users sl ON sl.userid=u.id INNER JOIN {$CFG->prefix}role_assignments ra ON ra.userid=u.id AND ra.contextid=?"; $enrolledUsers = sloodle_get_records_sql_params($sql, array($cid)); //return $enrolledUsers return $enrolledUsers; } function get_layout($layoutid) { $rec = sloodle_get_record('sloodle_layout', 'course', $this->course_object->id, 'id', $layoutid); return new SloodleLayout($rec); } // Make sure the course has at least one layout, creating one if necessary using the prefix $nameprefix // Returns true on success, false on failure function ensure_at_least_one_layout($nameprefix, $controllerid) { if ( count($this->get_layouts($controllerid)) > 0 ) { return true; } if (!$layoutname = SloodleLayout::UniqueName($nameprefix)) { return false; } $l = new SloodleLayout(); $l->name = $layoutname; $l->controllerid = $controllerid; $l->course = $this->course_object->id; return $l->insert(); } /** * Checks whether or not the CURRENTLY LOGGED-IN user can authorise objects on this course. * @return bool True if the user has object authorisation permission, or false otherwise. */ function can_user_authorise_objects() { global $USER; // Make sure some user data if (empty($USER) || $USER->id == 0) return FALSE; // Check the capability return has_capability('mod/sloodle:objectauth', get_context_instance(CONTEXT_COURSE, $this->get_course_id())); } } ?>