Skip to content

Commit

Permalink
ParserAfterTidy to check readOnly mode, refs 2432 (#2434)
Browse files Browse the repository at this point in the history
  • Loading branch information
mwjames committed May 13, 2017
1 parent 47cac6b commit e09fb92
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/MediaWiki/Hooks/HookRegistry.php
Expand Up @@ -143,6 +143,14 @@ private function addCallbackHandlers( $basePath, $globalVars ) {
*/
$this->handlers['ParserAfterTidy'] = function ( &$parser, &$text ) {

// MediaWiki\Services\ServiceDisabledException from line 340 of
// ...\ServiceContainer.php: Service disabled: DBLoadBalancer
try {
$isReadOnly = wfReadOnly();
} catch( \MediaWiki\Services\ServiceDisabledException $e ) {
$isReadOnly = true;
}

$parserAfterTidy = new ParserAfterTidy(
$parser
);
Expand All @@ -151,6 +159,10 @@ private function addCallbackHandlers( $basePath, $globalVars ) {
$GLOBALS['wgCommandLineMode']
);

$parserAfterTidy->isReadOnly(
$isReadOnly
);

return $parserAfterTidy->process( $text );
};

Expand Down
21 changes: 21 additions & 0 deletions src/MediaWiki/Hooks/ParserAfterTidy.php
Expand Up @@ -5,6 +5,7 @@
use Parser;
use SMW\ApplicationFactory;
use SMW\SemanticData;
use SMW\MediaWiki\MediaWiki;

/**
* Hook: ParserAfterTidy to add some final processing to the
Expand All @@ -29,6 +30,11 @@ class ParserAfterTidy extends HookHandler {
*/
private $isCommandLineMode = false;

/**
* @var boolean
*/
private $isReadOnly = false;

/**
* @since 1.9
*
Expand All @@ -49,6 +55,15 @@ public function isCommandLineMode( $isCommandLineMode ) {
$this->isCommandLineMode = (bool)$isCommandLineMode;
}

/**
* @since 3.0
*
* @param boolean $isReadOnly
*/
public function isReadOnly( $isReadOnly ) {
$this->isReadOnly = (bool)$isReadOnly;
}

/**
* @since 1.9
*
Expand All @@ -67,6 +82,12 @@ public function process( &$text ) {

private function canPerformUpdate() {

// #2432 avoid access to the DBLoadBalancer while being in readOnly mode
// when for example Title::isProtected is accessed
if ( $this->isReadOnly ) {
return false;
}

// ParserOptions::getInterfaceMessage is being used to identify whether a
// parse was initiated by `Message::parse`
if ( $this->parser->getTitle()->isSpecialPage() || $this->parser->getOptions()->getInterfaceMessage() ) {
Expand Down
16 changes: 16 additions & 0 deletions tests/phpunit/Unit/MediaWiki/Hooks/ParserAfterTidyTest.php
Expand Up @@ -68,6 +68,22 @@ public function testCanConstruct() {
);
}

public function testIsReadOnly() {

$parser = $this->getMockBuilder( 'Parser' )
->disableOriginalConstructor()
->getMock();

$parser->expects( $this->never() )
->method( 'getTitle' );

$instance = new ParserAfterTidy( $parser );
$instance->isReadOnly( true );

$text = '';
$instance->process( $text );
}

private function newMockCache( $id, $containsStatus, $fetchStatus ) {

$key = $this->applicationFactory->newCacheFactory()->getPurgeCacheKey( $id );
Expand Down

0 comments on commit e09fb92

Please sign in to comment.