From 2800ca2db7688802ff61ec38c6a4d7191c5060c3 Mon Sep 17 00:00:00 2001 From: "Mark A. Hershberger" Date: Fri, 15 Jan 2010 19:14:23 +0000 Subject: [PATCH] follow up r60832 and follow up r60763 * Don't set Parser::$mTitle to random garbage. * Remove ParserOutput::$displayTitle, make setDisplayTitle() and getDisplayTitle() wrappers for their *TitleText() equivalents. * Remove Parser::$mDo*Convert member variables, move test for $mDoubleUnderScores[] directives closer to the action. * Remove bogus "global $wgContLang". * Use accessor to get at $mConvRuleTitle * Fix up showtitle option in parserTests.inc * TODO: refactor FakeConverter class away --- includes/OutputPage.php | 8 +--- includes/parser/Parser.php | 47 +++++++-------------- includes/parser/ParserOutput.php | 12 +++--- languages/Language.php | 4 +- languages/LanguageConverter.php | 8 ++++ maintenance/parserTests.inc | 70 +++++++++++++++++--------------- maintenance/parserTests.txt | 1 + 7 files changed, 68 insertions(+), 82 deletions(-) diff --git a/includes/OutputPage.php b/includes/OutputPage.php index a33efb9676..3090e19903 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -347,8 +347,6 @@ class OutputPage { * Bad tags that were escaped in

