* In Skin::doEditSectionLink omitting the parameters $tooltip and $lang is
deprecated. For the $lang parameter, types other than Language are
deprecated.
+* The $wgUseKeyHeader configuration option and the
+ OutputPage::getKeyHeader() method have been deprecated; the relevant
+ draft IETF spec expired without becoming a standard.
=== Other changes in 1.32 ===
* (T198811) The following tables have had their UNIQUE indexes turned into
/**
* Send the Key HTTP header for better caching.
- * See https://datatracker.ietf.org/doc/draft-fielding-http-key/ for details.
+ * See https://datatracker.ietf.org/doc/draft-ietf-httpbis-key/ for details.
* @since 1.27
+ * @deprecated in 1.32, the IETF spec expired without becoming a standard.
*/
$wgUseKeyHeader = false;
* Get a complete Key header
*
* @return string
+ * @deprecated in 1.32; the IETF spec for this header expired w/o becoming
+ * a standard.
*/
public function getKeyHeader() {
+ wfDeprecated( '$wgUseKeyHeader', '1.32' );
+
$cvCookies = $this->getCacheVaryCookies();
$cookiesOption = [];
continue;
}
+ // XXX Note that this code is not strictly correct: we
+ // do a case-insensitive match in
+ // LanguageConverter::getHeaderVariant() while the
+ // (abandoned, draft) spec for the `Key` header only
+ // allows case-sensitive matches. To match the logic
+ // in LanguageConverter::getHeaderVariant() we should
+ // also be looking at fallback variants and deprecated
+ // mediawiki-internal codes, as well as BCP 47
+ // normalized forms.
+
$aloption[] = "substr=$variant";
// IE and some other browsers use BCP 47 standards in their Accept-Language header,
'WatchedItemStore' => function ( MediaWikiServices $services ) : WatchedItemStore {
$store = new WatchedItemStore(
- $services->getDBLoadBalancer(),
+ $services->getDBLoadBalancerFactory(),
new HashBagOStuff( [ 'maxKeys' => 100 ] ),
$services->getReadOnlyMode(),
$services->getMainConfig()->get( 'UpdateRowsPerQuery' )
throw new MWException( __CLASS__ . ': must call startWrite() before finishWrite()' );
}
- $dbw = $this->getWriteConnection();
- $dbw->startAtomic( __METHOD__ );
+ $trxProfiler = Profiler::instance()->getTransactionProfiler();
+ $oldSilenced = $trxProfiler->setSilenced( true );
try {
- $dbw->delete( 'l10n_cache', [ 'lc_lang' => $this->currentLang ], __METHOD__ );
- foreach ( array_chunk( $this->batch, 500 ) as $rows ) {
- $dbw->insert( 'l10n_cache', $rows, __METHOD__ );
- }
- $this->writesDone = true;
- } catch ( DBQueryError $e ) {
- if ( $dbw->wasReadOnlyError() ) {
- $this->readOnly = true; // just avoid site down time
- } else {
- throw $e;
+ $dbw = $this->getWriteConnection();
+ $dbw->startAtomic( __METHOD__ );
+ try {
+ $dbw->delete( 'l10n_cache', [ 'lc_lang' => $this->currentLang ], __METHOD__ );
+ foreach ( array_chunk( $this->batch, 500 ) as $rows ) {
+ $dbw->insert( 'l10n_cache', $rows, __METHOD__ );
+ }
+ $this->writesDone = true;
+ } catch ( DBQueryError $e ) {
+ if ( $dbw->wasReadOnlyError() ) {
+ $this->readOnly = true; // just avoid site down time
+ } else {
+ throw $e;
+ }
}
+ $dbw->endAtomic( __METHOD__ );
+ } finally {
+ $trxProfiler->setSilenced( $oldSilenced );
}
- $dbw->endAtomic( __METHOD__ );
$this->currentLang = null;
$this->batch = [];
* of fields.
* required - If specified, at least one group of fields must be submitted.
* format - HTMLForm display format to use when displaying the subfields:
- * 'table', 'div', or 'raw'.
+ * 'table', 'div', or 'raw'. This is ignored when using OOUI.
* row-legend - If non-empty, each group of subfields will be enclosed in a
* fieldset. The value is the name of a message key to use as the legend.
* create-button-message - Message to use as the text of the button to
}
if ( !isset( $fields['delete'] ) ) {
- $name = "{$this->mName}[$key][delete]";
- $label = $this->mParams['delete-button-message'] ?? 'htmlform-cloner-delete';
- $field = HTMLForm::loadInputFromParameters( $name, [
- 'type' => 'submit',
- 'formnovalidate' => true,
- 'name' => $name,
- 'id' => Sanitizer::escapeIdForAttribute( "{$this->mID}--$key--delete" ),
- 'cssclass' => 'mw-htmlform-cloner-delete-button',
- 'default' => $this->getMessage( $label )->text(),
- ], $this->mParent );
- $v = $field->getDefault();
+ $field = $this->getDeleteButtonHtml( $key );
if ( $displayFormat === 'table' ) {
- $html .= $field->$getFieldHtmlMethod( $v );
+ $html .= $field->$getFieldHtmlMethod( $field->getDefault() );
} else {
- $html .= $field->getInputHTML( $v );
+ $html .= $field->getInputHTML( $field->getDefault() );
}
}
return $html;
}
+ /**
+ * @param string $key Array key indicating to which field the delete button belongs
+ * @return HTMLFormField
+ */
+ protected function getDeleteButtonHtml( $key ) : HTMLFormField {
+ $name = "{$this->mName}[$key][delete]";
+ $label = $this->mParams['delete-button-message'] ?? 'htmlform-cloner-delete';
+ $field = HTMLForm::loadInputFromParameters( $name, [
+ 'type' => 'submit',
+ 'formnovalidate' => true,
+ 'name' => $name,
+ 'id' => Sanitizer::escapeIdForAttribute( "{$this->mID}--$key--delete" ),
+ 'cssclass' => 'mw-htmlform-cloner-delete-button',
+ 'default' => $this->getMessage( $label )->text(),
+ ], $this->mParent );
+ return $field;
+ }
+
+ protected function getCreateButtonHtml() : HTMLFormField {
+ $name = "{$this->mName}[create]";
+ $label = $this->mParams['create-button-message'] ?? 'htmlform-cloner-create';
+ return HTMLForm::loadInputFromParameters( $name, [
+ 'type' => 'submit',
+ 'formnovalidate' => true,
+ 'name' => $name,
+ 'id' => Sanitizer::escapeIdForAttribute( "{$this->mID}--create" ),
+ 'cssclass' => 'mw-htmlform-cloner-create-button',
+ 'default' => $this->getMessage( $label )->text(),
+ ], $this->mParent );
+ }
+
public function getInputHTML( $values ) {
$html = '';
'data-unique-id' => $this->uniqueId,
], $html );
- $name = "{$this->mName}[create]";
- $label = $this->mParams['create-button-message'] ?? 'htmlform-cloner-create';
- $field = HTMLForm::loadInputFromParameters( $name, [
- 'type' => 'submit',
- 'formnovalidate' => true,
- 'name' => $name,
- 'id' => Sanitizer::escapeIdForAttribute( "{$this->mID}--create" ),
- 'cssclass' => 'mw-htmlform-cloner-create-button',
- 'default' => $this->getMessage( $label )->text(),
- ], $this->mParent );
+ $field = $this->getCreateButtonHtml();
$html .= $field->getInputHTML( $field->getDefault() );
return $html;
}
+
+ /**
+ * Get the input OOUI HTML for the specified key.
+ *
+ * @param string $key Array key under which the fields should be named
+ * @param array $values
+ * @return string
+ */
+ protected function getInputOOUIForKey( $key, array $values ) {
+ $html = '';
+ $hidden = '';
+
+ $fields = $this->createFieldsForKey( $key );
+ foreach ( $fields as $fieldname => $field ) {
+ $v = array_key_exists( $fieldname, $values )
+ ? $values[$fieldname]
+ : $field->getDefault();
+
+ if ( $field instanceof HTMLHiddenField ) {
+ // HTMLHiddenField doesn't generate its own HTML
+ list( $name, $value, $params ) = $field->getHiddenFieldData( $v );
+ $hidden .= Html::hidden( $name, $value, $params ) . "\n";
+ } else {
+ $html .= $field->getOOUI( $v );
+ }
+ }
+
+ if ( !isset( $fields['delete'] ) ) {
+ $field = $this->getDeleteButtonHtml( $key );
+ $fieldHtml = $field->getInputOOUI( $field->getDefault() );
+ $fieldHtml->setInfusable( true );
+
+ $html .= $fieldHtml;
+ }
+
+ $classes = [
+ 'mw-htmlform-cloner-row',
+ ];
+
+ $attribs = [
+ 'class' => implode( ' ', $classes ),
+ ];
+
+ $html = Html::rawElement( 'div', $attribs, "\n$html\n" );
+
+ $html .= $hidden;
+
+ if ( !empty( $this->mParams['row-legend'] ) ) {
+ $legend = $this->msg( $this->mParams['row-legend'] )->text();
+ $html = Xml::fieldset( $legend, $html );
+ }
+
+ return $html;
+ }
+
+ public function getInputOOUI( $values ) {
+ $html = '';
+
+ foreach ( (array)$values as $key => $value ) {
+ if ( $key === 'nonjs' ) {
+ continue;
+ }
+ $html .= Html::rawElement( 'li', [ 'class' => 'mw-htmlform-cloner-li' ],
+ $this->getInputOOUIForKey( $key, $value )
+ );
+ }
+
+ $template = $this->getInputOOUIForKey( $this->uniqueId, [] );
+ $html = Html::rawElement( 'ul', [
+ 'id' => "mw-htmlform-cloner-list-{$this->mID}",
+ 'class' => 'mw-htmlform-cloner-ul',
+ 'data-template' => $template,
+ 'data-unique-id' => $this->uniqueId,
+ ], $html );
+
+ $field = $this->getCreateButtonHtml();
+ $fieldHtml = $field->getInputOOUI( $field->getDefault() );
+ $fieldHtml->setInfusable( true );
+
+ $html .= $fieldHtml;
+
+ return $html;
+ }
}
use Wikimedia\Rdbms\DBQueryError;
use Wikimedia\Rdbms\DBConnectionError;
use Wikimedia\Rdbms\LoadBalancer;
-use Wikimedia\Rdbms\TransactionProfiler;
+use Wikimedia\ScopedCallback;
use Wikimedia\WaitConditionLoop;
/**
$type = $info['type'] ?? 'mysql';
$host = $info['host'] ?? '[unknown]';
$this->logger->debug( __CLASS__ . ": connecting to $host" );
- // Use a blank trx profiler to ignore expections as this is a cache
- $info['trxProfiler'] = new TransactionProfiler();
$db = Database::factory( $type, $info );
$db->clearFlag( DBO_TRX ); // auto-commit mode
} else {
if ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' ) {
// Keep a separate connection to avoid contention and deadlocks
$db = $lb->getConnection( $index, [], false, $lb::CONN_TRX_AUTOCOMMIT );
- // @TODO: Use a blank trx profiler to ignore expections as this is a cache
} else {
// However, SQLite has the opposite behavior due to DB-level locking.
// Stock sqlite MediaWiki installs use a separate sqlite cache DB instead.
$result = true;
$exptime = (int)$expiry;
+ $silenceScope = $this->silenceTransactionProfiler();
foreach ( $keysByTable as $serverIndex => $serverKeys ) {
$db = null;
try {
protected function cas( $casToken, $key, $value, $exptime = 0 ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$exptime = intval( $exptime );
public function delete( $key ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$db->delete(
public function incr( $key, $step = 1 ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$step = intval( $step );
public function changeTTL( $key, $expiry = 0 ) {
list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
$db = null;
+ $silenceScope = $this->silenceTransactionProfiler();
try {
$db = $this->getDB( $serverIndex );
$db->update(
* @return bool
*/
public function deleteObjectsExpiringBefore( $timestamp, $progressCallback = false ) {
+ $silenceScope = $this->silenceTransactionProfiler();
for ( $serverIndex = 0; $serverIndex < $this->numServers; $serverIndex++ ) {
$db = null;
try {
* @return bool
*/
public function deleteAll() {
+ $silenceScope = $this->silenceTransactionProfiler();
for ( $serverIndex = 0; $serverIndex < $this->numServers; $serverIndex++ ) {
$db = null;
try {
return ( $loop->invoke() === $loop::CONDITION_REACHED );
}
+
+ /**
+ * Returns a ScopedCallback which resets the silence flag in the transaction profiler when it is
+ * destroyed on the end of a scope, for example on return or throw
+ * @return ScopedCallback
+ * @since 1.32
+ */
+ protected function silenceTransactionProfiler() {
+ $trxProfiler = Profiler::instance()->getTransactionProfiler();
+ $oldSilenced = $trxProfiler->setSilenced( true );
+ return new ScopedCallback( function () use ( $trxProfiler, $oldSilenced ) {
+ $trxProfiler->setSilenced( $oldSilenced );
+ } );
+ }
}
use Wikimedia\Rdbms\IDatabase;
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
use MediaWiki\Linker\LinkTarget;
-use MediaWiki\MediaWikiServices;
use Wikimedia\Assert\Assert;
use Wikimedia\ScopedCallback;
+use Wikimedia\Rdbms\ILBFactory;
use Wikimedia\Rdbms\LoadBalancer;
/**
*/
class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterface {
+ /**
+ * @var ILBFactory
+ */
+ private $lbFactory;
+
/**
* @var LoadBalancer
*/
private $stats;
/**
- * @param LoadBalancer $loadBalancer
+ * @param ILBFactory $lbFactory
* @param HashBagOStuff $cache
* @param ReadOnlyMode $readOnlyMode
* @param int $updateRowsPerQuery
*/
public function __construct(
- LoadBalancer $loadBalancer,
+ ILBFactory $lbFactory,
HashBagOStuff $cache,
ReadOnlyMode $readOnlyMode,
$updateRowsPerQuery
) {
- $this->loadBalancer = $loadBalancer;
+ $this->lbFactory = $lbFactory;
+ $this->loadBalancer = $lbFactory->getMainLB();
$this->cache = $cache;
$this->readOnlyMode = $readOnlyMode;
$this->stats = new NullStatsdDataFactory();
$fname = __METHOD__;
DeferredUpdates::addCallableUpdate(
function () use ( $timestamp, $watchers, $target, $fname ) {
- global $wgUpdateRowsPerQuery;
-
$dbw = $this->getConnectionRef( DB_MASTER );
- $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
- $ticket = $factory->getEmptyTransactionTicket( $fname );
+ $ticket = $this->lbFactory->getEmptyTransactionTicket( $fname );
- $watchersChunks = array_chunk( $watchers, $wgUpdateRowsPerQuery );
+ $watchersChunks = array_chunk( $watchers, $this->updateRowsPerQuery );
foreach ( $watchersChunks as $watchersChunk ) {
$dbw->update( 'watchlist',
[ /* SET */
], $fname
);
if ( count( $watchersChunks ) > 1 ) {
- $factory->commitAndWaitForReplication(
+ $this->lbFactory->commitAndWaitForReplication(
$fname, $ticket, [ 'domain' => $dbw->getDomainID() ]
);
}
var cloneCounter = 0;
- mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
- $root.find( '.mw-htmlform-cloner-delete-button' ).filter( ':input' ).click( function ( ev ) {
- ev.preventDefault();
- $( this ).closest( 'li.mw-htmlform-cloner-li' ).remove();
- } );
-
- $root.find( '.mw-htmlform-cloner-create-button' ).filter( ':input' ).click( function ( ev ) {
- var $ul, $li, html;
-
- ev.preventDefault();
-
- $ul = $( this ).prev( 'ul.mw-htmlform-cloner-ul' );
-
+ /**
+ * Appends a new row with fields to the cloner.
+ *
+ * @ignore
+ * @param {jQuery} $createButton
+ */
+ function appendToCloner( $createButton ) {
+ var $li,
+ $ul = $createButton.prev( 'ul.mw-htmlform-cloner-ul' ),
html = $ul.data( 'template' ).replace(
new RegExp( mw.RegExp.escape( $ul.data( 'uniqueId' ) ), 'g' ),
'clone' + ( ++cloneCounter )
);
- $li = $( '<li>' )
- .addClass( 'mw-htmlform-cloner-li' )
- .html( html )
- .appendTo( $ul );
+ $li = $( '<li>' )
+ .addClass( 'mw-htmlform-cloner-li' )
+ .html( html )
+ .appendTo( $ul );
- mw.hook( 'htmlform.enhance' ).fire( $li );
+ mw.hook( 'htmlform.enhance' ).fire( $li );
+ }
+
+ mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
+ var $deleteElement = $root.find( '.mw-htmlform-cloner-delete-button' ),
+ $createElement = $root.find( '.mw-htmlform-cloner-create-button' ),
+ createButton;
+
+ $deleteElement.each( function () {
+ var $element = $( this ),
+ deleteButton;
+
+ if ( $element.hasClass( 'oo-ui-widget' ) ) {
+ deleteButton = OO.ui.infuse( $element );
+ deleteButton.on( 'click', function () {
+ deleteButton.$element.closest( 'li.mw-htmlform-cloner-li' ).remove();
+ } );
+ } else {
+ $element.filter( ':input' ).click( function ( ev ) {
+ ev.preventDefault();
+ $( this ).closest( 'li.mw-htmlform-cloner-li' ).remove();
+ } );
+ }
} );
+
+ if ( $createElement.hasClass( 'oo-ui-widget' ) ) {
+ createButton = OO.ui.infuse( $createElement );
+ createButton.on( 'click', function () {
+ appendToCloner( createButton.$element );
+ } );
+ } else {
+ $createElement.filter( ':input' ).click( function ( ev ) {
+ ev.preventDefault();
+
+ appendToCloner( $( this ) );
+ } );
+ }
} );
}() );
'wgUseMediaWikiUIEverywhere' => false,
] );
- $langObj = Language::factory( 'en' );
+ $contLangObj = Language::factory( 'en' );
// Hardcode namespaces during test runs,
// so that html output based on existing namespaces
// can be properly evaluated.
- $langObj->setNamespaces( [
+ $contLangObj->setNamespaces( [
-2 => 'Media',
-1 => 'Special',
0 => '',
100 => 'Custom',
101 => 'Custom_talk',
] );
- $this->setUserLang( $langObj );
- $this->setContentLang( $langObj );
+ $this->setContentLang( $contLangObj );
+
+ $userLangObj = Language::factory( 'es' );
+ $userLangObj->setNamespaces( [
+ -2 => "Medio",
+ -1 => "Especial",
+ 0 => "",
+ 1 => "Discusión",
+ 2 => "Usuario",
+ 3 => "Usuario discusión",
+ 4 => "Wiki",
+ 5 => "Wiki discusión",
+ 6 => "Archivo",
+ 7 => "Archivo discusión",
+ 8 => "MediaWiki",
+ 9 => "MediaWiki discusión",
+ 10 => "Plantilla",
+ 11 => "Plantilla discusión",
+ 12 => "Ayuda",
+ 13 => "Ayuda discusión",
+ 14 => "CategorÃa",
+ 15 => "CategorÃa discusión",
+ 100 => "Personalizado",
+ 101 => "Personalizado discusión",
+ ] );
+ $this->setUserLang( $userLangObj );
+
$this->restoreWarnings = false;
}
public function testNamespaceSelector() {
$this->assertEquals(
'<select id="namespace" name="namespace">' . "\n" .
- '<option value="0">(Main)</option>' . "\n" .
+ '<option value="0">(Principal)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
$this->assertEquals(
'<label for="mw-test-namespace">Select a namespace:</label>' . "\u{00A0}" .
'<select id="mw-test-namespace" name="wpNamespace">' . "\n" .
- '<option value="all">all</option>' . "\n" .
- '<option value="0">(Main)</option>' . "\n" .
+ '<option value="all">todos</option>' . "\n" .
+ '<option value="0">(Principal)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2" selected="">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
$this->assertEquals(
'<label for="namespace">Select a namespace:</label>' . "\u{00A0}" .
'<select id="namespace" name="namespace">' . "\n" .
- '<option value="0">(Main)</option>' . "\n" .
+ '<option value="0">(Principal)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
public function testCanDisableANamespaces() {
$this->assertEquals(
'<select id="namespace" name="namespace">' . "\n" .
- '<option disabled="" value="0">(Main)</option>' . "\n" .
+ '<option disabled="" value="0">(Principal)</option>' . "\n" .
'<option disabled="" value="1">Talk</option>' . "\n" .
'<option disabled="" value="2">User</option>' . "\n" .
'<option disabled="" value="3">User talk</option>' . "\n" .
->will( $this->returnValue( $cookies ) );
TestingAccessWrapper::newFromObject( $op )->mVaryHeader = [];
+ $this->hideDeprecated( '$wgUseKeyHeader' );
foreach ( $calls as $call ) {
$op->addVaryHeader( ...$call );
}
/**
* @dataProvider provideAddAcceptLanguage
* @covers OutputPage::addAcceptLanguage
+ * @covers OutputPage::getKeyHeader
*/
public function testAddAcceptLanguage(
$code, array $variants, array $expected, array $options = []
// This will run addAcceptLanguage()
$op->sendCacheControl();
+ $this->hideDeprecated( '$wgUseKeyHeader' );
$keyHeader = $op->getKeyHeader();
if ( !$expected ) {
<?php
use MediaWiki\Linker\LinkTarget;
use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\LBFactory;
use Wikimedia\ScopedCallback;
use Wikimedia\TestingAccessWrapper;
return $mock;
}
+ /**
+ * @return PHPUnit_Framework_MockObject_MockObject|LBFactory
+ */
+ private function getMockLBFactory(
+ $mockDb,
+ $expectedConnectionType = null
+ ) {
+ $loadBalancer = $this->getMockLoadBalancer( $mockDb, $expectedConnectionType );
+ $mock = $this->getMockBuilder( LBFactory::class )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $mock->expects( $this->any() )
+ ->method( 'getMainLB' )
+ ->will( $this->returnValue( $loadBalancer ) );
+ return $mock;
+ }
+
/**
* @return PHPUnit_Framework_MockObject_MockObject|HashBagOStuff
*/
return $fakeRow;
}
- private function newWatchedItemStore( LoadBalancer $loadBalancer, HashBagOStuff $cache,
+ private function newWatchedItemStore( LBFactory $lbFactory, HashBagOStuff $cache,
ReadOnlyMode $readOnlyMode
) {
return new WatchedItemStore(
- $loadBalancer,
+ $lbFactory,
$cache,
$readOnlyMode,
1000
->with( 'RM-KEY' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->will( $this->returnValue( new FakeResultWrapper( [] ) ) );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$this->getMockCache(),
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:Some_Page:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
public function testAddWatchBatchForUser_readOnlyDBReturnsFalse() {
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $this->getMockDb() ),
+ $this->getMockLBFactory( $this->getMockDb() ),
$this->getMockCache(),
$this->getMockReadOnlyMode( true )
);
->with( '1:Some_Page:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
);
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
);
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->will( $this->returnValue( $cachedItem ) );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->will( $this->returnValue( false ) );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'set' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
public function testGetWatchedItemsForUser_optionsAndEmptyResult( $forWrite, $dbType ) {
$mockDb = $this->getMockDb();
$mockCache = $this->getMockCache();
- $mockLoadBalancer = $this->getMockLoadBalancer( $mockDb, $dbType );
+ $mockLoadBalancer = $this->getMockLBFactory( $mockDb, $dbType );
$user = $this->getMockNonAnonUserWithId( 1 );
$mockDb->expects( $this->once() )
public function testGetWatchedItemsForUser_badSortOptionThrowsException() {
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $this->getMockDb() ),
+ $this->getMockLBFactory( $this->getMockDb() ),
$this->getMockCache(),
$this->getMockReadOnlyMode()
);
);
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->will( $this->returnValue( false ) );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( $this->anything() );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeTitle:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
public function testSetNotificationTimestampsForUser_anonUser() {
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $this->getMockDb() ),
+ $this->getMockLBFactory( $this->getMockDb() ),
$this->getMockCache(),
$this->getMockReadOnlyMode()
);
} ) );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$this->getMockCache(),
$this->getMockReadOnlyMode()
);
} ) );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$this->getMockCache(),
$this->getMockReadOnlyMode()
);
->will( $this->returnValue( 'makeWhereFrom2d return value' ) );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$this->getMockCache(),
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
$mockCache->expects( $this->never() )->method( 'delete' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);
->with( '0:SomeDbKey:1' );
$store = $this->newWatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
+ $this->getMockLBFactory( $mockDb ),
$mockCache,
$this->getMockReadOnlyMode()
);