/** * Return an appropriately formatted LIKE query and the clause */ static function mungeQuery($query, $prot) { $field = 'el_index'; $rv = LinkFilter::makeLikeArray($query, $prot); if ($rv === false) { //makeLike doesn't handle wildcard in IP, so we'll have to munge here. if (preg_match('/^(:?[0-9]{1,3}\\.)+\\*\\s*$|^(:?[0-9]{1,3}\\.){3}[0-9]{1,3}:[0-9]*\\*\\s*$/', $query)) { $rv = array($prot . rtrim($query, " \t*"), $dbr->anyString()); $field = 'el_to'; } } return array($rv, $field); }
public function execute() { global $IP, $wgLocalDatabases, $wgUser; $username = wfMessage('spambot_username')->text(); $wgUser = User::newFromName($username); if (!$wgUser) { $this->error("Invalid username specified in 'spambot_username' message: {$username}", true); } // Create the user if necessary if (!$wgUser->getId()) { $wgUser->addToDatabase(); } $spec = $this->getArg(); $like = LinkFilter::makeLikeArray($spec); if (!$like) { $this->error("Not a valid hostname specification: {$spec}", true); } if ($this->hasOption('all')) { // Clean up spam on all wikis $this->output("Finding spam on " . count($wgLocalDatabases) . " wikis\n"); $found = false; foreach ($wgLocalDatabases as $wikiID) { $dbr = wfGetDB(DB_SLAVE, array(), $wikiID); $count = $dbr->selectField('externallinks', 'COUNT(*)', array('el_index' . $dbr->buildLike($like)), __METHOD__); if ($count) { $found = true; $cmd = wfShellWikiCmd("{$IP}/maintenance/cleanupSpam.php", array('--wiki', $wikiID, $spec)); passthru("{$cmd} | sed 's/^/{$wikiID}: /'"); } } if ($found) { $this->output("All done\n"); } else { $this->output("None found\n"); } } else { // Clean up spam on this wiki $dbr = wfGetDB(DB_SLAVE); $res = $dbr->select('externallinks', array('DISTINCT el_from'), array('el_index' . $dbr->buildLike($like)), __METHOD__); $count = $dbr->numRows($res); $this->output("Found {$count} articles containing {$spec}\n"); foreach ($res as $row) { $this->cleanupArticle($row->el_from, $spec); } if ($count) { $this->output("Done\n"); } } }
/** * @param $query String * @param $protocol String * @return null|string */ public function prepareUrlQuerySearchString($query = null, $protocol = null) { $db = $this->getDb(); if (!is_null($query) || $query != '') { if (is_null($protocol)) { $protocol = 'http://'; } $likeQuery = LinkFilter::makeLikeArray($query, $protocol); if (!$likeQuery) { $this->dieUsage('Invalid query', 'bad_query'); } $likeQuery = LinkFilter::keepOneWildcard($likeQuery); return 'el_index ' . $db->buildLike($likeQuery); } elseif (!is_null($protocol)) { return 'el_index ' . $db->buildLike("{$protocol}", $db->anyString()); } return null; }
/** * testMakeLikeArrayWithInvalidPatterns() * * Tests whether LinkFilter::makeLikeArray($pattern) will reject invalid search patterns * * @dataProvider provideInvalidPatterns * * @param string $pattern Invalid search pattern */ function testMakeLikeArrayWithInvalidPatterns($pattern) { $this->assertFalse(LinkFilter::makeLikeArray($pattern), "'{$pattern}' is not a valid pattern and should be rejected"); }
/** * Return an appropriately formatted LIKE query and the clause * * @param string $query Search pattern to search for * @param string $prot Protocol, e.g. 'http://' * * @return array */ static function mungeQuery($query, $prot) { $field = 'el_index'; $dbr = wfGetDB(DB_SLAVE); if ($query === '*' && $prot !== '') { // Allow queries like 'ftp://*' to find all ftp links $rv = array($prot, $dbr->anyString()); } else { $rv = LinkFilter::makeLikeArray($query, $prot); } if ($rv === false) { // LinkFilter doesn't handle wildcard in IP, so we'll have to munge here. $pattern = '/^(:?[0-9]{1,3}\\.)+\\*\\s*$|^(:?[0-9]{1,3}\\.){3}[0-9]{1,3}:[0-9]*\\*\\s*$/'; if (preg_match($pattern, $query)) { $rv = array($prot . rtrim($query, " \t*"), $dbr->anyString()); $field = 'el_to'; } } return array($rv, $field); }
private function run($resultPageSet = null) { $params = $this->extractRequestParams(); $protocol = $params['protocol']; $query = $params['query']; // Find the right prefix global $wgUrlProtocols; if ($protocol && !in_array($protocol, $wgUrlProtocols)) { foreach ($wgUrlProtocols as $p) { if (substr($p, 0, strlen($protocol)) === $protocol) { $protocol = $p; break; } } } else { $protocol = null; } $db = $this->getDB(); $this->addTables(array('page', 'externallinks')); // must be in this order for 'USE INDEX' $this->addOption('USE INDEX', 'el_index'); $this->addWhere('page_id=el_from'); $this->addWhereFld('page_namespace', $params['namespace']); if (!is_null($query) || $query != '') { if (is_null($protocol)) { $protocol = 'http://'; } $likeQuery = LinkFilter::makeLikeArray($query, $protocol); if (!$likeQuery) { $this->dieUsage('Invalid query', 'bad_query'); } $likeQuery = LinkFilter::keepOneWildcard($likeQuery); $this->addWhere('el_index ' . $db->buildLike($likeQuery)); } elseif (!is_null($protocol)) { $this->addWhere('el_index ' . $db->buildLike("{$protocol}", $db->anyString())); } $prop = array_flip($params['prop']); $fld_ids = isset($prop['ids']); $fld_title = isset($prop['title']); $fld_url = isset($prop['url']); if (is_null($resultPageSet)) { $this->addFields(array('page_id', 'page_namespace', 'page_title')); $this->addFieldsIf('el_to', $fld_url); } else { $this->addFields($resultPageSet->getPageTableFields()); } $limit = $params['limit']; $offset = $params['offset']; $this->addOption('LIMIT', $limit + 1); if (isset($offset)) { $this->addOption('OFFSET', $offset); } $res = $this->select(__METHOD__); $result = $this->getResult(); $count = 0; foreach ($res as $row) { if (++$count > $limit) { // We've reached the one extra which shows that there are additional pages to be had. Stop here... $this->setContinueEnumParameter('offset', $offset + $limit); break; } if (is_null($resultPageSet)) { $vals = array(); if ($fld_ids) { $vals['pageid'] = intval($row->page_id); } if ($fld_title) { $title = Title::makeTitle($row->page_namespace, $row->page_title); ApiQueryBase::addTitleInfo($vals, $title); } if ($fld_url) { $vals['url'] = $row->el_to; } $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals); if (!$fit) { $this->setContinueEnumParameter('offset', $offset + $count - 1); break; } } else { $resultPageSet->processDbRow($row); } } if (is_null($resultPageSet)) { $result->setIndexedTagName_internal(array('query', $this->getModuleName()), $this->getModulePrefix()); } }