seedTestUsers( $seedDataPath ); $importer = $this->getWikiImporter( $seedDataPath ); $importer->disableStatisticsUpdate(); // Ensure we actually create local user accounts in the DB $importer->setUsernamePrefix( '', true ); $importer->doImport(); self::$wasSeedDataImported = true; } /** * Import test accounts from seed data so that DPL queries can refer to them. * @param string $seedDataPath - path to seed data to be loaded */ private function seedTestUsers( string $seedDataPath ): void { $doc = new DOMDocument(); $doc->preserveWhiteSpace = false; $doc->load( $seedDataPath ); $xpath = new DOMXPath( $doc ); $xpath->registerNamespace( 'mw', 'http://www.mediawiki.org/xml/export-0.11/' ); $userNodes = $xpath->query( '//mw:mediawiki/mw:page/mw:revision/mw:contributor/mw:username' ); $usersByName = []; $authManager = $this->getAuthManager(); foreach ( $userNodes as $node ) { $userName = $node->nodeValue; // Already created if ( isset( $usersByName[$userName] ) ) { continue; } $usersByName[$userName] = true; $user = $this->newUserFromName( $userName ); if ( !$user || $user->idForName() !== 0 ) { // sanity return; } $status = $authManager->autoCreateUser( $user, $authManager::AUTOCREATE_SOURCE_MAINT, false ); if ( !$status->isOK() ) { return; } } } private function getWikiImporter( string $seedDataPath ): WikiImporter { $seedDataFile = fopen( $seedDataPath, 'rt' ); $source = new ImportStreamSource( $seedDataFile ); $services = MediaWikiServices::getInstance(); if ( version_compare( MW_VERSION, '1.42', '>=' ) ) { $performer = $this->getTestSysop()->getAuthority(); return $services->getWikiImporterFactory()->getWikiImporter( $source, $performer ); } return $services->getWikiImporterFactory()->getWikiImporter( $source ); } private function getAuthManager(): AuthManager { $services = MediaWikiServices::getInstance(); return $services->getAuthManager(); } private function newUserFromName( string $name ): ?User { $services = MediaWikiServices::getInstance(); return $services->getUserFactory()->newFromName( $name, UserFactory::RIGOR_CREATABLE ); } /** * Convenience function to return the list of page titles matching a DPL query * @param array $params - DPL invocation parameters * @param string $format * @return string[] */ protected function getDPLQueryResults( array $params, string $format = '%PAGE%' ): array { $params += [ // Use a custom format for executing the query to allow easily extracting results 'format' => "
,$format,|,
" ]; $html = $this->runDPLQuery( $params ); $doc = new DOMDocument(); $doc->loadHTML( $html ); $queryResults = $doc->getElementById( 'dpl-test-query' ); if ( $queryResults ) { return explode( "|", rtrim( $queryResults->textContent, "|" ) ); } return []; } /** * Build and execute a DPL invocation using the given parameters and return the HTML output. * @param array $params * @return string */ protected function runDPLQuery( array $params ): string { $invocation = ''; foreach ( $params as $paramName => $values ) { // multi-value parameters $values = (array)$values; foreach ( $values as $value ) { $invocation .= "$paramName=$value\n"; } } $invocation .= ''; $parser = MediaWikiServices::getInstance()->getParser(); $title = Title::makeTitle( NS_MAIN, 'DPLQueryTest' ); $parserOptions = ParserOptions::newCanonical( RequestContext::getMain() ); $parserOutput = $parser->parse( $invocation, $title, $parserOptions ); return $parserOutput->getText(); } }