2009-09-23 07:08:43 +00:00
< ? php
2014-07-23 09:58:29 +08:00
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
2006-04-19 02:20:48 +00:00
/** jsupdated . php - notes by Martin Langhoff < martin @ catalyst . net . nz >
2009-11-01 13:17:47 +00:00
**
2006-04-19 02:20:48 +00:00
** This is an alternative version of jsupdate . php that acts
** as a long - running daemon . It will feed / stall / feed JS updates
** to the client . From the module configuration select " Stream "
** updates .
2009-11-01 13:17:47 +00:00
**
** The client connection is not forever though . Once we reach
** CHAT_MAX_CLIENT_UPDATES , it will force the client to re - fetch it .
**
2006-04-19 02:20:48 +00:00
** This buys us all the benefits that chatd has , minus the setup ,
** as we are using apache to do the daemon handling .
**
**/
2009-09-23 07:08:43 +00:00
define ( 'CHAT_MAX_CLIENT_UPDATES' , 1000 );
2014-07-23 09:58:29 +08:00
define ( 'NO_MOODLE_COOKIES' , true ); // Session not used here.
2010-11-19 03:40:43 +00:00
define ( 'NO_OUTPUT_BUFFERING' , true );
2006-04-19 02:20:48 +00:00
2009-09-23 07:08:43 +00:00
require ( '../../../config.php' );
2020-12-04 10:43:46 -05:00
require_once ( '../lib.php' );
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
// We are going to run for a long time.
// Avoid being terminated by php.
2013-10-15 13:22:19 +01:00
core_php_time_limit :: raise ();
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
$chatsid = required_param ( 'chat_sid' , PARAM_ALPHANUM );
$chatlasttime = optional_param ( 'chat_lasttime' , 0 , PARAM_INT );
$chatlastrow = optional_param ( 'chat_lastrow' , 1 , PARAM_INT );
$chatlastid = optional_param ( 'chat_lastid' , 0 , PARAM_INT );
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
$url = new moodle_url ( '/mod/chat/gui_header_js/jsupdated.php' , array ( 'chat_sid' => $chatsid ));
if ( $chatlasttime !== 0 ) {
$url -> param ( 'chat_lasttime' , $chatlasttime );
2009-09-23 07:08:43 +00:00
}
2014-07-23 09:58:29 +08:00
if ( $chatlastrow !== 1 ) {
$url -> param ( 'chat_lastrow' , $chatlastrow );
2009-09-23 07:08:43 +00:00
}
2014-07-23 09:58:29 +08:00
if ( $chatlastid !== 1 ) {
$url -> param ( 'chat_lastid' , $chatlastid );
2009-09-23 07:08:43 +00:00
}
$PAGE -> set_url ( $url );
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
if ( ! $chatuser = $DB -> get_record ( 'chat_users' , array ( 'sid' => $chatsid ))) {
2009-09-23 07:08:43 +00:00
print_error ( 'notlogged' , 'chat' );
}
2007-01-28 21:18:08 +00:00
2014-07-23 09:58:29 +08:00
// Get the minimal course.
if ( ! $course = $DB -> get_record ( 'course' , array ( 'id' => $chatuser -> course ))) {
2009-09-23 07:08:43 +00:00
print_error ( 'invalidcourseid' );
}
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
// Get the user theme and enough info to be used in chat_format_message() which passes it along to
2009-09-23 07:08:43 +00:00
// chat_format_message_manually() -- and only id and timezone are used.
2014-07-23 09:58:29 +08:00
// No optimisation here, it would break again in future!
if ( ! $user = $DB -> get_record ( 'user' , array ( 'id' => $chatuser -> userid , 'deleted' => 0 , 'suspended' => 0 ))) {
2009-09-23 07:08:43 +00:00
print_error ( 'invaliduser' );
}
2013-10-01 09:23:42 +02:00
\core\session\manager :: set_user ( $user );
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
// Setup course, lang and theme.
2009-09-23 07:08:43 +00:00
$PAGE -> set_course ( $course );
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
// Force deleting of timed out users if there is a silence in room or just entering.
if (( time () - $chatlasttime ) > $CFG -> chat_old_ping ) {
// Must be done before chat_get_latest_message!
2009-09-23 07:08:43 +00:00
chat_delete_old_users ();
}
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
// Time to send headers, and lay out the basic JS updater page.
2009-09-23 07:08:43 +00:00
header ( 'Expires: Sun, 28 Dec 1997 09:32:45 GMT' );
header ( 'Last-Modified: ' . gmdate ( 'D, d M Y H:i:s' ) . ' GMT' );
header ( 'Cache-Control: no-cache, must-revalidate' );
header ( 'Pragma: no-cache' );
header ( 'Content-Type: text/html; charset=utf-8' );
2014-07-23 09:58:29 +08:00
$refreshurl = " { $CFG -> wwwroot } /mod/chat/gui_header_js/jsupdated.php? " .
" chat_sid= $chatsid &chat_lasttime= $chatlasttime &chat_lastrow= $chatnewrow &chat_lastid= $chatlastid " ;
2006-04-19 02:20:48 +00:00
?>
<! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >
< html >
< head >
2006-11-11 17:23:20 +00:00
< meta http - equiv = " content-type " content = " text/html; charset=utf-8 " />
2006-04-19 02:20:48 +00:00
< script type = " text/javascript " >
2006-12-22 05:42:36 +00:00
//<![CDATA[
2006-04-19 02:20:48 +00:00
if ( parent . msg . document . getElementById ( " msgStarted " ) == null ) {
parent . msg . document . close ();
parent . msg . document . open ( " text/html " , " replace " );
parent . msg . document . write ( " <!DOCTYPE html PUBLIC \" -//W3C//DTD XHTML 1.0 Transitional//EN \" \" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd \" > " );
parent . msg . document . write ( " <html><head> " );
2006-11-11 17:23:20 +00:00
parent . msg . document . write ( " <meta http-equiv= \" content-type \" content= \" text/html; charset=utf-8 \" /> " );
2006-04-19 02:20:48 +00:00
parent . msg . document . write ( " <base target= \" _blank \" /> " );
parent . msg . document . write ( " </head><body class= \" mod-chat-gui_header_js course-<?php echo $chatuser->course ?> \" id= \" mod-chat-gui_header_js-jsupdate \" ><div style= \" display: none \" id= \" msgStarted \" > </div> " );
}
2006-12-22 05:42:36 +00:00
//]]>
2006-04-19 02:20:48 +00:00
</ script >
2010-09-20 03:33:48 +00:00
</ head >
< body >
2006-04-19 02:20:48 +00:00
< ? php
2014-07-23 09:58:29 +08:00
// Ensure the HTML head makes it out there.
echo $CHAT_DUMMY_DATA ;
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
for ( $n = 0 ; $n <= CHAT_MAX_CLIENT_UPDATES ; $n ++ ) {
2009-11-01 13:17:47 +00:00
2014-07-23 09:58:29 +08:00
// Ping first so we can later shortcut as needed.
$chatuser -> lastping = time ();
$DB -> set_field ( 'chat_users' , 'lastping' , $chatuser -> lastping , array ( 'id' => $chatuser -> id ));
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
if ( $message = chat_get_latest_message ( $chatuser -> chatid , $chatuser -> groupid )) {
$chatnewlasttime = $message -> timestamp ;
$chatnewlastid = $message -> id ;
} else {
$chatnewlasttime = 0 ;
$chatnewlastid = 0 ;
print " \n " ;
print $CHAT_DUMMY_DATA ;
sleep ( $CFG -> chat_refresh_room );
continue ;
}
$timenow = time ();
$params = array ( 'groupid' => $chatuser -> groupid ,
'lastid' => $chatlastid ,
'lasttime' => $chatlasttime ,
'chatid' => $chatuser -> chatid );
$groupselect = $chatuser -> groupid ? " AND (groupid=:groupid OR groupid=0) " : " " ;
$newcriteria = '' ;
if ( $chatlastid > 0 ) {
$newcriteria = " id > :lastid " ;
} else {
if ( $chatlasttime == 0 ) { // Display some previous messages.
$chatlasttime = $timenow - $CFG -> chat_old_ping ; // TO DO - any better value?
2006-04-19 02:20:48 +00:00
}
2014-07-23 09:58:29 +08:00
$newcriteria = " timestamp > :lasttime " ;
}
2009-11-01 13:17:47 +00:00
2014-07-23 09:58:29 +08:00
$messages = $DB -> get_records_select ( " chat_messages_current " ,
" chatid = :chatid AND $newcriteria $groupselect " , $params ,
" timestamp ASC " );
if ( $messages ) {
$num = count ( $messages );
} else {
print " \n " ;
print $CHAT_DUMMY_DATA ;
sleep ( $CFG -> chat_refresh_room );
continue ;
}
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
print '<script type="text/javascript">' . " \n " ;
print " //<![CDATA[ \n \n " ;
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
$chatnewrow = ( $chatlastrow + $num ) % 2 ;
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
$refreshusers = false ;
$us = array ();
if (( $chatlasttime != $chatnewlasttime ) and $messages ) {
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
$beep = false ;
$refreshusers = false ;
foreach ( $messages as $message ) {
$chatlastrow = ( $chatlastrow + 1 ) % 2 ;
$formatmessage = chat_format_message ( $message , $chatuser -> course , $USER , $chatlastrow );
if ( $formatmessage -> beep ) {
$beep = true ;
2006-04-19 02:20:48 +00:00
}
2014-07-23 09:58:29 +08:00
if ( $formatmessage -> refreshusers ) {
$refreshusers = true ;
2006-04-19 02:20:48 +00:00
}
2014-07-23 09:58:29 +08:00
$us [ $message -> userid ] = $timenow - $message -> timestamp ;
echo " parent.msg.document.write(' " . addslashes_js ( $formatmessage -> html ) . " \\ n'); \n " ;
2006-04-19 02:20:48 +00:00
2008-10-08 06:48:57 +00:00
}
2014-07-23 09:58:29 +08:00
// From the last message printed.
// A strange case where lack of closures is useful!
$chatlasttime = $message -> timestamp ;
$chatlastid = $message -> id ;
}
if ( $refreshusers ) {
echo " if (parent.users.document.anchors[0] != null) { " .
" parent.users.location.href = parent.users.document.anchors[0].href;} \n " ;
} else {
foreach ( $us as $uid => $lastping ) {
$min = ( int ) ( $lastping / 60 );
$sec = $lastping - ( $min * 60 );
$min = $min < 10 ? '0' . $min : $min ;
$sec = $sec < 10 ? '0' . $sec : $sec ;
$idle = $min . ':' . $sec ;
echo " if (parent.users.document.getElementById('uidle { $uid } ') != null) { " .
" parent.users.document.getElementById('uidle { $uid } ').innerHTML = ' $idle ';} \n " ;
2006-04-19 02:20:48 +00:00
}
2014-07-23 09:58:29 +08:00
}
2006-04-19 02:20:48 +00:00
2014-07-23 09:58:29 +08:00
print <<< EOD
if ( parent . input ){
var autoscroll = parent . input . document . getElementById ( 'auto' );
if ( parent . msg && autoscroll && autoscroll . checked ){
parent . msg . scroll ( 1 , 5000000 );
}
}
EOD ;
2006-12-22 05:42:36 +00:00
print " //]]> \n " ;
2006-04-19 02:20:48 +00:00
print '</script>' . " \n \n " ;
2014-07-23 09:58:29 +08:00
if ( $beep ) {
2017-11-06 15:08:55 +08:00
print '<script> (function() {' ;
print 'var audioElement = document.createElement("audio");' ;
print 'audioElement.setAttribute("src", "../beep.mp3");' ;
print 'audioElement.play(); })();' ;
print '</script>' ;
2014-07-23 09:58:29 +08:00
}
print $CHAT_DUMMY_DATA ;
sleep ( $CFG -> chat_refresh_room );
} // Here ends the for() loop.
// Here & should be written & :-D.
$refreshurl = " { $CFG -> wwwroot } /mod/chat/gui_header_js/jsupdated.php? " ;
$refreshurl .= " chat_sid= $chatsid &chat_lasttime= $chatlasttime &chat_lastrow= $chatnewrow &chat_lastid= $chatlastid " ;
print '<script type="text/javascript">' . " \n " ;
print " //<![CDATA[ \n \n " ;
print " location.href = ' $refreshurl '; \n " ;
print " //]]> \n " ;
print '</script>' . " \n \n " ;
2006-04-19 02:20:48 +00:00
?>
</ body >
</ html >