roomID = intval($_GET['id']); $this->room = \chat\data\room\RoomCache::getInstance()->getRoom($this->roomID); if ($this->room === null) throw new IllegalLinkException(); if (!$this->room->canSee($user = null, $reason)) throw $reason; if (!$this->room->canSeeLog($user = null, $reason)) throw $reason; if (isset($_GET['messageid'])) $this->messageID = intval($_GET['messageid']); if ($this->messageID) { $this->message = new \chat\data\message\Message($this->messageID); if (!$this->message->getMessageType()->getProcessor()->canSeeInLog($this->message, $this->room)) { throw new PermissionDeniedException(); } } if (isset($_REQUEST['datetime'])) $this->datetime = strtotime($_REQUEST['datetime']); } /** * @inheritDoc */ public function readData() { parent::readData(); if ($this->datetime) { // Determine message types supporting fast select $objectTypes = \wcf\data\object\type\ObjectTypeCache::getInstance()->getObjectTypes('be.bastelstu.chat.messageType'); $fastSelect = array_map(function ($item) { return $item->objectTypeID; }, array_filter($objectTypes, function ($item) { // TODO: Consider a method couldAppearInLog(): bool return $item->getProcessor()->supportsFastSelect(); })); $minimum = 0; $loops = 0; do { // Build fast select filter $condition = new \wcf\system\database\util\PreparedStatementConditionBuilder(); $condition->add('((roomID = ? AND objectTypeID IN (?)) OR objectTypeID NOT IN (?))', [ $this->room->roomID, $fastSelect, $fastSelect ]); $condition->add('time >= ?', [ $this->datetime ]); if ($minimum) { $condition->add('messageID > ?', [ $minimum ]); } $sql = "SELECT messageID FROM chat1_message ".$condition." ORDER BY messageID ASC"; $statement = WCF::getDB()->prepare($sql, 20); $statement->execute($condition->getParameters()); $messageIDs = $statement->fetchAll(\PDO::FETCH_COLUMN); $objectList = new MessageList(); $objectList->setObjectIDs($messageIDs); $objectList->readObjects(); $objects = $objectList->getObjects(); if (empty($objects)) { // TODO: UserInputException? throw new IllegalLinkException(); } foreach ($objects as $message) { if ($message->getMessageType()->getProcessor()->canSeeInLog($message, $this->room)) { $parameters = [ 'application' => 'chat' , 'messageid' => $message->messageID , 'object' => $this->room ]; \wcf\util\HeaderUtil::redirect(\wcf\system\request\LinkHandler::getInstance()->getLink('Log', $parameters)); exit; } $minimum = $message->messageID; } } while (++$loops <= 3); // Do a best guess redirect to an ID that is as near as possible $parameters = [ 'application' => 'chat' , 'messageid' => $minimum , 'object' => $this->room ]; \wcf\util\HeaderUtil::redirect(\wcf\system\request\LinkHandler::getInstance()->getLink('Log', $parameters)); exit; } } /** * @inheritDoc */ public function assignVariables() { parent::assignVariables(); PageLocationManager::getInstance()->addParentLocation('be.bastelstu.chat.Room', $this->room->roomID, $this->room); WCF::getTPL()->assign([ 'room' => $this->room , 'roomList' => \chat\data\room\RoomCache::getInstance()->getRooms() , 'messageID' => $this->messageID , 'message' => $this->message , 'config' => $this->getConfig() ]); } }