[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/mod/chat/ -> lib.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Library of functions and constants for module chat
  19   *
  20   * @package   mod_chat
  21   * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  require_once($CFG->dirroot.'/calendar/lib.php');
  26  
  27  // The HTML head for the message window to start with (<!-- nix --> is used to get some browsers starting with output.
  28  global $CHAT_HTMLHEAD;
  29  $CHAT_HTMLHEAD = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head></head>\n<body>\n\n".padding(200);
  30  
  31  // The HTML head for the message window to start with (with js scrolling).
  32  global $CHAT_HTMLHEAD_JS;
  33  $CHAT_HTMLHEAD_JS = <<<EOD
  34  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
  35  <html><head><script type="text/javascript">
  36  //<![CDATA[
  37  function move() {
  38      if (scroll_active)
  39          window.scroll(1,400000);
  40      window.setTimeout("move()",100);
  41  }
  42  var scroll_active = true;
  43  move();
  44  //]]>
  45  </script>
  46  </head>
  47  <body onBlur="scroll_active = true" onFocus="scroll_active = false">
  48  EOD;
  49  global $CHAT_HTMLHEAD_JS;
  50  $CHAT_HTMLHEAD_JS .= padding(200);
  51  
  52  // The HTML code for standard empty pages (e.g. if a user was kicked out).
  53  global $CHAT_HTMLHEAD_OUT;
  54  $CHAT_HTMLHEAD_OUT = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>You are out!</title></head><body></body></html>";
  55  
  56  // The HTML head for the message input page.
  57  global $CHAT_HTMLHEAD_MSGINPUT;
  58  $CHAT_HTMLHEAD_MSGINPUT = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>Message Input</title></head><body>";
  59  
  60  // The HTML code for the message input page, with JavaScript.
  61  global $CHAT_HTMLHEAD_MSGINPUT_JS;
  62  $CHAT_HTMLHEAD_MSGINPUT_JS = <<<EOD
  63  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
  64  <html>
  65      <head><title>Message Input</title>
  66      <script type="text/javascript">
  67      //<![CDATA[
  68      scroll_active = true;
  69      function empty_field_and_submit() {
  70          document.fdummy.arsc_message.value=document.f.arsc_message.value;
  71          document.fdummy.submit();
  72          document.f.arsc_message.focus();
  73          document.f.arsc_message.select();
  74          return false;
  75      }
  76      //]]>
  77      </script>
  78      </head><body OnLoad="document.f.arsc_message.focus();document.f.arsc_message.select();">;
  79  EOD;
  80  
  81  // Dummy data that gets output to the browser as needed, in order to make it show output.
  82  global $CHAT_DUMMY_DATA;
  83  $CHAT_DUMMY_DATA = padding(200);
  84  
  85  /**
  86   * @param int $n
  87   * @return string
  88   */
  89  function padding($n) {
  90      $str = '';
  91      for ($i = 0; $i < $n; $i++) {
  92          $str .= "<!-- nix -->\n";
  93      }
  94      return $str;
  95  }
  96  
  97  /**
  98   * Given an object containing all the necessary data,
  99   * (defined by the form in mod_form.php) this function
 100   * will create a new instance and return the id number
 101   * of the new instance.
 102   *
 103   * @global object
 104   * @param object $chat
 105   * @return int
 106   */
 107  function chat_add_instance($chat) {
 108      global $DB;
 109  
 110      $chat->timemodified = time();
 111  
 112      $returnid = $DB->insert_record("chat", $chat);
 113  
 114      $event = new stdClass();
 115      $event->name        = $chat->name;
 116      $event->description = format_module_intro('chat', $chat, $chat->coursemodule);
 117      $event->courseid    = $chat->course;
 118      $event->groupid     = 0;
 119      $event->userid      = 0;
 120      $event->modulename  = 'chat';
 121      $event->instance    = $returnid;
 122      $event->eventtype   = 'chattime';
 123      $event->timestart   = $chat->chattime;
 124      $event->timeduration = 0;
 125  
 126      calendar_event::create($event);
 127  
 128      return $returnid;
 129  }
 130  
 131  /**
 132   * Given an object containing all the necessary data,
 133   * (defined by the form in mod_form.php) this function
 134   * will update an existing instance with new data.
 135   *
 136   * @global object
 137   * @param object $chat
 138   * @return bool
 139   */
 140  function chat_update_instance($chat) {
 141      global $DB;
 142  
 143      $chat->timemodified = time();
 144      $chat->id = $chat->instance;
 145  
 146      $DB->update_record("chat", $chat);
 147  
 148      $event = new stdClass();
 149  
 150      if ($event->id = $DB->get_field('event', 'id', array('modulename' => 'chat', 'instance' => $chat->id))) {
 151  
 152          $event->name        = $chat->name;
 153          $event->description = format_module_intro('chat', $chat, $chat->coursemodule);
 154          $event->timestart   = $chat->chattime;
 155  
 156          $calendarevent = calendar_event::load($event->id);
 157          $calendarevent->update($event);
 158      }
 159  
 160      return true;
 161  }
 162  
 163  /**
 164   * Given an ID of an instance of this module,
 165   * this function will permanently delete the instance
 166   * and any data that depends on it.
 167   *
 168   * @global object
 169   * @param int $id
 170   * @return bool
 171   */
 172  function chat_delete_instance($id) {
 173      global $DB;
 174  
 175      if (! $chat = $DB->get_record('chat', array('id' => $id))) {
 176          return false;
 177      }
 178  
 179      $result = true;
 180  
 181      // Delete any dependent records here.
 182  
 183      if (! $DB->delete_records('chat', array('id' => $chat->id))) {
 184          $result = false;
 185      }
 186      if (! $DB->delete_records('chat_messages', array('chatid' => $chat->id))) {
 187          $result = false;
 188      }
 189      if (! $DB->delete_records('chat_messages_current', array('chatid' => $chat->id))) {
 190          $result = false;
 191      }
 192      if (! $DB->delete_records('chat_users', array('chatid' => $chat->id))) {
 193          $result = false;
 194      }
 195  
 196      if (! $DB->delete_records('event', array('modulename' => 'chat', 'instance' => $chat->id))) {
 197          $result = false;
 198      }
 199  
 200      return $result;
 201  }
 202  
 203  /**
 204   * Given a course and a date, prints a summary of all chat rooms past and present
 205   * This function is called from block_recent_activity
 206   *
 207   * @global object
 208   * @global object
 209   * @global object
 210   * @param object $course
 211   * @param bool $viewfullnames
 212   * @param int|string $timestart Timestamp
 213   * @return bool
 214   */
 215  function chat_print_recent_activity($course, $viewfullnames, $timestart) {
 216      global $CFG, $USER, $DB, $OUTPUT;
 217  
 218      // This is approximate only, but it is really fast.
 219      $timeout = $CFG->chat_old_ping * 10;
 220  
 221      if (!$mcms = $DB->get_records_sql("SELECT cm.id, MAX(chm.timestamp) AS lasttime
 222                                           FROM {course_modules} cm
 223                                           JOIN {modules} md        ON md.id = cm.module
 224                                           JOIN {chat} ch           ON ch.id = cm.instance
 225                                           JOIN {chat_messages} chm ON chm.chatid = ch.id
 226                                          WHERE chm.timestamp > ? AND ch.course = ? AND md.name = 'chat'
 227                                       GROUP BY cm.id
 228                                       ORDER BY lasttime ASC", array($timestart, $course->id))) {
 229           return false;
 230      }
 231  
 232      $past     = array();
 233      $current  = array();
 234      $modinfo = get_fast_modinfo($course); // Reference needed because we might load the groups.
 235  
 236      foreach ($mcms as $cmid => $mcm) {
 237          if (!array_key_exists($cmid, $modinfo->cms)) {
 238              continue;
 239          }
 240          $cm = $modinfo->cms[$cmid];
 241          if (!$modinfo->cms[$cm->id]->uservisible) {
 242              continue;
 243          }
 244  
 245          if (groups_get_activity_groupmode($cm) != SEPARATEGROUPS
 246           or has_capability('moodle/site:accessallgroups', context_module::instance($cm->id))) {
 247              if ($timeout > time() - $mcm->lasttime) {
 248                  $current[] = $cm;
 249              } else {
 250                  $past[] = $cm;
 251              }
 252  
 253              continue;
 254          }
 255  
 256          // Verify groups in separate mode.
 257          if (!$mygroupids = $modinfo->get_groups($cm->groupingid)) {
 258              continue;
 259          }
 260  
 261          // Ok, last post was not for my group - we have to query db to get last message from one of my groups.
 262          // The only minor problem is that the order will not be correct.
 263          $mygroupids = implode(',', $mygroupids);
 264  
 265          if (!$mcm = $DB->get_record_sql("SELECT cm.id, MAX(chm.timestamp) AS lasttime
 266                                             FROM {course_modules} cm
 267                                             JOIN {chat} ch           ON ch.id = cm.instance
 268                                             JOIN {chat_messages_current} chm ON chm.chatid = ch.id
 269                                            WHERE chm.timestamp > ? AND cm.id = ? AND
 270                                                  (chm.groupid IN ($mygroupids) OR chm.groupid = 0)
 271                                         GROUP BY cm.id", array($timestart, $cm->id))) {
 272               continue;
 273          }
 274  
 275          $mcms[$cmid]->lasttime = $mcm->lasttime;
 276          if ($timeout > time() - $mcm->lasttime) {
 277              $current[] = $cm;
 278          } else {
 279              $past[] = $cm;
 280          }
 281      }
 282  
 283      if (!$past and !$current) {
 284          return false;
 285      }
 286  
 287      $strftimerecent = get_string('strftimerecent');
 288  
 289      if ($past) {
 290          echo $OUTPUT->heading(get_string("pastchats", 'chat').':', 3);
 291  
 292          foreach ($past as $cm) {
 293              $link = $CFG->wwwroot.'/mod/chat/view.php?id='.$cm->id;
 294              $date = userdate($mcms[$cm->id]->lasttime, $strftimerecent);
 295              echo '<div class="head"><div class="date">'.$date.'</div></div>';
 296              echo '<div class="info"><a href="'.$link.'">'.format_string($cm->name, true).'</a></div>';
 297          }
 298      }
 299  
 300      if ($current) {
 301          echo $OUTPUT->heading(get_string("currentchats", 'chat').':', 3);
 302  
 303          $oldest = floor((time() - $CFG->chat_old_ping) / 10) * 10;  // Better db caching.
 304  
 305          $timeold    = time() - $CFG->chat_old_ping;
 306          $timeold    = floor($timeold / 10) * 10;  // Better db caching.
 307          $timeoldext = time() - ($CFG->chat_old_ping * 10); // JSless gui_basic needs much longer timeouts.
 308          $timeoldext = floor($timeoldext / 10) * 10;  // Better db caching.
 309  
 310          $params = array('timeold' => $timeold, 'timeoldext' => $timeoldext, 'cmid' => $cm->id);
 311  
 312          $timeout = "AND ((chu.version<>'basic' AND chu.lastping>:timeold) OR (chu.version='basic' AND chu.lastping>:timeoldext))";
 313  
 314          foreach ($current as $cm) {
 315              // Count users first.
 316              $mygroupids = $modinfo->groups[$cm->groupingid];
 317              if (!empty($mygroupids)) {
 318                  list($subquery, $subparams) = $DB->get_in_or_equal($mygroupids, SQL_PARAMS_NAMED, 'gid');
 319                  $params += $subparams;
 320                  $groupselect = "AND (chu.groupid $subquery OR chu.groupid = 0)";
 321              } else {
 322                  $groupselect = "";
 323              }
 324  
 325              $userfields = user_picture::fields('u');
 326              if (!$users = $DB->get_records_sql("SELECT $userfields
 327                                                    FROM {course_modules} cm
 328                                                    JOIN {chat} ch        ON ch.id = cm.instance
 329                                                    JOIN {chat_users} chu ON chu.chatid = ch.id
 330                                                    JOIN {user} u         ON u.id = chu.userid
 331                                                   WHERE cm.id = :cmid $timeout $groupselect
 332                                                GROUP BY $userfields", $params)) {
 333              }
 334  
 335              $link = $CFG->wwwroot.'/mod/chat/view.php?id='.$cm->id;
 336              $date = userdate($mcms[$cm->id]->lasttime, $strftimerecent);
 337  
 338              echo '<div class="head"><div class="date">'.$date.'</div></div>';
 339              echo '<div class="info"><a href="'.$link.'">'.format_string($cm->name, true).'</a></div>';
 340              echo '<div class="userlist">';
 341              if ($users) {
 342                  echo '<ul>';
 343                  foreach ($users as $user) {
 344                      echo '<li>'.fullname($user, $viewfullnames).'</li>';
 345                  }
 346                  echo '</ul>';
 347              }
 348              echo '</div>';
 349          }
 350      }
 351  
 352      return true;
 353  }
 354  
 355  /**
 356   * Function to be run periodically according to the moodle cron
 357   * This function searches for things that need to be done, such
 358   * as sending out mail, toggling flags etc ...
 359   *
 360   * @global object
 361   * @return bool
 362   */
 363  function chat_cron () {
 364      global $DB;
 365  
 366      chat_update_chat_times();
 367  
 368      chat_delete_old_users();
 369  
 370      // Delete old messages with a single SQL query.
 371      $subselect = "SELECT c.keepdays
 372                      FROM {chat} c
 373                     WHERE c.id = {chat_messages}.chatid";
 374  
 375      $sql = "DELETE
 376                FROM {chat_messages}
 377               WHERE ($subselect) > 0 AND timestamp < ( ".time()." -($subselect) * 24 * 3600)";
 378  
 379      $DB->execute($sql);
 380  
 381      $sql = "DELETE
 382                FROM {chat_messages_current}
 383               WHERE timestamp < ( ".time()." - 8 * 3600)";
 384  
 385      $DB->execute($sql);
 386  
 387      return true;
 388  }
 389  
 390  /**
 391   * This standard function will check all instances of this module
 392   * and make sure there are up-to-date events created for each of them.
 393   * If courseid = 0, then every chat event in the site is checked, else
 394   * only chat events belonging to the course specified are checked.
 395   * This function is used, in its new format, by restore_refresh_events()
 396   *
 397   * @global object
 398   * @param int $courseid
 399   * @return bool
 400   */
 401  function chat_refresh_events($courseid = 0) {
 402      global $DB;
 403  
 404      if ($courseid) {
 405          if (! $chats = $DB->get_records("chat", array("course" => $courseid))) {
 406              return true;
 407          }
 408      } else {
 409          if (! $chats = $DB->get_records("chat")) {
 410              return true;
 411          }
 412      }
 413      $moduleid = $DB->get_field('modules', 'id', array('name' => 'chat'));
 414  
 415      foreach ($chats as $chat) {
 416          $cm = get_coursemodule_from_id('chat', $chat->id);
 417          $event = new stdClass();
 418          $event->name        = $chat->name;
 419          $event->description = format_module_intro('chat', $chat, $cm->id);
 420          $event->timestart   = $chat->chattime;
 421  
 422          if ($event->id = $DB->get_field('event', 'id', array('modulename' => 'chat', 'instance' => $chat->id))) {
 423              $calendarevent = calendar_event::load($event->id);
 424              $calendarevent->update($event);
 425          } else {
 426              $event->courseid    = $chat->course;
 427              $event->groupid     = 0;
 428              $event->userid      = 0;
 429              $event->modulename  = 'chat';
 430              $event->instance    = $chat->id;
 431              $event->eventtype   = 'chattime';
 432              $event->timeduration = 0;
 433              $event->visible = $DB->get_field('course_modules', 'visible', array('module' => $moduleid, 'instance' => $chat->id));
 434  
 435              calendar_event::create($event);
 436          }
 437      }
 438      return true;
 439  }
 440  
 441  // Functions that require some SQL.
 442  
 443  /**
 444   * @global object
 445   * @param int $chatid
 446   * @param int $groupid
 447   * @param int $groupingid
 448   * @return array
 449   */
 450  function chat_get_users($chatid, $groupid=0, $groupingid=0) {
 451      global $DB;
 452  
 453      $params = array('chatid' => $chatid, 'groupid' => $groupid, 'groupingid' => $groupingid);
 454  
 455      if ($groupid) {
 456          $groupselect = " AND (c.groupid=:groupid OR c.groupid='0')";
 457      } else {
 458          $groupselect = "";
 459      }
 460  
 461      if (!empty($groupingid)) {
 462          $groupingjoin = "JOIN {groups_members} gm ON u.id = gm.userid
 463                           JOIN {groupings_groups} gg ON gm.groupid = gg.groupid AND gg.groupingid = :groupingid ";
 464  
 465      } else {
 466          $groupingjoin = '';
 467      }
 468  
 469      $ufields = user_picture::fields('u');
 470      return $DB->get_records_sql("SELECT DISTINCT $ufields, c.lastmessageping, c.firstping
 471                                     FROM {chat_users} c
 472                                     JOIN {user} u ON u.id = c.userid $groupingjoin
 473                                    WHERE c.chatid = :chatid $groupselect
 474                                 ORDER BY c.firstping ASC", $params);
 475  }
 476  
 477  /**
 478   * @global object
 479   * @param int $chatid
 480   * @param int $groupid
 481   * @return array
 482   */
 483  function chat_get_latest_message($chatid, $groupid=0) {
 484      global $DB;
 485  
 486      $params = array('chatid' => $chatid, 'groupid' => $groupid);
 487  
 488      if ($groupid) {
 489          $groupselect = "AND (groupid=:groupid OR groupid=0)";
 490      } else {
 491          $groupselect = "";
 492      }
 493  
 494      $sql = "SELECT *
 495          FROM {chat_messages_current} WHERE chatid = :chatid $groupselect
 496          ORDER BY timestamp DESC";
 497  
 498      // Return the lastest one message.
 499      return $DB->get_record_sql($sql, $params, true);
 500  }
 501  
 502  /**
 503   * login if not already logged in
 504   *
 505   * @global object
 506   * @global object
 507   * @param int $chatid
 508   * @param string $version
 509   * @param int $groupid
 510   * @param object $course
 511   * @return bool|int Returns the chat users sid or false
 512   */
 513  function chat_login_user($chatid, $version, $groupid, $course) {
 514      global $USER, $DB;
 515  
 516      if (($version != 'sockets') and $chatuser = $DB->get_record('chat_users', array('chatid' => $chatid,
 517                                                                                      'userid' => $USER->id,
 518                                                                                      'groupid' => $groupid))) {
 519          // This will update logged user information.
 520          $chatuser->version  = $version;
 521          $chatuser->ip       = $USER->lastip;
 522          $chatuser->lastping = time();
 523          $chatuser->lang     = current_language();
 524  
 525          // Sometimes $USER->lastip is not setup properly during login.
 526          // Update with current value if possible or provide a dummy value for the db.
 527          if (empty($chatuser->ip)) {
 528              $chatuser->ip = getremoteaddr();
 529          }
 530  
 531          if (($chatuser->course != $course->id) or ($chatuser->userid != $USER->id)) {
 532              return false;
 533          }
 534          $DB->update_record('chat_users', $chatuser);
 535  
 536      } else {
 537          $chatuser = new stdClass();
 538          $chatuser->chatid   = $chatid;
 539          $chatuser->userid   = $USER->id;
 540          $chatuser->groupid  = $groupid;
 541          $chatuser->version  = $version;
 542          $chatuser->ip       = $USER->lastip;
 543          $chatuser->lastping = $chatuser->firstping = $chatuser->lastmessageping = time();
 544          $chatuser->sid      = random_string(32);
 545          $chatuser->course   = $course->id; // Caching - needed for current_language too.
 546          $chatuser->lang     = current_language(); // Caching - to resource intensive to find out later.
 547  
 548          // Sometimes $USER->lastip is not setup properly during login.
 549          // Update with current value if possible or provide a dummy value for the db.
 550          if (empty($chatuser->ip)) {
 551              $chatuser->ip = getremoteaddr();
 552          }
 553  
 554          $DB->insert_record('chat_users', $chatuser);
 555  
 556          if ($version == 'sockets') {
 557              // Do not send 'enter' message, chatd will do it.
 558          } else {
 559              chat_send_chatmessage($chatuser, 'enter', true);
 560          }
 561      }
 562  
 563      return $chatuser->sid;
 564  }
 565  
 566  /**
 567   * Delete the old and in the way
 568   *
 569   * @global object
 570   * @global object
 571   */
 572  function chat_delete_old_users() {
 573      // Delete the old and in the way.
 574      global $CFG, $DB;
 575  
 576      $timeold = time() - $CFG->chat_old_ping;
 577      $timeoldext = time() - ($CFG->chat_old_ping * 10); // JSless gui_basic needs much longer timeouts.
 578  
 579      $query = "(version<>'basic' AND lastping<?) OR (version='basic' AND lastping<?)";
 580      $params = array($timeold, $timeoldext);
 581  
 582      if ($oldusers = $DB->get_records_select('chat_users', $query, $params) ) {
 583          $DB->delete_records_select('chat_users', $query, $params);
 584          foreach ($oldusers as $olduser) {
 585              chat_send_chatmessage($olduser, 'exit', true);
 586          }
 587      }
 588  }
 589  
 590  /**
 591   * Updates chat records so that the next chat time is correct
 592   *
 593   * @global object
 594   * @param int $chatid
 595   * @return void
 596   */
 597  function chat_update_chat_times($chatid=0) {
 598      // Updates chat records so that the next chat time is correct.
 599      global $DB;
 600  
 601      $timenow = time();
 602  
 603      $params = array('timenow' => $timenow, 'chatid' => $chatid);
 604  
 605      if ($chatid) {
 606          if (!$chats[] = $DB->get_record_select("chat", "id = :chatid AND chattime <= :timenow AND schedule > 0", $params)) {
 607              return;
 608          }
 609      } else {
 610          if (!$chats = $DB->get_records_select("chat", "chattime <= :timenow AND schedule > 0", $params)) {
 611              return;
 612          }
 613      }
 614  
 615      foreach ($chats as $chat) {
 616          switch ($chat->schedule) {
 617              case 1: // Single event - turn off schedule and disable.
 618                  $chat->chattime = 0;
 619                  $chat->schedule = 0;
 620                  break;
 621              case 2: // Repeat daily.
 622                  while ($chat->chattime <= $timenow) {
 623                      $chat->chattime += 24 * 3600;
 624                  }
 625                  break;
 626              case 3: // Repeat weekly.
 627                  while ($chat->chattime <= $timenow) {
 628                      $chat->chattime += 7 * 24 * 3600;
 629                  }
 630                  break;
 631          }
 632          $DB->update_record("chat", $chat);
 633  
 634          $event = new stdClass(); // Update calendar too.
 635  
 636          $cond = "modulename='chat' AND instance = :chatid AND timestart <> :chattime";
 637          $params = array('chattime' => $chat->chattime, 'chatid' => $chatid);
 638  
 639          if ($event->id = $DB->get_field_select('event', 'id', $cond, $params)) {
 640              $event->timestart   = $chat->chattime;
 641              $calendarevent = calendar_event::load($event->id);
 642              $calendarevent->update($event, false);
 643          }
 644      }
 645  }
 646  
 647  /**
 648   * Send a message on the chat.
 649   *
 650   * @param object $chatuser The chat user record.
 651   * @param string $messagetext The message to be sent.
 652   * @param bool $system False for non-system messages, true for system messages.
 653   * @param object $cm The course module object, pass it to save a database query when we trigger the event.
 654   * @return int The message ID.
 655   * @since Moodle 2.6
 656   */
 657  function chat_send_chatmessage($chatuser, $messagetext, $system = false, $cm = null) {
 658      global $DB;
 659  
 660      $message = new stdClass();
 661      $message->chatid    = $chatuser->chatid;
 662      $message->userid    = $chatuser->userid;
 663      $message->groupid   = $chatuser->groupid;
 664      $message->message   = $messagetext;
 665      $message->system    = $system ? 1 : 0;
 666      $message->timestamp = time();
 667  
 668      $messageid = $DB->insert_record('chat_messages', $message);
 669      $DB->insert_record('chat_messages_current', $message);
 670      $message->id = $messageid;
 671  
 672      if (!$system) {
 673  
 674          if (empty($cm)) {
 675              $cm = get_coursemodule_from_instance('chat', $chatuser->chatid, $chatuser->course);
 676          }
 677  
 678          $params = array(
 679              'context' => context_module::instance($cm->id),
 680              'objectid' => $message->id,
 681              // We set relateduserid, because when triggered from the chat daemon, the event userid is null.
 682              'relateduserid' => $chatuser->userid
 683          );
 684          $event = \mod_chat\event\message_sent::create($params);
 685          $event->add_record_snapshot('chat_messages', $message);
 686          $event->trigger();
 687      }
 688  
 689      return $message->id;
 690  }
 691  
 692  /**
 693   * @global object
 694   * @global object
 695   * @param object $message
 696   * @param int $courseid
 697   * @param object $sender
 698   * @param object $currentuser
 699   * @param string $chatlastrow
 700   * @return bool|string Returns HTML or false
 701   */
 702  function chat_format_message_manually($message, $courseid, $sender, $currentuser, $chatlastrow = null) {
 703      global $CFG, $USER, $OUTPUT;
 704  
 705      $output = new stdClass();
 706      $output->beep = false;       // By default.
 707      $output->refreshusers = false; // By default.
 708  
 709      // Use get_user_timezone() to find the correct timezone for displaying this message.
 710      // It's either the current user's timezone or else decided by some Moodle config setting.
 711      // First, "reset" $USER->timezone (which could have been set by a previous call to here)
 712      // because otherwise the value for the previous $currentuser will take precedence over $CFG->timezone.
 713      $USER->timezone = 99;
 714      $tz = get_user_timezone($currentuser->timezone);
 715  
 716      // Before formatting the message time string, set $USER->timezone to the above.
 717      // This will allow dst_offset_on (called by userdate) to work correctly, otherwise the
 718      // message times appear off because DST is not taken into account when it should be.
 719      $USER->timezone = $tz;
 720      $message->strtime = userdate($message->timestamp, get_string('strftimemessage', 'chat'), $tz);
 721  
 722      $message->picture = $OUTPUT->user_picture($sender, array('size' => false, 'courseid' => $courseid, 'link' => false));
 723  
 724      if ($courseid) {
 725          $message->picture = "<a onclick=\"window.open('$CFG->wwwroot/user/view.php?id=$sender->id&amp;course=$courseid')\"".
 726                              " href=\"$CFG->wwwroot/user/view.php?id=$sender->id&amp;course=$courseid\">$message->picture</a>";
 727      }
 728  
 729      // Calculate the row class.
 730      if ($chatlastrow !== null) {
 731          $rowclass = ' class="r'.$chatlastrow.'" ';
 732      } else {
 733          $rowclass = '';
 734      }
 735  
 736      // Start processing the message.
 737  
 738      if (!empty($message->system)) {
 739          // System event.
 740          $output->text = $message->strtime.': '.get_string('message'.$message->message, 'chat', fullname($sender));
 741          $output->html  = '<table class="chat-event"><tr'.$rowclass.'><td class="picture">'.$message->picture.'</td>';
 742          $output->html .= '<td class="text"><span class="event">'.$output->text.'</span></td></tr></table>';
 743          $output->basic = '<tr class="r1">
 744                              <th scope="row" class="cell c1 title"></th>
 745                              <td class="cell c2 text">' . get_string('message'.$message->message, 'chat', fullname($sender)) . '</td>
 746                              <td class="cell c3">' . $message->strtime . '</td>
 747                            </tr>';
 748          if ($message->message == 'exit' or $message->message == 'enter') {
 749              $output->refreshusers = true; // Force user panel refresh ASAP.
 750          }
 751          return $output;
 752      }
 753  
 754      // It's not a system event.
 755      $text = trim($message->message);
 756  
 757      // Parse the text to clean and filter it.
 758      $options = new stdClass();
 759      $options->para = false;
 760      $text = format_text($text, FORMAT_MOODLE, $options, $courseid);
 761  
 762      // And now check for special cases.
 763      $patternto = '#^\s*To\s([^:]+):(.*)#';
 764      $special = false;
 765  
 766      if (substr($text, 0, 5) == 'beep ') {
 767          // It's a beep!
 768          $special = true;
 769          $beepwho = trim(substr($text, 5));
 770  
 771          if ($beepwho == 'all') {   // Everyone.
 772              $outinfobasic = get_string('messagebeepseveryone', 'chat', fullname($sender));
 773              $outinfo = $message->strtime . ': ' . $outinfobasic;
 774              $outmain = '';
 775  
 776              $output->beep = true;  // Eventually this should be set to a filename uploaded by the user.
 777  
 778          } else if ($beepwho == $currentuser->id) {  // Current user.
 779              $outinfobasic = get_string('messagebeepsyou', 'chat', fullname($sender));
 780              $outinfo = $message->strtime . ': ' . $outinfobasic;
 781              $outmain = '';
 782              $output->beep = true;
 783  
 784          } else {  // Something is not caught?
 785              return false;
 786          }
 787      } else if (substr($text, 0, 1) == '/') {     // It's a user command.
 788          $special = true;
 789          $pattern = '#(^\/)(\w+).*#';
 790          preg_match($pattern, $text, $matches);
 791          $command = isset($matches[2]) ? $matches[2] : false;
 792          // Support some IRC commands.
 793          switch ($command) {
 794              case 'me':
 795                  $outinfo = $message->strtime;
 796                  $outmain = '*** <b>'.$sender->firstname.' '.substr($text, 4).'</b>';
 797                  break;
 798              default:
 799                  // Error, we set special back to false to use the classic message output.
 800                  $special = false;
 801                  break;
 802          }
 803      } else if (preg_match($patternto, $text)) {
 804          $special = true;
 805          $matches = array();
 806          preg_match($patternto, $text, $matches);
 807          if (isset($matches[1]) && isset($matches[2])) {
 808              $outinfo = $message->strtime;
 809              $outmain = $sender->firstname.' '.get_string('saidto', 'chat').' <i>'.$matches[1].'</i>: '.$matches[2];
 810          } else {
 811              // Error, we set special back to false to use the classic message output.
 812              $special = false;
 813          }
 814      }
 815  
 816      if (!$special) {
 817          $outinfo = $message->strtime.' '.$sender->firstname;
 818          $outmain = $text;
 819      }
 820  
 821      // Format the message as a small table.
 822  
 823      $output->text  = strip_tags($outinfo.': '.$outmain);
 824  
 825      $output->html  = "<table class=\"chat-message\"><tr$rowclass><td class=\"picture\" valign=\"top\">$message->picture</td>";
 826      $output->html .= "<td class=\"text\"><span class=\"title\">$outinfo</span>";
 827      if ($outmain) {
 828          $output->html .= ": $outmain";
 829          $output->basic = '<tr class="r0">
 830                              <th scope="row" class="cell c1 title">' . $sender->firstname . '</th>
 831                              <td class="cell c2 text">' . $outmain . '</td>
 832                              <td class="cell c3">' . $message->strtime . '</td>
 833                            </tr>';
 834      } else {
 835          $output->basic = '<tr class="r1">
 836                              <th scope="row" class="cell c1 title"></th>
 837                              <td class="cell c2 text">' . $outinfobasic . '</td>
 838                              <td class="cell c3">' . $message->strtime . '</td>
 839                            </tr>';
 840      }
 841      $output->html .= "</td></tr></table>";
 842      return $output;
 843  }
 844  
 845  /**
 846   * Given a message object this function formats it appropriately into text and html then returns the formatted data
 847   * @global object
 848   * @param object $message
 849   * @param int $courseid
 850   * @param object $currentuser
 851   * @param string $chatlastrow
 852   * @return bool|string Returns HTML or false
 853   */
 854  function chat_format_message($message, $courseid, $currentuser, $chatlastrow=null) {
 855      global $DB;
 856  
 857      static $users;     // Cache user lookups.
 858  
 859      if (isset($users[$message->userid])) {
 860          $user = $users[$message->userid];
 861      } else if ($user = $DB->get_record('user', array('id' => $message->userid), user_picture::fields())) {
 862          $users[$message->userid] = $user;
 863      } else {
 864          return null;
 865      }
 866      return chat_format_message_manually($message, $courseid, $user, $currentuser, $chatlastrow);
 867  }
 868  
 869  /**
 870   * @global object
 871   * @param object $message message to be displayed.
 872   * @param mixed $chatuser user chat data
 873   * @param object $currentuser current user for whom the message should be displayed.
 874   * @param int $groupingid course module grouping id
 875   * @param string $theme name of the chat theme.
 876   * @return bool|string Returns HTML or false
 877   */
 878  function chat_format_message_theme ($message, $chatuser, $currentuser, $groupingid, $theme = 'bubble') {
 879      global $CFG, $USER, $OUTPUT, $COURSE, $DB, $PAGE;
 880      require_once($CFG->dirroot.'/mod/chat/locallib.php');
 881  
 882      static $users;     // Cache user lookups.
 883  
 884      $result = new stdClass();
 885  
 886      if (file_exists($CFG->dirroot . '/mod/chat/gui_ajax/theme/'.$theme.'/config.php')) {
 887          include($CFG->dirroot . '/mod/chat/gui_ajax/theme/'.$theme.'/config.php');
 888      }
 889  
 890      if (isset($users[$message->userid])) {
 891          $sender = $users[$message->userid];
 892      } else if ($sender = $DB->get_record('user', array('id' => $message->userid), user_picture::fields())) {
 893          $users[$message->userid] = $sender;
 894      } else {
 895          return null;
 896      }
 897  
 898      $USER->timezone = 99;
 899      $tz = get_user_timezone($currentuser->timezone);
 900      $USER->timezone = $tz;
 901  
 902      if (empty($chatuser->course)) {
 903          $courseid = $COURSE->id;
 904      } else {
 905          $courseid = $chatuser->course;
 906      }
 907  
 908      $message->strtime = userdate($message->timestamp, get_string('strftimemessage', 'chat'), $tz);
 909      $message->picture = $OUTPUT->user_picture($sender, array('courseid' => $courseid));
 910  
 911      $message->picture = "<a target='_blank'".
 912                          " href=\"$CFG->wwwroot/user/view.php?id=$sender->id&amp;course=$courseid\">$message->picture</a>";
 913  
 914      // Start processing the message.
 915      if (!empty($message->system)) {
 916          $result->type = 'system';
 917  
 918          $senderprofile = $CFG->wwwroot.'/user/view.php?id='.$sender->id.'&amp;course='.$courseid;
 919          $event = get_string('message'.$message->message, 'chat', fullname($sender));
 920          $eventmessage = new event_message($senderprofile, fullname($sender), $message->strtime, $event, $theme);
 921  
 922          $output = $PAGE->get_renderer('mod_chat');
 923          $result->html = $output->render($eventmessage);
 924  
 925          return $result;
 926      }
 927  
 928      // It's not a system event.
 929      $text = trim($message->message);
 930  
 931      // Parse the text to clean and filter it.
 932      $options = new stdClass();
 933      $options->para = false;
 934      $text = format_text($text, FORMAT_MOODLE, $options, $courseid);
 935  
 936      // And now check for special cases.
 937      $special = false;
 938      $outtime = $message->strtime;
 939  
 940      // Initialise variables.
 941      $outmain = '';
 942      $patternto = '#^\s*To\s([^:]+):(.*)#';
 943  
 944      if (substr($text, 0, 5) == 'beep ') {
 945          $special = true;
 946          // It's a beep!
 947          $result->type = 'beep';
 948          $beepwho = trim(substr($text, 5));
 949  
 950          if ($beepwho == 'all') {   // Everyone.
 951              $outmain = get_string('messagebeepseveryone', 'chat', fullname($sender));
 952          } else if ($beepwho == $currentuser->id) {  // Current user.
 953              $outmain = get_string('messagebeepsyou', 'chat', fullname($sender));
 954          } else if ($sender->id == $currentuser->id) {  // Something is not caught?
 955              // Allow beep for a active chat user only, else user can beep anyone and get fullname.
 956              if (!empty($chatuser) && is_numeric($beepwho)) {
 957                  $chatusers = chat_get_users($chatuser->chatid, $chatuser->groupid, $groupingid);
 958                  if (array_key_exists($beepwho, $chatusers)) {
 959                      $outmain = get_string('messageyoubeep', 'chat', fullname($chatusers[$beepwho]));
 960                  } else {
 961                      $outmain = get_string('messageyoubeep', 'chat', $beepwho);
 962                  }
 963              } else {
 964                  $outmain = get_string('messageyoubeep', 'chat', $beepwho);
 965              }
 966          }
 967      } else if (substr($text, 0, 1) == '/') {     // It's a user command.
 968          $special = true;
 969          $result->type = 'command';
 970          $pattern = '#(^\/)(\w+).*#';
 971          preg_match($pattern, $text, $matches);
 972          $command = isset($matches[2]) ? $matches[2] : false;
 973          // Support some IRC commands.
 974          switch ($command) {
 975              case 'me':
 976                  $outmain = '*** <b>'.$sender->firstname.' '.substr($text, 4).'</b>';
 977                  break;
 978              default:
 979                  // Error, we set special back to false to use the classic message output.
 980                  $special = false;
 981                  break;
 982          }
 983      } else if (preg_match($patternto, $text)) {
 984          $special = true;
 985          $result->type = 'dialogue';
 986          $matches = array();
 987          preg_match($patternto, $text, $matches);
 988          if (isset($matches[1]) && isset($matches[2])) {
 989              $outmain = $sender->firstname.' <b>'.get_string('saidto', 'chat').'</b> <i>'.$matches[1].'</i>: '.$matches[2];
 990          } else {
 991              // Error, we set special back to false to use the classic message output.
 992              $special = false;
 993          }
 994      }
 995  
 996      if (!$special) {
 997          $outmain = $text;
 998      }
 999  
1000      $result->text = strip_tags($outtime.': '.$outmain);
1001  
1002      $mymessageclass = '';
1003      if ($sender->id == $USER->id) {
1004          $mymessageclass = 'chat-message-mymessage';
1005      }
1006  
1007      $senderprofile = $CFG->wwwroot.'/user/view.php?id='.$sender->id.'&amp;course='.$courseid;
1008      $usermessage = new user_message($senderprofile, fullname($sender), $message->picture,
1009                                      $mymessageclass, $outtime, $outmain, $theme);
1010  
1011      $output = $PAGE->get_renderer('mod_chat');
1012      $result->html = $output->render($usermessage);
1013  
1014      // When user beeps other user, then don't show any timestamp to other users in chat.
1015      if (('' === $outmain) && $special) {
1016          return false;
1017      } else {
1018          return $result;
1019      }
1020  }
1021  
1022  /**
1023   * @global object $DB
1024   * @global object $CFG
1025   * @global object $COURSE
1026   * @global object $OUTPUT
1027   * @param object $users
1028   * @param object $course
1029   * @return array return formatted user list
1030   */
1031  function chat_format_userlist($users, $course) {
1032      global $CFG, $DB, $COURSE, $OUTPUT;
1033      $result = array();
1034      foreach ($users as $user) {
1035          $item = array();
1036          $item['name'] = fullname($user);
1037          $item['url'] = $CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$course->id;
1038          $item['picture'] = $OUTPUT->user_picture($user);
1039          $item['id'] = $user->id;
1040          $result[] = $item;
1041      }
1042      return $result;
1043  }
1044  
1045  /**
1046   * Print json format error
1047   * @param string $level
1048   * @param string $msg
1049   */
1050  function chat_print_error($level, $msg) {
1051      header('Content-Length: ' . ob_get_length() );
1052      $error = new stdClass();
1053      $error->level = $level;
1054      $error->msg   = $msg;
1055      $response['error'] = $error;
1056      echo json_encode($response);
1057      ob_end_flush();
1058      exit;
1059  }
1060  
1061  /**
1062   * List the actions that correspond to a view of this module.
1063   * This is used by the participation report.
1064   *
1065   * Note: This is not used by new logging system. Event with
1066   *       crud = 'r' and edulevel = LEVEL_PARTICIPATING will
1067   *       be considered as view action.
1068   *
1069   * @return array
1070   */
1071  function chat_get_view_actions() {
1072      return array('view', 'view all', 'report');
1073  }
1074  
1075  /**
1076   * List the actions that correspond to a post of this module.
1077   * This is used by the participation report.
1078   *
1079   * Note: This is not used by new logging system. Event with
1080   *       crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING
1081   *       will be considered as post action.
1082   *
1083   * @return array
1084   */
1085  function chat_get_post_actions() {
1086      return array('talk');
1087  }
1088  
1089  /**
1090   * @global object
1091   * @global object
1092   * @param array $courses
1093   * @param array $htmlarray Passed by reference
1094   */
1095  function chat_print_overview($courses, &$htmlarray) {
1096      global $USER, $CFG;
1097  
1098      if (empty($courses) || !is_array($courses) || count($courses) == 0) {
1099          return array();
1100      }
1101  
1102      if (!$chats = get_all_instances_in_courses('chat', $courses)) {
1103          return;
1104      }
1105  
1106      $strchat = get_string('modulename', 'chat');
1107      $strnextsession  = get_string('nextsession', 'chat');
1108  
1109      foreach ($chats as $chat) {
1110          if ($chat->chattime and $chat->schedule) {  // A chat is scheduled.
1111              $str = '<div class="chat overview"><div class="name">'.
1112                     $strchat.': <a '.($chat->visible ? '' : ' class="dimmed"').
1113                     ' href="'.$CFG->wwwroot.'/mod/chat/view.php?id='.$chat->coursemodule.'">'.
1114                     $chat->name.'</a></div>';
1115              $str .= '<div class="info">'.$strnextsession.': '.userdate($chat->chattime).'</div></div>';
1116  
1117              if (empty($htmlarray[$chat->course]['chat'])) {
1118                  $htmlarray[$chat->course]['chat'] = $str;
1119              } else {
1120                  $htmlarray[$chat->course]['chat'] .= $str;
1121              }
1122          }
1123      }
1124  }
1125  
1126  
1127  /**
1128   * Implementation of the function for printing the form elements that control
1129   * whether the course reset functionality affects the chat.
1130   *
1131   * @param object $mform form passed by reference
1132   */
1133  function chat_reset_course_form_definition(&$mform) {
1134      $mform->addElement('header', 'chatheader', get_string('modulenameplural', 'chat'));
1135      $mform->addElement('advcheckbox', 'reset_chat', get_string('removemessages', 'chat'));
1136  }
1137  
1138  /**
1139   * Course reset form defaults.
1140   *
1141   * @param object $course
1142   * @return array
1143   */
1144  function chat_reset_course_form_defaults($course) {
1145      return array('reset_chat' => 1);
1146  }
1147  
1148  /**
1149   * Actual implementation of the reset course functionality, delete all the
1150   * chat messages for course $data->courseid.
1151   *
1152   * @global object
1153   * @global object
1154   * @param object $data the data submitted from the reset course.
1155   * @return array status array
1156   */
1157  function chat_reset_userdata($data) {
1158      global $CFG, $DB;
1159  
1160      $componentstr = get_string('modulenameplural', 'chat');
1161      $status = array();
1162  
1163      if (!empty($data->reset_chat)) {
1164          $chatessql = "SELECT ch.id
1165                          FROM {chat} ch
1166                         WHERE ch.course=?";
1167          $params = array($data->courseid);
1168  
1169          $DB->delete_records_select('chat_messages', "chatid IN ($chatessql)", $params);
1170          $DB->delete_records_select('chat_messages_current', "chatid IN ($chatessql)", $params);
1171          $DB->delete_records_select('chat_users', "chatid IN ($chatessql)", $params);
1172          $status[] = array('component' => $componentstr, 'item' => get_string('removemessages', 'chat'), 'error' => false);
1173      }
1174  
1175      // Updating dates - shift may be negative too.
1176      if ($data->timeshift) {
1177          shift_course_mod_dates('chat', array('chattime'), $data->timeshift, $data->courseid);
1178          $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => false);
1179      }
1180  
1181      return $status;
1182  }
1183  
1184  /**
1185   * Returns all other caps used in module
1186   *
1187   * @return array
1188   */
1189  function chat_get_extra_capabilities() {
1190      return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames');
1191  }
1192  
1193  
1194  /**
1195   * @param string $feature FEATURE_xx constant for requested feature
1196   * @return mixed True if module supports feature, null if doesn't know
1197   */
1198  function chat_supports($feature) {
1199      switch($feature) {
1200          case FEATURE_GROUPS:
1201              return true;
1202          case FEATURE_GROUPINGS:
1203              return true;
1204          case FEATURE_MOD_INTRO:
1205              return true;
1206          case FEATURE_BACKUP_MOODLE2:
1207              return true;
1208          case FEATURE_COMPLETION_TRACKS_VIEWS:
1209              return true;
1210          case FEATURE_GRADE_HAS_GRADE:
1211              return false;
1212          case FEATURE_GRADE_OUTCOMES:
1213              return true;
1214          case FEATURE_SHOW_DESCRIPTION:
1215              return true;
1216          default:
1217              return null;
1218      }
1219  }
1220  
1221  function chat_extend_navigation($navigation, $course, $module, $cm) {
1222      global $CFG;
1223  
1224      $currentgroup = groups_get_activity_group($cm, true);
1225  
1226      if (has_capability('mod/chat:chat', context_module::instance($cm->id))) {
1227          $strenterchat    = get_string('enterchat', 'chat');
1228  
1229          $target = $CFG->wwwroot.'/mod/chat/';
1230          $params = array('id' => $cm->instance);
1231  
1232          if ($currentgroup) {
1233              $params['groupid'] = $currentgroup;
1234          }
1235  
1236          $links = array();
1237  
1238          $url = new moodle_url($target.'gui_'.$CFG->chat_method.'/index.php', $params);
1239          $action = new popup_action('click', $url, 'chat'.$course->id.$cm->instance.$currentgroup,
1240                                     array('height' => 500, 'width' => 700));
1241          $links[] = new action_link($url, $strenterchat, $action);
1242  
1243          $url = new moodle_url($target.'gui_basic/index.php', $params);
1244          $action = new popup_action('click', $url, 'chat'.$course->id.$cm->instance.$currentgroup,
1245                                     array('height' => 500, 'width' => 700));
1246          $links[] = new action_link($url, get_string('noframesjs', 'message'), $action);
1247  
1248          foreach ($links as $link) {
1249              $navigation->add($link->text, $link, navigation_node::TYPE_SETTING, null , null, new pix_icon('i/group' , ''));
1250          }
1251      }
1252  
1253      $chatusers = chat_get_users($cm->instance, $currentgroup, $cm->groupingid);
1254      if (is_array($chatusers) && count($chatusers) > 0) {
1255          $users = $navigation->add(get_string('currentusers', 'chat'));
1256          foreach ($chatusers as $chatuser) {
1257              $userlink = new moodle_url('/user/view.php', array('id' => $chatuser->id, 'course' => $course->id));
1258              $users->add(fullname($chatuser).' '.format_time(time() - $chatuser->lastmessageping),
1259                          $userlink, navigation_node::TYPE_USER, null, null, new pix_icon('i/user', ''));
1260          }
1261      }
1262  }
1263  
1264  /**
1265   * Adds module specific settings to the settings block
1266   *
1267   * @param settings_navigation $settings The settings navigation object
1268   * @param navigation_node $chatnode The node to add module settings to
1269   */
1270  function chat_extend_settings_navigation(settings_navigation $settings, navigation_node $chatnode) {
1271      global $DB, $PAGE, $USER;
1272      $chat = $DB->get_record("chat", array("id" => $PAGE->cm->instance));
1273  
1274      if ($chat->chattime && $chat->schedule) {
1275          $nextsessionnode = $chatnode->add(get_string('nextsession', 'chat').
1276                                            ': '.userdate($chat->chattime).
1277                                            ' ('.usertimezone($USER->timezone));
1278          $nextsessionnode->add_class('note');
1279      }
1280  
1281      $currentgroup = groups_get_activity_group($PAGE->cm, true);
1282      if ($currentgroup) {
1283          $groupselect = " AND groupid = '$currentgroup'";
1284      } else {
1285          $groupselect = '';
1286      }
1287  
1288      if ($chat->studentlogs || has_capability('mod/chat:readlog', $PAGE->cm->context)) {
1289          if ($DB->get_records_select('chat_messages', "chatid = ? $groupselect", array($chat->id))) {
1290              $chatnode->add(get_string('viewreport', 'chat'), new moodle_url('/mod/chat/report.php', array('id' => $PAGE->cm->id)));
1291          }
1292      }
1293  }
1294  
1295  /**
1296   * user logout event handler
1297   *
1298   * @param \core\event\user_loggedout $event The event.
1299   * @return void
1300   */
1301  function chat_user_logout(\core\event\user_loggedout $event) {
1302      global $DB;
1303      $DB->delete_records('chat_users', array('userid' => $event->objectid));
1304  }
1305  
1306  /**
1307   * Return a list of page types
1308   * @param string $pagetype current page type
1309   * @param stdClass $parentcontext Block's parent context
1310   * @param stdClass $currentcontext Current context of block
1311   */
1312  function chat_page_type_list($pagetype, $parentcontext, $currentcontext) {
1313      $modulepagetype = array('mod-chat-*' => get_string('page-mod-chat-x', 'chat'));
1314      return $modulepagetype;
1315  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1