module_tracker.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. <?php
  2. /**
  3. * This file is part of SLOODLE Tracker.
  4. * Copyright (c) 2009 Sloodle
  5. *
  6. * SLOODLE Tracker is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * SLOODLE Tracker is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * If not, see <http://www.gnu.org/licenses/>
  18. *
  19. * @todo: add backup/restore methods
  20. *
  21. * Contributors:
  22. * Peter R. Bloomfield
  23. * Julio Lopez (SL: Julio Solo)
  24. * Michael Callaghan (SL: HarmonyHill Allen)
  25. * Kerri McCusker (SL: Kerri Macchi)
  26. * Edmund Edgar (SL: Edmund Earp)
  27. *
  28. * A project developed by the Serious Games and Virtual Worlds Group.
  29. * Intelligent Systems Research Centre.
  30. * University of Ulster, Magee
  31. */
  32. /** The Sloodle module base. */
  33. require_once(SLOODLE_LIBROOT.'/modules/module_base.php');
  34. /** General Sloodle functions. */
  35. require_once(SLOODLE_LIBROOT.'/general.php');
  36. /**
  37. * The Sloodle SLOODLE Tracker module class.
  38. * @package sloodle
  39. */
  40. class SloodleModuleTracker extends SloodleModule
  41. {
  42. // DATA //
  43. /**
  44. * Internal for Moodle only - course module instance.
  45. * Corresponds to one record from the Moodle 'course_modules' table.
  46. * @var object
  47. * @access private
  48. */
  49. var $cm = null;
  50. /**
  51. * Internal only - Sloodle module instance database object.
  52. * Corresponds to one record from the Moodle 'mdl_sloodle' table.
  53. * @var object
  54. * @access private
  55. */
  56. var $sloodle_instance = null;
  57. /**
  58. * Secondary data about this instance.
  59. * Corresponds to one record from the Moodle 'mdl_sloodle_tracker' table.
  60. * @var object
  61. * @access private
  62. */
  63. var $tracker = null;
  64. // FUNCTIONS //
  65. /**
  66. * Constructor
  67. */
  68. function SloodleModuleTracker(&$_session = null)
  69. {
  70. $constructor = get_parent_class($this);
  71. parent::$constructor($_session);
  72. }
  73. /**
  74. * Loads data from the database.
  75. * Note: even if the function fails, it may still have overwritten some or all existing data in the object.
  76. * @param mixed $id The site-wide unique identifier for all modules. Type depends on VLE. On Moodle, it is an integer course module identifier ('id' field of 'course_modules' table)
  77. * @return bool True if successful, or false otherwise
  78. */
  79. function load($id)
  80. {
  81. // Make sure the ID is valid
  82. $id = (int)$id;
  83. if ($id <= 0) return false;
  84. // Fetch the course module data
  85. if (!($this->cm = get_coursemodule_from_id('sloodle', $id))) {
  86. sloodle_debug("Failed to load course module instance #$id.<br/>");
  87. return false;
  88. }
  89. // Make sure the module is visible
  90. if ($this->cm->visible == 0) {
  91. sloodle_debug("Error: course module instance #$id not visible.<br/>");
  92. return false;
  93. }
  94. // Load from the primary table: sloodle instance
  95. if (!($this->sloodle_instance = sloodle_get_record('sloodle', 'id', $this->cm->instance))) {
  96. sloodle_debug("Failed to load Sloodle module with instance ID #{$this->cm->instance}.<br/>");
  97. return false;
  98. }
  99. // Load from the secondary table: sloodle_tracker
  100. if (!($this->tracker = sloodle_get_record('sloodle_tracker', 'sloodleid', $this->cm->instance))) {
  101. sloodle_debug("Failed to load Tracker record with sloodleid #{$this->cm->instance}.<br/>");
  102. return false;
  103. }
  104. return true;
  105. }
  106. /**
  107. * Gets a list of all tools for this SLOODLE Tracker.
  108. * @return an array of strings, each string containing the name of one tool.
  109. */
  110. function get_objects()
  111. {
  112. // Get all tool record entries for this SLOODLE Tracker, sorted by name
  113. $recs = sloodle_get_records('sloodle_activity_tool', 'trackerid', $this->sloodle_instance->id, 'name');
  114. if (!$recs) return array();
  115. // Convert it to an array of strings
  116. $entries = array();
  117. foreach ($recs as $r) {
  118. $entries[] = stripslashes($recs->name);
  119. }
  120. return $entries;
  121. }
  122. /**
  123. * Sets the list of tools/tasks for this SLOODLE Tracker.
  124. * @return bool True if successful, or false if not
  125. */
  126. function record_object($uuid,$name,$type,$trackerid,$description,$taskname)
  127. {
  128. $timestamp = time();
  129. $result = true;
  130. $entry = sloodle_get_record('sloodle_activity_tool', 'uuid', $uuid);
  131. // The tool doesn't exist in the database
  132. if (!$entry) {
  133. // Construct the new record
  134. $entry = new stdClass();
  135. $entry->uuid = $uuid;
  136. $entry->name = $name;
  137. $entry->type = $type;
  138. $entry->trackerid = $trackerid;
  139. $entry->description = $description;
  140. $entry->taskname = $taskname;
  141. $entry->timeupdated = $timestamp;
  142. // Insert it
  143. $entry->id = sloodle_insert_record('sloodle_activity_tool', $entry);
  144. if (!$entry->id) $result = false;
  145. }
  146. // The tool already exists, it has to be updated
  147. else{
  148. $entry->name = $name;
  149. $entry->type = $type;
  150. $entry->trackerid = $trackerid;
  151. $entry->description = $description;
  152. $entry->taskname = $taskname;
  153. $entry->timeupdated = $timestamp;
  154. // Update it
  155. if (!sloodle_update_record('sloodle_activity_tool', $entry)) $result = false;
  156. }
  157. return $result;
  158. }
  159. /**
  160. * Sets the actions completed by an avatar in Second Life. An avatar interacts with an object in SL, and this action is recorded
  161. * @param $trackerid: The site-wide unique identifier for this Second Life Tracker module
  162. * @param $objuudi: The SL unique identifier for the object/tool (task)
  163. * @param $avuuid: The SL unique identifier for the avatar
  164. * @return bool True if successful, or false if not
  165. */
  166. function record_action($trackerid,$objuuid,$avuuid)
  167. {
  168. $timestamp = time();
  169. $result = true;
  170. // Has the avatar already interact with this object?
  171. $entry = sloodle_get_record('sloodle_activity_tracker', 'objuuid', $objuuid, 'avuuid',$avuuid);
  172. // If not, the new action is recorded
  173. if (!$entry) {
  174. // Construct the new record
  175. $entry = new stdClass();
  176. $entry->objuuid = $objuuid;
  177. $entry->avuuid = $avuuid;
  178. $entry->trackerid = $trackerid;
  179. $entry->timeupdated = $timestamp;
  180. // Insert it
  181. $entry->id = sloodle_insert_record('sloodle_activity_tracker', $entry);
  182. if (!$entry->id) $result = false;
  183. }
  184. // If yes, "old" interaction is updated
  185. else{
  186. $entry->trackerid = $trackerid;
  187. $entry->timeupdated = $timestamp;
  188. if (!sloodle_update_record('sloodle_activity_tracker', $entry)) $result = false;
  189. }
  190. return $result;
  191. }
  192. // BACKUP AND RESTORE //
  193. /**
  194. * Backs-up secondary data regarding this module.
  195. * That includes everything except the main 'sloodle' database table for this instance.
  196. * @param $bf Handle to the file which backup data should be written to.
  197. * @param bool $includeuserdata Indicates whether or not to backup 'user' data, i.e. any content. Most SLOODLE tools don't have any user data.
  198. * @return bool True if successful, or false on failure.
  199. */
  200. function backup($bf, $includeuserdata)
  201. {
  202. /* //EXAMPLE CODE FROM PRESENTER
  203. // Data about the Presenter itself
  204. fwrite($bf, full_tag('ID', 5, false, $this->presenter->id));
  205. fwrite($bf, full_tag('FRAMEWIDTH', 5, false, $this->presenter->framewidth));
  206. fwrite($bf, full_tag('FRAMEHEIGHT', 5, false, $this->presenter->frameheight));
  207. // Attempt to fetch all the slides in the presentation
  208. $slides = $this->get_slides();
  209. if (!$slides) return false;
  210. // Data about the slides in the presenter.
  211. // Currently this will only backup the raw URLs, and won't transfer any files.
  212. // In future, it should backup any files which are on the same server.
  213. fwrite($bf, start_tag('SLIDES', 5, true));
  214. foreach ($slides as $slide) {
  215. fwrite($bf, start_tag('SLIDE', 6, true));
  216. // Convert plugin class names back to simple slide types
  217. switch ($slide->type) {
  218. case 'SloodlePluginPresenterSlideImage': case 'PresenterSlideImage': $slide->type = 'image'; break;
  219. case 'SloodlePluginPresenterSlideVideo': case 'PresenterSlideVideo': $slide->type = 'video'; break;
  220. case 'SloodlePluginPresenterSlideWeb': case 'PresenterSlideWeb': $slide->type = 'web'; break;
  221. }
  222. fwrite($bf, full_tag('ID', 7, false, $slide->id));
  223. fwrite($bf, full_tag('NAME', 7, false, $slide->name));
  224. fwrite($bf, full_tag('SOURCE', 7, false, $slide->source));
  225. fwrite($bf, full_tag('TYPE', 7, false, $slide->type));
  226. fwrite($bf, full_tag('ORDERING', 7, false, $slide->ordering));
  227. fwrite($bf, end_tag('SLIDE', 6, true));
  228. }
  229. fwrite($bf, end_tag('SLIDES', 5, true));
  230. return true;*/
  231. return false;
  232. }
  233. /**
  234. * Restore this module's secondary data into the database.
  235. * This ignores any member data, so can be called statically.
  236. * @param int $sloodleid The ID of the primary SLOODLE entry this restore belongs to (i.e. the ID of the record in the "sloodle" table)
  237. * @param array $info An associative array representing the XML backup information for the secondary module data
  238. * @param bool $includeuserdata Indicates whether or not to restore user data
  239. * @return bool True if successful, or false on failure.
  240. */
  241. function restore($sloodleid, $info, $includeuserdata)
  242. {
  243. /* // EXAMPLE CODE FROM PRESENTER
  244. // Construct the database record for the Presenter itself
  245. $presenter = new object();
  246. $presenter->sloodleid = $sloodleid;
  247. $presenter->framewidth = $info['FRAMEWIDTH']['0']['#'];
  248. $presenter->frameheight = $info['FRAMEHEIGHT']['0']['#'];
  249. $presenter->id = sloodle_insert_record('sloodle_presenter', $presenter);
  250. // Go through each slide in the presenter backup
  251. $numslides = count($info['SLIDES']['0']['#']['SLIDE']);
  252. $curslide = null;
  253. for ($slidenum = 0; $slidenum < $numslides; $slidenum++) {
  254. // Get the current slide data
  255. $curslide = $info['SLIDES']['0']['#']['SLIDE'][$slidenum]['#'];
  256. // Construct a new Presenter slide database object
  257. $slide = new object();
  258. $slide->sloodleid = $sloodleid;
  259. $slide->name = $curslide['NAME']['0']['#'];
  260. $slide->source = $curslide['SOURCE']['0']['#'];
  261. $slide->type = $curslide['TYPE']['0']['#'];
  262. $slide->ordering = $curslide['ORDERING']['0']['#'];
  263. $slide->id = sloodle_insert_record('sloodle_presenter_entry', $slide);
  264. }
  265. return true;*/
  266. return false;
  267. }
  268. /**
  269. * Gets the name of the user data required by this type, or an empty string if none is required.
  270. * For example, a chatroom would use the name "Messages" for user data.
  271. * Note that this should respect current language settings in Moodle.
  272. * @return string Localised name of the user data.
  273. */
  274. function get_user_data_name()
  275. {
  276. return '';
  277. }
  278. /**
  279. * Gets the number of user data records to be backed-up.
  280. * @return int A count of the number of user data records which can be backed-up.
  281. */
  282. function get_user_data_count()
  283. {
  284. return 0;
  285. }
  286. // ACCESSORS //
  287. /**
  288. * Gets the name of this module instance.
  289. * @return string The name of this module
  290. */
  291. function get_name()
  292. {
  293. return $this->sloodle_instance->name;
  294. }
  295. /**
  296. * Gets the intro description of this module instance, if available.
  297. * @return string The intro description of this controller
  298. */
  299. function get_intro()
  300. {
  301. return $this->sloodle_instance->intro;
  302. }
  303. /**
  304. * Gets the identifier of the course this controller belongs to.
  305. * @return mixed Course identifier. Type depends on VLE. (In Moodle, it will be an integer).
  306. */
  307. function get_course_id()
  308. {
  309. return (int)$this->sloodle_instance->course;
  310. }
  311. /**
  312. * Gets the time at which this instance was created, or 0 if unknown.
  313. * @return int Timestamp
  314. */
  315. function get_creation_time()
  316. {
  317. return (int)$this->sloodle_instance->timecreated;
  318. }
  319. /**
  320. * Gets the time at which this instance was last modified, or 0 if unknown.
  321. * @return int Timestamp
  322. */
  323. function get_modification_time()
  324. {
  325. return (int)$this->sloodle_instance->timemodified;
  326. }
  327. /**
  328. * Gets the short type name of this instance.
  329. * @return string
  330. */
  331. function get_type()
  332. {
  333. return SLOODLE_TYPE_TRACKER;
  334. }
  335. /**
  336. * Gets the full type name of this instance, according to the current language pack, if available.
  337. * Note: should be overridden by sub-classes.
  338. * @return string Full type name if possible, or the short name otherwise.
  339. */
  340. function get_type_full()
  341. {
  342. return get_string('moduletype:'.SLOODLE_TYPE_TRACKER, 'sloodle');
  343. }
  344. /*
  345. Returns an array of error messages for requirements that haven't been satisfied.
  346. ...eg. If an object has been configured to require 3 gold coins, and the user doesn't have enough, it'll return a message saying you don't have enough gold coins.
  347. */
  348. function RequirementFailures( $relevant_configs, $controllerid, $multiplier, $userid, $useruuid, $objectuuid ) {
  349. global $CFG;
  350. if ( isset($relevant_configs['sloodletrackerrequire_taskcompleted']) ) {
  351. $required_task = $relevant_configs['sloodletrackerrequire_taskcompleted'];
  352. if (!$required_task){
  353. return false;
  354. }
  355. }
  356. if ( !SloodleModuleTracker::UserHasCompleted($useruuid, $controllerid, $task) ) {
  357. if (isset($relevant_configs['sloodletrackerrequire_tasknotcompletedmessage']) && $relevant_configs['sloodletrackerrequire_tasknotcompletedmessage'] != '') {
  358. return $relevant_configs['sloodletrackerrequire_tasknotcompletedmessage'];
  359. } else {
  360. return get_string('tracker:requiredtasknotcompleted', 'sloodle');
  361. }
  362. }
  363. return '';
  364. }
  365. /*
  366. An array of the names of config parameters that are understood by this module to mean it should do something.
  367. Will have the name of the specific interaction appended to it.
  368. eg. awards makes available an interaction config called "sloodleawardsdeposit_numpoints".
  369. The quiz would then have a config name=>value pair like sloodleawards_deposit_numpoints_answerquestion => 3
  370. Via the ActiveObject, the quiz will tell the awards module that answerquestion has happened to a particular user
  371. ...and the awards module will give them the points.
  372. */
  373. function ActionConfigNames() {
  374. /*
  375. return array(
  376. 'sloodletrackersatisfy_taskcompleted'
  377. );
  378. */
  379. }
  380. /*
  381. An array of the names of config parameters that are understood by this module to check something before doing whatever it would normally do.
  382. Will have the name of the specific interaction appended to it.
  383. */
  384. function RequirementConfigNames() {
  385. /*
  386. return array(
  387. 'sloodletrackerrequire_taskcompleted',
  388. 'sloodletrackerrequire_tasknotcompletedmessage'
  389. );
  390. */
  391. }
  392. /*
  393. Not yet implemented
  394. When we authorize an object, we should run this function for each module that has it allowing us to do whatever setup tasks the module defines.
  395. */
  396. function HandleObjectInitializationSteps( $relevant_configs, $active_object ) {
  397. $taskname = isset($relevant_configs['sloodletrackersatisfy_taskcompleted']) ? $relevant_configs['sloodletrackersatisfy_taskcompleted'] : '';
  398. $description = isset($relevant_configs['sloodletrackersatisfy_taskcompleteddescription']) ? $relevant_configs['sloodletrackersatisfy_taskcompleteddescription'] : '';
  399. if ( isset($relevant_configs['sloodletrackersatisfy_taskcompleted']) ) {
  400. }
  401. SloodleModuleTracker::record_object($active_object->uuid,$active_object->name,$active_object->type,$active_object->controllerid,$description,$taskname);
  402. }
  403. function ProcessActions( $relevant_configs, $controllerid, $multiplier, $userid, $useruuid, $objectuuid) {
  404. return true;
  405. global $CFG;
  406. $controller = new SloodleController();
  407. if (!$controller->load_by_course_module_id($controllerid)) {
  408. return false;
  409. }
  410. $time = time();
  411. if ( isset($relevant_configs['sloodletrackersatisfy_taskcompleted']) ) {
  412. }
  413. return true;
  414. }
  415. }
  416. ?>