will still be escaped in , and good tags like <i> will be dropped entirely. */ public function setPageTitle( $name ) { - global $wgContLang; - # change "<script>foo&bar</script>" to "<script>foo&bar</script>" # but leave "<i>foobar</i>" alone $nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) ); @@ -617,12 +615,8 @@ class OutputPage { } } // Page title - $dt = $parserOutput->getDisplayTitle(); $title = $parserOutput->getTitleText(); - if ( $dt !== false ) { - $this->setPageTitle( $dt ); - } - else if ( $title != '' ) { + if ( $title != '' ) { $this->setPageTitle( $title ); } diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 47a6b828e8..ebed9ebd82 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -93,7 +93,7 @@ class Parser var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables, $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerIndex, $mPreprocessor, $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList, $mVarCache, $mConf, - $mFunctionTagHooks, $mDoTitleConvert, $mDoContentConvert; + $mFunctionTagHooks; # Cleared with clearState(): @@ -147,8 +147,6 @@ class Parser } $this->mMarkerIndex = 0; $this->mFirstCall = true; - $this->mDoTitleConvert = true; - $this->mDoContentConvert = true; } /** @@ -258,18 +256,9 @@ class Parser * Set the context title */ function setTitle( $t ) { - // If don't have a Title object, then convert what we have to - // a string and then to Title. If you pass in an object, make - // sure it has a __toString() method or you'll get a - // "Catchable fatal error" - if ( $t && !($t instanceOf FakeTitle) - && !($t instanceOf Title) ) { - $t = Title::newFromText( "$t" ); - } - - if ( !($t instanceOf Title) ) { - $t = Title::newFromText( 'NO TITLE' ); - } + if ( !$t || $t instanceof FakeTitle ) { + $t = Title::newFromText( 'NO TITLE' ); + } if ( strval( $t->getFragment() ) !== '' ) { # Strip the fragment to avoid various odd effects @@ -316,7 +305,7 @@ class Parser * to internalParse() which does all the real work. */ - global $wgUseTidy, $wgAlwaysUseTidy, $wgContLang; + global $wgUseTidy, $wgAlwaysUseTidy, $wgContLang, $wgDisableLangConversion; $fname = __METHOD__.'-' . wfGetCaller(); wfProfileIn( __METHOD__ ); wfProfileIn( $fname ); @@ -360,7 +349,10 @@ class Parser // The position of the convert() call should not be changed. it // assumes that the links are all replaced and the only thing left // is the <nowiki> mark. - if ( $this->mDoContentConvert && !$this->mTitle->isConversionTable()) { + if ( !( $wgDisableLangConversion + || isset( $this->mDoubleUnderscores['nocontentconvert'] ) + || $this->mTitle->isTalkPage() + || $this->mTitle->isConversionTable() ) ) { $text = $wgContLang->convert( $text ); } @@ -369,9 +361,10 @@ class Parser // rule but content conversion was not done, then the parser // won't pick it up. This is probably expected behavior. if ( $wgContLang->getConvRuleTitle() ) { - $this->setTitle( $wgContLang->getConvRuleTitle() ); - } elseif ( $this->mDoTitleConvert && !$this->mTitle->isConversionTable() ) { - $this->setTitle( $wgContLang->convert( $title ) ); + $this->mOutput->setTitleText( $wgContLang->getConvRuleTitle() ); + } elseif ( !( $wgDisableLangConversion + || isset( $this->mDoubleUnderscores['notitleconvert'] ) ) ) { + $this->mOutput->setTitleText( $wgContLang->convert( $title ) ); } $text = $this->mStripState->unstripNoWiki( $text ); @@ -451,6 +444,7 @@ class Parser $text .= "\n<!-- \n$limitReport-->\n"; } $this->mOutput->setText( $text ); + $this->mRevisionId = $oldRevisionId; $this->mRevisionTimestamp = $oldRevisionTimestamp; wfProfileOut( $fname ); @@ -3423,7 +3417,6 @@ class Parser * Fills $this->mDoubleUnderscores, returns the modified text */ function doDoubleUnderscore( $text ) { - global $wgDisableLangConversion; wfProfileIn( __METHOD__ ); // The position of __TOC__ needs to be recorded @@ -3466,18 +3459,6 @@ class Parser $this->addTrackingCategory( 'index-category' ); } - if ( !$wgDisableLangConversion ) { - if( isset( $this->mDoubleUnderscores['notitleconvert'] ) ){ - $this->mDoTitleConvert = false; - } - - // Don't convert talk pages - if( isset( $this->mDoubleUnderscores['nocontentconvert'] ) - && !$this->mTitle->isTalkPage() ){ - $this->mDoContentConvert = false; - } - } - wfProfileOut( __METHOD__ ); return $text; } diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php index 38d21fb55b..235011859e 100644 --- a/includes/parser/ParserOutput.php +++ b/includes/parser/ParserOutput.php @@ -28,11 +28,6 @@ class ParserOutput $mTOCHTML = ''; # HTML of the TOC private $mIndexPolicy = ''; # 'index' or 'noindex'? Any other value will result in no change. - /** - * Overridden title for display - */ - private $displayTitle = false; - function ParserOutput( $text = '', $languageLinks = array(), $categoryLinks = array(), $containsOldMagic = false, $titletext = '' ) { @@ -183,7 +178,7 @@ class ParserOutput * @param string $text Desired title text */ public function setDisplayTitle( $text ) { - $this->displayTitle = $text; + $this->setTitleText( $text ); } /** @@ -192,7 +187,10 @@ class ParserOutput * @return string */ public function getDisplayTitle() { - return $this->displayTitle; + $t = $this->getTitleText( $text ); + if( $t === '' ) { + return false; + } } /** diff --git a/languages/Language.php b/languages/Language.php index 0648b62bf3..4cd4ffa12f 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -34,12 +34,12 @@ if( function_exists( 'mb_strtoupper' ) ) { */ class FakeConverter { var $mLang; - var $mConvRuleTitle; function FakeConverter($langobj) {$this->mLang = $langobj;} function autoConvertToAllVariants($text) {return $text;} function convert($t, $i) {return $t;} function getVariants() { return array( $this->mLang->getCode() ); } function getPreferredVariant() { return $this->mLang->getCode(); } + function getConvRuleTitle() { return false; } function findVariantLink(&$l, &$n, $ignoreOtherCond = false) {} function getExtraHashOptions() {return '';} function getParsedTitle() {return '';} @@ -2670,6 +2670,6 @@ class Language { * Get the conversion rule title, if any. */ function getConvRuleTitle() { - return $this->mConverter->mConvRuleTitle; + return $this->mConverter->getConvRuleTitle(); } } diff --git a/languages/LanguageConverter.php b/languages/LanguageConverter.php index e06fa95aa7..8a4b711ac4 100644 --- a/languages/LanguageConverter.php +++ b/languages/LanguageConverter.php @@ -130,6 +130,14 @@ class LanguageConverter { return $this->mMainLanguageCode; } + /** + * Get the title produced by the conversion rule. + * @returns string + */ + function getConvRuleTitle() { + return $this->mConvRuleTitle; + } + /** * Get preferred language variants. * @param boolean $fromUser Get it from $wgUser's preferences diff --git a/maintenance/parserTests.inc b/maintenance/parserTests.inc index bf4f00fea6..45e6215a5d 100644 --- a/maintenance/parserTests.inc +++ b/maintenance/parserTests.inc @@ -28,7 +28,9 @@ $options = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record'. 'run-disabled' ); $optionsWithArgs = array( 'regex', 'seed', 'setversion' ); -require_once( dirname(__FILE__) . '/commandLine.inc' ); +if ( !defined( "NO_COMMAND_LINE" ) ) { + require_once( dirname(__FILE__) . '/commandLine.inc' ); +} require_once( "$IP/maintenance/parserTestsParserHook.php" ); require_once( "$IP/maintenance/parserTestsStaticParserHook.php" ); require_once( "$IP/maintenance/parserTestsParserTime.php" ); @@ -97,7 +99,7 @@ class ParserTest { isset( $options['quiet'] ) && ( isset( $options['record'] ) || isset( $options['compare'] ) ) ); // redundant output - + $this->showOutput = isset( $options['show-output'] ); @@ -359,7 +361,7 @@ class ParserTest { } if (!isset( $data['config'] ) ) $data['config'] = ''; - + if ( (preg_match('/\\bdisabled\\b/i', $data['options']) || !preg_match("/{$this->regex}/i", $data['test'])) && !$this->runDisabled ) { # disabled test @@ -477,6 +479,9 @@ class ParserTest { $output = $parser->parse( $input, $title, $options, true, true, 1337 ); $out = $output->getText(); + if ( isset( $opts['showtitle'] ) ) { + $out = $output->getTitleText() . "\n$out"; + } if (isset( $opts['ill'] ) ) { $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) ); } elseif( isset( $opts['cat'] ) ) { @@ -493,9 +498,6 @@ class ParserTest { $result = $this->tidy($result); } - if ( isset( $opts['showtitle'] ) ) { - $out = $parser->mTitle . "\n$out"; - } $this->teardownGlobals(); @@ -521,7 +523,7 @@ class ParserTest { return $default; } } - + private function parseOptions( $instring ) { $opts = array(); $lines = explode( "\n", $instring ); @@ -577,7 +579,7 @@ class ParserTest { } return $opts; } - + private function cleanupOption( $opt ) { if( substr( $opt, 0, 1 ) == '"' ) { return substr( $opt, 1, -1 ); @@ -605,7 +607,7 @@ class ParserTest { self::getOptionValue( 'variant', $opts, false ); $maxtoclevel = self::getOptionValue( 'wgMaxTocLevel', $opts, 999 ); - $linkHolderBatchSize = + $linkHolderBatchSize = self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 ); $settings = array( @@ -664,17 +666,19 @@ class ParserTest { if ($config) { $configLines = explode( "\n", $config ); - + foreach( $configLines as $line ) { list( $var, $value ) = explode( '=', $line, 2 ); - + $settings[$var] = eval("return $value;" ); } } - + $this->savedGlobals = array(); foreach( $settings as $var => $val ) { - $this->savedGlobals[$var] = $GLOBALS[$var]; + if( array_key_exists( $var, $GLOBALS ) ) { + $this->savedGlobals[$var] = $GLOBALS[$var]; + } $GLOBALS[$var] = $val; } $langObj = Language::factory( $lang ); @@ -706,9 +710,9 @@ class ParserTest { 'archive', 'user_groups', 'page_props', 'category' ); - if ($wgDBtype === 'mysql') + if ($wgDBtype === 'mysql') array_push( $tables, 'searchindex' ); - + // Allow extensions to add to the list of tables to duplicate; // may be necessary if they hook into page save or other code // which will require them while running tests. @@ -791,7 +795,7 @@ class ParserTest { if ($wgDBtype == 'oracle') { # Insert 0 and 1 user_ids to prevent FK violations - + #Anonymous user $db->insert( 'user', array( 'user_id' => 0, @@ -867,7 +871,7 @@ class ParserTest { $db->query('BEGIN FILL_WIKI_INFO; END;'); */ } - + /** * Create a dummy uploads directory which will contain a couple * of files in order to pass existence tests. @@ -1310,8 +1314,8 @@ class DbTestPreviewer extends TestRecorder { global $wgDBtype, $wgDBprefix; parent::start(); - if( ! $this->db->tableExists( 'testrun' ) - or ! $this->db->tableExists( 'testitem' ) ) + if( ! $this->db->tableExists( 'testrun' ) + or ! $this->db->tableExists( 'testitem' ) ) { print "WARNING> `testrun` table not found in database.\n"; $this->prevRun = false; @@ -1347,7 +1351,7 @@ class DbTestPreviewer extends TestRecorder { $res = $this->db->select( 'testitem', array( 'ti_name', 'ti_success' ), array( 'ti_run' => $this->prevRun ), __METHOD__ ); foreach ( $res as $row ) { - if ( !$this->parent->regex + if ( !$this->parent->regex || preg_match( "/{$this->parent->regex}/i", $row->ti_name ) ) { $prevResults[$row->ti_name] = $row->ti_success; @@ -1420,7 +1424,7 @@ class DbTestPreviewer extends TestRecorder { // Otherwise, this test has previous recorded results. // See when this test last had a different result to what we're seeing now. - $conds = array( + $conds = array( 'ti_name' => $testname, 'ti_success' => ($after == 'f' ? "1" : "0") ); if ( $this->curRun ) { @@ -1483,8 +1487,8 @@ class DbTestRecorder extends DbTestPreviewer { global $wgDBtype, $wgDBprefix, $options; $this->db->begin(); - if( ! $this->db->tableExists( 'testrun' ) - or ! $this->db->tableExists( 'testitem' ) ) + if( ! $this->db->tableExists( 'testrun' ) + or ! $this->db->tableExists( 'testitem' ) ) { print "WARNING> `testrun` table not found in database. Trying to create table.\n"; if ($wgDBtype === 'postgres') @@ -1495,7 +1499,7 @@ class DbTestRecorder extends DbTestPreviewer { $this->db->sourceFile( dirname(__FILE__) . '/testRunner.sql' ); echo "OK, resuming.\n"; } - + parent::start(); $this->db->insert( 'testrun', @@ -1537,17 +1541,17 @@ class RemoteTestRecorder extends TestRecorder { $this->results = array(); $this->ping( 'running' ); } - + function record( $test, $result ) { parent::record( $test, $result ); $this->results[$test] = (bool)$result; } - + function end() { $this->ping( 'complete', $this->results ); parent::end(); } - + /** * Inform a CodeReview instance that we've started or completed a test run... * @param $remote array: info on remote target @@ -1558,16 +1562,16 @@ class RemoteTestRecorder extends TestRecorder { */ function ping( $status, $results=false ) { global $wgParserTestRemote, $IP; - + $remote = $wgParserTestRemote; $revId = SpecialVersion::getSvnRevision( $IP ); $jsonResults = json_encode( $results ); - + if( !$remote ) { print "Can't do remote upload without configuring \$wgParserTestRemote!\n"; exit( 1 ); } - + // Generate a hash MAC to validate our credentials $message = array( $remote['repo'], @@ -1579,7 +1583,7 @@ class RemoteTestRecorder extends TestRecorder { $message[] = $jsonResults; } $hmac = hash_hmac( "sha1", implode( "|", $message ), $remote['secret'] ); - + $postData = array( 'action' => 'codetestupload', 'format' => 'json', @@ -1593,7 +1597,7 @@ class RemoteTestRecorder extends TestRecorder { $postData['results'] = $jsonResults; } $response = $this->post( $remote['api-url'], $postData ); - + if( $response === false ) { print "CodeReview info upload failed to reach server.\n"; exit( 1 ); @@ -1611,7 +1615,7 @@ class RemoteTestRecorder extends TestRecorder { exit( 1 ); } } - + function post( $url, $data ) { // @fixme: for whatever reason, I get a 417 fail when using CURL's multipart form submit. // If we do form URL encoding ourselves, though, it should work. diff --git a/maintenance/parserTests.txt b/maintenance/parserTests.txt index 6952179720..7ccfdbdf49 100644 --- a/maintenance/parserTests.txt +++ b/maintenance/parserTests.txt @@ -21,6 +21,7 @@ # language=XXX set content language to XXX for this test # variant=XXX set the variant of language for this test (eg zh-tw) # disabled do not run test +# showtitle make the first line the title # comment run through Linker::formatComment() instead of main parser # local format section links in edit comment text as local links # -- 2.20.1