/** * Directly check for IP block which is quicker than looping through all filters as we don't support * anything other than exact for IP blocks, and this significantly improves performance * * @author grunny */ protected static function blockCheckIP(User $user, $text, $writeStats = true) { global $wgMemc, $wgExternalSharedDB; wfProfileIn(__METHOD__); PhalanxShadowing::setType(Phalanx::TYPE_USER); $dbr = wfGetDB(DB_SLAVE, array(), $wgExternalSharedDB); $moduleId = Phalanx::TYPE_USER; $timestampNow = wfTimestampNow(); $ipAddr = IP::toHex($text); $row = $dbr->selectRow('phalanx', '*', array("p_type & {$moduleId} = {$moduleId}", "p_lang IS NULL", 'p_ip_hex' => $ipAddr, "p_expire IS NULL OR p_expire > {$dbr->addQuotes($timestampNow)}"), __METHOD__); if ($row !== false) { $blockData = array('id' => $row->p_id, 'author_id' => $row->p_author_id, 'text' => $row->p_text, 'type' => $row->p_type, 'timestamp' => $row->p_timestamp, 'expire' => $row->p_expire, 'exact' => $row->p_exact, 'regex' => $row->p_regex, 'case' => $row->p_case, 'reason' => $row->p_reason, 'lang' => $row->p_lang); Wikia::log(__METHOD__, __LINE__, "Block '{$blockData['text']}' blocked '{$text}'."); if ($writeStats) { Phalanx::addStats($blockData['id'], $blockData['type']); } self::setUserData($user, $blockData, $text, true); $cachedState = array('timestamp' => wfTimestampNow(), 'block' => $blockData, 'return' => false); $wgMemc->set(self::getCacheKey($user), $cachedState); PhalanxShadowing::check($user->getName(), $blockData['id']); wfProfileOut(__METHOD__); return false; } PhalanxShadowing::check($user->getName(), 0); wfProfileOut(__METHOD__); return true; }
/** * test if provided text is blocked * @param string $text string to be tested against filter * @param array $blocksData blocks data (text, params, id), either in full or short format * @param boolean $writeStats should stats be recorded? * @param array $matchingBlockData (out) block data that matched * * @return Array with 'blocked' key containing boolean status * * @author Maciej Błaszkowski <marooned at wikia-inc.com> * @author Władysław Bodzek */ static function findBlocked($text, $blocksData, $writeStats = true, &$matchingBlockData = null) { wfProfileIn(__METHOD__); $result = array('blocked' => false, 'msg' => ''); foreach ($blocksData as $blockData) { if (isset($blockData['id'])) { // full format $blockId = $blockData['id']; $blockText = $blockData['text']; $isRegex = $blockData['regex']; $isExact = $blockData['exact']; $isCase = $blockData['case']; } else { // short format list($blockId, $blockText, $blockFlags) = $blockData; $isRegex = ($blockFlags & self::FLAG_REGEX) > 0; $isExact = ($blockFlags & self::FLAG_EXACT) > 0; $isCase = ($blockFlags & self::FLAG_CASE) > 0; } $origText = $blockText; if ($isRegex) { //escape slashes uses as regex delimiter $blockText = str_replace('/', '\\/', preg_replace('|\\\\*/|', '/', $blockText)); if ($isExact) { //add begining and end anchor only once (user might added it already) if (strpos($blockText, '^') !== 0) { $blockText = '^' . $blockText; } if (substr($blockText, -1) != '$') { $blockText .= '$'; } } $blockText = "/{$blockText}/"; if (!$isCase) { $blockText .= 'i'; } //QuickFix™ for bad regexes //TODO: validate regexes on save/edit wfSuppressWarnings(); $matched = preg_match($blockText, $text, $matches); if ($matched === false) { Wikia::log(__METHOD__, __LINE__, "Bad regex found: {$blockText}"); } wfRestoreWarnings(); if ($matched) { $blockData = Phalanx::getFromId($blockId); if ($blockData) { if ($writeStats) { self::addStats($blockData['id'], $blockData['type']); } $result['blocked'] = true; $result['msg'] = $matches[0]; } } } else { //plain text if (!$isCase) { $text = strtolower($text); $blockText = strtolower($blockText); } if ($isExact) { if ($text == $blockText) { $blockData = Phalanx::getFromId($blockId); if ($blockData) { if ($writeStats) { self::addStats($blockData['id'], $blockData['type']); } $result['blocked'] = true; $result['msg'] = $origText; //original case } } } else { if (!empty($blockText) && strpos($text, $blockText) !== false) { $blockData = Phalanx::getFromId($blockId); if ($blockData) { if ($writeStats) { self::addStats($blockData['id'], $blockData['type']); } $result['blocked'] = true; $result['msg'] = $origText; //original case } } } } if ($result['blocked']) { $matchingBlockData = $blockData; break; } } $expected_id = isset($matchingBlockData) && $matchingBlockData['id'] ? $matchingBlockData['id'] : 0; PhalanxShadowing::check($text, $expected_id); wfProfileOut(__METHOD__); return $result; }