/** * Chat entry point - rendered via Ajax or pre-rendered in JS variable */ public function executeContents() { global $wgUser, $wgSitename, $wgOut, $wgExtensionsPath, $wgContLang, $wgReadOnly, $wgEnableWallExt; wfProfileIn(__METHOD__); // Since there is no chat in the backup datacenter yet, if we're in read-only, disable the entry-point. // Depending on the actual failure, chat may or may not work, but the user would have to get there via URL which // is essentially saying that they accept some risk since they're going somewhere our interface doesn't direct them to. // If it's just, eg: a database problem, then they may get lucky and be able to use most of the chat features (kickbanning wouldn't work, etc.). if (empty($wgReadOnly)) { // Main variables $this->profileType = !empty($wgEnableWallExt) ? 'message-wall' : 'talk-page'; $this->linkToSpecialChat = SpecialPage::getTitleFor("Chat")->escapeLocalUrl(); $this->isLoggedIn = $wgUser->isLoggedIn(); $this->profileAvatarUrl = $this->isLoggedIn ? AvatarService::getAvatarUrl($wgUser->getName(), ChatRailController::AVATAR_SIZE) : ''; // List of other people in chat $this->totalInRoom = 0; // Gets array of users currently in chat to populate rail module and user stats menus $chattersIn = NodeApiClient::getChatters($this->totalInRoom); $this->totalInRoom = count($chattersIn); $chatters = array(); foreach ($chattersIn as $i => $val) { $chatters[$i] = array(); $cacheChatter = $this->getCachedUser($val); if (!empty($cacheChatter)) { $chatters[$i] = $cacheChatter; continue; } $chatters[$i]['username'] = $val; $chatters[$i]['avatarUrl'] = AvatarService::getAvatarUrl($chatters[$i]['username'], ChatRailController::AVATAR_SIZE); // get stats for edit count and member since $user = User::newFromName($val); if (is_object($user)) { $userStatsService = new UserStatsService($user->getId()); $stats = $userStatsService->getStats(); // edit count $chatters[$i]['editCount'] = $wgContLang->formatNum((int) $stats['edits']); // member since $chatters[$i]['showSince'] = $chatters[$i]['editCount'] != 0; $date = getdate(strtotime($stats['date'])); global $wgLang; $chatters[$i]['since'] = $wgLang->getMonthAbbreviation($date['mon']) . ' ' . $date['year']; // profile page if ($this->profileType == 'message-wall') { $chatters[$i]['profileUrl'] = Title::makeTitle(NS_USER_WALL, $chatters[$i]['username'])->getFullURL(); } else { $chatters[$i]['profileUrl'] = Title::makeTitle(NS_USER_TALK, $chatters[$i]['username'])->getFullURL(); } // contribs page $chatters[$i]['contribsUrl'] = SpecialPage::getTitleFor('Contributions', $chatters[$i]['username'])->getFullURL(); } $this->cacheUser($val, $chatters[$i]); } $this->chatters = $chatters; } // Cache the entire call in varnish (and browser). $this->response->setCacheValidity(self::CACHE_DURATION, self::CACHE_DURATION, array(WikiaResponse::CACHE_TARGET_BROWSER, WikiaResponse::CACHE_TARGET_VARNISH)); wfProfileOut(__METHOD__); }
/** * Does the request to the Node server and returns the responseText (empty string on failure). */ private static function makeRequest($params) { global $wgReadOnly; wfProfileIn(__METHOD__); $response = ""; // NOTE: When we fail over, the chat server host doesn't change which backend it points to (since there isn't // even a chat server in the backup datacenter(s)), so if we're in read-only, even though this isn't a write // operation, abort trying to contact the node server since it could be unavailable (in the event of complete // network unavailability in the primary datacenter). - BugzId 11047 if (empty($wgReadOnly)) { $requestUrl = "http://" . NodeApiClient::getHostAndPort() . "/api?" . http_build_query($params); $response = Http::get($requestUrl, 'default', array('noProxy' => true)); if ($response === false) { $response = ""; } } wfProfileOut(__METHOD__); return $response; }
/** * Ajax endpoint for createing / accessing private rooms */ public static function getPrivateRoomID() { ChatHelper::info(__METHOD__ . ': Method called'); global $wgRequest; wfProfileIn(__METHOD__); $users = json_decode($wgRequest->getVal('users')); $roomId = NodeApiClient::getDefaultRoomId('private', $users); wfProfileOut(__METHOD__); return array("id" => $roomId); }
public function executeIndex() { global $wgUser, $wgDevelEnvironment, $wgRequest, $wgCityId, $wgFavicon, $wgOut; wfProfileIn(__METHOD__); // String replacement logic taken from includes/Skin.php $this->wgFavicon = str_replace('images.wikia.com', 'images1.wikia.nocookie.net', $wgFavicon); $this->mainPageURL = Title::newMainPage()->getLocalURL(); // add messages (fetch them using <script> tag) F::build('JSMessages')->enqueuePackage('Chat', JSMessages::EXTERNAL); // package defined in Chat_setup.php $this->jsMessagePackagesUrl = F::build('JSMessages')->getExternalPackagesUrl(); // Variables for this user $this->username = $wgUser->getName(); $this->avatarUrl = AvatarService::getAvatarUrl($this->username, ChatController::CHAT_AVATAR_DIMENSION); // Find the chat for this wiki (or create it, if it isn't there yet). $roomName = $roomTopic = ""; $this->roomId = (int) NodeApiClient::getDefaultRoomId($roomName, $roomTopic); $this->roomName = $roomName; $this->roomTopic = $roomTopic; $this->chatkey = Chat::echoCookies(); // Set the hostname of the node server that the page will connect to. $server = ChatHelper::getServer('Main'); $this->nodePort = $server['port']; $this->nodeHostname = $server['host']; // Some building block for URLs that the UI needs. $this->pathToProfilePage = Title::makeTitle(!empty($this->wg->EnableWallExt) ? NS_USER_WALL : NS_USER_TALK, '$1')->getFullURL(); $this->pathToContribsPage = SpecialPage::getTitleFor('Contributions', '$1')->getFullURL(); $this->bodyClasses = ""; if ($wgUser->isAllowed('chatmoderator')) { $this->isChatMod = 1; $this->bodyClasses .= ' chat-mod '; } else { $this->isChatMod = 0; } // Adding chatmoderator group for other users. CSS classes added to body tag to hide/show option in menu. $userChangeableGroups = $wgUser->changeableGroups(); if (in_array('chatmoderator', $userChangeableGroups['add'])) { $this->bodyClasses .= ' can-give-chat-mod '; } $this->app->registerHook('MakeGlobalVariablesScript', 'ChatController', 'onMakeGlobalVariablesScript', array(), false, $this); $wgOut->getResourceLoader()->getModule('mediawiki'); $ret = implode("\n", array($wgOut->getHeadLinks(null, true), $wgOut->buildCssLinks(), $wgOut->getHeadScripts(), $wgOut->getHeadItems())); $this->globalVariablesScript = $ret; //Theme Designer stuff $themeSettingObj = new ThemeSettings(); $themeSettings = $themeSettingObj->getSettings(); $this->themeSettings = $themeSettings; $this->wordmarkThumbnailUrl = ''; if ($themeSettings['wordmark-type'] == 'graphic') { $title = Title::newFromText($themeSettings['wordmark-image-name'], NS_FILE); if ($title) { $image = wfFindFile($title); if ($image) { $this->wordmarkThumbnailUrl = $image->createThumb(self::CHAT_WORDMARK_WIDTH, self::CHAT_WORDMARK_HEIGHT); } } if (empty($this->wordmarkThumbnailUrl)) { $this->wordmarkThumbnailUrl = WikiFactory::getLocalEnvURL($themeSettings['wordmark-image-url']); } } wfProfileOut(__METHOD__); }
/** * Return information about users present in the chat channel. This method has its internal cache. Method returns * an array, where each of the users is described by the following attributes: * * username - chatter login * * avatarUrl - chatter avatar url * * editCount - number of chatter's edits * * showSince - flag indicating if we can display the information when the chatter joined the wiki * * since_year && since_month - month and year, when chatter joined this wiki * * profileUrl - link to chatter talk page (or message wall, if it's enabled) * * contribsUrl - link to chatter contribution page * @return array array containing chatters info */ public static function getChatUsersInfo() { ChatHelper::info(__METHOD__ . ': Method called'); global $wgReadOnly; wfProfileIn(__METHOD__); $chatters = []; if (empty($wgReadOnly)) { // cache the whole response // individual users are cached anyway, but still we gain performance making just one memcache request instead of several $chatters = WikiaDataAccess::cache(self::getChatUsersMemcKey(), ChatEntryPoint::CHAT_USER_LIST_CACHE, function () { global $wgEnableWallExt; $chatters = []; // Gets array of users currently in chat to populate rail module and user stats menus $chattersIn = NodeApiClient::getChatters(); foreach ($chattersIn as $i => $val) { $chatters[$i] = WikiaDataAccess::cache(wfMemcKey('chatavatars', $val, 'v2'), 60 * 60, function () use($wgEnableWallExt, $val) { $chatter = ['username' => $val, 'avatarUrl' => AvatarService::getAvatarUrl($val, ChatRailController::AVATAR_SIZE)]; // get stats for edit count and member since $user = User::newFromName($val); if ($user instanceof User) { $userStatsService = new UserStatsService($user->getId()); $stats = $userStatsService->getStats(); // edit count $chatter['editCount'] = $stats['edits']; // member since $chatter['showSince'] = $chatter['editCount'] != 0; if ($chatter['showSince']) { $date = getdate(strtotime($stats['date'])); $chatter['since_year'] = $date['year']; $chatter['since_month'] = $date['mon']; } if (!empty($wgEnableWallExt)) { $chatter['profileUrl'] = Title::makeTitle(NS_USER_WALL, $chatter['username'])->getFullURL(); } else { $chatter['profileUrl'] = Title::makeTitle(NS_USER_TALK, $chatter['username'])->getFullURL(); } $chatter['contribsUrl'] = SpecialPage::getTitleFor('Contributions', $chatter['username'])->getFullURL(); } return $chatter; }); } return $chatters; }); } wfProfileOut(__METHOD__); return $chatters; }
/** * Ajax endpoint for createing / accessing private rooms */ public static function getPrivateRoomID() { global $wgRequest; wfProfileIn(__METHOD__); // TODO: change this $roomName = 'private room name'; $roomTopic = 'private room topic'; $users = explode(',', $wgRequest->getVal('users')); $roomId = NodeApiClient::getDefaultRoomId($roomName, $roomTopic, 'private', $users); wfProfileOut(__METHOD__); return array("id" => $roomId); }
public function executeIndex() { ChatHelper::info(__METHOD__ . ': Method called'); global $wgUser, $wgFavicon, $wgOut, $wgHooks, $wgSitename; wfProfileIn(__METHOD__); // String replacement logic taken from includes/Skin.php $this->wgFavicon = str_replace('images.wikia.com', 'images1.wikia.nocookie.net', $wgFavicon); $this->mainPageURL = Title::newMainPage()->getLocalURL(); // add messages (fetch them using <script> tag) JSMessages::enqueuePackage('Chat', JSMessages::EXTERNAL); // package defined in Chat_setup.php $this->jsMessagePackagesUrl = JSMessages::getExternalPackagesUrl(); // Variables for this user $this->username = $wgUser->getName(); $this->avatarUrl = AvatarService::getAvatarUrl($this->username, ChatController::CHAT_AVATAR_DIMENSION); // Find the chat for this wiki (or create it, if it isn't there yet). $this->roomId = (int) NodeApiClient::getDefaultRoomId(); // we overwrite here data from redis since it causes a bug DAR-1532 $this->roomName = $wgSitename; $this->roomTopic = wfMsg('chat-default-topic', $wgSitename); $this->chatkey = Chat::echoCookies(); // Set the hostname of the node server that the page will connect to. $chathost = ChatHelper::getChatConfig('ChatHost'); $server = explode(":", $chathost); $this->nodeHostname = $server[0]; $this->nodePort = $server[1]; $chatmain = ChatHelper::getServer('Main'); $this->nodeInstance = $chatmain['serverId']; // Some building block for URLs that the UI needs. $this->pathToProfilePage = Title::makeTitle(!empty($this->wg->EnableWallExt) ? NS_USER_WALL : NS_USER_TALK, '$1')->getFullURL(); $this->pathToContribsPage = SpecialPage::getTitleFor('Contributions', '$1')->getFullURL(); $this->bodyClasses = ""; if ($wgUser->isAllowed('chatmoderator')) { $this->isChatMod = 1; $this->bodyClasses .= ' chat-mod '; } else { $this->isChatMod = 0; } // Adding chatmoderator group for other users. CSS classes added to body tag to hide/show option in menu. $userChangeableGroups = $wgUser->changeableGroups(); if (in_array('chatmoderator', $userChangeableGroups['add'])) { $this->bodyClasses .= ' can-give-chat-mod '; } // set up global js variables just for the chat page $wgHooks['MakeGlobalVariablesScript'][] = array($this, 'onMakeGlobalVariablesScript'); $wgOut->getResourceLoader()->getModule('mediawiki'); $ret = implode("\n", array($wgOut->getHeadLinks(null, true), $wgOut->buildCssLinks(), $wgOut->getHeadScripts(), $wgOut->getHeadItems())); $this->globalVariablesScript = $ret; //Theme Designer stuff $themeSettingObj = new ThemeSettings(); $themeSettings = $themeSettingObj->getSettings(); $this->themeSettings = $themeSettings; $this->wordmarkThumbnailUrl = ''; if ($themeSettings['wordmark-type'] == 'graphic') { $title = Title::newFromText($themeSettings['wordmark-image-name'], NS_FILE); if ($title) { $image = wfFindFile($title); if ($image) { $this->wordmarkThumbnailUrl = $image->createThumb(self::CHAT_WORDMARK_WIDTH, self::CHAT_WORDMARK_HEIGHT); } } if (empty($this->wordmarkThumbnailUrl)) { $this->wordmarkThumbnailUrl = WikiFactory::getLocalEnvURL($themeSettings['wordmark-image-url']); } } // CONN-436: Invalidate Varnish cache for ChatRail:GetUsers ChatRailController::purgeMethod('GetUsers', ['format' => 'json']); wfProfileOut(__METHOD__); }