/** * @see \wcf\system\dashboard\box\IDashboardBox::init() */ public function init(DashboardBox $box, IPage $page) { parent::init($box, $page); $this->member = new UserProfileList(); $this->member->sqlOrderBy = 'user_table.jCoinsBalance DESC'; $this->member->sqlLimit = JCOINS_DASHBOARD_SIDEBAR_RICHEST_NUM; $this->member->readObjects(); $this->fetched(); }
/** * @see \wcf\page\IPage::assignVariables() */ public function readData() { parent::readData(); if (empty($_POST)) { // get marked user ids if (empty($this->action)) { // get type id $objectTypeID = ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.user'); if ($objectTypeID === null) { throw new SystemException("Unknown clipboard item type 'com.woltlab.wcf.user'"); } // get user ids $users = ClipboardHandler::getInstance()->getMarkedItems($objectTypeID); if (empty($users)) { throw new IllegalLinkException(); } // load users $this->userIDs = array_keys($users); } if (MAIL_USE_FORMATTED_ADDRESS) { $this->from = MAIL_FROM_NAME . ' <' . MAIL_FROM_ADDRESS . '>'; } else { $this->from = MAIL_FROM_ADDRESS; } } if (!empty($this->userIDs)) { $this->userList = new UserList(); $this->userList->getConditionBuilder()->add("user_table.userID IN (?)", array($this->userIDs)); $this->userList->sqlOrderBy = "user_table.username ASC"; $this->userList->readObjects(); } $this->groups = UserGroup::getAccessibleGroups(array(), array(UserGroup::GUESTS, UserGroup::EVERYONE)); }
/** * @see \wcf\system\user\activity\event\IUserActivityEvent::prepare() */ public function prepare(array $events) { $responseIDs = array(); foreach ($events as $event) { $responseIDs[] = $event->objectID; } $responseList = new CommentResponseList(); $responseList->getConditionBuilder()->add("comment_response.responseID IN (?)", array($responseIDs)); $responseList->readObjects(); $responses = $responseList->getObjects(); $commentIDs = $comments = array(); foreach ($responses as $response) { $commentIDs[] = $response->commentID; } if (!empty($commentIDs)) { $commentList = new CommentList(); $commentList->getConditionBuilder()->add("comment.commentID IN (?)", array($commentIDs)); $commentList->readObjects(); $comments = $commentList->getObjects(); } // fetch news entries $entryIDs = $entry = array(); foreach ($comments as $comment) { $entryIDs[] = $comment->objectID; } if (!empty($entryIDs)) { $entryList = new ViewableEntryList(); $entryList->getConditionBuilder()->add("news_entry.entryID IN (?)", array($entryIDs)); $entryList->readObjects(); $entry = $entryList->getObjects(); } $userIDs = $user = array(); foreach ($comments as $comment) { $userIDs[] = $comment->userID; } if (!empty($userIDs)) { $userList = new UserList(); $userList->getConditionBuilder()->add("user_table.userID IN (?)", array($userIDs)); $userList->readObjects(); $users = $userList->getObjects(); } foreach ($events as $event) { if (isset($responses[$event->objectID])) { $response = $responses[$event->objectID]; $comment = $comments[$response->commentID]; if (isset($entry[$comment->objectID]) && isset($users[$comment->userID])) { $newsEntry = $entry[$comment->objectID]; if (!$newsEntry->canRead()) { continue; } $event->setIsAccessible(); $text = WCF::getLanguage()->getDynamicVariable('cms.recentActivity.newsCommentResponse', array('commentAuthor' => $users[$comment->userID], 'entry' => $newsEntry)); $event->setTitle($text); $event->setDescription($response->getExcerpt()); continue; } } $event->setIsOrphaned(); } }
/** * Checks if the users with the given ids should be assigned to new user * groups. * * Note: This method uses the user ids as a parameter instead of user objects * on purpose to make sure the latest data of the users are fetched. * * @param array<integer> $userIDs */ public function checkUsers(array $userIDs) { if (empty($userIDs)) { return; } $userList = new UserList(); $userList->getConditionBuilder()->add('user_table.userID IN (?)', array($userIDs)); $userList->readObjects(); $assignments = UserGroupAssignmentCacheBuilder::getInstance()->getData(); foreach ($userList as $user) { $groupIDs = $user->getGroupIDs(); $newGroupIDs = array(); foreach ($assignments as $assignment) { if (in_array($assignment->groupID, $groupIDs) || in_array($assignment->groupID, $newGroupIDs)) { continue; } $checkFailed = false; $conditions = $assignment->getConditions(); foreach ($conditions as $condition) { if (!$condition->getObjectType()->getProcessor()->checkUser($condition, $user)) { $checkFailed = true; break; } } if (!$checkFailed) { $newGroupIDs[] = $assignment->groupID; } } if (!empty($newGroupIDs)) { $userAction = new UserAction(array($user), 'addToGroups', array('addDefaultGroups' => false, 'deleteOldGroups' => false, 'groups' => $newGroupIDs)); $userAction->executeAction(); } } }
/** * Adds a log entry for newly added conversation participants. * * @param \wcf\data\conversation\Conversation $conversation * @param array<integer> $participantIDs */ public function addParticipants(Conversation $conversation, array $participantIDs) { $participants = array(); $userList = new UserList(); $userList->setObjectIDs($participantIDs); $userList->readObjects(); foreach ($userList as $user) { $participants[] = array('userID' => $user->userID, 'username' => $user->username); } $this->add($conversation, 'addParticipants', array('participants' => $participants)); }
/** * Loads the users. */ protected function readUsers() { $this->users = array(); if (empty($this->userIDs)) { return; } $this->userIDs = array_unique($this->userIDs); $userList = new UserList(); $userList->getConditionBuilder()->add('user_table.userID IN (?)', array($this->userIDs)); $userList->readObjects(); $this->users = $userList->getObjects(); }
/** * @see \wcf\system\worker\IWorker::execute() */ public function execute() { $userList = new UserList(); $userList->decoratorClassName = 'wcf\\data\\user\\UserEditor'; $userList->getConditionBuilder()->add('user_table.userID IN (?)', array($this->parameters['userIDs'])); $userList->sqlLimit = $this->limit; $userList->sqlOffset = $this->limit * $this->loopCount; $userList->readObjects(); foreach ($userList as $userEditor) { $this->sendNewPassword($userEditor); } }
/** * @see \wcf\system\user\activity\event\IUserActivityEvent::prepare() */ public function prepare(array $events) { $commentsIDs = $responseIDs = $userIDs = array(); foreach ($events as $event) { $responseIDs[] = $event->objectID; } $responseList = new CommentResponseList(); $responseList->setObjectIDs($responseIDs); $responseList->readObjects(); $responses = $responseList->getObjects(); foreach ($responses as $response) { $commentIDs[] = $response->commentID; } $commentList = new CommentList(); $commentList->setObjectIDs($commentIDs); $commentList->readObjects(); $comments = $commentList->getObjects(); foreach ($comments as $comment) { if (!in_array($comment->userID, $userIDs)) { $userIDs[] = $comment->userID; } } $userList = new UserList(); $userList->setObjectIDs($userIDs); $userList->readObjects(); $users = $userList->getObjects(); foreach ($events as $event) { if (isset($responses[$event->objectID])) { $response = $responses[$event->objectID]; $comment = $comments[$response->commentID]; $page = PageCache::getInstance()->getPage($comment->objectID); if ($page !== null && isset($users[$comment->userID])) { if (!$page->canRead()) { continue; } $event->setIsAccessible(); $text = WCF::getLanguage()->getDynamicVariable('wcf.user.profile.recentActivity.pageCommentResponse', array('author' => $users[$comment->userID], 'page' => $pages[$comment->objectID])); $event->setTitle($text); $event->setDescription($response->getFormattedMessage()); continue; } } else { $event->setIsOrphaned(); } } }
/** * @see \wcf\system\user\activity\event\IUserActivityEvent::prepare() */ public function prepare(array $events) { $objectIDs = array(); foreach ($events as $event) { $objectIDs[] = $event->objectID; } // fetch user id and username $userList = new UserList(); $userList->getConditionBuilder()->add("user_table.userID IN (?)", array($objectIDs)); $userList->readObjects(); $users = $userList->getObjects(); // set message foreach ($events as $event) { if (isset($users[$event->objectID])) { $event->setIsAccessible(); $text = WCF::getLanguage()->getDynamicVariable('wcf.user.profile.recentActivity.follow', array('user' => $users[$event->objectID])); $event->setTitle($text); } else { $event->setIsOrphaned(); } } }
/** * @see \wcf\system\moderation\queue\IModerationQueueHandler::populate() */ public function populate(array $queues) { $objectIDs = array(); foreach ($queues as $object) { $objectIDs[] = $object->objectID; } // fetch users $userList = new UserList(); $userList->setObjectIDs($objectIDs); $userList->readObjects(); $users = $userList->getObjects(); foreach ($queues as $object) { if (isset($users[$object->objectID])) { $object->setAffectedObject($users[$object->objectID]); } else { $object->setIsOrphaned(); } } }
/** * @see \wcf\system\user\activity\event\IUserActivityEvent::prepare() */ public function prepare(array $events) { $responseIDs = array(); foreach ($events as $event) { $responseIDs[] = $event->objectID; } // fetch responses $responseList = new CommentResponseList(); $responseList->setObjectIDs($responseIDs); $responseList->readObjects(); $responses = $responseList->getObjects(); // fetch comments $commentIDs = $comments = array(); foreach ($responses as $response) { $commentIDs[] = $response->commentID; } if (!empty($commentIDs)) { $commentList = new CommentList(); $commentList->setObjectIDs($commentIDs); $commentList->readObjects(); $comments = $commentList->getObjects(); } // fetch entries $entryIDs = $entries = array(); foreach ($comments as $comment) { $entryIDs[] = $comment->objectID; } if (!empty($entryIDs)) { $entryList = new EntryList(); $entryList->setObjectIDs($entryIDs); $entryList->readObjects(); $entries = $entryList->getObjects(); } // fetch users $userIDs = $user = array(); foreach ($comments as $comment) { $userIDs[] = $comment->userID; } if (!empty($userIDs)) { $userList = new UserList(); $userList->setObjectIDs($userIDs); $userList->readObjects(); $users = $userList->getObjects(); } // set message foreach ($events as $event) { if (isset($responses[$event->objectID])) { $response = $responses[$event->objectID]; $comment = $comments[$response->commentID]; if (isset($entries[$comment->objectID]) && isset($users[$comment->userID])) { $entry = $entries[$comment->objectID]; // check permissions if (!$entry->canRead()) { continue; } $event->setIsAccessible(); // title $text = WCF::getLanguage()->getDynamicVariable('linklist.recentActivity.entryCommentResponse', array('commentAuthor' => $users[$comment->userID], 'entry' => $entry)); $event->setTitle($text); // description $event->setDescription($response->getExcerpt()); continue; } } $event->setIsOrphaned(); } }
/** * Returns a list of users. * * @param array $userIDs * @return array<User> */ public static function getUsers(array $userIDs) { $userList = new UserList(); $userList->getConditionBuilder()->add("user_table.userID IN (?)", array($userIDs)); $userList->readObjects(); return $userList->getObjects(); }
/** * @see \wcf\system\event\listener\IParameterizedEventListener::execute() */ public function execute($eventObj, $className, $eventName, array &$parameters) { if (!$eventObj->text) { return; } // check if needed url BBCode is allowed if ($eventObj->allowedBBCodes !== null && !BBCode::isAllowedBBCode('url', $eventObj->allowedBBCodes)) { return; } static $userRegex = null; if ($userRegex === null) { $userRegex = new Regex("\n\t\t\t\t(?:^|(?<=\\s|\\]))\t\t\t\t\t# either at start of string, or after whitespace\n\t\t\t\t@\n\t\t\t\t(\n\t\t\t\t\t([^',\\s][^,\\s]{2,})(?:\\s[^,\\s]+)?\t# either at most two strings, not containing\n\t\t\t\t\t\t\t\t\t\t# whitespace or the comma, not starting with a single quote\n\t\t\t\t\t\t\t\t\t\t# separated by a single whitespace character\n\t\t\t\t|\n\t\t\t\t\t'(?:''|[^']){3,}'\t\t\t# or a string delimited by single quotes\n\t\t\t\t)\n\t\t\t", Regex::IGNORE_WHITESPACE); } // cache quotes // @see \wcf\system\bbcode\BBCodeParser::buildTagArray() $pattern = '~\\[(?:/(?:quote)|(?:quote) (?:= (?:\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|[^,\\]]*) (?:,(?:\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|[^,\\]]*))* )?)\\]~ix'; preg_match_all($pattern, $eventObj->text, $quoteMatches); $textArray = preg_split($pattern, $eventObj->text); $text = $textArray[0]; $openQuotes = 0; $quote = ''; foreach ($quoteMatches[0] as $i => $quoteTag) { if (mb_substr($quoteTag, 1, 1) == '/') { $openQuotes--; $quote .= $quoteTag; if ($openQuotes) { $quote .= $textArray[$i + 1]; } else { $text .= StringStack::pushToStringStack($quote, 'preParserUserMentions', '@@@') . $textArray[$i + 1]; $quote = ''; } } else { $openQuotes++; $quote .= $quoteTag . $textArray[$i + 1]; } } if ($quote) { $text .= $quote; } $userRegex->match($text, true, Regex::ORDER_MATCH_BY_SET); $matches = $userRegex->getMatches(); if (!empty($matches)) { $usernames = array(); foreach ($matches as $match) { // we don't care about the full match array_shift($match); foreach ($match as $username) { $username = self::getUsername($username); if (!in_array($username, $usernames)) { $usernames[] = $username; } } } if (!empty($usernames)) { // fetch users $userList = new UserList(); $userList->getConditionBuilder()->add('user_table.username IN (?)', array($usernames)); $userList->readObjects(); $users = array(); foreach ($userList as $user) { $users[mb_strtolower($user->username)] = $user; } $text = $userRegex->replace($text, new Callback(function ($matches) use($users) { // containing the full match $usernames = array($matches[1]); // containing only the part before the first space if (isset($matches[2])) { $usernames[] = $matches[2]; } $usernames = array_map(array('\\wcf\\system\\event\\listener\\PreParserAtUserListener', 'getUsername'), $usernames); foreach ($usernames as $username) { if (!isset($users[$username])) { continue; } $link = LinkHandler::getInstance()->getLink('User', array('appendSession' => false, 'object' => $users[$username])); $mention = "[url='" . $link . "']@" . $users[$username]->username . '[/url]'; // check if only the part before the first space matched, in that case append the second word if (isset($matches[2]) && strcasecmp($matches[2], $username) === 0) { $mention .= mb_substr($matches[1], strlen($matches[2])); } return $mention; } return $matches[0]; })); } } // reinsert cached quotes $eventObj->text = StringStack::reinsertStrings($text, 'preParserUserMentions'); }
/** * @see \wcf\system\cronjob\ICronjob::execute() */ public function execute(Cronjob $cronjob) { parent::execute($cronjob); // get user ids $userIDs = array(); $sql = "SELECT\tDISTINCT userID\n\t\t\tFROM\twcf" . WCF_N . "_user_notification\n\t\t\tWHERE\tmailNotified = ?\n\t\t\t\tAND time < ?\n\t\t\t\tAND confirmTime = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array(0, TIME_NOW - 3600 * 23, 0)); while ($row = $statement->fetchArray()) { $userIDs[] = $row['userID']; } if (empty($userIDs)) { return; } // get users $userList = new UserList(); $userList->setObjectIDs($userIDs); $userList->readObjects(); $users = $userList->getObjects(); // get notifications $conditions = new PreparedStatementConditionBuilder(); $conditions->add("notification.userID IN (?)", array($userIDs)); $conditions->add("notification.mailNotified = ?", array(0)); $conditions->add("notification.confirmTime = ?", array(0)); $sql = "SELECT\t\tnotification.*, notification_event.eventID, object_type.objectType\n\t\t\tFROM\t\twcf" . WCF_N . "_user_notification notification\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_user_notification_event notification_event\n\t\t\tON\t\t(notification_event.eventID = notification.eventID)\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_object_type object_type\n\t\t\tON\t\t(object_type.objectTypeID = notification_event.objectTypeID)\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\tnotification.time"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); // mark notifications as done $conditions = new PreparedStatementConditionBuilder(); $conditions->add("userID IN (?)", array($userIDs)); $conditions->add("mailNotified = ?", array(0)); $sql = "UPDATE\twcf" . WCF_N . "_user_notification\n\t\t\tSET\tmailNotified = 1\n\t\t\t" . $conditions; $statement2 = WCF::getDB()->prepareStatement($sql); $statement2->execute($conditions->getParameters()); // collect data $eventsToUser = $objectTypes = $eventIDs = $notificationObjects = array(); $availableObjectTypes = UserNotificationHandler::getInstance()->getAvailableObjectTypes(); while ($row = $statement->fetchArray()) { if (!isset($eventsToUser[$row['userID']])) { $eventsToUser[$row['userID']] = array(); } $eventsToUser[$row['userID']][] = $row['notificationID']; // cache object types if (!isset($objectTypes[$row['objectType']])) { $objectTypes[$row['objectType']] = array('objectType' => $availableObjectTypes[$row['objectType']], 'objectIDs' => array(), 'objects' => array()); } $objectTypes[$row['objectType']]['objectIDs'][] = $row['objectID']; $eventIDs[] = $row['eventID']; $notificationObjects[$row['notificationID']] = new UserNotification(null, $row); } // load authors $conditions = new PreparedStatementConditionBuilder(); $conditions->add("notificationID IN (?)", array(array_keys($notificationObjects))); $sql = "SELECT\t\tnotificationID, authorID\n\t\t\tFROM\t\twcf" . WCF_N . "_user_notification_author\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\ttime ASC"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); $authorIDs = $authorToNotification = array(); while ($row = $statement->fetchArray()) { if ($row['authorID']) { $authorIDs[] = $row['authorID']; } if (!isset($authorToNotification[$row['notificationID']])) { $authorToNotification[$row['notificationID']] = array(); } $authorToNotification[$row['notificationID']][] = $row['authorID']; } // load authors $authors = UserProfile::getUserProfiles($authorIDs); $unknownAuthor = new UserProfile(new User(null, array('userID' => null, 'username' => WCF::getLanguage()->get('wcf.user.guest')))); // load objects associated with each object type foreach ($objectTypes as $objectType => $objectData) { $objectTypes[$objectType]['objects'] = $objectData['objectType']->getObjectsByIDs($objectData['objectIDs']); } // load required events $eventList = new UserNotificationEventList(); $eventList->getConditionBuilder()->add("user_notification_event.eventID IN (?)", array($eventIDs)); $eventList->readObjects(); $eventObjects = $eventList->getObjects(); foreach ($eventsToUser as $userID => $events) { if (!isset($users[$userID])) { continue; } $user = $users[$userID]; // no notifications for disabled or banned users if ($user->activationCode) { continue; } if ($user->banned) { continue; } // add mail header $message = $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.header', array('user' => $user)); foreach ($events as $notificationID) { $notification = $notificationObjects[$notificationID]; $className = $eventObjects[$notification->eventID]->className; $class = new $className($eventObjects[$notification->eventID]); $class->setObject($notification, $objectTypes[$notification->objectType]['objects'][$notification->objectID], isset($authors[$notification->authorID]) ? $authors[$notification->authorID] : $unknownAuthor, $notification->additionalData); $class->setLanguage($user->getLanguage()); if (isset($authorToNotification[$notification->notificationID])) { $eventAuthors = array(); foreach ($authorToNotification[$notification->notificationID] as $userID) { if (!$userID) { $eventAuthors[0] = $unknownAuthor; } else { if (isset($authors[$userID])) { $eventAuthors[$userID] = $authors[$userID]; } } } if (!empty($eventAuthors)) { $class->setAuthors($eventAuthors); } } $message .= "\n\n"; $message .= $class->getEmailMessage('daily'); } // append notification mail footer $token = $user->notificationMailToken; if (!$token) { // generate token if not present $token = mb_substr(StringUtil::getHash(serialize(array($user->userID, StringUtil::getRandomID()))), 0, 20); $editor = new UserEditor($user); $editor->update(array('notificationMailToken' => $token)); } $message .= "\n\n"; $message .= $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.daily.footer', array('user' => $user, 'token' => $token)); // build mail $mail = new Mail(array($user->username => $user->email), $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.daily.subject', array('count' => count($events))), $message); $mail->setLanguage($user->getLanguage()); $mail->send(); } }