MDL-10680:
[moodle-linuxchix.git] / search / documents / chat_document.php
blobf3196d7da02a1edf972d328e0c2fc2576fe9b032
1 <?php
2 /**
3 * Global Search Engine for Moodle
4 * add-on 1.8+ : Valery Fremaux [valery.fremaux@club-internet.fr]
5 * 2007/08/02
7 * document handling for chat activity module
8 * This file contains the mapping between a chat history and it's indexable counterpart,
10 * Functions for iterating and retrieving the necessary records are now also included
11 * in this file, rather than mod/chat/lib.php
12 **/
14 require_once("$CFG->dirroot/search/documents/document.php");
15 require_once("$CFG->dirroot/mod/chat/lib.php");
17 /*
18 * a class for representing searchable information
20 **/
21 class ChatTrackSearchDocument extends SearchDocument {
23 /**
24 * constructor
27 public function __construct(&$chatsession, $chat_module_id, $course_id, $group_id, $context_id) {
28 // generic information; required
29 $doc->docid = $chat_module_id.'-'.$chatsession['sessionstart'].'-'.$chatsession['sessionend'];
30 $doc->documenttype = SEARCH_TYPE_CHAT;
31 $doc->itemtype = 'session';
32 $doc->contextid = $context_id;
34 $duration = $chatsession['sessionend'] - $chatsession['sessionstart'];
35 // we cannot call userdate with relevant locale at indexing time.
36 $doc->title = get_string('chatreport', 'chat').' '.get_string('openedon', 'search').' TT_'.$chatsession['sessionstart'].'_TT ('.get_string('duration', 'search').' : '.get_string('numseconds', '', $duration).')';
37 $doc->date = $chatsession['sessionend'];
39 //remove '(ip.ip.ip.ip)' from chat author list
40 $doc->author = preg_replace('/\(.*?\)/', '', $chatsession['authors']);
41 $doc->contents = $chatsession['content'];
42 $doc->url = chat_make_link($chat_module_id, $chatsession['sessionstart'], $chatsession['sessionend']);
44 // module specific information; optional
45 $data->chat = $chat_module_id;
47 // construct the parent class
48 parent::__construct($doc, $data, $course_id, $group_id, 0, PATH_FOR_SEARCH_TYPE_CHAT);
49 } //constructor
50 } //ChatTrackSearchDocument
53 /**
54 * constructs a valid link to a chat content
55 * @param cm_id the chat course module
56 * @param start the start time of the session
57 * @param end th end time of the session
58 * @return a well formed link to session display
60 function chat_make_link($cm_id, $start, $end) {
61 global $CFG;
63 return $CFG->wwwroot.'/mod/chat/report.php?id='.$cm_id.'&amp;start='.$start.'&amp;end='.$end;
64 } //chat_make_link
66 /**
67 * fetches all the records for a given session and assemble them as a unique track
68 * we revamped here the code of report.php for making sessions, but without any output.
69 * note that we should collect sessions "by groups" if groupmode() is SEPARATEGROUPS.
70 * @param chat_id the database
71 * @return an array of objects representing the chat sessions.
73 function chat_get_session_tracks($chat_id, $fromtime = 0, $totime = 0) {
74 global $CFG;
76 $chat = get_record('chat', 'id', $chat_id);
77 $course = get_record('course', 'id', $chat->course);
78 $coursemodule = get_field('modules', 'id', 'name', 'data');
79 $cm = get_record('course_modules', 'course', $course->id, 'module', $coursemodule, 'instance', $chat->id);
80 $groupmode = groupmode($course, $cm);
82 $fromtimeclause = ($fromtime) ? "AND timestamp >= {$fromtime}" : '';
83 $totimeclause = ($totime) ? "AND timestamp <= {$totime}" : '';
84 $tracks = array();
85 $messages = get_records_select('chat_messages', "chatid = '{$chat_id}' $fromtimeclause $totimeclause", "timestamp DESC");
86 if ($messages){
87 // splits discussions against groups
88 $groupedMessages = array();
89 if ($groupmode != SEPARATEGROUPS){
90 foreach($messages as $aMessage){
91 $groupedMessages[$aMessage->groupid][] = $aMessage;
94 else{
95 $groupedMessages[-1] = &$messages;
97 $sessiongap = 5 * 60; // 5 minutes silence means a new session
98 $sessionend = 0;
99 $sessionstart = 0;
100 $sessionusers = array();
101 $lasttime = time();
103 foreach ($groupedMessages as $groupId => $messages) { // We are walking BACKWARDS through the messages
104 $messagesleft = count($messages);
105 foreach ($messages as $message) { // We are walking BACKWARDS through the messages
106 $messagesleft --; // Countdown
108 if ($message->system) {
109 continue;
111 // we are within a session track
112 if ((($lasttime - $message->timestamp) < $sessiongap) and $messagesleft) { // Same session
113 if (count($tracks) > 0){
114 if ($message->userid) { // Remember user and count messages
115 $tracks[count($tracks) - 1]->sessionusers[$message->userid] = $message->userid;
116 // update last track (if exists) record appending content (remember : we go backwards)
118 $tracks[count($tracks) - 1]->content .= ' '.$message->message;
119 $tracks[count($tracks) - 1]->sessionstart = $message->timestamp;
122 // we initiate a new session track (backwards)
123 else {
124 $track = new Object();
125 $track->sessionend = $message->timestamp;
126 $track->sessionstart = $message->timestamp;
127 $track->content = $message->message;
128 // reset the accumulator of users
129 $track->sessionusers = array();
130 $track->sessionusers[$message->userid] = $message->userid;
131 $track->groupid = $groupId;
132 $tracks[] = $track;
134 $lasttime = $message->timestamp;
138 return $tracks;
139 } //chat_get_session_tracks
142 * part of search engine API
145 function chat_iterator() {
146 $chatrooms = get_records('chat');
147 return $chatrooms;
148 } //chat_iterator
151 * part of search engine API
154 function chat_get_content_for_index(&$chat) {
155 $documents = array();
156 $course = get_record('course', 'id', $chat->course);
157 $coursemodule = get_field('modules', 'id', 'name', 'chat');
158 $cm = get_record('course_modules', 'course', $course->id, 'module', $coursemodule, 'instance', $chat->id);
159 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
161 // getting records for indexing
162 $sessionTracks = chat_get_session_tracks($chat->id);
163 if ($sessionTracks){
164 foreach($sessionTracks as $aTrackId => $aTrack) {
165 foreach($aTrack->sessionusers as $aUserId){
166 $user = get_record('user', 'id', $aUserId);
167 $aTrack->authors = ($user) ? $user->firstname.' '.$user->lastname : '' ;
168 $documents[] = new ChatTrackSearchDocument(get_object_vars($aTrack), $cm->id, $chat->course, $aTrack->groupid, $context->id);
172 return $documents;
173 } //chat_get_content_for_index
176 * returns a single data search document based on a chat_session id
177 * chat session id is a text composite identifier made of :
178 * - the chat id
179 * - the timestamp when the session starts
180 * - the timestamp when the session ends
181 * @param id the multipart chat session id
182 * @param itemtype the type of information (session is the only type)
184 function chat_single_document($id, $itemtype) {
185 list($chat_id, $sessionstart, $sessionend) = split('-', $id);
186 $chat = get_record('chat', 'id', $chat_id);
187 $course = get_record('course', 'id', $chat->course);
188 $coursemodule = get_field('modules', 'id', 'name', 'chat');
189 $cm = get_record('course_modules', 'course', $course->id, 'module', $coursemodule, 'instance', $chat->id);
190 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
192 // should be only one
193 $tracks = chat_get_session_tracks($chat->id, $sessionstart, $sessionstart);
194 if ($tracks){
195 $aTrack = $tracks[0];
196 $documents[] = new ChatTrackSearchDocument(get_object_vars($aTrack), $cm->id, $chat->course, $aTrack->groupid, $context->id);
198 } //chat_single_document
201 * dummy delete function that packs id with itemtype.
202 * this was here for a reason, but I can't remember it at the moment.
205 function chat_delete($info, $itemtype) {
206 $object->id = $info;
207 $object->itemtype = $itemtype;
208 return $object;
209 } //chat_delete
212 * returns the var names needed to build a sql query for addition/deletions
213 * // TODO chat indexable records are virtual. Should proceed in a special way
215 function chat_db_names() {
216 //[primary id], [table name], [time created field name], [time modified field name]
217 return null;
218 } //chat_db_names
221 * this function handles the access policy to contents indexed as searchable documents. If this
222 * function does not exist, the search engine assumes access is allowed.
223 * When this point is reached, we already know that :
224 * - user is legitimate in the surrounding context
225 * - user may be guest and guest access is allowed to the module
226 * - the function may perform local checks within the module information logic
227 * @param path the access path to the module script code
228 * @param itemtype the information subclassing (usefull for complex modules, defaults to 'standard')
229 * @param this_id the item id within the information class denoted by entry_type. In chats, this id
230 * points out a session history which is a close sequence of messages.
231 * @param user the user record denoting the user who searches
232 * @param group_id the current group used by the user when searching
233 * @return true if access is allowed, false elsewhere
235 function chat_check_text_access($path, $itemtype, $this_id, $user, $group_id, $context_id){
236 global $CFG;
238 include_once("{$CFG->dirroot}/{$path}/lib.php");
240 list($chat_id, $sessionstart, $sessionend) = split('-', $id);
242 // get the chat session and all related stuff
243 $chat = get_record('chat', 'id', $chat_id);
244 $course = get_record('course', 'id', $chat->course);
245 $module_context = get_record('context', 'id', $context_id);
246 $cm = get_record('course_modules', 'id', $module_context->instanceid);
247 if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $module_context)) return false;
249 //group consistency check : checks the following situations about groups
250 // trap if user is not same group and groups are separated
251 $current_group = get_current_group($course->id);
252 if ((groupmode($course) == SEPARATEGROUPS) && !ismember($group_id) && !has_capability('moodle/site:accessallgroups', $module_context)) return false;
254 //ownership check : checks the following situations about user
255 // trap if user is not owner and has cannot see other's entries
256 // TODO : typically may be stored into indexing cache
257 if (!has_capability('mod/chat:readlog', $module_context)) return false;
259 return true;
260 } //chat_check_text_access
263 * this call back is called when displaying the link for some last post processing
266 function chat_link_post_processing($title){
267 setLocale(LC_TIME, substr(current_language(), 0, 2));
268 $title = preg_replace('/TT_(.*)_TT/e', "userdate(\\1)", $title);
269 return $title;
270 } //chat_link_post_processing