module_chat.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <?php
  2. // This file is part of the Sloodle project (www.sloodle.org)
  3. /**
  4. * This file defines a chat module for Sloodle.
  5. *
  6. * @package sloodle
  7. * @copyright Copyright (c) 2008 Sloodle (various contributors)
  8. * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
  9. *
  10. * @contributor Peter R. Bloomfield
  11. */
  12. /** The Sloodle module base. */
  13. require_once(SLOODLE_LIBROOT.'/modules/module_base.php');
  14. /** General Sloodle functions. */
  15. require_once(SLOODLE_LIBROOT.'/general.php');
  16. /**
  17. * The Sloodle chat module class.
  18. * @package sloodle
  19. */
  20. class SloodleModuleChat extends SloodleModule
  21. {
  22. // DATA //
  23. /**
  24. * Internal for Moodle only - course module instance.
  25. * Corresponds to one record from the Moodle 'course_modules' table.
  26. * @var object
  27. * @access private
  28. */
  29. var $cm = null;
  30. /**
  31. * Internal only - Moodle chat module instance database object.
  32. * Corresponds to one record from the Moodle 'chat' table.
  33. * @var object
  34. * @access private
  35. */
  36. var $moodle_chat_instance = null;
  37. // FUNCTIONS //
  38. /**
  39. * Constructor
  40. */
  41. function SloodleModuleChat(&$_session)
  42. {
  43. $constructor = get_parent_class($this);
  44. parent::$constructor($_session);
  45. }
  46. /**
  47. * Loads data from the database.
  48. * Note: even if the function fails, it may still have overwritten some or all existing data in the object.
  49. * @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)
  50. * @return bool True if successful, or false otherwise
  51. */
  52. function load($id)
  53. {
  54. // Make sure the ID is valid
  55. $id = (int)$id;
  56. if ($id <= 0) return false;
  57. // Fetch the course module data
  58. if (!($this->cm = get_coursemodule_from_id('chat', $id))) {
  59. sloodle_debug("Failed to load course module instance #$id.<br/>");
  60. return false;
  61. }
  62. // Make sure the module is visible
  63. if ($this->cm->visible == 0) {
  64. sloodle_debug("Error: course module instance #$id not visible.<br/>");
  65. return false;
  66. }
  67. // Load from the primary table: chat instance
  68. if (!($this->moodle_chat_instance = sloodle_get_record('chat', 'id', $this->cm->instance))) {
  69. sloodle_debug("Failed to load chatroom with instance ID #{$cm->instance}.<br/>");
  70. return false;
  71. }
  72. return true;
  73. }
  74. /**
  75. * Gets a recent history of messages from the chatroom.
  76. * @param int $time How far back to search the database (in seconds) (default: 1 minute)
  77. * @return array A numeric array of {@link SloodleChatMessage} object, in order of oldest to newest
  78. */
  79. function get_chat_history($time = 60)
  80. {
  81. // Calculate the earliest acceptable timestamp
  82. $earliest = time() - $time;
  83. // Get all message records for this chatroom
  84. $recs = sloodle_get_records_select_params('chat_messages', "chatid = ? AND timestamp >= ?", array($this->moodle_chat_instance->id, $earliest), 'timestamp ASC');
  85. if (!$recs) return array();
  86. // We'll need to lookup all the user data.
  87. // Cache the user records so we don't need to duplicate searches.
  88. // This will be an associative array of user ID's to SloodleUser objects.
  89. $usercache = array();
  90. // Prepare an array of chat message objects
  91. $chatmessages = array();
  92. // Go through each result
  93. foreach ($recs as $r) {
  94. // Do we already have the current user cached?
  95. if (!isset($usercache[$r->userid])) {
  96. // No - query the database
  97. $usercache[$r->userid] = new SloodleUser($this->_session);
  98. if ($usercache[$r->userid]->load_user($r->userid)) {
  99. // Attempt to load any linked avatar data too
  100. $usercache[$r->userid]->load_linked_avatar();
  101. }
  102. }
  103. // Construct and add a message object
  104. $chatmessages[] = new SloodleChatMessage($r->id, $r->message, $usercache[$r->userid], $r->timestamp);
  105. }
  106. return $chatmessages;
  107. }
  108. /**
  109. * Adds a new chat message.
  110. * <b>Note:</b> if the $author parameter is omitted or invalid, then the function will attempt to use the {@link SloodleUser} member
  111. * of the current {@link SloodleSession} object;
  112. * If that is unavailable, then it will try to use the user currently 'logged-in' to the VLE (i.e. the $USER variable in Moodle).
  113. * If all else fails, it will attempt to attribute the message to the guest user.
  114. * @param string $message The text of the message.
  115. * @param mixed $user The user who wrote the message -- either a VLE user ID or (preferably) a {@link SloodleUser} object. If null, then the user in the current SloodleSession object will be used. At that fails, then the guest user is used if possible.
  116. * @param int $timestamp Timestamp of the message. If omitted or <= 0 then the current timestamp is used
  117. * @return bool True if successful, or false otherwise
  118. */
  119. function add_message($message, $user = null, $timestamp = null)
  120. {
  121. // Ignore empty messages
  122. if (empty($message)) return false;
  123. // Make sure the message is safe
  124. $message = clean_text(stripslashes($message));
  125. // We need to get the user ID for the message
  126. $userid = 0;
  127. // Has a user object been provided?
  128. if (is_object($user)) {
  129. // Yes - grab the user ID
  130. $userid = $user->get_user_id();
  131. } else if ($user != null) {
  132. // May be an ID
  133. $userid = (int)$user;
  134. }
  135. // Did we end up with a valid user ID?
  136. if ((int)$userid <= 0) {
  137. // No - do we have a user in the session parameter?
  138. if (isset($this->_session->user)) {
  139. // Store the user ID
  140. $userid = $this->_session->user->get_user_id();
  141. }
  142. }
  143. // Are we still lacking a valid user?
  144. if ((int)$userid <= 0) {
  145. // Yes - user the guest user
  146. $guest = guest_user();
  147. if ($guest) $userid = $guest->id;
  148. }
  149. // Prepare the timestamp variable if necessary
  150. if (is_null($timestamp)) $timestamp = time();
  151. // Create a chat message record object
  152. $rec = new stdClass();
  153. $rec->chatid = $this->moodle_chat_instance->id;
  154. $rec->userid = $userid;
  155. $rec->message = $message;
  156. $rec->timestamp = $timestamp;
  157. // Attempt to insert the chat message
  158. $result = sloodle_insert_record('chat_messages', $rec);
  159. if (!$result) return false;
  160. if (SLOODLE_IS_ENVIRONMENT_MOODLE_2) {
  161. $result = sloodle_insert_record('chat_messages_current', $rec);
  162. if (!$result) return false;
  163. }
  164. if (!is_null($this->_session->active_object)) {
  165. $this->_session->active_object->process_interaction( 'default', 1, $userid );
  166. // TODO: Maybe we should set a side effect code here?
  167. }
  168. // We successfully added a chat message
  169. // If possible, add an appropriate side effect code to our response
  170. if (isset($this->_session->response)) {
  171. $this->_session->response->add_side_effect(10101);
  172. }
  173. return true;
  174. }
  175. // ACCESSORS //
  176. /**
  177. * Gets the name of this module instance.
  178. * @return string The name of this controller
  179. */
  180. function get_name()
  181. {
  182. return $this->moodle_chat_instance->name;
  183. }
  184. /**
  185. * Gets the intro description of this module instance, if available.
  186. * @return string The intro description of this controller
  187. */
  188. function get_intro()
  189. {
  190. return $this->moodle_chat_instance->intro;
  191. }
  192. /**
  193. * Gets the identifier of the course this controller belongs to.
  194. * @return mixed Course identifier. Type depends on VLE. (In Moodle, it will be an integer).
  195. */
  196. function get_course_id()
  197. {
  198. return (int)$this->moodle_chat_instance->course;
  199. }
  200. /**
  201. * Gets the time at which this instance was created, or 0 if unknown.
  202. * @return int Timestamp
  203. */
  204. function get_creation_time()
  205. {
  206. return 0;
  207. }
  208. /**
  209. * Gets the time at which this instance was last modified, or 0 if unknown.
  210. * @return int Timestamp
  211. */
  212. function get_modification_time()
  213. {
  214. return $this->moodle_chat_instance->timemodified;
  215. }
  216. /**
  217. * Gets the short type name of this instance.
  218. * @return string
  219. */
  220. function get_type()
  221. {
  222. return 'chat';
  223. }
  224. /**
  225. * Gets the full type name of this instance, according to the current language pack, if available.
  226. * Note: should be overridden by sub-classes.
  227. * @return string Full type name if possible, or the short name otherwise.
  228. */
  229. function get_type_full()
  230. {
  231. return get_string('modulename', 'chat');
  232. }
  233. }
  234. /**
  235. * Represents a single chat message
  236. * @package sloodle
  237. */
  238. class SloodleChatMessage
  239. {
  240. /**
  241. * Constructor - initialises members.
  242. * @param mixed $id The ID of this message - type depends on VLE, but is typically an integer
  243. * @param string $message The chat message
  244. * @param SloodleUser $user The user who wrote the message
  245. * @param int $timestamp The timestamp of the message
  246. */
  247. function SloodleChatMessage($id, $message, $user, $timestamp)
  248. {
  249. $this->id = $id;
  250. $this->message = $message;
  251. $this->user = $user;
  252. $this->timestamp = $timestamp;
  253. }
  254. /**
  255. * Accessor - set all members in a single call.
  256. * @param mixed $id The ID of this message - type depends on VLE, but is typically an integer
  257. * @param string $message The chat message
  258. * @param SloodleUser $user The user who wrote the message
  259. * @param int $timestamp The timestamp of the message
  260. */
  261. function set($id, $message, $user, $timestamp)
  262. {
  263. $this->id = $id;
  264. $this->message = $message;
  265. $this->user = $user;
  266. $this->timestamp = $timestamp;
  267. }
  268. /**
  269. * The ID of the message.
  270. * The type depends on the VLE, but typically is an integer.
  271. * @var mixed
  272. * @access public
  273. */
  274. var $id = 0;
  275. /**
  276. * The text of the message.
  277. * @var string
  278. * @access public
  279. */
  280. var $message = '';
  281. /**
  282. * The user who wrote this message.
  283. * @var SloodleUser
  284. * @access public
  285. */
  286. var $user = null;
  287. /**
  288. * Timestamp of the message.
  289. * @var int
  290. * @access public
  291. */
  292. var $timestamp = 0;
  293. }
  294. ?>