load_by_course_module_id($id);
}
/**
* Loads data from the database.
* Note: even if the function fails, it may still have overwritten some or all existing data in the object.
* @param mixed $id The site-wide unique identifier for all modules. Course module identifier ('id' field of 'course_modules' table)
* @return bool True if successful, or false otherwise
*/
function load_by_course_module_id($cmid) {
// Make sure the ID is valid
$cmid = (int)$cmid;
if ($cmid <= 0) return false;
// Fetch the course module data
if (!($this->cm = get_coursemodule_from_id('sloodle', $cmid))) {
sloodle_debug("Failed to load controler course module.
");
return false;
}
// Load from the primary table: Sloodle instance
if (!($this->sloodle_module_instance = sloodle_get_record('sloodle', 'id', $this->cm->instance))) {
sloodle_debug("Failed to load controller Sloodle module instance.
");
return false;
}
// Check that it is the correct type
if ($this->sloodle_module_instance->type != SLOODLE_TYPE_CTRL) {
sloodle_debug("Loaded Sloodle module instance is not a controller.
");
return false;
}
// Load from the secondary table: Controller instance
if (!($this->sloodle_controller_instance = sloodle_get_record('sloodle_controller', 'sloodleid', $this->cm->instance))) {
sloodle_debug("Failed to load controller secondary data table.
");
return false;
}
return true;
}
/**
* Updates the currently loaded entry in the database.
* Note: the data *must* have been previously loaded using {@link load_from_db()}.
* This function cannot be used to create new entries.
* @return bool True if successful, or false otherwise
*/
function write()
{
// Make sure we have all the necessary data
if (empty($this->sloodle_module_instance) || empty($this->sloodle_controller_instance)) return false;
// Attempt to update the primary table
$this->sloodle_module_instance->timemodified = time();
if (!sloodle_update_record('sloodle', $this->sloodle_module_instance)) return false;
// Attempt to update the secondary table
if (!sloodle_update_record('sloodle_controller', $this->sloodle_controller_instance)) return false;
// Everything seems OK
return true;
}
// ACCESSORS //
/**
* Determines whether or not this controller is loaded.
* @return bool
*/
function is_loaded()
{
if (empty($this->cm) || empty($this->sloodle_module_instance) || empty($this->sloodle_controller_instance)) return false;
return true;
}
/**
* DEPRECATED - use get_course_module_id instead
* Gets the site-wide unique identifier for this module.
* @return mixed Identifier representing the course module identifier.
*/
function get_id()
{
return $this->get_course_module_id();
}
/**
* Gets the site-wide unique identifier for this module.
* @return mixed Identifier. Type is dependent on VLE. On Moodle, it is an integer course module identifier.
*/
function get_course_module_id()
{
return $this->cm->id;
}
/**
* Gets the identifier for controller.
* DEPRECATED to make it less ambiguous how we're identifying controllers, since we have at least 3 different IDs that can refer to the same thing.
* If you need this, use get_controller_instance_id instead.
* TODO (Ed): We shouldn't really need to use this at all or even have it in the database, as the record was already uniquely identified by "sloodleid".
* @return mixed Identifier. 'id' field of the 'sloodle_controller' table
*/
function get_controller_id()
{
return $this->get_controller_instance_id();
}
/**
* Gets the identifier for controller instance.
* NB Elsewhere when we have a variable called "sloodlecontrollerid", that refers to the course module ID, not the instance ID.
* @return mixed Identifier. 'id' field of the 'sloodle_controller' table
*/
function get_controller_instance_id()
{
return $this->sloodle_controller_instance->id;
}
/**
* Gets the name of this controller.
* @return string The name of this controller
*/
function get_name()
{
return $this->sloodle_module_instance->name;
}
/**
* Sets the name of this controller.
* @param string $name The new name for this controller - ignored if empty
* @return void
*/
function set_name($name)
{
if (!empty($name)) $this->sloodle_module_instance->name = $name;
}
/**
* Gets the intro description of this controller.
* @return string The intro description of this controller
*/
function get_intro()
{
return $this->sloodle_module_instance->intro;
}
/**
* Sets the intro description of this controller.
* @param string $intro The new intro for this controller - ignored if empty
* @return void
*/
function set_intro($intro)
{
if (!empty($intro)) $this->sloodle_module_instance->intro = $intro;
}
/**
* Gets the identifier of the course this controller belongs to.
* @return mixed Course identifier. Type depends on VLE. (In Moodle, it will be an integer).
*/
function get_course_id()
{
return (int)$this->sloodle_module_instance->course;
}
/**
* Gets the time at which this controller was created.
* @return int Timestamp
*/
function get_creation_time()
{
return $this->sloodle_module_instance->timecreated;
}
/**
* Gets the time at which this controller was last modified.
* @return int Timestamp
*/
function get_modification_time()
{
return $this->sloodle_module_instance->timemodified;
}
/**
* Determines whether or not this controller is available (i.e. not hidden).
* Note: this is separate from being enabled or disabled.
* @return bool True if the controller is available.
*/
function is_available()
{
//return (bool)($this->cm->visible);
return true;
}
/**
* Determines if this controller is enabled or not.
* @return bool True if the controller is enabled, or false otherwise.
*/
function is_enabled()
{
return (bool)($this->sloodle_controller_instance->enabled);
}
/**
* Enables this controller
* @return void
*/
function enable()
{
$this->sloodle_controller_instance->enabled = true;
}
/**
* Disables this controller
* @return void
*/
function disable()
{
$this->sloodle_controller_instance->enabled = false;
}
/**
* Gets the prim password of this controller.
* @return string The current prim password.
*/
function get_password()
{
return $this->sloodle_controller_instance->password;
}
/**
* Sets the prim password of this controller.
* Also checks for validity before storing.
* @param string $password The new prim password
* @return bool True if successfully stored, or false if the password is invalid
*/
function set_password($password)
{
// Check validity
if (!sloodle_validate_prim_password($password)) return false;
// Store it
$this->sloodle_controller_instance->password = $password;
return true;
}
/**
* Registers a new active object (or renew an existing authorisation) with this controller.
* @param string $uuid The UUID of the object to be registered
* @param string $name Name of the object to be registered
* @param SloodleUser $user The user who is authorising the object
* @param string $password The password for the object
* @param string $type Type identifier of the object to be registered
* @param int $timestamp The timestamp of the object's registration, or null to use the current time.
* @return int|bool The new authorisation ID if successful, or false if not
*/
function register_object($uuid, $name, $user, $password, $httpinpassword = '', $type = '', $timestamp = null)
{
SloodleDebugLogger::log('DEBUG', "registering object with name $name and type $type");
// Use the current timestamp if necessary
if ($timestamp == null) $timestamp = time();
// Extract the user ID, if available
$userid = 0;
if ($user->is_user_loaded()) $userid = $user->get_user_id();
// Check to see if an entry already exists for this object
$entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
if (!$entry) {
// Create a new entry
$entry = new stdClass();
$entry->controllerid = $this->cm->id;
$entry->uuid = $uuid;
$entry->name = $name;
$entry->userid = $userid;
$entry->password = $password;
$entry->httpinpassword = $httpinpassword;
$entry->type = $type;
$entry->timeupdated = $timestamp;
// Attempt to insert the entry
$entry->id = sloodle_insert_record('sloodle_active_object', $entry);
if (!$entry->id) return false;
} else {
// Update the existing entry
$entry->controllerid = $this->cm->id;
$entry->name = $name;
$entry->userid = $userid;
$entry->password = $password;
$entry->httpinpassword = $httpinpassword;
$entry->type = $type;
$entry->timeupdated = $timestamp;
// Attempt to update the database
if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
}
return $entry->id;
}
/**
* Configures a registered object based on the defaults for its layout entry id
* @param int $authid The ID of the object as registered by register_object in the active_objects table
* @param int $layout_entry_id The ID of the layout entry corresponding to this object
* NB The reverse of this process, where we create a layout entry config based on the active object,
* ...is in the SloodleLayoutEntry class.
* TODO: Would this be better there?
*/
function configure_object_from_layout_entry($authid, $layout_entry_id, $rezzeruuid = null) {
$ao = new SloodleActiveObject();
if (!$ao->load($authid)) {
return false;
}
$entry = sloodle_get_record('sloodle_layout_entry', 'id', $layout_entry_id);
if (!$entry) {
return false;
}
$ao->layoutentryid = $entry->id;
$ao->rotation = $entry->rotation;
$ao->position = $entry->position;
$ao->rezzeruuid = $rezzeruuid;
if (!$ao->save()) {
return false;
}
$configs = sloodle_get_records('sloodle_layout_entry_config','layout_entry',$layout_entry_id);
$ok = true;
if (count($configs) > 0) {
foreach($configs as $config) {
$config->id = null;
$config->object = $authid;
if (!sloodle_insert_record('sloodle_object_config',$config)) {
$ok = false;
}
}
}
/*
$lconfig = new stdClass();
$lconfig->id = null;
$lconfig->object = $authid;
$lconfig->name = 'sloodlelayoutentryid';
$lconfig->value = $layout_entry_id;
sloodle_insert_record('sloodle_object_config',$lconfig);
*/
return $ok;
}
function configure_object_from_parent($authid, $parent_object) {
// Fetch the UUID of the current object from the header
// ...then clone its config
// Check to see if an entry already exists for this object
$parententry = sloodle_get_record('sloodle_active_object', 'uuid', $parent_object);
/*
if (!$parententry) {
return false;
}
*/
$parentconfigs = sloodle_get_records('sloodle_object_config','object',$parententry->id);
$ok = true;
if (count($parentconfigs) > 0) {
$clonedconfig = new stdClass();
foreach($parentconfigs as $config) {
$clonedconfig->object = $authid;
$clonedconfig->name = $config->name;
$clonedconfig->value = $config->value;
if (!sloodle_insert_record('sloodle_object_config',$clonedconfig)) {
$ok = false;
}
}
}
return $ok;
}
/**
* Registers a new unauthorised object.
* (Can be called statically).
* Creates a new active object entry, not linked to any user or controller.
* @param string $uuid The UUID of the object to be registered
* @param string $name Name of the object to be registered
* @param string $password The password for the object
* @param string $type Type identifier of the object to be registered
* @param int $timestamp The timestamp of the object's registration, or null to use the current time.
* @return int|bool The integer ID of the active object entry, or false if not
*/
function register_unauth_object($uuid, $name, $password, $type = '', $timestamp = null, $httpinurl = null, $httpinpassword = null)
{
// Use the current timestamp if necessary
if ($timestamp == null) $timestamp = time();
// Check to see if an entry already exists for this object
$entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
if (!$entry) {
// Create a new entry
$entry = new stdClass();
$entry->controllerid = 0;
$entry->uuid = $uuid;
$entry->name = $name;
$entry->userid = 0;
$entry->password = $password;
$entry->type = $type;
$entry->httpinurl = $httpinurl;
$entry->httpinpassword = $httpinpassword;
$entry->timeupdated = $timestamp;
// Attempt to insert the entry
$entry->id = sloodle_insert_record('sloodle_active_object', $entry);
if (!$entry->id) return false;
} else {
// Update the existing entry
$entry->controllerid = 0;
$entry->name = $name;
$entry->password = $password;
$entry->type = $type;
$entry->userid = 0;
$entry->timeupdated = $timestamp;
$entry->httpinurl = $httpinurl;
$entry->httpinpassword = $httpinpassword;
// Attempt to update the database
if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
}
return $entry->id;
}
/**
* Updates the type of a given active object to the specified type.
* @param string $uuid The UUID of the object being updated
* @param string $type Name of the new type identifier
* @return bool True if successful, or false if not
*/
function update_object_type($uuid, $type)
{
// Attempt to find an entry for the object
$entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
if (!$entry) return false;
// Update the type and time
$entry->type = $type;
$entry->timeupdated = time();
if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
return true;
}
/**
* Authorises an otherwise unauthorised active object against the given user and the current controller.
* (NOTE: the object must previously have been registered using {@link register_object()}).
* Must not be called statically.
* @param string $uuid The UUID of the object being updated
* @param SloodleUser $user The user to authorise the object against
* @param string $type (Optional). Specifies the type to store for this object. Ignored if null.
* @return bool True if successful, or false if not
*/
function authorise_object($uuid, $user, $type = null)
{
// Attempt to find an unauthorised entry for the object
$entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
if (!$entry) return false;
// Update the controller, user and time
$entry->controllerid = $this->get_course_module_id();
$entry->userid = $user->get_user_id();
if (!empty($type)) $entry->type = $type;
$entry->timeupdated = time();
if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
return true;
}
/**
* Checks if the specified object is authorised for this controller with the given password.
* @param object SloodleActiveObject $active_object The active object representing the prim that is talking to us.
* @param string $password The password to check
* @return bool True if object is authorised, or false if not
*/
function check_authorisation($active_object, $password)
{
if (is_null($active_object)) {
return false;
}
if ($active_object->controllerid != $this->get_course_module_id()) {
return false;
}
// Make sure we have the type data
// Edmund Edgar, 2009-01-31:
// The type-checking is breaking the auto-configuration based on a profile.
// It should probably already have been filled in somewhere, so this is probably an auto-configuration bug.
// But we should probably be doing this check somewhere else, as it's not an authorization check.
// Maybe it needs its own error code?
//if (empty($entry->type)) return false;
// Verify the password
return ($password == $active_object->password);
}
/**
* Gets the ID of the user who authorised the specified object.
* @return mixed|bool Returns the user ID if successful, or FALSE if not
*/
function get_authorizing_user($uuid)
{
// Attempt to find an entry for the object
$entry = sloodle_get_record('sloodle_active_object', 'controllerid', $this->get_course_module_id(), 'uuid', $uuid);
if (!$entry) return false;
return (int)$entry->userid;
}
/**
* Removes an active object and all its related items.
* @param mixed $id If it is an integer, then it is treated as the active object ID. If a string, it is treated as the object UUID.
* @return void
*/
// TODO: This is now duplicated by delete() in the SloodleActiveObject class.
// That seems like a better place to do this.
// We should either change whatever's calling this to use SloodleActiveObject instead
// ...or change this function to call SloodleActiveObject->delete().
function remove_object($id)
{
// Check what type the ID is
if (is_string($id)) $entry = sloodle_get_record('sloodle_active_object', 'uuid', $id);
else $entry = sloodle_get_record('sloodle_active_object', 'id', (int)$id);
if (!$entry) return;
// Delete all config entries and the object record itself
sloodle_delete_records('sloodle_object_config', 'object', $entry->id);
sloodle_delete_records('sloodle_active_object', 'id', $entry->id);
}
/**
* Gets data about an active object.
* @param mixed $id If an integer, it is the ID of an active object. If it is a string it is the object's UUID.
* @return SloodleActiveObject|bool Returns false on failure
* TODO: Refactor this if anything's using it - it's got nothing to do with the controller, and shouldn't be in here.
*/
function get_object($id)
{
// Check what type the ID is
if (is_string($id)) $entry = sloodle_get_record('sloodle_active_object', 'uuid', $id);
else $entry = sloodle_get_record('sloodle_active_object', 'id', (int)$id);
if (!$entry) return false;
// Create a dummy SloodleSession
$sloodle = new SloodleSession(false);
// Construct a structure
$obj = new SloodleActiveObject();
$obj->uuid = $entry->uuid;
$obj->name = $entry->name;
$obj->password = $entry->password;
$obj->type = $entry->type;
$obj->course = $sloodle->course;
$obj->course->load_by_controller($entry->controllerid);
$obj->user = $sloodle->user;
if ($entry->id > 0) {
$obj->user->load_user($entry->userid);
$obj->user->load_linked_avatar();
}
return $obj;
}
/**
* Returns an array of active object records, or false if something went wrong.
* (Cannot be called statically... object must be authorised for this controller).
* @param string $rezzeruuid: The uuid of the rezzer which rezzed the object, or null for all active objects, regardless of rezzer.
* @param int $layoutentryid: The layout entry id object, or null for all active objects, regardless of layout entry.
* @return array() active object objects, or false on failure
*/
function get_active_objects( $rezzeruuid = null, $layoutentryid = null ) {
$id = $this->get_course_module_id();
$aos = array();
if (!$id) {
return false;
}
$recs = array();
$params = array();
$select = 'controllerid = ?';
$params[] =intval($id);
if ($rezzeruuid) {
$select .= " and rezzeruuid = ?";
$params[] = $rezzeruuid;
}
if ($layoutentryid) {
$select .= " and layoutentryid = ?";
$params[] = intval($layoutentryid);
}
$recs = sloodle_get_records_select_params('sloodle_active_object', $select, $params);
if (!$recs) {
return false;
}
foreach($recs as $rec) {
if ($rec && $rec->id) {
$ao = new SloodleActiveObject();
$ao->loadFromRecord($rec);
$aos[] = $ao;
}
}
return $aos;
}
/*
* Return the ID of the currently active round for the controller.
* @return int $roundid or null if there isn't one
*/
function get_active_roundid($force_create = false) {
$open_rounds = sloodle_get_records( 'sloodle_award_rounds', 'controllerid', $this->get_course_module_id() );
foreach($open_rounds as $or ) {
if ($or->timeended > 0) { // closed
continue;
}
return $or->id;
}
if ($force_create) {
$created_round = $this->make_new_round();
return $created_round->id;
}
return 0;
}
function clone_round_participation($fromroundid, $toroundid) {
global $CFG;
$prefix = $CFG->prefix;
$user_curr = array();
$scores = sloodle_get_records('sloodle_award_points', 'roundid', $fromroundid);
if ($scores) {
foreach($scores as $score) {
$userid = $score->userid;
$currencyid = $score->currencyid;
if (isset($user_curr[ $userid ][$currencyid] )) {
continue;
}
$score->amount = 0;
$score->id = null;
$score->description = null;
$score->roundid = $toroundid;
sloodle_insert_record( 'sloodle_award_points', $score );
$user_curr[ $userid ] = array();
$user_curr[ $userid ][$currencyid] = true;
}
}
return true;
}
function make_new_round( $clone_active_round_participation = false ) {
if (!$courseid = intval($this->get_course_id())) {
return false;
}
$previous_round_id = 0;
if ($clone_active_round_participation) {
$previous_round_id = $this->get_active_roundid();
}
$round = new stdClass();
$round->timestarted = time();
$round->timeended = 0;
$round->name = '';
$round->controllerid = $this->get_course_module_id();
$round->courseid = $courseid; // We specify this too so that you can delete the controller but keep the scores.
if (!$roundid = sloodle_insert_record('sloodle_award_rounds', $round)) {
return false;
}
if ($clone_active_round_participation) {
$this->clone_round_participation( $previous_round_id, $roundid );
}
$round->id = $roundid;
$this->close_rounds_except( $roundid );
return $round;
}
function close_rounds_except( $roundid ) {
$open_rounds = sloodle_get_records( 'sloodle_award_rounds', 'controllerid', $this->get_course_module_id() );
foreach($open_rounds as $or ) {
if ($or->id == $roundid) {
continue;
}
if ($or->timeended > 0) {
continue;
}
$or->timeended = time();
sloodle_update_record( 'sloodle_award_rounds', $or );
}
return true;
}
}