/**
  * group_member_added
  *
  * @param \core\event\group_member_added $event Event object containing useful data
  * @return bool true if success
  */
 public static function group_member_added(\core\event\group_member_added $event)
 {
     global $DB;
     $sql = "SELECT DISTINCT grpt.id, grpt.ifmemberadded, grpt.course,\n                                agrp.id agrpid\n                FROM {grouptool} grpt\n                JOIN {grouptool_agrps} agrp ON agrp.grouptoolid = grpt.id\n                WHERE (agrp.groupid = ?) AND (agrp.active = ?) AND (grpt.ifmemberadded = ?)";
     $params = array($event->objectid, 1, GROUPTOOL_FOLLOW);
     if (!($grouptools = $DB->get_records_sql($sql, $params))) {
         return true;
     }
     $agrpssql = "SELECT agrps.grouptoolid AS grouptoolid, agrps.id AS id FROM {grouptool_agrps} agrps\n        WHERE agrps.groupid = :groupid";
     $agrp = $DB->get_records_sql($agrpssql, array('groupid' => $event->objectid));
     $regsql = "SELECT reg.agrpid AS id\n                     FROM {grouptool_agrps} agrps\n               INNER JOIN {grouptool_registered} reg ON agrps.id = reg.agrpid\n                    WHERE reg.modified_by >= 0 AND agrps.groupid = :groupid AND reg.userid = :userid";
     $regs = $DB->get_records_sql($regsql, array('groupid' => $event->objectid, 'userid' => $event->relateduserid));
     $markssql = "SELECT reg.agrpid, reg.id, reg.userid, reg.timestamp\n                       FROM {grouptool_agrps} agrps\n                 INNER JOIN {grouptool_registered} reg ON agrps.id = reg.agrpid\n                      WHERE reg.modified_by = -1 AND agrps.groupid = :groupid AND reg.userid = :userid";
     $marks = $DB->get_records_sql($markssql, array('groupid' => $event->objectid, 'userid' => $event->relateduserid));
     foreach ($grouptools as $grouptool) {
         if (!key_exists($grouptool->agrpid, $regs)) {
             $reg = new stdClass();
             $reg->agrpid = $agrp[$grouptool->id]->id;
             $reg->userid = $event->relateduserid;
             $reg->timestamp = time();
             $reg->modified_by = 0;
             // There's no way we can get the teachers id!
             if (!$DB->record_exists('grouptool_registered', array('agrpid' => $reg->agrpid, 'userid' => $reg->userid))) {
                 $reg->id = $DB->insert_record('grouptool_registered', $reg);
                 $reg->groupid = $event->objectid;
                 $cm = get_coursemodule_from_instance('grouptool', $grouptool->id, $grouptool->course, false, MUST_EXIST);
                 \mod_grouptool\event\registration_created::create_via_eventhandler($cm, $reg)->trigger();
             }
         } else {
             if (key_exists($grouptool->agrpid, $marks)) {
                 $record = $marks[$grouptool->agrpid];
                 $record->modified_by = 0;
                 $DB->update_record('grouptool_registered', $record);
                 $reg->groupid = $event->objectid;
                 $cm = get_coursemodule_from_instance('grouptool', $grouptool->id, $grouptool->course, false, MUST_EXIST);
                 \mod_grouptool\event\registration_created::create_via_eventhandler($cm, $record)->trigger();
             }
         }
     }
     return true;
 }
 /**
  * registers/queues a user in a certain active-group
  *
  * @param int $agrpid active-group-id to register/queue user to
  * @param int $userid user to register/queue
  * @param bool $previewonly optional don't act, just return a preview
  * @param bool $movefromqueue optional whether or not the move is from the queue
  * @return array ($error, $message)
  */
 private function register_in_agrp($agrpid = 0, $userid = 0, $previewonly = false, $movefromqueue = false)
 {
     global $USER, $PAGE, $DB, $SESSION;
     $grouptool = $this->grouptool;
     if (empty($agrpid)) {
         print_error('missing_param', null, $PAGE->url);
     }
     if (empty($userid)) {
         $userid = $USER->id;
         require_capability('mod/grouptool:register', $this->context);
     }
     $regopen = $this->grouptool->allow_reg && ($this->grouptool->timedue == 0 || time() < $this->grouptool->timedue) && $this->grouptool->timeavailable < time();
     if (!$regopen && !has_capability('mod/grouptool:register_students', $this->context)) {
         return array(true, get_string('reg_not_open', 'grouptool'));
     }
     $message = new stdClass();
     if ($userid != $USER->id) {
         $userdata = $DB->get_record('user', array('id' => $userid));
         $message->username = fullname($userdata);
     }
     $groupdata = $this->get_active_groups(true, true, $agrpid);
     if (count($groupdata) == 1) {
         $groupdata = current($groupdata);
         $message->groupname = $groupdata->name;
         // We have to filter only active groups to ensure no problems counting userregs and -queues.
         $agrpids = $DB->get_fieldset_select('grouptool_agrps', 'id', "grouptoolid = ? AND active = 1", array($grouptool->id));
         list($agrpsql, $params) = $DB->get_in_or_equal($agrpids);
         array_unshift($params, $userid);
         $userregs = $DB->count_records_select('grouptool_registered', "modified_by >= 0 AND userid = ? AND agrpid " . $agrpsql, $params);
         $userqueues = $DB->count_records_select('grouptool_queued', "userid = ? AND agrpid " . $agrpsql, $params);
         $max = $grouptool->allow_multiple ? $grouptool->choose_max : 1;
         $min = $grouptool->allow_multiple ? $grouptool->choose_min : 0;
         if (!empty($groupdata->registered) && $this->get_rank_in_queue($groupdata->registered, $userid) != false) {
             // We're sorry, but user's already registered in this group!
             if ($userid != $USER->id) {
                 return array(true, get_string('already_registered', 'grouptool', $message));
             } else {
                 return array(true, get_string('you_are_already_registered', 'grouptool', $message));
             }
         }
         if (empty($movefromqueue) && !empty($groupdata->queued) && $this->get_rank_in_queue($groupdata->queued, $userid) != false) {
             // We're sorry, but user's already queued in this group!
             if ($userid != $USER->id) {
                 return array(true, get_string('already_queued', 'grouptool', $message));
             } else {
                 return array(true, get_string('you_are_aleady_queued', 'grouptol', $message));
             }
         }
         if ($this->grpmarked($groupdata->agrpid, $userid)) {
             // Allready marked for registration?
             if ($userid != $USER->id) {
                 return array(true, get_string('already_marked', 'grouptool', $message));
             } else {
                 return array(true, get_string('you_are_already_marked', 'grouptool', $message));
             }
         }
         if (empty($movefromqueue) && ($userqueues == 1 && $userregs == $max - 1) || $userqueues + $userregs == 1 && $max == 1) {
             // Groupchange!
             if (empty($grouptool->allow_unreg)) {
                 return array(true, get_string('unreg_not_allowed', 'grouptool'));
             }
             if ($previewonly) {
                 if (!$this->grouptool->use_size || count($groupdata->registered) < $groupdata->grpsize || $this->grouptool->use_queue && $userqueues < $this->grouptool->queues_max) {
                     return array(-1, get_string('change_group_to', 'grouptool', $message));
                 } else {
                     if (!$this->grouptool->use_queue) {
                         // Group is full!
                         if ($userid != $USER->id) {
                             return array(1, get_string('reg_in_full_group', 'grouptool', $message));
                         } else {
                             return array(1, get_string('reg_you_in_full_group', 'grouptool', $message));
                         }
                     } else {
                         if ($userqueues >= $this->grouptool->queues_max) {
                             if ($userid != $USER->id) {
                                 return array(1, get_string('too_many_queue_places', 'grouptool'));
                             } else {
                                 return array(1, get_string('you_have_too_many_queue_places', 'grouptool'));
                             }
                         }
                     }
                 }
             } else {
                 if (!$this->grouptool->use_size || count($groupdata->registered) < $groupdata->grpsize || $this->grouptool->use_queue && $userqueues - 1 < $this->grouptool->queues_max) {
                     $record = new stdClass();
                     $record->agrpid = $agrpid;
                     $record->userid = $userid;
                     $record->timestamp = time();
                     $record->modified_by = $USER->id;
                     if ($userqueues == 1) {
                         // Delete his queue!
                         $queues = $DB->get_records_sql("SELECT queued.*, agrp.groupid\n                                                          FROM {grouptool_queued} queued\n                                                          JOIN {grouptool_agrps} agrp ON agrp.id = queued.agrpid\n                                                          WHERE userid = ? AND agrpid " . $agrpsql, $params);
                         $DB->delete_records_select('grouptool_queued', "userid = ? AND agrpid " . $agrpsql, $params);
                         foreach ($queues as $cur) {
                             // Trigger the event!
                             \mod_grouptool\event\queue_entry_deleted::create_direct($this->cm, $cur);
                         }
                     } else {
                         if ($userregs == 1) {
                             $oldgrp = $DB->get_field_sql("SELECT agrp.groupid\n                                                        FROM {grouptool_registered} reg\n                                                        JOIN {grouptool_agrps} agrp ON agrp.id = reg.agrpid\n                                                       WHERE reg.userid = ? AND reg.agrpid " . $agrpsql, $params, MUST_EXIST);
                             $regs = $DB->get_records_select('grouptool_registered', "userid = ? AND agrpid " . $agrpsql, $params);
                             $DB->delete_records_select('grouptool_registered', "userid = ? AND agrpid " . $agrpsql, $params);
                             if (!empty($oldgrp) && !empty($this->grouptool->immediate_reg)) {
                                 groups_remove_member($oldgrp, $userid);
                             }
                             foreach ($regs as $cur) {
                                 // Trigger the event!
                                 $cur->groupid = $oldgrp;
                                 \mod_grouptool\event\registration_deleted::create_direct($this->cm, $cur);
                             }
                         }
                     }
                     if (!$this->grouptool->use_size || count($groupdata->registered) < $groupdata->grpsize) {
                         $record->id = $DB->insert_record('grouptool_registered', $record);
                         if ($this->grouptool->immediate_reg) {
                             groups_add_member($groupdata->id, $userid);
                         }
                         // Trigger the event!
                         $record->groupid = $groupdata->id;
                         \mod_grouptool\event\registration_created::create_direct($this->cm, $record)->trigger();
                     } else {
                         if ($this->grouptool->use_queue && $userqueues - 1 < $this->grouptool->queues_max) {
                             $record->id = $DB->insert_record('grouptool_queued', $record);
                             // Trigger the Event!
                             $record->groupid = $groupdata->id;
                             \mod_grouptool\event\queue_entry_created::create_direct($this->cm, $record)->trigger();
                         } else {
                             if (!$this->grouptool->use_queue) {
                                 // Group is full!
                                 if ($userid != $USER->id) {
                                     return array(1, get_string('reg_in_full_group', 'grouptool', $message));
                                 } else {
                                     return array(1, get_string('reg_you_in_full_group', 'grouptool', $message));
                                 }
                             } else {
                                 if ($userqueues - 1 >= $this->grouptool->queues_max) {
                                     if ($userid != $USER->id) {
                                         return array(1, get_string('too_many_queue_places', 'grouptool'));
                                     } else {
                                         return array(1, get_string('you_have_too_many_queue_places', 'grouptool'));
                                     }
                                 }
                             }
                         }
                     }
                     if ($userid != $USER->id) {
                         return array(-1, get_string('change_group_to_success', 'grouptool', $message));
                     } else {
                         return array(-1, get_string('you_change_group_to_success', 'grouptool', $message));
                     }
                 }
             }
         }
         if (empty($movefromqueue) && $userregs + $userqueues >= $max || !empty($movefromqueue) && $userregs + $userqueues - 1 >= $max) {
             return array(1, get_string('too_many_regs', 'grouptool'));
         }
         // Get users marks!
         $marks = $this->count_user_marks($userid);
         if ($grouptool->use_size) {
             if (count($groupdata->registered) < $groupdata->grpsize) {
                 // Register!
                 if ($previewonly) {
                     if ($userid != $USER->id) {
                         return array(false, get_string('register_in_group', 'grouptool', $message));
                     } else {
                         return array(false, get_string('register_you_in_group', 'grouptool', $message));
                     }
                 } else {
                     if (empty($movefromqueue) && $this->grouptool->allow_multiple && $this->grouptool->choose_min > $marks + $userregs + $userqueues + 1) {
                         // Cache data until enough registrations are made!
                         $record = new stdClass();
                         $record->agrpid = $agrpid;
                         $record->userid = $userid;
                         $record->timestamp = time();
                         $record->modified_by = -1;
                         $DB->insert_record('grouptool_registered', $record);
                         if ($userid != $USER->id) {
                             return array(false, get_string('place_allocated_in_group_success', 'grouptool', $message));
                         } else {
                             return array(false, get_string('your_place_allocated_in_group_success', 'grouptool', $message));
                         }
                     } else {
                         if ($this->grouptool->allow_multiple) {
                             // Enough registrations have been made, save them!
                             if (!empty($marks)) {
                                 $usermarks = $this->get_user_marks($userid);
                                 foreach ($usermarks as $cur) {
                                     if ($cur->type == 'reg') {
                                         unset($cur->type);
                                         $cur->modified_by = $USER->id;
                                         $DB->update_record('grouptool_registered', $cur);
                                         if ($this->grouptool->immediate_reg) {
                                             groups_add_member($cur->groupid, $cur->userid);
                                         }
                                     } else {
                                         unset($cur->type);
                                         $DB->insert_record('grouptool_queued', $cur);
                                     }
                                 }
                                 $this->delete_user_marks($userid);
                             }
                         }
                         $record = new stdClass();
                         $record->agrpid = $agrpid;
                         $record->userid = $userid;
                         $record->timestamp = time();
                         $record->modified_by = $USER->id;
                         $record->id = $DB->insert_record('grouptool_registered', $record);
                         if ($this->grouptool->immediate_reg) {
                             groups_add_member($groupdata->id, $userid);
                         }
                         $record->groupid = $groupdata->id;
                         \mod_grouptool\event\registration_created::create_direct($this->cm, $record)->trigger();
                         $regcnt = $this->get_user_reg_count(0, $userid);
                         if ($this->grouptool->allow_multiple && $regcnt >= $this->grouptool->choose_max || !$this->grouptool->allow_multiple) {
                             $agrps = $this->get_active_groups(false, false, 0, 0, 0, false);
                             if (count($agrps) > 0) {
                                 $agrpids = array_keys($agrps);
                                 list($sql, $params) = $DB->get_in_or_equal($agrpids);
                                 $queues = $DB->get_records_sql('SELECT queued.*, agrp.groupid
                                                               FROM {grouptool_queued} queued
                                                               JOIN {grouptool_agrps} agrp ON agrp.id = queued.agrpid
                                                              WHERE  userid = ? AND agrpid ' . $sql, array_merge(array($userid), $params));
                                 $DB->delete_records_select('grouptool_queued', ' userid = ? AND agrpid ' . $sql, array_merge(array($userid), $params));
                                 foreach ($queues as $cur) {
                                     // Trigger the event!
                                     \mod_grouptool\event\queue_entry_deleted::create_limit_violation($this->cm, $cur)->trigger();
                                 }
                             }
                         }
                         if ($userid != $USER->id) {
                             return array(false, get_string('register_in_group_success', 'grouptool', $message));
                         } else {
                             return array(false, get_string('register_you_in_group_success', 'grouptool', $message));
                         }
                     }
                 }
             } else {
                 if ($grouptool->use_queue) {
                     // Try to queue!
                     if ($userqueues >= $grouptool->queues_max) {
                         if ($userid != $USER->id) {
                             return array(1, get_string('too_many_queue_places', 'grouptool'));
                         } else {
                             return array(1, get_string('you_have_too_many_queue_places', 'grouptool'));
                         }
                     }
                     $marks = $this->count_user_marks($userid);
                     if ($previewonly) {
                         if ($userid != $USER->id) {
                             return array(-1, get_string('queue_in_group', 'grouptool', $message));
                         } else {
                             return array(-1, get_string('queue_you_in_group', 'grouptool', $message));
                         }
                     } else {
                         if ($this->grouptool->allow_multiple && $this->grouptool->choose_min > $marks + $userregs + $userqueues + 1) {
                             // Cache data until enough registrations are made!
                             // TODO events for place allocation?
                             $record = new stdClass();
                             $record->agrpid = $agrpid;
                             $record->grp_id = $groupdata->id;
                             $record->userid = $userid;
                             $record->timestamp = time();
                             $record->modified_by = -1;
                             $DB->insert_record('grouptool_registered', $record);
                             if ($userid != $USER->id) {
                                 return array(false, get_string('place_allocated_in_group_success', 'grouptool', $message));
                             } else {
                                 return array(false, get_string('your_place_allocated_in_group_success', 'grouptool', $message));
                             }
                         } else {
                             if ($this->grouptool->allow_multiple) {
                                 if (!empty($marks)) {
                                     // Enough registrations have been made, save them!
                                     $usermarks = $this->get_user_marks($userid);
                                     foreach ($usermarks as $cur) {
                                         if ($cur->type == 'reg') {
                                             unset($cur->type);
                                             if ($this->grouptool->immediate_reg) {
                                                 groups_add_member($cur->groupid, $cur->userid);
                                             }
                                             // Premature triggering because of unsetting $cur->groupid afterwards.
                                             \mod_grouptool\event\registration_created::create_direct($this->cm, $cur)->trigger();
                                             unset($cur->groupid);
                                             $cur->modified_by = $USER->id;
                                             $DB->update_record('grouptool_registered', $cur);
                                         } else {
                                             unset($cur->type);
                                             // Trigger the event!
                                             \mod_grouptool\event\queue_entry_created::create_direct($this->cm, $cur)->trigger();
                                             unset($cur->groupid);
                                             $cur->id = $DB->insert_record('grouptool_queued', $cur);
                                         }
                                     }
                                     // TODO: Event for marks deletion?
                                     $this->delete_user_marks($userid);
                                 }
                             }
                             $record = new stdClass();
                             $record->agrpid = $agrpid;
                             $record->userid = $userid;
                             $record->timestamp = time();
                             $record->id = $DB->insert_record('grouptool_queued', $record);
                             // Trigger the event!
                             $record->groupid = $groupdata->id;
                             \mod_grouptool\event\queue_entry_created::create_direct($this->cm, $record)->trigger();
                             if ($userid != $USER->id) {
                                 return array(-1, get_string('queue_in_group_success', 'grouptool', $message));
                             } else {
                                 return array(-1, get_string('queue_you_in_group_success', 'grouptool', $message));
                             }
                         }
                     }
                 } else {
                     // Group is full!
                     if ($userid != $USER->id) {
                         return array(1, get_string('reg_in_full_group', 'grouptool', $message));
                     } else {
                         return array(1, get_string('reg_you_in_full_group', 'grouptool', $message));
                     }
                 }
             }
         } else {
             // Register him!
             if ($previewonly) {
                 if ($userid != $USER->id) {
                     return array(false, get_string('register_in_group', 'grouptool', $message));
                 } else {
                     return array(false, get_string('register_you_in_group', 'grouptool', $message));
                 }
             } else {
                 if ($this->grouptool->allow_multiple && $this->grouptool->choose_min > $marks + $userregs + $userqueues + 1) {
                     // TODO Place allocation event!
                     // Cache data until enough registrations are made!
                     $record = new stdClass();
                     $record->agrpid = $agrpid;
                     $record->grp_id = $groupdata->id;
                     $record->userid = $userid;
                     $record->timestamp = time();
                     $record->modified_by = -1;
                     $DB->insert_record('grouptool_registered', $record);
                     if ($userid != $USER->id) {
                         return array(false, get_string('place_allocated_in_group_success', 'grouptool', $message));
                     } else {
                         return array(false, get_string('your_place_allocated_in_group_success', 'grouptool', $message));
                     }
                 } else {
                     if ($this->grouptool->allow_multiple) {
                         // Enough registrations have been made, save them!
                         if ($marks) {
                             $usermarks = $this->get_user_marks($userid);
                             foreach ($usermarks as $cur) {
                                 if ($cur->type == 'reg') {
                                     unset($cur->type);
                                     $cur->modified_by = $USER->id;
                                     if ($this->grouptool->immediate_reg) {
                                         groups_add_member($cur->groupid, $cur->userid);
                                     }
                                     // Premature triggering because of unsetting $cur->groupid afterwards!
                                     \mod_grouptool\event\registration_created::create_direct($this->cm, $cur)->trigger();
                                     unset($cur->groupid);
                                     $DB->update_record('grouptool_registered', $cur);
                                 } else {
                                     unset($cur->type);
                                     $DB->insert_record('grouptool_queued', $cur);
                                     // Trigger the event!
                                     \mod_grouptool\event\queue_entry_created::create_direct($this->cm, $cur)->trigger();
                                 }
                             }
                             // TODO event for deletion of users marks?
                             $this->delete_user_marks($userid);
                         }
                     }
                     $record = new stdClass();
                     $record->agrpid = $agrpid;
                     $record->userid = $userid;
                     $record->timestamp = time();
                     $record->modified_by = $USER->id;
                     $record->id = $DB->insert_record('grouptool_registered', $record);
                     if ($this->grouptool->immediate_reg) {
                         groups_add_member($groupdata->id, $userid);
                     }
                     // Trigger the event!
                     $record->groupid = $groupdata->id;
                     \mod_grouptool\event\registration_created::create_direct($this->cm, $record)->trigger();
                     $regcnt = $this->get_user_reg_count(0, $userid);
                     if ($this->grouptool->allow_multiple && $regcnt >= $this->grouptool->choose_max || !$this->grouptool->allow_multiple) {
                         $agrps = $this->get_active_groups(false, false, 0, 0, 0, false);
                         if (count($agrps) > 0) {
                             $agrpids = array_keys($agrps);
                             list($sql, $params) = $DB->get_in_or_equal($agrpids);
                             $queues = $DB->get_records_sql('SELECT queued.*, agrp.groupid
                                                           FROM {grouptool_queued} queued
                                                           JOIN {grouptool_agrps} agrp ON queued.agrpid = agrp.id
                                                          WHERE queued.userid = ? AND queued.agrpid ' . $sql, array_merge(array($userid), $params));
                             $DB->delete_records_select('grouptool_queued', ' userid = ? AND agrpid ' . $sql, array_merge(array($userid), $params));
                             foreach ($queues as $cur) {
                                 // Trigger the event!
                                 \mod_grouptool\event\queue_entry_deleted::create_limit_violation($this->cm, $cur)->trigger();
                             }
                         }
                     }
                     if ($userid != $USER->id) {
                         return array(false, get_string('register_in_group_success', 'grouptool', $message));
                     } else {
                         return array(false, get_string('register_you_in_group_success', 'grouptool', $message));
                     }
                 }
             }
         }
     } else {
         return array(true, get_string('error_getting_data', 'grouptool'));
     }
 }