/**
  * @return Array: empty or a message key with parameters
  */
 static function getUserBlockErrors($user, $ip)
 {
     static $result = null;
     // Instance cache
     if (!is_null($result)) {
         return $result;
     }
     $block = self::getGlobalBlockingBlock($ip, $user->isAnon());
     if ($block) {
         global $wgLang;
         // Check for local whitelisting
         if (GlobalBlocking::getWhitelistInfo($block->gb_id)) {
             // Block has been whitelisted.
             return $result = array();
         }
         if ($user->isAllowed('ipblock-exempt') || $user->isAllowed('globalblock-exempt')) {
             // User is exempt from IP blocks.
             return $result = array();
         }
         # Messy B/C until $wgLang->formatExpiry() is well embedded
         if (Block::decodeExpiry($block->gb_expiry) == 'infinity') {
             $expiry = wfMsgExt('infiniteblock', 'parseinline');
         } else {
             $expiry = Block::decodeExpiry($block->gb_expiry);
             $expiry = wfMsgExt('expiringblock', 'parseinline', $wgLang->date($expiry), $wgLang->time($expiry));
         }
         $display_wiki = self::getWikiName($block->gb_by_wiki);
         $user_display = self::maybeLinkUserpage($block->gb_by_wiki, $block->gb_by);
         return $result = array('globalblocking-blocked', $user_display, $display_wiki, $block->gb_reason, $expiry, $ip);
     }
     return $result = array();
 }
 function formatRow($row)
 {
     global $wgLang, $wgUser;
     ## One-time setup
     static $sk = null;
     if (is_null($sk)) {
         $sk = $wgUser->getSkin();
     }
     ## Setup
     $timestamp = $row->gb_timestamp;
     $expiry = $row->gb_expiry;
     $options = array();
     # Messy B/C until $wgLang->formatExpiry() is well embedded
     if (Block::decodeExpiry($expiry) == 'infinity') {
         $options[] = wfMsgExt('infiniteblock', 'parseinline');
     } else {
         $expiry = Block::decodeExpiry($expiry);
         $options[] = wfMsgExt('expiringblock', 'parseinline', $wgLang->date($expiry), $wgLang->time($expiry));
     }
     # Check for whitelisting.
     $wlinfo = GlobalBlocking::getWhitelistInfo($row->gb_id);
     if ($wlinfo) {
         $options[] = wfMsg('globalblocking-list-whitelisted', User::whois($wlinfo['user']), $wlinfo['reason']);
     }
     $timestamp = $wgLang->timeanddate(wfTimestamp(TS_MW, $timestamp), true);
     if ($row->gb_anon_only) {
         $options[] = wfMsg('globalblocking-list-anononly');
     }
     ## Do afterthoughts (comment, links for admins)
     $info = array();
     if ($wgUser->isAllowed('globalunblock')) {
         $unblockTitle = SpecialPage::getTitleFor("RemoveGlobalBlock");
         $info[] = $sk->link($unblockTitle, wfMsgExt('globalblocking-list-unblock', 'parseinline'), array(), array('address' => $row->gb_address));
     }
     global $wgApplyGlobalBlocks;
     if ($wgUser->isAllowed('globalblock-whitelist') && $wgApplyGlobalBlocks) {
         $whitelistTitle = SpecialPage::getTitleFor("GlobalBlockStatus");
         $info[] = $sk->link($whitelistTitle, wfMsgExt('globalblocking-list-whitelist', 'parseinline'), array(), array('address' => $row->gb_address));
     }
     if ($wgUser->isAllowed('globalblock')) {
         $reblockTitle = SpecialPage::getTitleFor('GlobalBlock');
         $msg = wfMsgExt('globalblocking-list-modify', 'parseinline');
         $info[] = $sk->link($reblockTitle, $msg, array(), array('wpAddress' => $row->gb_address, 'modify' => 1));
     }
     ## Userpage link / Info on originating wiki
     $display_wiki = GlobalBlocking::getWikiName($row->gb_by_wiki);
     $user_display = GlobalBlocking::maybeLinkUserpage($row->gb_by_wiki, $row->gb_by);
     $infoItems = count($info) ? wfMsg('parentheses', $wgLang->pipeList($info)) : '';
     ## Put it all together.
     return Html::rawElement('li', array(), wfMsgExt('globalblocking-list-blockitem', array('parseinline'), $timestamp, $user_display, $display_wiki, $row->gb_address, $wgLang->commaList($options)) . ' ' . $sk->commentBlock($row->gb_reason) . ' ' . $infoItems);
 }