function msgQueryLocations($aRequest) { global $gSite; global $gGame; loadGameSettings(); $Out = Out::getInstance(); if (validRaidlead()) { $Connector = Connector::getInstance(); // Locations $ListLocations = $Connector->prepare('Select * FROM `' . RP_TABLE_PREFIX . 'Location` WHERE Game = :Game ORDER BY Name'); $ListLocations->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); $Locations = array(); $ListLocations->loop(function ($Data) use(&$Locations) { $LocationData = array('id' => $Data['LocationId'], 'name' => $Data['Name'], 'image' => $Data['Image']); array_push($Locations, $LocationData); }); $Out->pushValue('location', $Locations); // Images $Images = @scandir('../themes/icons/' . $gSite['Iconset'] . '/raidsmall'); $ImageList = array(); if ($Images != null) { foreach ($Images as $Image) { if (strripos($Image, '.png') !== false) { array_push($ImageList, $Image); } } } $Out->pushValue('locationimage', $ImageList); } else { $Out->pushError(L('AccessDenied')); } }
function msgQueryNewRaidData($aRequest) { $Out = Out::getInstance(); if (validRaidlead()) { $Connector = Connector::getInstance(); // Settings $NewRaidSettings = $Connector->prepare('SELECT Name, IntValue, TextValue FROM `' . RP_TABLE_PREFIX . 'Setting`'); $IntOfInterest = array('RaidSize', 'RaidStartHour', 'RaidStartMinute', 'RaidEndHour', 'RaidEndMinute', 'StartOfWeek'); $TextOfInterest = array('RaidMode'); $Settings = array(); $NewRaidSettings->loop(function ($Data) use(&$Settings, $IntOfInterest, $TextOfInterest) { $KeyValue = array('name' => $Data['Name'], 'value' => null); if (in_array($Data['Name'], $IntOfInterest)) { $KeyValue['value'] = $Data['IntValue']; } elseif (in_array($Data['Name'], $TextOfInterest)) { $KeyValue['value'] = $Data['TextValue']; } array_push($Settings, $KeyValue); }); $Out->pushValue('setting', $Settings); // Locations msgQueryLocations($aRequest); } else { $Out->pushError(L('AccessDenied')); } }
function msgQueryUser($aRequest) { $Out = Out::getInstance(); if (registeredUser()) { $CurrentUser = UserProxy::getInstance(); $CharacterIds = array(); $CharacterGames = array(); $CharacterNames = array(); $CharacterClasses = array(); $CharacterRoles1 = array(); $CharacterRoles2 = array(); $Settings = array(); foreach ($CurrentUser->Characters as $Character) { array_push($CharacterIds, $Character->CharacterId); array_push($CharacterGames, $Character->Game); array_push($CharacterNames, $Character->Name); array_push($CharacterClasses, explode(':', $Character->ClassName)); array_push($CharacterRoles1, $Character->Role1); array_push($CharacterRoles2, $Character->Role2); } $Out->pushValue('registeredUser', true); $Out->pushValue('id', $CurrentUser->UserId); $Out->pushValue('name', $CurrentUser->UserName); $Out->pushValue('characterIds', $CharacterIds); $Out->pushValue('characterGames', $CharacterGames); $Out->pushValue('characterNames', $CharacterNames); $Out->pushValue('characterClass', $CharacterClasses); $Out->pushValue('role1', $CharacterRoles1); $Out->pushValue('role2', $CharacterRoles2); $Out->pushValue('validUser', validUser()); $Out->pushValue('isRaidlead', validRaidlead()); $Out->pushValue('isAdmin', validAdmin()); $Out->pushValue('settings', $CurrentUser->Settings); $Session = Session::get(); if (isset($Session['Calendar'])) { $Out->pushValue('calendar', $Session['Calendar']); } else { $Out->pushValue('calendar', null); } } else { $Out->pushValue('registeredUser', false); } }
function msgRaidDelete($aRequest) { if (validRaidlead()) { $Connector = Connector::getInstance(); // Call plugins $RaidId = intval($aRequest['id']); PluginRegistry::ForEachPlugin(function ($PluginInstance) use($RaidId) { $PluginInstance->onRaidRemove($RaidId); }); do { // Delete raid $Connector->beginTransaction(); $DeleteRaidQuery = $Connector->prepare('DELETE FROM `' . RP_TABLE_PREFIX . 'Raid` WHERE RaidId = :RaidId LIMIT 1'); $DeleteRaidQuery->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); if (!$DeleteRaidQuery->execute()) { $Connector->rollBack(); return; // ### return, error ### } // Delete attendance $DeleteAttendanceQuery = $Connector->prepare('DELETE FROM `' . RP_TABLE_PREFIX . 'Attendance` WHERE RaidId = :RaidId'); $DeleteAttendanceQuery->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); if (!$DeleteAttendanceQuery->execute()) { $Connector->rollBack(); return; // ### return, error ### } } while (!$Connector->commit()); $Session = Session::get(); $ShowMonth = isset($Session['Calendar']) && isset($Session['Calendar']['month']) ? $Session['Calendar']['month'] : $aRequest['month']; $ShowYear = isset($Session['Calendar']) && isset($Session['Calendar']['year']) ? $Session['Calendar']['year'] : $aRequest['year']; msgQueryCalendar(prepareCalRequest($ShowMonth, $ShowYear)); } else { $Out = Out::getInstance(); $Out->pushError(L('AccessDenied')); } }
function msgRaidCreate($aRequest) { if (validRaidlead()) { global $gGame; loadGameSettings(); $Connector = Connector::getInstance(); $LocationId = $aRequest['locationId']; // Create location if ($LocationId == 0) { $NewLocationQuery = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Location`' . '(Game, Name, Image) VALUES (:Game, :Name, :Image)'); $NewLocationQuery->bindValue(':Name', requestToXML($aRequest['locationName'], ENT_COMPAT, 'UTF-8'), PDO::PARAM_STR); $NewLocationQuery->bindValue(':Image', $aRequest['raidImage'], PDO::PARAM_STR); $NewLocationQuery->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); if (!$NewLocationQuery->execute()) { return; } // ### return, location could not be created ### $LocationId = $Connector->lastInsertId(); } // Create raid if ($LocationId != 0) { // First raid time calculation $StartHour = intval($aRequest['startHour']); $StartMinute = intval($aRequest['startMinute']); $StartDay = intval($aRequest['startDay']); $StartMonth = intval($aRequest['startMonth']); $StartYear = intval($aRequest['startYear']); $EndHour = intval($aRequest['endHour']); $EndMinute = intval($aRequest['endMinute']); $EndDay = intval($aRequest['endDay']); $EndMonth = intval($aRequest['endMonth']); $EndYear = intval($aRequest['endYear']); // Get users on vacation $UserSettingsQuery = $Connector->prepare('SELECT UserId, Name, IntValue, TextValue FROM `' . RP_TABLE_PREFIX . 'UserSetting` ' . 'WHERE Name = "VacationStart" OR Name = "VacationEnd" OR Name = "VacationMessage" ORDER BY UserId'); $VactionUsers = array(); $UserSettingsQuery->loop(function ($Settings) use(&$VactionUsers) { if (!isset($VactionUsers[$Settings['UserId']])) { $VactionUsers[$Settings['UserId']] = array('Message' => ''); } switch ($Settings['Name']) { case 'VacationStart': $VactionUsers[$Settings['UserId']]['Start'] = $Settings['IntValue']; break; case 'VacationEnd': $VactionUsers[$Settings['UserId']]['End'] = $Settings['IntValue']; break; case 'VacationMessage': $VactionUsers[$Settings['UserId']]['Message'] = $Settings['TextValue']; break; default: break; } }); // Prepare posting raids to forum $PostTargets = array(); PluginRegistry::ForEachBinding(function ($PluginInstance) use(&$PostTargets) { if ($PluginInstance->isActive() && $PluginInstance->postRequested()) { array_push($PostTargets, $PluginInstance); } }); $LocationData = null; if (count($PostTargets) > 0) { loadSiteSettings(); $LocationQuery = $Connector->prepare('SELECT * FROM `' . RP_TABLE_PREFIX . 'Location` WHERE LocationId = :LocationId LIMIT 1'); $LocationQuery->bindValue(':LocationId', $LocationId, PDO::PARAM_INT); $LocationData = $LocationQuery->fetchFirst(); } // Get opt-out list or auto attend users $AutoAttendUsers = array(); if (strtolower($aRequest['mode'] == 'optout')) { $UserQuery = $Connector->prepare('SELECT UserId, CharacterId, Class, Role1 FROM `' . RP_TABLE_PREFIX . 'User` ' . 'LEFT JOIN `' . RP_TABLE_PREFIX . 'Character` USING(UserId) ' . 'WHERE Mainchar="true" AND Game=:Game'); $UserQuery->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); $UserQuery->loop(function ($aUser) use(&$AutoAttendUsers) { array_push($AutoAttendUsers, $aUser); }); } else { $UserQuery = $Connector->prepare('SELECT UserId, CharacterId, Class, Role1 FROM `' . RP_TABLE_PREFIX . 'UserSetting` ' . 'LEFT JOIN `' . RP_TABLE_PREFIX . 'Character` USING(UserId) ' . 'WHERE `' . RP_TABLE_PREFIX . 'UserSetting`.Name="AutoAttend" AND Mainchar="true" AND Game=:Game'); $UserQuery->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); $UserQuery->loop(function ($aUser) use(&$AutoAttendUsers) { array_push($AutoAttendUsers, $aUser); }); } // Create raids(s) $Repeat = max(0, intval($aRequest['repeat'])) + 1; // repeat at least once $GroupInfo = $gGame['Groups'][$aRequest['locationSize']]; $SlotRoles = implode(':', array_keys($GroupInfo)); $SlotCount = implode(':', $GroupInfo); $RaidMode = $aRequest['mode'] == 'optout' ? 'manual' : $aRequest['mode']; for ($rc = 0; $rc < $Repeat; ++$rc) { $NewRaidQuery = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Raid` ' . '(LocationId, Size, Start, End, Mode, Description, SlotRoles, SlotCount ) ' . 'VALUES (:LocationId, :Size, FROM_UNIXTIME(:Start), FROM_UNIXTIME(:End), :Mode, :Description, ' . ':SlotRoles, :SlotCount)'); $StartDateTime = mktime($StartHour, $StartMinute, 0, $StartMonth, $StartDay, $StartYear); $EndDateTime = mktime($EndHour, $EndMinute, 0, $EndMonth, $EndDay, $EndYear); // Convert to UTC $StartDateTime += $aRequest['startOffset'] * 60; $EndDateTime += $aRequest['endOffset'] * 60; $NewRaidQuery->bindValue(':LocationId', $LocationId, PDO::PARAM_INT); $NewRaidQuery->bindValue(':Size', $aRequest['locationSize'], PDO::PARAM_INT); $NewRaidQuery->bindValue(':Start', $StartDateTime, PDO::PARAM_INT); $NewRaidQuery->bindValue(':End', $EndDateTime, PDO::PARAM_INT); $NewRaidQuery->bindValue(':Mode', $RaidMode, PDO::PARAM_STR); $NewRaidQuery->bindValue(':Description', requestToXML($aRequest['description'], ENT_COMPAT, 'UTF-8'), PDO::PARAM_STR); $NewRaidQuery->bindValue(':SlotRoles', $SlotRoles, PDO::PARAM_STR); $NewRaidQuery->bindValue(':SlotCount', $SlotCount, PDO::PARAM_STR); $NewRaidQuery->execute(); $RaidId = $Connector->lastInsertId(); // Attend players when mode is optout if (count($AutoAttendUsers > 0)) { $Status = $RaidMode == 'all' || $RaidMode == 'attend' ? 'ok' : 'available'; foreach ($AutoAttendUsers as $User) { $UserId = intval($User['UserId']); if (isset($VactionUsers[$UserId]) && ($StartDateTime >= $VactionUsers[$UserId]['Start'] && $StartDateTime <= $VactionUsers[$UserId]['End'])) { continue; // ### continue, user is on vacation ### } $Classes = explode(':', $User['Class']); $ClassId = $Classes[0]; $RoleId = $gGame['ClassMode'] == 'multi' ? $gGame['Classes'][$ClassId]['roles'][0] : $User['Role1']; $AttendQuery = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Attendance` (UserId, RaidId, CharacterId, Class, Role, Status) ' . 'VALUES (:UserId, :RaidId, :CharId, :Class, :Role, :Status)'); $AttendQuery->bindValue(':UserId', $UserId, PDO::PARAM_INT); $AttendQuery->bindValue(':RaidId', $RaidId, PDO::PARAM_INT); $AttendQuery->bindValue(':CharId', $User['CharacterId'], PDO::PARAM_INT); $AttendQuery->bindValue(':Class', $ClassId, PDO::PARAM_STR); $AttendQuery->bindValue(':Role', $RoleId, PDO::PARAM_STR); $AttendQuery->bindValue(':Status', $Status, PDO::PARAM_STR); $AttendQuery->execute(); } if ($RaidMode == 'attend') { removeOverbooked($RaidId, $SlotRoles, $SlotCount); } } // Set vacation attendances foreach ($VactionUsers as $UserId => $Settings) { if ($StartDateTime >= $Settings['Start'] && $StartDateTime <= $Settings['End']) { $AbsentQuery = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Attendance` (UserId, RaidId, Status, Comment) ' . 'VALUES (:UserId, :RaidId, "unavailable", :Message)'); $AbsentQuery->bindValue(':UserId', $UserId, PDO::PARAM_INT); $AbsentQuery->bindValue(':RaidId', $RaidId, PDO::PARAM_INT); $AbsentQuery->bindValue(':Message', $Settings['Message'], PDO::PARAM_STR); $AbsentQuery->execute(); } } // Post raids to forum if (count($PostTargets) > 0) { $RaidQuery = $Connector->prepare('SELECT * FROM `' . RP_TABLE_PREFIX . 'Raid` WHERE RaidId=:RaidId LIMIT 1'); $RaidQuery->bindValue(':RaidId', $RaidId, PDO::PARAM_INT); $RaidData = $RaidQuery->fetchFirst(); $MessageData = Binding::generateMessage($RaidData, $LocationData); try { foreach ($PostTargets as $PluginInstance) { $PluginInstance->post($MessageData['subject'], $MessageData['message']); } } catch (PDOException $Exception) { Out::getInstance()->pushError($Exception->getMessage()); } } // Call plugins PluginRegistry::ForEachPlugin(function ($PluginInstance) use($RaidId) { $PluginInstance->onRaidCreate($RaidId); }); // Increment start/end switch ($aRequest['stride']) { case 'day': ++$StartDay; ++$EndDay; break; case 'week': $StartDay += 7; $EndDay += 7; break; case 'month': ++$StartMonth; ++$EndMonth; break; default: case 'once': $rc = $Repeat; // Force done break; } } // reload calendar $Session = Session::get(); $ShowMonth = isset($Session['Calendar']) && isset($Session['Calendar']['month']) ? $Session['Calendar']['month'] : $aRequest['month']; $ShowYear = isset($Session['Calendar']) && isset($Session['Calendar']['year']) ? $Session['Calendar']['year'] : $aRequest['year']; msgQueryCalendar(prepareCalRequest($ShowMonth, $ShowYear)); } } else { $Out = Out::getInstance(); $Out->pushError(L('AccessDenied')); } }
function msgRaidupdate($aRequest) { if (validRaidlead()) { global $gGame; loadGameSettings(); $Connector = Connector::getInstance(); // The whole update is packed into one transaction. // The transaction will be rolled back upon error so no half-updated // data is stored in the database. This requires the database to // support transactions. do { $Connector->beginTransaction(); $LocationId = $aRequest['locationId']; // Insert new location if necessary if ($LocationId == 0) { $NewLocationQuery = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Location`' . '(Name, Game, Image) VALUES (:Name, :Game, :Image)'); $NewLocationQuery->bindValue(':Name', requestToXML($aRequest['locationName'], ENT_COMPAT, 'UTF-8'), PDO::PARAM_STR); $NewLocationQuery->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); $NewLocationQuery->bindValue(':Image', $aRequest['raidImage'], PDO::PARAM_STR); if (!$NewLocationQuery->execute()) { $Connector->rollBack(); return; // ### return, error ### } $LocationId = $Connector->lastInsertId(); } // Update raid $UpdateRaidQuery = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Raid` SET ' . 'LocationId = :LocationId, Size = :Size, ' . 'Stage = :Stage, ' . 'Start = FROM_UNIXTIME(:Start), End = FROM_UNIXTIME(:End), ' . 'Description = :Description, ' . 'Mode = :Mode, ' . 'SlotRoles = :SlotRoles, SlotCount = :SlotCount ' . 'WHERE RaidId = :RaidId'); $StartDateTime = mktime(intval($aRequest['startHour']), intval($aRequest['startMinute']), 0, intval($aRequest['startMonth']), intval($aRequest['startDay']), intval($aRequest['startYear'])); $EndDateTime = mktime(intval($aRequest['endHour']), intval($aRequest['endMinute']), 0, intval($aRequest['endMonth']), intval($aRequest['endDay']), intval($aRequest['endYear'])); // Convert to UTC $StartDateTime += $aRequest['startOffset'] * 60; $EndDateTime += $aRequest['endOffset'] * 60; $UpdateRaidQuery->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); $UpdateRaidQuery->bindValue(':LocationId', $LocationId, PDO::PARAM_INT); $UpdateRaidQuery->bindValue(':Stage', $aRequest['stage'], PDO::PARAM_STR); $UpdateRaidQuery->bindValue(':Size', $aRequest['locationSize'], PDO::PARAM_INT); $UpdateRaidQuery->bindValue(':Start', $StartDateTime, PDO::PARAM_INT); $UpdateRaidQuery->bindValue(':End', $EndDateTime, PDO::PARAM_INT); $UpdateRaidQuery->bindValue(':Mode', $aRequest['mode'], PDO::PARAM_STR); $UpdateRaidQuery->bindValue(':Description', requestToXML($aRequest['description'], ENT_COMPAT, 'UTF-8'), PDO::PARAM_STR); $UpdateRaidQuery->bindValue(':SlotRoles', implode(':', $aRequest['slotRoles']), PDO::PARAM_STR); $UpdateRaidQuery->bindValue(':SlotCount', implode(':', $aRequest['slotCount']), PDO::PARAM_STR); if (!$UpdateRaidQuery->execute()) { $Connector->rollBack(); return; // ### return, error ### } // Remove the attends marked for delete. // Only random player attends can be removed. $NumRemoved = isset($aRequest['removed']) ? count($aRequest['removed']) : 0; for ($i = 0; $i < $NumRemoved; ++$i) { $RemoveSlot = $Connector->prepare('DELETE FROM `' . RP_TABLE_PREFIX . 'Attendance` ' . 'WHERE AttendanceId = :AttendanceId AND CharacterId = 0 AND UserId = 0'); $RemoveSlot->bindValue(':AttendanceId', $aRequest['removed'][$i], PDO::PARAM_INT); if (!$RemoveSlot->execute()) { $Connector->rollBack(); return; // ### return, error ### } } // Now iterate over all role lists and update the players in it // Random player will be converted to 'real' player, i.e. they loose their // negative pseudo-id. foreach ($gGame['Roles'] as $Role) { if (isset($aRequest['role_' . $Role['id']])) { $NumAttends = 0; $AttendsForRole = $aRequest['role_' . $Role['id']]; // Attendances are passed in the form [id,status,id,status, … ] // So we iterate with a stride of 2 for ($AttendIdx = 0; $AttendIdx < count($AttendsForRole);) { $UpdateSlot = null; // $Id = UserId when not having an attendance record // $Id = AttendanceId for all others $Id = intVal($AttendsForRole[$AttendIdx++]); $Status = $AttendsForRole[$AttendIdx++]; $OldTimestamp = $AttendsForRole[$AttendIdx++]; $Flags = intVal($AttendsForRole[$AttendIdx++]); if ($Status == 'undecided') { continue; } // ### continue, skip undecided ### // Get extra parameters if (($Flags & PlayerFlagCharId) != 0) { $CharId = intval($AttendsForRole[$AttendIdx++]); $ActiveClass = $AttendsForRole[$AttendIdx++]; } if (($Flags & PlayerFlagUserId) != 0) { $UserId = intVal($AttendsForRole[$AttendIdx++]); } if (($Flags & PlayerFlagName) != 0) { $Name = $AttendsForRole[$AttendIdx++]; } if (($Flags & PlayerFlagComment) != 0) { $Comment = $AttendsForRole[$AttendIdx++]; } if (($Flags & PlayerFlagNew) != 0) { // New entries if (($Flags & PlayerFlagComment) != 0 && ($Flags & PlayerFlagUserId) != 0 && ($Flags & PlayerFlagCharId) != 0) { // Undecided set-up $UpdateSlot = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Attendance` ' . '( CharacterId, Class, UserId, RaidId, Status, Role, Comment ) ' . 'VALUES ( :CharId, :Class, :UserId, :RaidId, :Status, :Role, :Comment )'); $UpdateSlot->bindValue(':CharId', $CharId, PDO::PARAM_INT); $UpdateSlot->bindValue(':Class', $ActiveClass, PDO::PARAM_STR); $UpdateSlot->bindValue(':UserId', $UserId, PDO::PARAM_INT); $UpdateSlot->bindValue(':Comment', $Comment, PDO::PARAM_STR); } else { if (($Flags & PlayerFlagComment) != 0 && ($Flags & PlayerFlagCharId) != 0) { // Undecied absent $UpdateSlot = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Attendance` ' . '( CharacterId, Class, UserId, RaidId, Status, Role, Comment ) ' . 'VALUES ( :CharId, :Class, :UserId, :RaidId, :Status, :Role, :Comment )'); $UpdateSlot->bindValue(':CharId', $CharId, PDO::PARAM_INT); $UpdateSlot->bindValue(':Class', $ActiveClass, PDO::PARAM_STR); $UpdateSlot->bindValue(':UserId', $UserId, PDO::PARAM_INT); $UpdateSlot->bindValue(':Comment', $Comment, PDO::PARAM_STR); } else { if (($Flags & PlayerFlagName) != 0) { // Random player. Set name. $UpdateSlot = $Connector->prepare('INSERT INTO `' . RP_TABLE_PREFIX . 'Attendance` ' . '( CharacterId, UserId, RaidId, Status, Class, Role, Comment ) ' . 'VALUES ( 0, 0, :RaidId, :Status, :Class, :Role, :Name )'); $UpdateSlot->bindValue(':Name', $Name, PDO::PARAM_STR); $UpdateSlot->bindValue(':Class', '___', PDO::PARAM_STR); } else { $Out = Out::getInstance(); $Out->pushError('Invalid user flags'); } } } } else { // Update existing entries if (($Flags & PlayerFlagComment) != 0 && ($Flags & PlayerFlagCharId) != 0) { // Used when setting up an absent player $UpdateSlot = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Attendance` SET ' . 'Status = :Status, CharacterId = :CharId, Class = :Class, Comment = :Comment, Role = :Role, LastUpdate = FROM_UNIXTIME(:TimestampNow) ' . 'WHERE RaidId = :RaidId AND LastUpdate = FROM_UNIXTIME(:LastUpdate) AND AttendanceId = :AttendanceId LIMIT 1'); $UpdateSlot->bindValue(':Comment', $Comment, PDO::PARAM_STR); $UpdateSlot->bindValue(':CharId', $CharId, PDO::PARAM_INT); $UpdateSlot->bindValue(':Class', $ActiveClass, PDO::PARAM_STR); } else { if (($Flags & PlayerFlagCharId) != 0) { // Used when changing a character $UpdateSlot = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Attendance` SET ' . 'Status = :Status, CharacterId = :CharId, Class = :Class, Role = :Role, LastUpdate = FROM_UNIXTIME(:TimestampNow) ' . 'WHERE RaidId = :RaidId AND LastUpdate = FROM_UNIXTIME(:LastUpdate) AND AttendanceId = :AttendanceId LIMIT 1'); $UpdateSlot->bindValue(':CharId', $CharId, PDO::PARAM_INT); $UpdateSlot->bindValue(':Class', $ActiveClass, PDO::PARAM_STR); } else { if (($Flags & PlayerFlagComment) != 0) { // Used when setting a player to absent $UpdateSlot = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Attendance` SET ' . 'Status = :Status, Comment = :Comment, Role = :Role, LastUpdate = FROM_UNIXTIME(:TimestampNow) ' . 'WHERE RaidId = :RaidId AND LastUpdate = FROM_UNIXTIME(:LastUpdate) AND AttendanceId = :AttendanceId LIMIT 1'); $UpdateSlot->bindValue(':Comment', $Comment, PDO::PARAM_STR); } else { if (($Flags & PlayerFlagName) != 0) { // Used when changing the name of a random player $UpdateSlot = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Attendance` SET ' . 'Status = :Status, Role = :Role, Comment = :Name, LastUpdate = FROM_UNIXTIME(:TimestampNow) ' . 'WHERE RaidId = :RaidId AND LastUpdate = FROM_UNIXTIME(:LastUpdate) AND AttendanceId = :AttendanceId LIMIT 1'); $UpdateSlot->bindValue(':Name', $Name, PDO::PARAM_STR); } else { // Existing player, update $UpdateSlot = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Attendance` SET ' . 'Status = :Status, Role = :Role, LastUpdate = FROM_UNIXTIME(:TimestampNow) ' . 'WHERE RaidId = :RaidId AND LastUpdate = FROM_UNIXTIME(:LastUpdate) AND AttendanceId = :AttendanceId LIMIT 1'); } } } } $UpdateSlot->bindValue(':AttendanceId', $Id, PDO::PARAM_INT); $UpdateSlot->bindValue(':LastUpdate', $OldTimestamp, PDO::PARAM_INT); $UpdateSlot->bindValue(':TimestampNow', time(), PDO::PARAM_INT); } $UpdateSlot->bindValue(':Status', $Status, PDO::PARAM_STR); $UpdateSlot->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); $UpdateSlot->bindValue(':Role', $Role['id'], PDO::PARAM_STR); if (!$UpdateSlot->execute()) { $Connector->rollBack(); return; // ### return, error ### } } } } // Assure mode constraints if ($aRequest['mode'] == 'all') { // Mode 'all' means all players are either 'ok' or 'unavailable' $AttendenceQuery = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Attendance` SET Status = "ok" ' . 'WHERE RaidId = :RaidId AND Status = "available"'); $AttendenceQuery->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); if (!$AttendenceQuery->execute()) { $Connector->rollBack(); return; // ### return, error ### } } else { if ($aRequest['mode'] != 'overbook') { // Assure there not more 'ok' players than allowed by slot size $SlotSizes = array_combine($aRequest['slotRoles'], $aRequest['slotCount']); foreach ($aRequest['slotRoles'] as $RoleId) { if ($SlotSizes[$RoleId] > 0) { $AttendenceQuery = $Connector->prepare('SELECT AttendanceId ' . 'FROM `' . RP_TABLE_PREFIX . 'Attendance` ' . 'WHERE RaidId = :RaidId AND Status = "ok" AND Role = :RoleId ' . 'ORDER BY AttendanceId DESC LIMIT :MaxCount'); $AttendenceQuery->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); $AttendenceQuery->bindValue(':RoleId', $RoleId, PDO::PARAM_STR); $AttendenceQuery->bindValue(':MaxCount', $SlotSizes[$RoleId], PDO::PARAM_INT); $LastAttend = $AttendenceQuery->fetchFirst(); if ($AttendenceQuery->getAffectedRows() == $SlotSizes[$RoleId]) { // Fix the overhead $FixQuery = $Connector->prepare('UPDATE `' . RP_TABLE_PREFIX . 'Attendance` SET Status = "available" ' . 'WHERE RaidId = :RaidId AND Status = "ok" AND Role = :RoleId ' . 'AND AttendanceId > :FirstId'); $FixQuery->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); $FixQuery->bindValue(':RoleId', $RoleId, PDO::PARAM_STR); $FixQuery->bindValue(':FirstId', $LastAttend['AttendanceId'], PDO::PARAM_INT); if (!$FixQuery->execute()) { $Connector->rollBack(); return; // ### return, error ### } } } } } } } while (!$Connector->commit()); // Call plugins $RaidId = intval($aRequest['id']); PluginRegistry::ForEachPlugin(function ($PluginInstance) use($RaidId) { $PluginInstance->onRaidModify($RaidId); }); // reload detailed view msgRaidDetail($aRequest); } else { $Out = Out::getInstance(); $Out->pushError(L('AccessDenied')); } }
function msgRaidDetail($aRequest) { if (validUser()) { global $gGame; loadGameSettings(); $Out = Out::getInstance(); $Connector = Connector::getInstance(); $Out->pushValue('show', $aRequest['showPanel']); $ListRaidQuery = $Connector->prepare('SELECT ' . RP_TABLE_PREFIX . 'Raid.*, ' . RP_TABLE_PREFIX . 'Location.Name AS LocationName, ' . RP_TABLE_PREFIX . 'Location.Image AS LocationImage, ' . RP_TABLE_PREFIX . 'Attendance.AttendanceId, ' . RP_TABLE_PREFIX . 'Attendance.UserId, ' . RP_TABLE_PREFIX . 'Attendance.CharacterId, ' . RP_TABLE_PREFIX . 'Attendance.Status, ' . RP_TABLE_PREFIX . 'Attendance.Role, ' . RP_TABLE_PREFIX . 'Attendance.Class AS ActiveClass, ' . RP_TABLE_PREFIX . 'Attendance.Comment, ' . 'UNIX_TIMESTAMP(' . RP_TABLE_PREFIX . 'Attendance.LastUpdate) AS LastUpdate, ' . RP_TABLE_PREFIX . 'Character.Name, ' . RP_TABLE_PREFIX . 'Character.Class, ' . RP_TABLE_PREFIX . 'Character.Mainchar, ' . RP_TABLE_PREFIX . 'Character.Role1, ' . RP_TABLE_PREFIX . 'Character.Role2, ' . 'UNIX_TIMESTAMP(' . RP_TABLE_PREFIX . 'Raid.Start) AS StartUTC, ' . 'UNIX_TIMESTAMP(' . RP_TABLE_PREFIX . 'Raid.End) AS EndUTC ' . 'FROM `' . RP_TABLE_PREFIX . 'Raid` ' . 'LEFT JOIN `' . RP_TABLE_PREFIX . 'Location` USING(LocationId) ' . 'LEFT JOIN `' . RP_TABLE_PREFIX . 'Attendance` USING(RaidId) ' . 'LEFT JOIN `' . RP_TABLE_PREFIX . 'Character` USING(CharacterId) ' . 'WHERE RaidId = :RaidId ORDER BY `' . RP_TABLE_PREFIX . 'Attendance`.AttendanceId'); $ListRaidQuery->bindValue(':RaidId', $aRequest['id'], PDO::PARAM_INT); $Data = $ListRaidQuery->fetchFirstOfLoop(); if ($Data != null) { $Participants = array(); $StartDate = getdate($Data['StartUTC']); $EndDate = getdate($Data['EndUTC']); $EndTimestamp = $Data['EndUTC']; $Slots = array_combine(explode(':', $Data['SlotRoles']), explode(':', $Data['SlotCount'])); $Out->pushValue('raidId', $Data['RaidId']); $Out->pushValue('locationid', $Data['LocationId']); $Out->pushValue('locationname', $Data['LocationName']); $Out->pushValue('stage', $Data['Stage']); $Out->pushValue('mode', $Data['Mode']); $Out->pushValue('image', $Data['LocationImage']); $Out->pushValue('size', $Data['Size']); $Out->pushValue('startDate', intval($StartDate['year']) . '-' . leadingZero10($StartDate['mon']) . '-' . leadingZero10($StartDate['mday'])); $Out->pushValue('start', leadingZero10($StartDate['hours']) . ':' . leadingZero10($StartDate['minutes'])); $Out->pushValue('endDate', intval($EndDate['year']) . '-' . leadingZero10($EndDate['mon']) . '-' . leadingZero10($EndDate['mday'])); $Out->pushValue('end', leadingZero10($EndDate['hours']) . ':' . leadingZero10($EndDate['minutes'])); $Out->pushValue('description', $Data['Description']); $Out->pushValue('slots', $Slots); $Attendees = array(); $MaxAttendanceId = 1; $NumAttended = 0; if ($Data['UserId'] != NULL) { $ListRaidQuery->loop(function ($Data) use(&$gGame, &$Connector, &$MaxAttendanceId, &$Participants, &$Attendees, &$NumAttended) { // Track max attendance id to give undecided players (without a comment) a distinct one. $MaxAttendanceId = Max($MaxAttendanceId, $Data['AttendanceId']); if ($Data['UserId'] != 0) { array_push($Participants, intval($Data['UserId'])); } if ($Data['CharacterId'] == 0) { // CharacterId is 0 on random players or players that are absent if ($Data['UserId'] != 0) { // Fetch the mainchar of the registered player and display this // character as 'absent' $CharQuery = $Connector->prepare('SELECT ' . RP_TABLE_PREFIX . 'Character.*, ' . RP_TABLE_PREFIX . 'User.Login AS UserName ' . 'FROM `' . RP_TABLE_PREFIX . 'Character` LEFT JOIN `' . RP_TABLE_PREFIX . 'User` USING(UserId) ' . 'WHERE UserId = :UserId AND Game = :Game ' . 'ORDER BY Mainchar, CharacterId ASC'); $CharQuery->bindValue(':UserId', $Data['UserId'], PDO::PARAM_INT); $CharQuery->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); $CharData = $CharQuery->fetchFirstOfLoop(); if ($CharData != null && $CharData['CharacterId'] != null) { $Classes = explode(':', $CharData['Class']); $AttendeeData = array('id' => $Data['AttendanceId'], 'hasId' => true, 'userId' => $Data['UserId'], 'timestamp' => $Data['LastUpdate'], 'charid' => $CharData['CharacterId'], 'name' => $CharData['Name'], 'mainchar' => $CharData['Mainchar'], 'classname' => $Classes, 'activeclass' => $Classes[0], 'role' => $CharData['Role1'], 'role1' => $CharData['Role1'], 'role2' => $CharData['Role2'], 'status' => $Data['Status'], 'comment' => $Data['Comment'], 'character' => array()); $CharQuery->loop(function ($CharData) use(&$AttendeeData) { $Character = array('id' => $CharData['CharacterId'], 'name' => $CharData['Name'], 'mainchar' => $CharData['Mainchar'], 'classname' => explode(':', $CharData['Class']), 'role1' => $CharData['Role1'], 'role2' => $CharData['Role2']); array_push($AttendeeData['character'], $Character); }); array_push($Attendees, $AttendeeData); } } else { // CharacterId and UserId set to 0 means 'random player' $AttendeeData = array('id' => $Data['AttendanceId'], 'hasId' => true, 'userId' => 0, 'timestamp' => $Data['LastUpdate'], 'charid' => 0, 'name' => $Data['Comment'], 'mainchar' => false, 'classname' => array('___'), 'activeclass' => '___', 'role' => $Data['Role'], 'role1' => $Data['Role'], 'role2' => $Data['Role'], 'status' => $Data['Status'], 'comment' => '', 'character' => array()); array_push($Attendees, $AttendeeData); ++$NumAttended; } } else { // CharacterId is set $AttendeeData = array('id' => $Data['AttendanceId'], 'hasId' => true, 'userId' => $Data['UserId'], 'timestamp' => $Data['LastUpdate'], 'charid' => $Data['CharacterId'], 'name' => $Data['Name'], 'mainchar' => $Data['Mainchar'], 'classname' => explode(':', $Data['Class']), 'activeclass' => $Data['ActiveClass'], 'role' => $Data['Role'], 'role1' => $Data['Role1'], 'role2' => $Data['Role2'], 'status' => $Data['Status'], 'comment' => $Data['Comment'], 'character' => array()); $CharQuery = $Connector->prepare('SELECT ' . RP_TABLE_PREFIX . 'Character.*, ' . RP_TABLE_PREFIX . 'User.Login AS UserName ' . 'FROM `' . RP_TABLE_PREFIX . 'User` LEFT JOIN `' . RP_TABLE_PREFIX . 'Character` USING(UserId) ' . 'WHERE UserId = :UserId AND Game = :Game ' . 'ORDER BY Mainchar, CharacterId ASC'); $CharQuery->bindValue(':UserId', $Data['UserId'], PDO::PARAM_INT); $CharQuery->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); $CharQuery->loop(function ($CharData) use(&$AttendeeData) { $Character = array('id' => $CharData['CharacterId'], 'name' => $CharData['Name'], 'mainchar' => $CharData['Mainchar'], 'classname' => explode(':', $CharData['Class']), 'role1' => $CharData['Role1'], 'role2' => $CharData['Role2']); array_push($AttendeeData['character'], $Character); }); if ($Data['Status'] == 'ok' || $Data['Status'] == 'available') { ++$NumAttended; } array_push($Attendees, $AttendeeData); } }); } // Fetch all registered and unblocked users $AllUsersQuery = $Connector->prepare('SELECT ' . RP_TABLE_PREFIX . 'User.UserId ' . 'FROM `' . RP_TABLE_PREFIX . 'User` ' . 'WHERE `Group` != "none"'); $AllUsersQuery->loop(function ($User) use(&$gGame, &$Connector, &$MaxAttendanceId, &$EndTimestamp, &$Participants, &$Attendees) { if (!in_array(intval($User['UserId']), $Participants)) { // Users that are not registered for this raid are undecided // Fetch their character data, maincharacter first $CharQuery = $Connector->prepare('SELECT ' . RP_TABLE_PREFIX . 'Character.*, ' . RP_TABLE_PREFIX . 'User.Login AS UserName ' . 'FROM `' . RP_TABLE_PREFIX . 'Character` LEFT JOIN `' . RP_TABLE_PREFIX . 'User` USING(UserId) ' . 'WHERE UserId = :UserId AND Created < FROM_UNIXTIME(:RaidEnd) AND Game = :Game ' . 'ORDER BY Mainchar, CharacterId ASC'); $CharQuery->bindValue(':UserId', $User['UserId'], PDO::PARAM_INT); $CharQuery->bindValue(':RaidEnd', $EndTimestamp, PDO::PARAM_INT); $CharQuery->bindValue(':Game', $gGame['GameId'], PDO::PARAM_STR); $UserData = $CharQuery->fetchFirstOfLoop(); if ($UserData != null) { // Absent user have no attendance Id, so we need to generate one // that is not in use (for this raid). ++$MaxAttendanceId; $Classes = explode(':', $UserData['Class']); $AttendeeData = array('id' => $MaxAttendanceId, 'hasId' => false, 'userId' => $UserData['UserId'], 'timestamp' => time(), 'charid' => $UserData['CharacterId'], 'name' => $UserData['Name'], 'mainchar' => $UserData['Mainchar'], 'classname' => $Classes, 'activeclass' => $Classes[0], 'role' => $UserData['Role1'], 'role1' => $UserData['Role1'], 'role2' => $UserData['Role2'], 'status' => 'undecided', 'comment' => '', 'character' => array()); $CharQuery->loop(function ($UserData) use(&$AttendeeData) { $Character = array('id' => $UserData['CharacterId'], 'name' => $UserData['Name'], 'mainchar' => $UserData['Mainchar'], 'classname' => explode(':', $UserData['Class']), 'role1' => $UserData['Role1'], 'role2' => $UserData['Role2']); array_push($AttendeeData['character'], $Character); }); array_push($Attendees, $AttendeeData); } } }); $Out->pushValue('attendee', $Attendees); $Out->pushValue('attended', $NumAttended); $ExportParameter = Api::normalizeArgsRaid(array('raid' => intval($aRequest['id']), 'attends' => true)); $Out->pushValue('token', Api::getPublicToken($ExportParameter)); } if (validRaidlead()) { msgQueryLocations($aRequest); } } else { $Out = Out::getInstance(); $Out->pushError(L('AccessDenied')); } }