controller.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. <?php
  2. // This file is part of the Sloodle project (www.sloodle.org)
  3. /**
  4. * This file defines the Sloodle Controller module sub-type.
  5. *
  6. * @package sloodle
  7. * @copyright Copyright (c) 2008 - 2011 various contributors
  8. * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
  9. *
  10. * @contributor Peter R. Bloomfield
  11. * @contributor Edmund Edgar
  12. */
  13. /** General Sloodle functionality. */
  14. require_once(SLOODLE_LIBROOT.'/general.php');
  15. /** The active object structure. */
  16. require_once(SLOODLE_LIBROOT.'/active_object.php');
  17. /**
  18. * The data structure of a controller is as follows:
  19. *
  20. * coursemodule
  21. * id
  22. * instance - refers to the ID in the sloodle table
  23. *
  24. * sloodle
  25. * id
  26. *
  27. * sloodle_controller
  28. * id - ID of this record, redundant as it's already uniquely identified by sloodleid?
  29. * sloodleid - refers to the ID in the sloodle table
  30. *
  31. */
  32. /**
  33. * Represents a Sloodle Controller, including data such as prim password.
  34. * @package sloodle
  35. */
  36. class SloodleController
  37. {
  38. // DATA //
  39. /**
  40. * Internal for Moodle only - course module instance.
  41. * Corresponds to one record from the Moodle 'course_modules' table.
  42. * @var object
  43. * @access private
  44. */
  45. var $cm = null;
  46. /**
  47. * Internal only - Sloodle module instance database object.
  48. * Corresponds to one record from the Moodle 'sloodle' table.
  49. * @var object
  50. * @access private
  51. */
  52. var $sloodle_module_instance = null;
  53. /**
  54. * Internal only - Sloodle Controller instance database object.
  55. * Corresponds to one record from the Moodle 'sloodle_controller' table.
  56. * @var object
  57. * @access private
  58. */
  59. var $sloodle_controller_instance = null;
  60. // FUNCTIONS //
  61. /**
  62. * Constructor
  63. */
  64. function SloodleController()
  65. {
  66. }
  67. /**
  68. * DEPRECATED in an attempt to make the use of various IDs around the controller less baffling. Use load_by_course_module_id instead.
  69. * Loads data from the database based on the course module id.
  70. * Note: even if the function fails, it may still have overwritten some or all existing data in the object.
  71. * @param mixed $id The site-wide unique identifier for all modules. Course module identifier ('id' field of 'course_modules' table)
  72. * @return bool True if successful, or false otherwise
  73. */
  74. function load($id)
  75. {
  76. return $this->load_by_course_module_id($id);
  77. }
  78. /**
  79. * Loads data from the database.
  80. * Note: even if the function fails, it may still have overwritten some or all existing data in the object.
  81. * @param mixed $id The site-wide unique identifier for all modules. Course module identifier ('id' field of 'course_modules' table)
  82. * @return bool True if successful, or false otherwise
  83. */
  84. function load_by_course_module_id($cmid) {
  85. // Make sure the ID is valid
  86. $cmid = (int)$cmid;
  87. if ($cmid <= 0) return false;
  88. // Fetch the course module data
  89. if (!($this->cm = get_coursemodule_from_id('sloodle', $cmid))) {
  90. sloodle_debug("Failed to load controler course module.<br>");
  91. return false;
  92. }
  93. // Load from the primary table: Sloodle instance
  94. if (!($this->sloodle_module_instance = sloodle_get_record('sloodle', 'id', $this->cm->instance))) {
  95. sloodle_debug("Failed to load controller Sloodle module instance.<br>");
  96. return false;
  97. }
  98. // Check that it is the correct type
  99. if ($this->sloodle_module_instance->type != SLOODLE_TYPE_CTRL) {
  100. sloodle_debug("Loaded Sloodle module instance is not a controller.<br>");
  101. return false;
  102. }
  103. // Load from the secondary table: Controller instance
  104. if (!($this->sloodle_controller_instance = sloodle_get_record('sloodle_controller', 'sloodleid', $this->cm->instance))) {
  105. sloodle_debug("Failed to load controller secondary data table.<br>");
  106. return false;
  107. }
  108. return true;
  109. }
  110. /**
  111. * Updates the currently loaded entry in the database.
  112. * Note: the data *must* have been previously loaded using {@link load_from_db()}.
  113. * This function cannot be used to create new entries.
  114. * @return bool True if successful, or false otherwise
  115. */
  116. function write()
  117. {
  118. // Make sure we have all the necessary data
  119. if (empty($this->sloodle_module_instance) || empty($this->sloodle_controller_instance)) return false;
  120. // Attempt to update the primary table
  121. $this->sloodle_module_instance->timemodified = time();
  122. if (!sloodle_update_record('sloodle', $this->sloodle_module_instance)) return false;
  123. // Attempt to update the secondary table
  124. if (!sloodle_update_record('sloodle_controller', $this->sloodle_controller_instance)) return false;
  125. // Everything seems OK
  126. return true;
  127. }
  128. // ACCESSORS //
  129. /**
  130. * Determines whether or not this controller is loaded.
  131. * @return bool
  132. */
  133. function is_loaded()
  134. {
  135. if (empty($this->cm) || empty($this->sloodle_module_instance) || empty($this->sloodle_controller_instance)) return false;
  136. return true;
  137. }
  138. /**
  139. * DEPRECATED - use get_course_module_id instead
  140. * Gets the site-wide unique identifier for this module.
  141. * @return mixed Identifier representing the course module identifier.
  142. */
  143. function get_id()
  144. {
  145. return $this->get_course_module_id();
  146. }
  147. /**
  148. * Gets the site-wide unique identifier for this module.
  149. * @return mixed Identifier. Type is dependent on VLE. On Moodle, it is an integer course module identifier.
  150. */
  151. function get_course_module_id()
  152. {
  153. return $this->cm->id;
  154. }
  155. /**
  156. * Gets the identifier for controller.
  157. * 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.
  158. * If you need this, use get_controller_instance_id instead.
  159. * 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".
  160. * @return mixed Identifier. 'id' field of the 'sloodle_controller' table
  161. */
  162. function get_controller_id()
  163. {
  164. return $this->get_controller_instance_id();
  165. }
  166. /**
  167. * Gets the identifier for controller instance.
  168. * NB Elsewhere when we have a variable called "sloodlecontrollerid", that refers to the course module ID, not the instance ID.
  169. * @return mixed Identifier. 'id' field of the 'sloodle_controller' table
  170. */
  171. function get_controller_instance_id()
  172. {
  173. return $this->sloodle_controller_instance->id;
  174. }
  175. /**
  176. * Gets the name of this controller.
  177. * @return string The name of this controller
  178. */
  179. function get_name()
  180. {
  181. return $this->sloodle_module_instance->name;
  182. }
  183. /**
  184. * Sets the name of this controller.
  185. * @param string $name The new name for this controller - ignored if empty
  186. * @return void
  187. */
  188. function set_name($name)
  189. {
  190. if (!empty($name)) $this->sloodle_module_instance->name = $name;
  191. }
  192. /**
  193. * Gets the intro description of this controller.
  194. * @return string The intro description of this controller
  195. */
  196. function get_intro()
  197. {
  198. return $this->sloodle_module_instance->intro;
  199. }
  200. /**
  201. * Sets the intro description of this controller.
  202. * @param string $intro The new intro for this controller - ignored if empty
  203. * @return void
  204. */
  205. function set_intro($intro)
  206. {
  207. if (!empty($intro)) $this->sloodle_module_instance->intro = $intro;
  208. }
  209. /**
  210. * Gets the identifier of the course this controller belongs to.
  211. * @return mixed Course identifier. Type depends on VLE. (In Moodle, it will be an integer).
  212. */
  213. function get_course_id()
  214. {
  215. return (int)$this->sloodle_module_instance->course;
  216. }
  217. /**
  218. * Gets the time at which this controller was created.
  219. * @return int Timestamp
  220. */
  221. function get_creation_time()
  222. {
  223. return $this->sloodle_module_instance->timecreated;
  224. }
  225. /**
  226. * Gets the time at which this controller was last modified.
  227. * @return int Timestamp
  228. */
  229. function get_modification_time()
  230. {
  231. return $this->sloodle_module_instance->timemodified;
  232. }
  233. /**
  234. * Determines whether or not this controller is available (i.e. not hidden).
  235. * Note: this is separate from being enabled or disabled.
  236. * @return bool True if the controller is available.
  237. */
  238. function is_available()
  239. {
  240. //return (bool)($this->cm->visible);
  241. return true;
  242. }
  243. /**
  244. * Determines if this controller is enabled or not.
  245. * @return bool True if the controller is enabled, or false otherwise.
  246. */
  247. function is_enabled()
  248. {
  249. return (bool)($this->sloodle_controller_instance->enabled);
  250. }
  251. /**
  252. * Enables this controller
  253. * @return void
  254. */
  255. function enable()
  256. {
  257. $this->sloodle_controller_instance->enabled = true;
  258. }
  259. /**
  260. * Disables this controller
  261. * @return void
  262. */
  263. function disable()
  264. {
  265. $this->sloodle_controller_instance->enabled = false;
  266. }
  267. /**
  268. * Gets the prim password of this controller.
  269. * @return string The current prim password.
  270. */
  271. function get_password()
  272. {
  273. return $this->sloodle_controller_instance->password;
  274. }
  275. /**
  276. * Sets the prim password of this controller.
  277. * Also checks for validity before storing.
  278. * @param string $password The new prim password
  279. * @return bool True if successfully stored, or false if the password is invalid
  280. */
  281. function set_password($password)
  282. {
  283. // Check validity
  284. if (!sloodle_validate_prim_password($password)) return false;
  285. // Store it
  286. $this->sloodle_controller_instance->password = $password;
  287. return true;
  288. }
  289. /**
  290. * Registers a new active object (or renew an existing authorisation) with this controller.
  291. * @param string $uuid The UUID of the object to be registered
  292. * @param string $name Name of the object to be registered
  293. * @param SloodleUser $user The user who is authorising the object
  294. * @param string $password The password for the object
  295. * @param string $type Type identifier of the object to be registered
  296. * @param int $timestamp The timestamp of the object's registration, or null to use the current time.
  297. * @return int|bool The new authorisation ID if successful, or false if not
  298. */
  299. function register_object($uuid, $name, $user, $password, $httpinpassword = '', $type = '', $timestamp = null)
  300. {
  301. SloodleDebugLogger::log('DEBUG', "registering object with name $name and type $type");
  302. // Use the current timestamp if necessary
  303. if ($timestamp == null) $timestamp = time();
  304. // Extract the user ID, if available
  305. $userid = 0;
  306. if ($user->is_user_loaded()) $userid = $user->get_user_id();
  307. // Check to see if an entry already exists for this object
  308. $entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
  309. if (!$entry) {
  310. // Create a new entry
  311. $entry = new stdClass();
  312. $entry->controllerid = $this->cm->id;
  313. $entry->uuid = $uuid;
  314. $entry->name = $name;
  315. $entry->userid = $userid;
  316. $entry->password = $password;
  317. $entry->httpinpassword = $httpinpassword;
  318. $entry->type = $type;
  319. $entry->timeupdated = $timestamp;
  320. // Attempt to insert the entry
  321. $entry->id = sloodle_insert_record('sloodle_active_object', $entry);
  322. if (!$entry->id) return false;
  323. } else {
  324. // Update the existing entry
  325. $entry->controllerid = $this->cm->id;
  326. $entry->name = $name;
  327. $entry->userid = $userid;
  328. $entry->password = $password;
  329. $entry->httpinpassword = $httpinpassword;
  330. $entry->type = $type;
  331. $entry->timeupdated = $timestamp;
  332. // Attempt to update the database
  333. if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
  334. }
  335. return $entry->id;
  336. }
  337. /**
  338. * Configures a registered object based on the defaults for its layout entry id
  339. * @param int $authid The ID of the object as registered by register_object in the active_objects table
  340. * @param int $layout_entry_id The ID of the layout entry corresponding to this object
  341. * NB The reverse of this process, where we create a layout entry config based on the active object,
  342. * ...is in the SloodleLayoutEntry class.
  343. * TODO: Would this be better there?
  344. */
  345. function configure_object_from_layout_entry($authid, $layout_entry_id, $rezzeruuid = null) {
  346. $ao = new SloodleActiveObject();
  347. if (!$ao->load($authid)) {
  348. return false;
  349. }
  350. $entry = sloodle_get_record('sloodle_layout_entry', 'id', $layout_entry_id);
  351. if (!$entry) {
  352. return false;
  353. }
  354. $ao->layoutentryid = $entry->id;
  355. $ao->rotation = $entry->rotation;
  356. $ao->position = $entry->position;
  357. $ao->rezzeruuid = $rezzeruuid;
  358. if (!$ao->save()) {
  359. return false;
  360. }
  361. $configs = sloodle_get_records('sloodle_layout_entry_config','layout_entry',$layout_entry_id);
  362. $ok = true;
  363. if (count($configs) > 0) {
  364. foreach($configs as $config) {
  365. $config->id = null;
  366. $config->object = $authid;
  367. if (!sloodle_insert_record('sloodle_object_config',$config)) {
  368. $ok = false;
  369. }
  370. }
  371. }
  372. /*
  373. $lconfig = new stdClass();
  374. $lconfig->id = null;
  375. $lconfig->object = $authid;
  376. $lconfig->name = 'sloodlelayoutentryid';
  377. $lconfig->value = $layout_entry_id;
  378. sloodle_insert_record('sloodle_object_config',$lconfig);
  379. */
  380. return $ok;
  381. }
  382. function configure_object_from_parent($authid, $parent_object) {
  383. // Fetch the UUID of the current object from the header
  384. // ...then clone its config
  385. // Check to see if an entry already exists for this object
  386. $parententry = sloodle_get_record('sloodle_active_object', 'uuid', $parent_object);
  387. /*
  388. if (!$parententry) {
  389. return false;
  390. }
  391. */
  392. $parentconfigs = sloodle_get_records('sloodle_object_config','object',$parententry->id);
  393. $ok = true;
  394. if (count($parentconfigs) > 0) {
  395. $clonedconfig = new stdClass();
  396. foreach($parentconfigs as $config) {
  397. $clonedconfig->object = $authid;
  398. $clonedconfig->name = $config->name;
  399. $clonedconfig->value = $config->value;
  400. if (!sloodle_insert_record('sloodle_object_config',$clonedconfig)) {
  401. $ok = false;
  402. }
  403. }
  404. }
  405. return $ok;
  406. }
  407. /**
  408. * Registers a new unauthorised object.
  409. * (Can be called statically).
  410. * Creates a new active object entry, not linked to any user or controller.
  411. * @param string $uuid The UUID of the object to be registered
  412. * @param string $name Name of the object to be registered
  413. * @param string $password The password for the object
  414. * @param string $type Type identifier of the object to be registered
  415. * @param int $timestamp The timestamp of the object's registration, or null to use the current time.
  416. * @return int|bool The integer ID of the active object entry, or false if not
  417. */
  418. function register_unauth_object($uuid, $name, $password, $type = '', $timestamp = null, $httpinurl = null, $httpinpassword = null)
  419. {
  420. // Use the current timestamp if necessary
  421. if ($timestamp == null) $timestamp = time();
  422. // Check to see if an entry already exists for this object
  423. $entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
  424. if (!$entry) {
  425. // Create a new entry
  426. $entry = new stdClass();
  427. $entry->controllerid = 0;
  428. $entry->uuid = $uuid;
  429. $entry->name = $name;
  430. $entry->userid = 0;
  431. $entry->password = $password;
  432. $entry->type = $type;
  433. $entry->httpinurl = $httpinurl;
  434. $entry->httpinpassword = $httpinpassword;
  435. $entry->timeupdated = $timestamp;
  436. // Attempt to insert the entry
  437. $entry->id = sloodle_insert_record('sloodle_active_object', $entry);
  438. if (!$entry->id) return false;
  439. } else {
  440. // Update the existing entry
  441. $entry->controllerid = 0;
  442. $entry->name = $name;
  443. $entry->password = $password;
  444. $entry->type = $type;
  445. $entry->userid = 0;
  446. $entry->timeupdated = $timestamp;
  447. $entry->httpinurl = $httpinurl;
  448. $entry->httpinpassword = $httpinpassword;
  449. // Attempt to update the database
  450. if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
  451. }
  452. return $entry->id;
  453. }
  454. /**
  455. * Updates the type of a given active object to the specified type.
  456. * @param string $uuid The UUID of the object being updated
  457. * @param string $type Name of the new type identifier
  458. * @return bool True if successful, or false if not
  459. */
  460. function update_object_type($uuid, $type)
  461. {
  462. // Attempt to find an entry for the object
  463. $entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
  464. if (!$entry) return false;
  465. // Update the type and time
  466. $entry->type = $type;
  467. $entry->timeupdated = time();
  468. if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
  469. return true;
  470. }
  471. /**
  472. * Authorises an otherwise unauthorised active object against the given user and the current controller.
  473. * (NOTE: the object must previously have been registered using {@link register_object()}).
  474. * <b>Must not be called statically.</b>
  475. * @param string $uuid The UUID of the object being updated
  476. * @param SloodleUser $user The user to authorise the object against
  477. * @param string $type (Optional). Specifies the type to store for this object. Ignored if null.
  478. * @return bool True if successful, or false if not
  479. */
  480. function authorise_object($uuid, $user, $type = null)
  481. {
  482. // Attempt to find an unauthorised entry for the object
  483. $entry = sloodle_get_record('sloodle_active_object', 'uuid', $uuid);
  484. if (!$entry) return false;
  485. // Update the controller, user and time
  486. $entry->controllerid = $this->get_course_module_id();
  487. $entry->userid = $user->get_user_id();
  488. if (!empty($type)) $entry->type = $type;
  489. $entry->timeupdated = time();
  490. if (!sloodle_update_record('sloodle_active_object', $entry)) return false;
  491. return true;
  492. }
  493. /**
  494. * Checks if the specified object is authorised for this controller with the given password.
  495. * @param object SloodleActiveObject $active_object The active object representing the prim that is talking to us.
  496. * @param string $password The password to check
  497. * @return bool True if object is authorised, or false if not
  498. */
  499. function check_authorisation($active_object, $password)
  500. {
  501. if (is_null($active_object)) {
  502. return false;
  503. }
  504. if ($active_object->controllerid != $this->get_course_module_id()) {
  505. return false;
  506. }
  507. // Make sure we have the type data
  508. // Edmund Edgar, 2009-01-31:
  509. // The type-checking is breaking the auto-configuration based on a profile.
  510. // It should probably already have been filled in somewhere, so this is probably an auto-configuration bug.
  511. // But we should probably be doing this check somewhere else, as it's not an authorization check.
  512. // Maybe it needs its own error code?
  513. //if (empty($entry->type)) return false;
  514. // Verify the password
  515. return ($password == $active_object->password);
  516. }
  517. /**
  518. * Gets the ID of the user who authorised the specified object.
  519. * @return mixed|bool Returns the user ID if successful, or FALSE if not
  520. */
  521. function get_authorizing_user($uuid)
  522. {
  523. // Attempt to find an entry for the object
  524. $entry = sloodle_get_record('sloodle_active_object', 'controllerid', $this->get_course_module_id(), 'uuid', $uuid);
  525. if (!$entry) return false;
  526. return (int)$entry->userid;
  527. }
  528. /**
  529. * Removes an active object and all its related items.
  530. * @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.
  531. * @return void
  532. */
  533. // TODO: This is now duplicated by delete() in the SloodleActiveObject class.
  534. // That seems like a better place to do this.
  535. // We should either change whatever's calling this to use SloodleActiveObject instead
  536. // ...or change this function to call SloodleActiveObject->delete().
  537. function remove_object($id)
  538. {
  539. // Check what type the ID is
  540. if (is_string($id)) $entry = sloodle_get_record('sloodle_active_object', 'uuid', $id);
  541. else $entry = sloodle_get_record('sloodle_active_object', 'id', (int)$id);
  542. if (!$entry) return;
  543. // Delete all config entries and the object record itself
  544. sloodle_delete_records('sloodle_object_config', 'object', $entry->id);
  545. sloodle_delete_records('sloodle_active_object', 'id', $entry->id);
  546. }
  547. /**
  548. * Gets data about an active object.
  549. * @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.
  550. * @return SloodleActiveObject|bool Returns false on failure
  551. * TODO: Refactor this if anything's using it - it's got nothing to do with the controller, and shouldn't be in here.
  552. */
  553. function get_object($id)
  554. {
  555. // Check what type the ID is
  556. if (is_string($id)) $entry = sloodle_get_record('sloodle_active_object', 'uuid', $id);
  557. else $entry = sloodle_get_record('sloodle_active_object', 'id', (int)$id);
  558. if (!$entry) return false;
  559. // Create a dummy SloodleSession
  560. $sloodle = new SloodleSession(false);
  561. // Construct a structure
  562. $obj = new SloodleActiveObject();
  563. $obj->uuid = $entry->uuid;
  564. $obj->name = $entry->name;
  565. $obj->password = $entry->password;
  566. $obj->type = $entry->type;
  567. $obj->course = $sloodle->course;
  568. $obj->course->load_by_controller($entry->controllerid);
  569. $obj->user = $sloodle->user;
  570. if ($entry->id > 0) {
  571. $obj->user->load_user($entry->userid);
  572. $obj->user->load_linked_avatar();
  573. }
  574. return $obj;
  575. }
  576. /**
  577. * Returns an array of active object records, or false if something went wrong.
  578. * (Cannot be called statically... object must be authorised for this controller).
  579. * @param string $rezzeruuid: The uuid of the rezzer which rezzed the object, or null for all active objects, regardless of rezzer.
  580. * @param int $layoutentryid: The layout entry id object, or null for all active objects, regardless of layout entry.
  581. * @return array() active object objects, or false on failure
  582. */
  583. function get_active_objects( $rezzeruuid = null, $layoutentryid = null ) {
  584. $id = $this->get_course_module_id();
  585. $aos = array();
  586. if (!$id) {
  587. return false;
  588. }
  589. $recs = array();
  590. $params = array();
  591. $select = 'controllerid = ?';
  592. $params[] =intval($id);
  593. if ($rezzeruuid) {
  594. $select .= " and rezzeruuid = ?";
  595. $params[] = $rezzeruuid;
  596. }
  597. if ($layoutentryid) {
  598. $select .= " and layoutentryid = ?";
  599. $params[] = intval($layoutentryid);
  600. }
  601. $recs = sloodle_get_records_select_params('sloodle_active_object', $select, $params);
  602. if (!$recs) {
  603. return false;
  604. }
  605. foreach($recs as $rec) {
  606. if ($rec && $rec->id) {
  607. $ao = new SloodleActiveObject();
  608. $ao->loadFromRecord($rec);
  609. $aos[] = $ao;
  610. }
  611. }
  612. return $aos;
  613. }
  614. /*
  615. * Return the ID of the currently active round for the controller.
  616. * @return int $roundid or null if there isn't one
  617. */
  618. function get_active_roundid($force_create = false) {
  619. $open_rounds = sloodle_get_records( 'sloodle_award_rounds', 'controllerid', $this->get_course_module_id() );
  620. foreach($open_rounds as $or ) {
  621. if ($or->timeended > 0) { // closed
  622. continue;
  623. }
  624. return $or->id;
  625. }
  626. if ($force_create) {
  627. $created_round = $this->make_new_round();
  628. return $created_round->id;
  629. }
  630. return 0;
  631. }
  632. function clone_round_participation($fromroundid, $toroundid) {
  633. global $CFG;
  634. $prefix = $CFG->prefix;
  635. $user_curr = array();
  636. $scores = sloodle_get_records('sloodle_award_points', 'roundid', $fromroundid);
  637. if ($scores) {
  638. foreach($scores as $score) {
  639. $userid = $score->userid;
  640. $currencyid = $score->currencyid;
  641. if (isset($user_curr[ $userid ][$currencyid] )) {
  642. continue;
  643. }
  644. $score->amount = 0;
  645. $score->id = null;
  646. $score->description = null;
  647. $score->roundid = $toroundid;
  648. sloodle_insert_record( 'sloodle_award_points', $score );
  649. $user_curr[ $userid ] = array();
  650. $user_curr[ $userid ][$currencyid] = true;
  651. }
  652. }
  653. return true;
  654. }
  655. function make_new_round( $clone_active_round_participation = false ) {
  656. if (!$courseid = intval($this->get_course_id())) {
  657. return false;
  658. }
  659. $previous_round_id = 0;
  660. if ($clone_active_round_participation) {
  661. $previous_round_id = $this->get_active_roundid();
  662. }
  663. $round = new stdClass();
  664. $round->timestarted = time();
  665. $round->timeended = 0;
  666. $round->name = '';
  667. $round->controllerid = $this->get_course_module_id();
  668. $round->courseid = $courseid; // We specify this too so that you can delete the controller but keep the scores.
  669. if (!$roundid = sloodle_insert_record('sloodle_award_rounds', $round)) {
  670. return false;
  671. }
  672. if ($clone_active_round_participation) {
  673. $this->clone_round_participation( $previous_round_id, $roundid );
  674. }
  675. $round->id = $roundid;
  676. $this->close_rounds_except( $roundid );
  677. return $round;
  678. }
  679. function close_rounds_except( $roundid ) {
  680. $open_rounds = sloodle_get_records( 'sloodle_award_rounds', 'controllerid', $this->get_course_module_id() );
  681. foreach($open_rounds as $or ) {
  682. if ($or->id == $roundid) {
  683. continue;
  684. }
  685. if ($or->timeended > 0) {
  686. continue;
  687. }
  688. $or->timeended = time();
  689. sloodle_update_record( 'sloodle_award_rounds', $or );
  690. }
  691. return true;
  692. }
  693. }