--- /dev/null
+version: v4
+base: docker-registry.wikimedia.org/dev/stretch-php72-fpm-apache2
+
+lives:
+ in: /var/www/html
+
+variants:
+ dev:
+ runs:
+ insecurely: true
+ builder:
+ command: [.pipeline/dev_prereq.sh]
+ requirements: [.pipeline, .pipeline/dev_prereq.sh, composer.json]
+ copies: [local]
--- /dev/null
+pipelines:
+ publish:
+ blubberfile: blubber.yaml
+ stages:
+ - name: dev
+ build: dev
+ publish:
+ image: true
+ tags: [dev]
--- /dev/null
+#!/bin/sh
+
+mkdir /tmp/php
+mkdir -p extensions
+
+git clone --depth 1 https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor.git /var/www/html/extensions/VisualEditor
+git clone --depth 1 https://gerrit.wikimedia.org/r/mediawiki/skins/Vector /var/www/html/skins/Vector
+cd /var/www/html/extensions/VisualEditor
+git submodule update --depth 1 --init
+
+cd /var/www/html
+composer install
+cat <<PHP > LocalSettings.php
+<?php
+require_once '/var/config/LocalSettings.php';
+PHP
* Specifying a SpecialPage object for the list of special pages (either through
the SpecialPage_initList hook or by adding to $wgSpecialPages) is now
deprecated.
+* WebInstaller::getInfoBox(), getWarningBox() and getErrorBox() are deprecated.
+ Use Html::errorBox() or Html::warningBox() instead.
* Use of ActorMigration with 'ar_user', 'img_user', 'oi_user', 'fa_user',
'rc_user', 'log_user', and 'ipb_by' is deprecated. Queries should be adjusted
to use the corresponding actor fields directly. Note that use with
/**
* Set this to an array of special page names to prevent
* maintenance/updateSpecialPages.php from updating those pages.
+ * Mapping each special page name to an run mode like 'periodical' if a cronjob is set up.
*/
$wgDisableQueryPageUpdate = false;
/**
* Get HTML for an information message box with an icon.
*
- * @internal For use by the WebInstaller class.
+ * @internal For use by the WebInstaller class only.
* @param string $rawHtml HTML
* @param string $icon Path to icon file (used as 'src' attribute)
* @param string $alt Alternate text for the icon
$titlesByPageId = [];
foreach ( $rows as $row ) {
if ( isset( $rowsByRevId[$row->rev_id] ) ) {
- throw new InvalidArgumentException( "Duplicate rows in newRevisionsFromBatch {$row->rev_id}" );
+ $result->warning(
+ 'internalerror',
+ "Duplicate rows in newRevisionsFromBatch, rev_id {$row->rev_id}"
+ );
}
if ( $title && $row->rev_page != $title->getArticleID() ) {
throw new InvalidArgumentException(
);
$class = MWLBFactory::getLBFactoryClass( $lbConf );
- $instance = new $class( $lbConf );
- MWLBFactory::setSchemaAliases( $instance, $mainConfig->get( 'DBtype' ) );
-
- return $instance;
+ return new $class( $lbConf );
},
'EventRelayerGroup' => function ( MediaWikiServices $services ) : EventRelayerGroup {
$res = $this->select( __METHOD__ );
if ( is_null( $resultPageSet ) ) {
+ $this->executeGenderCacheFromResultWrapper( $res, __METHOD__ );
+
$count = 0;
foreach ( $res as $row ) {
if ( ++$count > $params['limit'] ) {
* @file
*/
+use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\IDatabase;
use Wikimedia\Rdbms\IResultWrapper;
);
}
+ /**
+ * Preprocess the result set to fill the GenderCache with the necessary information
+ * before using self::addTitleInfo
+ *
+ * @param IResultWrapper $res Result set to work on.
+ * The result set must have _namespace and _title fields with the provided field prefix
+ * @param string $fname The caller function name, always use __METHOD__
+ * @param string $fieldPrefix Prefix for fields to check gender for
+ */
+ protected function executeGenderCacheFromResultWrapper(
+ IResultWrapper $res, $fname = __METHOD__, $fieldPrefix = 'page'
+ ) {
+ if ( !$res->numRows() ) {
+ return;
+ }
+
+ $services = MediaWikiServices::getInstance();
+ $nsInfo = $services->getNamespaceInfo();
+ $namespaceField = $fieldPrefix . '_namespace';
+ $titleField = $fieldPrefix . '_title';
+
+ $usernames = [];
+ foreach ( $res as $row ) {
+ if ( $nsInfo->hasGenderDistinction( $row->$namespaceField ) ) {
+ $usernames[] = $row->$titleField;
+ }
+ }
+
+ if ( $usernames === [] ) {
+ return;
+ }
+
+ $genderCache = $services->getGenderCache();
+ $genderCache->doQuery( $usernames, $fname );
+ }
+
/** @} */
/************************************************************************//**
"apihelp-edit-param-summary": "編集の要約。$1section=new で $1sectiontitle が設定されていない場合は節名としても利用されます。",
"apihelp-edit-param-tags": "この版に適用する変更タグ。",
"apihelp-edit-param-minor": "この編集に細部の変更の印を付ける",
- "apihelp-edit-param-notminor": "細部の編集ではない。",
+ "apihelp-edit-param-notminor": "利用者設定で「{{int:tog-minordefault}}」を指定してあっても、細部の編集とマークしないでください。",
"apihelp-edit-param-bot": "この編集をボットの編集としてマークする。",
"apihelp-edit-param-basetimestamp": "編集前の版のタイムスタンプ。編集競合を検出するために使用されます。\n[[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]] で取得できます。",
"apihelp-edit-param-starttimestamp": "編集作業を開始したときのタイムスタンプ。編集競合を検出するために使用されます。適切な値は <var>[[Special:ApiHelp/main|curtimestamp]]</var> を使用して編集作業を開始するとき (たとえば、編集するページの本文を読み込んだとき) に取得できます。",
"apihelp-options-example-change": "<kbd>skin</kbd> および <kbd>hideminor</kbd> の個人設定を変更する。",
"apihelp-options-example-complex": "すべての個人設定を初期化し、<kbd>skin</kbd> および <kbd> nickname </kbd> を設定する。",
"apihelp-paraminfo-summary": "API モジュールに関する情報を取得します。",
- "apihelp-paraminfo-param-modules": "モジュールの名前のリスト (<var>action</var> および <var>format</var> パラメーターの値, または <kbd>main</kbd>). <kbd>+</kbd> を使用して下位モジュールを指定できます。",
+ "apihelp-paraminfo-param-modules": "モジュール名のリスト (<var>action</var> および <var>format</var> パラメーターまたは <kbd>main</kbd>の値)。特定の下位モジュールの指定は<kbd>+</kbd> 、全下位モジュールの指定は<kbd>+*</kbd>を使い、あるいは<kbd>+**</kbd>ですべての下位モジュールを再帰的に指定します。",
"apihelp-paraminfo-param-helpformat": "ヘルプ文字列の形式。",
"apihelp-paraminfo-param-querymodules": "クエリモジュール名のリスト (<var>prop</var>, <var>meta</var> or <var>list</var> パラメータの値)。<kbd>$1querymodules=foo</kbd> の代わりに <kbd>$1modules=query+foo</kbd> を使用してください。",
"apihelp-paraminfo-example-1": "<kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>, and <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> に関する情報を表示する。",
"apihelp-parse-paramvalue-prop-revid": "構文解析されたページの版IDを追加します。",
"apihelp-parse-paramvalue-prop-displaytitle": "構文解析されたウィキテキストのタイトルを追加します。",
"apihelp-parse-paramvalue-prop-headitems": "ページの <code><head></code> の中に入れてアイテムを提供します。",
- "apihelp-parse-paramvalue-prop-headhtml": "ページの解析された <code><head></code> を与える。",
+ "apihelp-parse-paramvalue-prop-headhtml": "ページの<code><html></code>と<code><head></code>の要素を開いて<code><body></code>を開示し、Doctype を解析する。",
"apihelp-parse-paramvalue-prop-jsconfigvars": "ページに固有のJavaScriptの設定変数を提供します。適用するには、<code>mw.config.set()</code>を使用します。",
"apihelp-parse-paramvalue-prop-encodedjsconfigvars": "JSON文字列としてページに固有のJavaScriptの設定変数を提供します。",
"apihelp-parse-paramvalue-prop-indicators": "ページ上で使用されるページのステータスインジケータのHTMLを提供します。",
use MediaWiki\Config\ServiceOptions;
use MediaWiki\Logger\LoggerFactory;
-use Wikimedia\Rdbms\LBFactory;
use Wikimedia\Rdbms\DatabaseDomain;
/**
return $class;
}
- /**
- * @param LBFactory $lbFactory
- * @param string $dbType 'mysql', 'sqlite', etc.
- * @internal For use with service wiring
- */
- public static function setSchemaAliases( LBFactory $lbFactory, $dbType ) {
- if ( $dbType === 'mysql' ) {
- /**
- * When SQLite indexes were introduced in r45764, it was noted that
- * SQLite requires index names to be unique within the whole database,
- * not just within a schema. As discussed in CR r45819, to avoid the
- * need for a schema change on existing installations, the indexes
- * were implicitly mapped from the new names to the old names.
- *
- * This mapping can be removed if DB patches are introduced to alter
- * the relevant tables in existing installations. Note that because
- * this index mapping applies to table creation, even new installations
- * of MySQL have the old names (except for installations created during
- * a period where this mapping was inappropriately removed, see
- * T154872).
- */
- $lbFactory->setIndexAliases( [
- 'ar_usertext_timestamp' => 'usertext_timestamp',
- 'un_user_id' => 'user_id',
- 'un_user_ip' => 'user_ip',
- ] );
- }
- }
-
/**
* Log a database deprecation warning
* @param string $msg Deprecation message
}
$class = $config['class'];
- // @FIXME: ideally this would default to the DB domain (which includes the schema)
- $config['domainId'] = $config['domainId'] ?? ( $config['wikiId'] ?? wfWikiID() );
+ if ( isset( $config['domainId'] ) ) {
+ $domainId = $config['domainId'];
+ } elseif ( isset( $config['wikiId'] ) ) {
+ $domainId = $config['wikiId']; // b/c
+ } else {
+ // Only use the raw database/prefix for backwards compatibility
+ $ld = WikiMap::getCurrentWikiDbDomain();
+ $domainId = strlen( $ld->getTablePrefix() )
+ ? "{$ld->getDatabase()}-{$ld->getTablePrefix()}"
+ : $ld->getDatabase();
+ // If the local wiki ID and local domain ID do not match, probably due to a
+ // non-default schema, issue a warning. A non-default schema indicates that
+ // it might be used to disambiguate different wikis.
+ $wikiId = WikiMap::getWikiIdFromDbDomain( $ld );
+ if ( $ld->getSchema() !== null && $domainId !== $wikiId ) {
+ wfWarn(
+ "\$wgFileBackend entry '$name' should have 'domainId' set.\n" .
+ "Legacy default 'domainId' is '$domainId' but wiki ID is '$wikiId'."
+ );
+ }
+ }
+ $config['domainId'] = $domainId;
$config['readOnly'] = $config['readOnly'] ?? $readOnlyReason;
unset( $config['class'] ); // backend won't need this
/**
* Store a file to a given destination.
*
- * @param string $srcPath Source file system path, storage path, or virtual URL
+ * Using FSFile/TempFSFile can improve performance via caching.
+ * Using TempFSFile can further improve performance by signalling that it is safe
+ * to touch the source file or write extended attribute metadata to it directly.
+ *
+ * @param string|FSFile $srcPath Source file system path, storage path, or virtual URL
* @param string $dstZone Destination zone
* @param string $dstRel Destination relative path
* @param int $flags Bitwise combination of the following flags:
/**
* Store a batch of files
*
+ * @see FileRepo::store()
+ *
* @param array $triplets (src, dest zone, dest rel) triplets as per store()
* @param int $flags Bitwise combination of the following flags:
* self::OVERWRITE Overwrite an existing destination file instead of failing
$operations = [];
// Validate each triplet and get the store operation...
foreach ( $triplets as $triplet ) {
- list( $srcPath, $dstZone, $dstRel ) = $triplet;
+ list( $src, $dstZone, $dstRel ) = $triplet;
+ $srcPath = ( $src instanceof FSFile ) ? $src->getPath() : $src;
wfDebug( __METHOD__
. "( \$src='$srcPath', \$dstZone='$dstZone', \$dstRel='$dstRel' )\n"
);
-
+ // Resolve source path
+ if ( $src instanceof FSFile ) {
+ $op = 'store';
+ } else {
+ $src = $this->resolveToStoragePathIfVirtual( $src );
+ $op = FileBackend::isStoragePath( $src ) ? 'copy' : 'store';
+ }
// Resolve destination path
$root = $this->getZonePath( $dstZone );
if ( !$root ) {
return $this->newFatal( 'directorycreateerror', $dstDir );
}
- // Resolve source to a storage path if virtual
- $srcPath = $this->resolveToStoragePathIfVirtual( $srcPath );
-
// Copy the source file to the destination
$operations[] = [
- 'op' => FileBackend::isStoragePath( $srcPath ) ? 'copy' : 'store',
- 'src' => $srcPath, // storage path (copy) or local file path (store)
+ 'op' => $op,
+ 'src' => $src, // storage path (copy) or local file path (store)
'dst' => $dstPath,
'overwrite' => ( $flags & self::OVERWRITE ) ? true : false,
'overwriteSame' => ( $flags & self::OVERWRITE_SAME ) ? true : false,
* This function can be used to write to otherwise read-only foreign repos.
* This is intended for copying generated thumbnails into the repo.
*
+ * Using FSFile/TempFSFile can improve performance via caching.
+ * Using TempFSFile can further improve performance by signalling that it is safe
+ * to touch the source file or write extended attribute metadata to it directly.
+ *
* @param string|FSFile $src Source file system path, storage path, or virtual URL
* @param string $dst Virtual URL or storage path
* @param array|string|null $options An array consisting of a key named headers
return $this->quickImportBatch( [ [ $src, $dst, $options ] ] );
}
- /**
- * Purge a file from the repo. This does no locking nor journaling.
- * This function can be used to write to otherwise read-only foreign repos.
- * This is intended for purging thumbnails.
- *
- * @param string $path Virtual URL or storage path
- * @return Status
- */
- final public function quickPurge( $path ) {
- return $this->quickPurgeBatch( [ $path ] );
- }
-
- /**
- * Deletes a directory if empty.
- * This function can be used to write to otherwise read-only foreign repos.
- *
- * @param string $dir Virtual URL (or storage path) of directory to clean
- * @return Status
- */
- public function quickCleanDir( $dir ) {
- $status = $this->newGood();
- $status->merge( $this->backend->clean(
- [ 'dir' => $this->resolveToStoragePathIfVirtual( $dir ) ] ) );
-
- return $status;
- }
-
/**
* Import a batch of files from the local file system into the repo.
* This does no locking nor journaling and overrides existing files.
* This function can be used to write to otherwise read-only foreign repos.
* This is intended for copying generated thumbnails into the repo.
*
+ * @see FileRepo::quickImport()
+ *
* All path parameters may be a file system path, storage path, or virtual URL.
* When "headers" are given they are used as HTTP headers if supported.
*
$operations[] = [
'op' => $op,
- 'src' => $src,
+ 'src' => $src, // storage path (copy) or local path/FSFile (store)
'dst' => $dst,
'headers' => $headers
];
return $status;
}
+ /**
+ * Purge a file from the repo. This does no locking nor journaling.
+ * This function can be used to write to otherwise read-only foreign repos.
+ * This is intended for purging thumbnails.
+ *
+ * @param string $path Virtual URL or storage path
+ * @return Status
+ */
+ final public function quickPurge( $path ) {
+ return $this->quickPurgeBatch( [ $path ] );
+ }
+
+ /**
+ * Deletes a directory if empty.
+ * This function can be used to write to otherwise read-only foreign repos.
+ *
+ * @param string $dir Virtual URL (or storage path) of directory to clean
+ * @return Status
+ */
+ public function quickCleanDir( $dir ) {
+ $status = $this->newGood();
+ $status->merge( $this->backend->clean(
+ [ 'dir' => $this->resolveToStoragePathIfVirtual( $dir ) ] ) );
+
+ return $status;
+ }
+
/**
* Purge a batch of files from the repo.
* This function can be used to write to otherwise read-only foreign repos.
* Returns a Status object. On success, the value contains "new" or
* "archived", to indicate whether the file was new with that name.
*
+ * Using FSFile/TempFSFile can improve performance via caching.
+ * Using TempFSFile can further improve performance by signalling that it is safe
+ * to touch the source file or write extended attribute metadata to it directly.
+ *
* Options to $options include:
* - headers : name/value map of HTTP headers to use in response to GET/HEAD requests
*
/**
* Publish a batch of files
*
+ * @see FileRepo::publish()
+ *
* @param array $ntuples (source, dest, archive) triplets or
* (source, dest, archive, options) 4-tuples as per publish().
* @param int $flags Bitfield, may be FileRepo::DELETE_SOURCE to indicate
} else {
$operations[] = [
'op' => 'store',
- 'src' => $src, // FSFile (preferred) or local file path
+ 'src' => $src, // storage path (copy) or local path/FSFile (store)
'dst' => $dstPath,
'overwrite' => true, // replace current
'headers' => $headers
[ 'modifyTable', 'job', 'patch-job-params-mediumblob.sql' ],
// 1.34
+ [ 'dropIndex', 'archive', 'ar_usertext_timestamp',
+ 'patch-drop-archive-ar_usertext_timestamp.sql' ],
+ [ 'dropIndex', 'archive', 'usertext_timestamp', 'patch-drop-archive-usertext_timestamp.sql' ],
[ 'dropField', 'logging', 'log_user', 'patch-drop-user-fields.sql' ],
+ [ 'addIndex', 'user_newtalk', 'un_user_ip', 'patch-rename-mysql-user_newtalk-indexes.sql' ],
];
}
/**
* Get HTML for an error box with an icon.
*
+ * @deprecated since 1.34 Use Html::errorBox() instead.
* @param string $text Wikitext, get this with wfMessage()->plain()
*
* @return string
*/
public function getErrorBox( $text ) {
+ wfDeprecated( __METHOD__, '1.34' );
return $this->getInfoBox( $text, 'critical-32.png', 'config-error-box' );
}
/**
* Get HTML for a warning box with an icon.
*
+ * @deprecated since 1.34 Use Html::warningBox() instead.
* @param string $text Wikitext, get this with wfMessage()->plain()
*
* @return string
*/
public function getWarningBox( $text ) {
+ wfDeprecated( __METHOD__, '1.34' );
return $this->getInfoBox( $text, 'warning-32.png', 'config-warning-box' );
}
/**
* Get HTML for an information message box with an icon.
*
+ * @deprecated since 1.34.
* @param string|HtmlArmor $text Wikitext to be parsed (from Message::plain) or raw HTML.
* @param string|bool $icon Icon name, file in mw-config/images. Default: false
* @param string|bool $class Additional class name to add to the wrapper div. Default: false.
* @return string HTML
*/
public function getInfoBox( $text, $icon = false, $class = false ) {
+ wfDeprecated( __METHOD__, '1.34' );
$html = ( $text instanceof HtmlArmor ) ?
HtmlArmor::getHtml( $text ) :
$this->parse( $text, true );
"config-restart": "Ja, erneut starten",
"config-welcome": "=== Prüfung der Installationsumgebung ===\nDie Basisprüfungen werden jetzt durchgeführt, um festzustellen, ob die Installationsumgebung für MediaWiki geeignet ist.\nNotiere diese Informationen und gib sie an, sofern du Hilfe beim Installieren benötigst.",
"config-welcome-section-copyright": "=== Lizenz und Nutzungsbedingungen ===\n\n$1\n\nDieses Programm ist freie Software, d. h. es kann, gemäß den Bedingungen der von der Free Software Foundation veröffentlichten ''GNU General Public License'', weiterverteilt und/oder modifiziert werden. Dabei kann die Version 2, oder nach eigenem Ermessen, jede neuere Version der Lizenz verwendet werden.\n\nDieses Programm wird in der Hoffnung verteilt, dass es nützlich sein wird, allerdings '''ohne jegliche Garantie''' und sogar ohne die implizierte Garantie einer '''Marktgängigkeit''' oder '''Eignung für einen bestimmten Zweck'''. Hierzu sind weitere Hinweise in der ''GNU General Public License'' enthalten.\n\nEine [$2 Kopie der GNU General Public License] sollte zusammen mit diesem Programm verteilt worden sein. Sofern dies nicht der Fall war, kann eine Kopie bei der Free Software Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, schriftlich angefordert oder auf deren Website [https://www.gnu.org/copyleft/gpl.html online gelesen] werden.",
- "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/de Website von MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/de Benutzeranleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/de Administratorenanleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/de Häufig gestellte Fragen]\n----\n* <doclink href=Readme>Lies mich</doclink>\n* <doclink href=ReleaseNotes>Versionsinformationen</doclink>\n* <doclink href=Copying>Lizenzbestimmungen</doclink>\n* <doclink href=UpgradeDoc>Aktualisierung</doclink>",
+ "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/de Website von MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/de Benutzeranleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/de Administratorenanleitung]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/de Häufig gestellte Fragen]",
"config-sidebar-readme": "Lies mich",
"config-sidebar-relnotes": "Veröffentlichungsinformationen",
"config-sidebar-license": "Kopieren",
"config-uploads-not-safe": "'''Warnung:''' Das Standardverzeichnis für hochgeladene Dateien <code>$1</code> ist für die willkürliche Ausführung von Skripten anfällig.\nObwohl MediaWiki die hochgeladenen Dateien auf Sicherheitsrisiken überprüft, wird dennoch dringend empfohlen, diese [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security Sicherheitslücke] zu schließen, bevor das Hochladen von Dateien aktiviert wird.",
"config-no-cli-uploads-check": "'''Warnung''': Das Standardverzeichnis für hochgeladene Dateien (<code>$1</code>) wird, während der Installation über die Kommandozeile, nicht auf Sicherheitsanfälligkeiten hinsichtlich willkürlicher Skriptausführungen geprüft.",
"config-brokenlibxml": "Das System nutzt eine Kombination aus PHP- und libxml2-Versionen, die fehleranfällig ist und versteckte Datenfehler bei MediaWiki und anderen Webanwendungen verursachen kann.\nAktualisiere auf libxml2 2.7.3 oder später, um das Problem zu lösen. Installationsabbruch ([https://bugs.php.net/bug.php?id=45996 siehe hierzu die Fehlermeldung bei PHP]).",
- "config-suhosin-max-value-length": "Suhosin ist installiert und beschränkt die Länge des GET-Parameters auf $1 Bytes.\nDer ResouceLoader von MediaWiki wird zwar unter diesen Bedingungen funktionieren, allerdings nur mit verminderter Leistungsfähigkeit.\nSofern möglich, sollte der Parameter <code>suhosin.get.max_value_length</code> in der Datei <code>php.ini</code> auf 1024 oder höher festgelegt werden.\nGleichzeitig muss der Parameter <code>$wgResourceLoaderMaxQueryLength</code> in der Datei <code>LocalSettings.php</code> auf den selben Wert eingestellt werden.",
+ "config-suhosin-max-value-length": "Suhosin ist installiert und beschränkt die Länge des GET-Parameters auf $1 Bytes.\nMediaWiki wird nur funktionieren, wenn code>suhosin.get.max_value_length</code> $2 oder höher ist. Deaktiviere diese Einstellung oder ändere sie in <code>php.ini</code> zu $3.",
"config-using-32bit": "<strong>Warnung:</strong> Es scheint, als ob dein System mit 32-Bit-Ganzzahlen läuft. Dies wird [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit nicht empfohlen].",
"config-db-type": "Datenbanksystem:",
"config-db-host": "Datenbankserver:",
"config-extension-not-found": "拡張機能「$1」の登録ファイルは見つかりませんでした",
"config-extension-dependency": "拡張機能「$1」のインストール中に依存関係エラーが発生しました: $2",
"mainpagetext": "<strong>MediaWiki はインストール済みです。</strong>",
- "mainpagedocfooter": "ウィキソフトウェアの使い方に関する情報は[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents 利用者案内]を参照してください。\n\n== はじめましょう ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/ja 設定の一覧]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ja MediaWiki よくある質問と回答]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki リリース情報メーリングリスト]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation/ja MediaWiki のあなたの言語へのローカライズ]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam あなたのウィキでスパムと戦う方法を学ぶ]"
+ "mainpagedocfooter": "ウィキソフトウェアの使い方に関する情報は[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents 利用者案内]を参照してください。\n\nウィキソフトウェアの使い方に関する情報は[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents 利用者案内]を参照してください。\n\n== はじめましょう ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/ja 設定の一覧]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ja MediaWiki よくある質問]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki リリース情報メーリングリスト]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation/ja MediaWiki をご使用の言語へ地域化]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam ご使用のウィキでスパムと戦う方法を学ぶ]"
}
"config-uploads-not-safe": "'''Увага:''' Ваша типова папка для завантажень <code>$1</code> вразлива до виконання довільних скриптів.\nХоча MediaWiki перевіряє усі завантажені файли на наявність загроз, наполегливо рекомендується [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security закрити дану вразливість] перед тим, як дозволяти завантаження файлів.",
"config-no-cli-uploads-check": "'''Увага:''' Ваша типова папка для завантажень (<code>$1</code>) не перевірялась на вразливість до виконання довільних скриптів під час встановлення CLI.",
"config-brokenlibxml": "У Вашій системі невдале поєднання версій PHP і libxml2, яке може спричинити пошкодження прихованих даних у MediaWiki та інших веб-застосунках.\nОновіть libxml2 до версії 2.7.3 або пізнішої ([https://bugs.php.net/bug.php?id=45996 відомості про помилку]).\nВстановлення перервано.",
- "config-suhosin-max-value-length": "Suhosin вÑ\81Ñ\82ановлено Ñ\96 обмежÑ\83Ñ\94 паÑ\80амеÑ\82Ñ\80а GET <code>length</code> до $1 байÑ\82а. Ð\9aомпоненÑ\82 MediaWiki ResourceLoader бÑ\83де обÑ\85одиÑ\82и Ñ\86е обмеженнÑ\8f, однак Ñ\86е зменÑ\88иÑ\82Ñ\8c пÑ\80одÑ\83кÑ\82ивнÑ\96Ñ\81Ñ\82Ñ\8c. ЯкÑ\89о Ñ\86е можливо, Ð\92ам ваÑ\80Ñ\82о вÑ\81Ñ\82ановиÑ\82и знаÑ\87еннÑ\8f <code>suhosin.get.max_value_length</code> Ñ\8fк 1024 Ñ\96 бÑ\96лÑ\8cÑ\88е Ñ\83 <code>php.ini</code> Ñ\96 вÑ\81Ñ\82ановиÑ\82и Ñ\82аке ж знаÑ\87еннÑ\8f <code>$wgResourceLoaderMaxQueryLength</code> Ñ\83 LocalSettings.php .",
+ "config-suhosin-max-value-length": "Suhosin вÑ\81Ñ\82ановлено Ñ\96 вÑ\96н обмежÑ\83Ñ\94 GET-паÑ\80амеÑ\82Ñ\80 <code>length</code> до $1 {{PLURAL:$1|байÑ\82|байÑ\82а|байÑ\82}}. Ð\94лÑ\8f MediaWiki поÑ\82Ñ\80Ñ\96бно, Ñ\89об знаÑ\87еннÑ\8f <code>suhosin.get.max_value_length</code> бÑ\83ло Ñ\85оÑ\87а б $2. Ð\92имкнÑ\96Ñ\82Ñ\8c Ñ\86е налаÑ\88Ñ\82Ñ\83ваннÑ\8f, або збÑ\96лÑ\8cÑ\88Ñ\96Ñ\82Ñ\8c знаÑ\87еннÑ\8f Ñ\83 <code>php.ini</code> до $3.",
"config-using-32bit": "<strong>Попередження:</strong> схоже, що Ваша система працює з 32-бітними цілими числами. Таке [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit не рекомендується].",
"config-db-type": "Тип бази даних:",
"config-db-host": "Хост бази даних:",
// Nested callback process cache use is not lag-safe with regard to HOLDOFF_TTL since
// process cached values are more lagged than persistent ones as they are not purged.
if ( $pCache && $this->callbackDepth == 0 ) {
- $cached = $pCache->get( $this->getProcessCacheKey( $key, $version ), INF, false );
+ $cached = $pCache->get( $this->getProcessCacheKey( $key, $version ), $pcTTL, false );
if ( $cached !== false ) {
return $cached;
}
if ( !isset( $this->processCaches[$group] ) ) {
list( , $size ) = explode( ':', $group );
$this->processCaches[$group] = new MapCacheLRU( (int)$size );
+ if ( $this->wallClockOverride !== null ) {
+ $this->processCaches[$group]->setMockTime( $this->wallClockOverride );
+ }
}
return $this->processCaches[$group];
public function setMockTime( &$time ) {
$this->wallClockOverride =& $time;
$this->cache->setMockTime( $time );
+ foreach ( $this->processCaches as $pCache ) {
+ $pCache->setMockTime( $time );
+ }
}
}
}
// the outer div is need for styling the revision info and nav in MobileFrontend
- $outputPage->addSubtitle( "<div class=\"mw-revision\">" . $revisionInfo .
+ $outputPage->addSubtitle( "<div class=\"mw-revision warningbox\">" . $revisionInfo .
"<div id=\"mw-revision-nav\">" . $cdel .
$context->msg( 'revision-nav' )->rawParams(
$prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff
return $qp;
}
+ /**
+ * Get a list of query pages disabled and with it's run mode
+ * @param Config $config
+ * @return string[]
+ */
+ public static function getDisabledQueryPages( Config $config ) {
+ $disableQueryPageUpdate = $config->get( 'DisableQueryPageUpdate' );
+
+ if ( !is_array( $disableQueryPageUpdate ) ) {
+ return [];
+ }
+
+ $pages = [];
+ foreach ( $disableQueryPageUpdate as $name => $runMode ) {
+ if ( is_int( $name ) ) {
+ // The run mode may be omitted
+ $pages[$runMode] = 'disabled';
+ } else {
+ $pages[$name] = $runMode;
+ }
+ }
+ return $pages;
+ }
+
/**
* A mutator for $this->listoutput;
*
# If updates on this page have been disabled, let the user know
# that the data set won't be refreshed for now
- if ( is_array( $this->getConfig()->get( 'DisableQueryPageUpdate' ) )
- && in_array( $this->getName(), $this->getConfig()->get( 'DisableQueryPageUpdate' ) )
- ) {
- $out->wrapWikiMsg(
- "<div class=\"mw-querypage-no-updates\">\n$1\n</div>",
- 'querypage-no-updates'
- );
+ $disabledQueryPages = self::getDisabledQueryPages( $this->getConfig() );
+ if ( isset( $disabledQueryPages[$this->getName()] ) ) {
+ $runMode = $disabledQueryPages[$this->getName()];
+ if ( $runMode === 'disabled' ) {
+ $out->wrapWikiMsg(
+ "<div class=\"mw-querypage-no-updates\">\n$1\n</div>",
+ 'querypage-no-updates'
+ );
+ } else {
+ // Messages used here: querypage-updates-periodical
+ $out->wrapWikiMsg(
+ "<div class=\"mw-querypage-updates-" . $runMode . "\">\n$1\n</div>",
+ 'querypage-updates-' . $runMode
+ );
+ }
}
}
}
"sp-contributions-userrights": "idareyê heqanê {{GENDER:$1|karberan}}",
"sp-contributions-blocked-notice": "Eno karber/ena karbere emanet blokekerdeyo/blokekerdiya.\nCıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:",
"sp-contributions-blocked-notice-anon": "Eno adresê IPi bloke biyo.\nCıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:",
- "sp-contributions-search": "Dekerdena cı geyrê",
+ "sp-contributions-search": "İştırakan cı geyrê",
"sp-contributions-username": "Adresa IPy ya zi nameyê karberi:",
"sp-contributions-toponly": "Tenya tewr çım ra viyarnayışanê peyniyan bımocne",
"sp-contributions-newonly": "Tenya vurnayışanê pelevıraştışi bımocne",
"perfcached": "The following data is cached and may not be up to date. A maximum of {{PLURAL:$1|one result is|$1 results are}} available in the cache.",
"perfcachedts": "The following data is cached, and was last updated $1. A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
"querypage-no-updates": "Updates for this page are currently disabled.\nData here will not presently be refreshed.",
+ "querypage-updates-periodical": "Updates for this page are run periodically.",
"viewsource": "View source",
"viewsource-title": "View source for $1",
"actionthrottled": "Action throttled",
"oct": "okt",
"nov": "nov",
"dec": "dec",
- "january-date": "Január $1",
- "february-date": "Február $1",
- "march-date": "Március $1",
- "april-date": "Ã\81prilis $1",
- "may-date": "Május $1",
- "june-date": "Június $1",
- "july-date": "Július $1",
- "august-date": "Augusztus $1",
- "september-date": "Szeptember $1",
- "october-date": "Október $1",
- "november-date": "November $1",
- "december-date": "December $1",
+ "january-date": "január $1",
+ "february-date": "február $1",
+ "march-date": "március $1",
+ "april-date": "április $1",
+ "may-date": "május $1",
+ "june-date": "június $1",
+ "july-date": "július $1",
+ "august-date": "augusztus $1",
+ "september-date": "szeptember $1",
+ "october-date": "október $1",
+ "november-date": "november $1",
+ "december-date": "december $1",
"period-am": "de.",
"period-pm": "du.",
"pagecategories": "{{PLURAL:$1|Kategória|Kategória}}",
"category_header": "A(z) „$1” kategóriába tartozó lapok",
"subcategories": "Alkategóriák",
"category-media-header": "A(z) „$1” kategóriába tartozó médiafájlok",
- "category-empty": "''Ebben a kategóriában pillanatnyilag egyetlen lap vagy médiafájl sem szerepel.''",
+ "category-empty": "<em>Ebben a kategóriában pillanatnyilag egyetlen lap vagy médiafájl sem szerepel.</em>",
"hidden-categories": "{{PLURAL:$1|Rejtett kategória|Rejtett kategóriák}}",
"hidden-category-category": "Rejtett kategóriák",
"category-subcat-count": "{{PLURAL:$2|Ennek a kategóriának csak egyetlen alkategóriája van.|Ez a kategória az alábbi {{PLURAL:$1|alkategóriával|$1 alkategóriával}} rendelkezik (összesen $2 alkategóriája van).}}",
"botpasswords-insert-failed": "ボット「$1」の追加に失敗しました。既に追加されていないか確認してください。",
"botpasswords-update-failed": "ボット「$1」の更新に失敗しました。削除されていないか確認してください。",
"botpasswords-created-title": "ボット用パスワードが作成されました",
- "botpasswords-created-body": "利用者「$2」のボット名「$1」のためのパスワードが作成されました。",
+ "botpasswords-created-body": "{{GENDER:$2|利用者}}「$2」のボット「$1」のパスワードが作成されました。",
"botpasswords-updated-title": "ボット用パスワードが更新されました",
- "botpasswords-updated-body": "利用者「$2」のボット名「$1」のためのパスワードが更新されました。",
+ "botpasswords-updated-body": "{{GENDER:$2|利用者}}「$2」のボット「$1」のパスワードが更新されました。",
"botpasswords-deleted-title": "ボット用パスワードが削除されました",
- "botpasswords-deleted-body": "利用者「$2」のボット名「$1」のためのパスワードが削除されました。",
+ "botpasswords-deleted-body": "{{GENDER:$2|利用者}}「$2」のボット「$1」のパスワードが削除されました。",
"botpasswords-newpassword": "<strong>$1</strong>用の新しいパスワードは<strong>$2</strong>です。<em>後で参照するために、この情報を控えておいてください。</em><br />(古いボットの制約などでログイン名と利用者名が同じでなければならない場合は、<strong>$3</strong>を利用者名とし、<strong>$4</strong>をパスワードとしてください。)",
"botpasswords-no-provider": "BotPasswordsSessionProvider が有効ではありません。",
"botpasswords-restriction-failed": "ボットパスワード制限によりログインできません。",
"tags-delete-not-allowed": "拡張機能によって定義されているタグは削除できません(ただし拡張機能が明示的に削除を許可している場合を除く)。",
"tags-delete-not-found": "タグ「$1」は存在しません。",
"tags-delete-too-many-uses": "タグ「$1」は少なくとも$2版に付与されており、削除できません。",
- "tags-delete-warnings-after-delete": "ã\82¿ã\82°ã\80\8c$1ã\80\8dã\81®å\89\8aé\99¤ã\81\97ã\81¾ã\81\97ã\81\9fã\81\8c、以下の{{PLURAL:$2|警告}}が発生しました:",
+ "tags-delete-warnings-after-delete": "ã\82¿ã\82°ã\80\8c$1ã\80\8dã\82\92å\89\8aé\99¤ã\81\97ã\81\9fã\81¨ã\81\93ã\82\8d、以下の{{PLURAL:$2|警告}}が発生しました:",
"tags-delete-no-permission": "変更タグを削除する権限がありません。",
"tags-activate-title": "タグの有効化",
"tags-activate-question": "タグ「$1」を有効化しようとしています。",
"Macofe",
"Saraiki",
"BukhariSaeed",
- "Fitoschido"
+ "Fitoschido",
+ "Amire80"
]
},
"tog-underline": "ربطو خط کشیدگی",
"showpreview": "示覽",
"showdiff": "示異",
"anoneditwarning": "'''警示:'''子未登簿,若確纂,IP將誌。茍[$1 登]或[$2 開戶口],是纂欲存以子名,及他效。",
- "anonpreviewwarning": "''子未登簿,IP將誌。''",
+ "anonpreviewwarning": "子未登簿,IP將誌。",
"missingsummary": "'''醒示:'''子未概之,復「$1」則文倍焉。",
"missingcommenttext": "請贊之",
"missingcommentheader": "'''醒示:'''子未概標之,復「$1」則文倍焉。",
"errorpagetitle": "Sbaglio",
"returnto": "Torna a $1.",
"tagline": "'A {{SITENAME}}.",
- "help": "Ajùto",
+ "help": "Ajuto",
"help-mediawiki": "Ajuto ncopp' 'a MediaWiki",
- "search": "Truova",
+ "search": "Cerca",
"search-ignored-headings": " #<!-- lassa sta linea comme sta --> <pre>\n# Testate ca se sarranno gnurate int' 'a ricerca.\n# Cagnamiente a chesto addeventarranno affettive quanno 'a paggena sarrà innecizzata.\n# Vuje putite forzà 'a reinnecezzazzione d' 'a paggena facenno nu cagnamiento abbacante.\n# 'A sintasse è 'a seguente:\n# * Ogneccosa 'a 'o carattere \"#\" 'nzegna 'a fine d' 'a linea è 'nu cummanno\n# * Ogne linea chiena è 'o titolo esatto 'a gnurà, case e tutteccose\nRiferimente\nJonte 'e fore\nVide pure\n #</pre> <!-- lassa sta linea comme sta -->",
- "searchbutton": "Truova",
+ "searchbutton": "Cerca",
"go": "Vàje",
- "searcharticle": "Vàje",
+ "searcharticle": "Vaje",
"history": "Verziune 'e primma",
"history_short": "Cronologgia",
"history_small": "cronologgia",
"updatedmarker": "cagnamiénte 'e ll'urdema visita d' 'a mia",
- "printableversion": "Verzione pe' stampa",
+ "printableversion": "Verzione p''a stampa",
"permalink": "Jonta permanente",
"print": "Stampà",
"view": "Vire",
"view-foreign": "Vide ncopp'a $1",
- "edit": "Càgna",
+ "edit": "Cagna",
"edit-local": "Càgna descrizione lucale",
"create": "Crèa",
"create-local": "Azzecca descrizione lucale",
"protect_change": "càgna",
"unprotect": "Càgna prutezzione",
"newpage": "Paggena nova",
- "talkpagelinktext": "Chiàcchiera",
+ "talkpagelinktext": "chiacchiera",
"specialpage": "Paggena speciàle",
- "personaltools": "Strumiente perzonale",
- "talk": "Chiàcchiera",
+ "personaltools": "Strumente perzonale",
+ "talk": "Chiacchiera",
"views": "Visite",
- "toolbox": "Strumiente",
+ "toolbox": "Strumente",
"tool-link-userrights": "Càgna gruppe {{GENDER:$1|utente}}",
"tool-link-userrights-readonly": "Vire gruppe {{GENDER:$1|utente}}",
"tool-link-emailuser": "Manna na masciata email a st'{{GENDER:$1|utente}}",
"viewcount": "Chesta paggena è stata liggiùta {{PLURAL:$1|una vòta|$1 vòte}}.",
"protectedpage": "Paggena prutetta",
"jumpto": "Vaje a:",
- "jumptonavigation": "navigazione",
- "jumptosearch": "truova",
+ "jumptonavigation": "navigazzione",
+ "jumptosearch": "cerca",
"view-pool-error": "Ve cercammo scusa, 'e servers hanno troppo carico mo'.\nTroppe utente stanno cercanno 'e veré sta paggena.\nPe' piacere, aspettate nu poco primma 'e turnà a carrecà sta paggena.\n\n$1",
"generic-pool-error": "Ve cercammo scusa, 'e servers hanno troppo carico mo'.\nTroppe utente stanno cercanno 'e veré sta risorsa.\nPe' piacere, aspettate nu poco primma 'e turnà a carrecà sta risorsa.",
"pool-timeout": "Tiempo pe' s'aspettà ô blocco",
"pool-errorunknown": "Errore scanusciuto",
"pool-servererror": "'O servizio contatore d''e fatiche nun è a disposizióne ($1).",
"poolcounter-usage-error": "Errore d'uso: $1",
- "aboutsite": "'Nfrummazione ncòpp'a {{SITENAME}}",
- "aboutpage": "Project:'Nfrummazione",
+ "aboutsite": "'Nfurmazzione ncòpp''a {{SITENAME}}",
+ "aboutpage": "Project:'Nfurmazzione",
"copyright": "Cuntenute suggiette a licienza 'e auso $1 se nun fuje ritto atro.",
"copyrightpage": "{{ns:project}}:Copyrights",
"currentevents": "Nuvità",
"currentevents-url": "Project:Novità",
- "disclaimers": "Avvertimiènte",
- "disclaimerpage": "Project:Avvertimiènte generale",
+ "disclaimers": "Avvertimiente",
+ "disclaimerpage": "Project:Avvertimiente generale",
"edithelp": "Guida",
"helppage-top-gethelp": "Ajùto",
"mainpage": "Paggena prencepale",
"mainpage-description": "Paggena prencepale",
"policy-url": "Project:Policy",
- "portal": "Porta d’'a commonetà",
- "portal-url": "Project:Porta d''a commonetà",
- "privacy": "'Nformazzione ppe a privacy",
- "privacypage": "Project:'Nfrummazione ncopp'â privacy",
+ "portal": "Porta d''a communetà",
+ "portal-url": "Project:Porta d''a communetà",
+ "privacy": "'Nfurmazzione p''a privacy",
+ "privacypage": "Project:'Nfurmazzione p''a privacy",
"badaccess": "Nun aie bastante licenzia",
"badaccess-group0": "Nun tiene 'a licenzia pe ffà l'azione richiesta.",
"badaccess-groups": "L'azione ch'ê addemmannato 'a pô ffà sulamente ll'utente ca stanno dint'a {{PLURAL:$2|'o gruppo|uno d' 'e gruppe}}: $1.",
"newmessageslinkplural": "{{PLURAL:$1|na mmasciata nova|999=mmasciate nnove}}",
"newmessagesdifflinkplural": "{{PLURAL:$1|urdemo cagnamiento|999=urdeme cagnamiente}}",
"youhavenewmessagesmulti": "Tiene nuove mmasciate $1",
- "editsection": "càgna",
+ "editsection": "cagna",
"editold": "càgna",
"viewsourceold": "vire sorgente",
"editlink": "càgna",
"site-atom-feed": "Feed Atom 'e $1",
"page-rss-feed": "Feed RSS pe' \"$1\"",
"page-atom-feed": "Feed Atom ppe \"$1\"",
- "red-link-title": "$1 ('a paggena nun esiste)",
+ "red-link-title": "$1 (sta paggena nun esiste)",
"sort-descending": "Urdinamento dicriscente",
"sort-ascending": "Urdinamento criscente",
"nstab-main": "Articulo",
"loginlanguagelabel": "Lengua: $1",
"suspicious-userlogout": "'A richiesta 'e disconnessione d' 'a toja è stata negate pecché pare ca fosse mannata 'a nu navigatóre rutto o nu proxy 'e \"caching\".",
"createacct-another-realname-tip": "'O nomme overo vuosto è ozzionale.\nSi sciglite 'e nzertà 'o nomme overo, chesto s'ausarrà pe' dà l'utente l'attribuzione d' 'a fatica fatta.",
- "pt-login": "Tràse",
+ "pt-login": "Trase",
"pt-login-button": "Tràse",
"pt-login-continue-button": "Và annanze e tràse",
- "pt-createaccount": "Crèa nu cunto nuovo",
+ "pt-createaccount": "Crea 'nu cunto nuovo",
"pt-userlogout": "Jèsce",
"php-mail-error-unknown": "Errore scanusciuto dint'a funzione PHP mail()",
"user-mail-no-addy": "Avite cercato 'e mannà na mmasciata e-mail senza indirizzo.",
"nchanges": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|'a ll'urdema visita}}",
"enhancedrc-history": "cronologgia",
- "recentchanges": "Urdeme nove",
+ "recentchanges": "Urdeme cagnamiente",
"recentchanges-legend": "Opzione urdeme cagnamiénte",
"recentchanges-summary": "Ncopp'a chesta paggena song' appresentate ll'urdeme cagnamiente fatte ê cuntenute d\"o sito.",
"recentchanges-noresult": "Nisciuno cagnamiento dint'o periodo dato ca soddisfà sti criterie.",
"minoreditletter": "m",
"newpageletter": "N",
"boteditletter": "b",
- "rc-change-size-new": "$1 {{PLURAL:$1|byte|byte}} aropp'ô cagnamiento",
+ "rc-change-size-new": "$1 {{PLURAL:$1|byte}} aropp''o cagnamiento",
"newsectionsummary": "/* $1 */ sezziona nnova",
"rc-enhanced-expand": "Fa vede dettaglie",
"rc-enhanced-hide": "Annascunne dettaglie",
"recentchanges-page-removed-from-category": "[[:$1]] luvato d' 'a categurìa",
"recentchanges-page-removed-from-category-bundled": "[[:$1]] luvate 'e categurìa, [[Special:WhatLinksHere/$1|sta paggena è azzeccata dint'a n'ati paggene]]",
"autochange-username": "Cagnamiento automateco MediaWiki",
- "upload": "Carreca file",
+ "upload": "Careca 'na fiùra",
"uploadbtn": "Carreca file",
"reuploaddesc": "Torna a 'o modulo pe ffà 'a carreca",
"upload-tryagain": "Manna 'a descrizione d' 'o file cagnato",
"sp-contributions-newonly": "Sulamente 'e contribbute ca songo criazione 'e paggene",
"sp-contributions-hideminor": "Annascunne cagnamiénte piccerille",
"sp-contributions-submit": "Truova",
- "whatlinkshere": "Paggene ca cullegano a chesta",
+ "whatlinkshere": "Paggene ca se cullegano a chesta",
"whatlinkshere-title": "Paggene ca cullegano a $1",
"whatlinkshere-page": "Paggena:",
"linkshere": "'E ppaggene ccà abbascio teneno jonte a <strong>$2</strong>.",
"tooltip-pt-watchlist": "'A lista d' 'e paggene ca state a cuntrullà",
"tooltip-pt-mycontris": "N'elenco 'e cuntribbute {{GENDER:|vòste}}",
"tooltip-pt-anoncontribs": "N'elenco 'e cagnamiente fatte 'a st'indirizzo IP",
- "tooltip-pt-login": "A reggistrazione è cunsigliata",
+ "tooltip-pt-login": "Ve cunsigliamme 'e trasì dint'o cunto vostro, ma nun l'avite a ffà pe' fforza",
"tooltip-pt-logout": "Jésce (logout)",
- "tooltip-pt-createaccount": "Pigliateve curaggio e criate n'utente e trasìte; eziamme ca chisto nun s'avesse 'a ffà pe' fforza",
- "tooltip-ca-talk": "Vide 'e chiacchere rilative a chesta paggena",
+ "tooltip-pt-createaccount": "Ve cunsigliamme 'e ve reggistrà 'nu cunte e trasì, ma nun l'avite a ffà pe' fforza",
+ "tooltip-ca-talk": "Vide 'e chiacchere 'e chesta paggena",
"tooltip-ca-edit": "Cagna sta paggena",
"tooltip-ca-addsection": "Cummincia 'na nova sezzione",
"tooltip-ca-viewsource": "Chista paggena è prutetta, ma può verè 'o codice sorgente",
- "tooltip-ca-history": "Vversione 'e primma 'e chesta paggena",
+ "tooltip-ca-history": "Verzione 'e primma 'e chesta paggena",
"tooltip-ca-protect": "Prutegge chesta paggena",
"tooltip-ca-unprotect": "Càgna 'a prutezzione 'e chesta paggena",
"tooltip-ca-delete": "Scancèlla chesta paggena",
"tooltip-ca-move": "Mòve sta paggena",
"tooltip-ca-watch": "Azzecca sta paggena int' 'a lista 'e paggene cuntrullate vuosta",
"tooltip-ca-unwatch": "Lèva sta paggena d' 'a lista 'e paggene cuntrullate vuosta",
- "tooltip-search": "Truova dint'a {{SITENAME}}",
- "tooltip-search-go": "Vaje â paggena cu stu nomme si esiste",
- "tooltip-search-fulltext": "Ascià 'o testo indicato dint'e paggene",
+ "tooltip-search": "Cerca dint''a {{SITENAME}}",
+ "tooltip-search-go": "Vaje a 'na paggena cu stu nomme, si ce sta",
+ "tooltip-search-fulltext": "Cerca chistu testo dint''e paggene",
"tooltip-p-logo": "Visita a paggena prencepale",
"tooltip-n-mainpage": "Visita a paggena prencepale",
"tooltip-n-mainpage-description": "Visita a paggena prencepale",
- "tooltip-n-portal": "Descrizione d' 'o prugietto, che po' ffa, addò truvà 'e ccose",
+ "tooltip-n-portal": "Descrizione d''o prugietto, che putite fà e addò putite truvà 'e ccose",
"tooltip-n-currentevents": "Ascìa 'e nfurmaziune ncopp' 'e fatte succiesse mo mmo",
- "tooltip-n-recentchanges": "Ennece dde urdeme cagnamiénte d' 'o sito",
- "tooltip-n-randompage": "Na paggena qualsiase",
- "tooltip-n-help": "Paggena 'e ajùto",
- "tooltip-t-whatlinkshere": "'Na lista 'e tutte e paggene ca song cullegate a chista",
+ "tooltip-n-recentchanges": "Ennece 'e ll'urdeme cagnamiente d''o sito",
+ "tooltip-n-randompage": "Careca 'na paggena qualonca",
+ "tooltip-n-help": "Paggena 'e ajuto",
+ "tooltip-t-whatlinkshere": "Ennece 'e tutte e paggene ca so' cullegate a chesta",
"tooltip-t-recentchangeslinked": "Urdeme cagnamiénte dde paggene ca cullegano a chesta",
"tooltip-feed-rss": "RSS feed pe sta pàggena",
"tooltip-feed-atom": "Atom feed pe sta pàggena",
"tooltip-t-contributions": "Lista dde contributte fatte 'a {{GENDER:$1|chist'utente}}",
"tooltip-t-emailuser": "Manna 'nu email a {{GENDER:$1|chist'utente}}",
"tooltip-t-info": "Cchiù nfurmaziune ncopp'a sta paggena",
- "tooltip-t-upload": "Carreca file",
- "tooltip-t-specialpages": "Lista 'e tutte e paggene speciale",
- "tooltip-t-print": "Vversione pe stampà 'a chesta paggena",
+ "tooltip-t-upload": "Careca cchiù fiùre",
+ "tooltip-t-specialpages": "Lista 'e tutte 'e paggene speciale",
+ "tooltip-t-print": "Verzione p''a stampa 'e chesta paggena",
"tooltip-t-permalink": "Jonta permanente a chesta vversione dda paggena",
"tooltip-ca-nstab-main": "Vire 'a paggena 'e contenuto",
"tooltip-ca-nstab-user": "Vire 'a paggena utente",
"pageinfo-hidden-categories": "{{PLURAL:$1|Categurìa annascunnuta|Categurìe annascunnute}} ($1)",
"pageinfo-templates": "Template {{PLURAL:$1|appennuto|appennute}} ($1)",
"pageinfo-transclusions": "{{PLURAL:$1|Paggena appennuta|Paggene appennute}} ncopp'a ($1)",
- "pageinfo-toolboxlink": "Nfurmaziune d' 'a paggena",
+ "pageinfo-toolboxlink": "'Nfurmazzione d''a paggena",
"pageinfo-redirectsto": "Reindirizza a",
"pageinfo-redirectsto-info": "nfurmaziune",
"pageinfo-contentpage": "Cuntata comme na paggena 'e cuntenute",
"feedback-thanks": "Grazie! 'O feedback vuosto s'è mpizzato dint' 'a paggena \"[$2 $1]\".",
"feedback-thanks-title": "Ve ringraziammo!",
"feedback-useragent": "Aggente utente:",
- "searchsuggest-search": "Truova dint'a {{SITENAME}}",
+ "searchsuggest-search": "Cerca dint''a {{SITENAME}}",
"searchsuggest-containing": "tène...",
"api-error-badtoken": "Errore interno: 'O token nun è buono.",
"api-error-emptypage": "'A criazione 'e paggene nuove abbacante nun è permessa.",
"createaccountmail": "ߓߍ߲߬ߛߋ߲߬ߡߊ߬ ߕߊߡߌ߲ߞߊ߲ ߕߎ߬ߡߊ߬ߞߎ߲߬ߡߊ ߟߊߓߊ߯ߙߊ߫ ߞߊ߬ ߓߊ߲߫ ߞߵߊ߬ ߗߋ߫ ߢߎߡߍߙߋ߲߫ ߞߏ߲ߘߏ߫ ߓߟߏߡߊߞߊ߬ߣߍ߲ ߡߊ߬.",
"createaccountmail-help": "ߊ߬ ߕߍ߫ ߛߐ߲߬ ߠߊߓߊ߯ߙߊ߫ ߟߊ߫߸ ߞߊ߬ ߡߐ߰ ߜߘߍ߫ ߟߊ߫ ߖߊ߬ߕߋ߬ߘߊ ߛߌ߲ߘߌ߫߸ ߣߴߌ ߡߊ߫ ߕߊ߬ߡߌ߲߬ߞߊ߲ ߞߊ߬ߙߊ߲߬.",
"createacct-realname": "ߕߐ߮ ߓߘߍ (ߛߎߥߊ߲ߘߟߌ)",
- "createacct-reason": "ß\8a߬ ß\9bß\8aß\93ß\8eß«",
+ "createacct-reason": "ß\8a߬ ß\9eß\8eß²ß",
"createacct-reason-ph": "ߡߎ߲߬ߠߊ߫ ߌ ߦߋ߫ ߖߊ߬ߕߋ߬ߘߊ߰ ߜߘߍ߫ ߛߌ߲ߘߌ߫ ߟߊ߫",
"createacct-reason-help": "ߗߋߛߓߍ ߦߌ߬ߘߊ߬ ߖߊ߬ߕߋ߬ߘߊ ߛߌ߲ߘߟߌ ߘߊ߲ߖߐ ߘߐ߫",
"createacct-submit": "ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߘߊߦߟߍ߬",
"newarticle": "(ߞߎߘߊ)",
"newarticletext": "ߌ ߓߘߊ߫ ߛߘߌ߬ߜߋ߲ ߘߏ߫ ߟߊߓߊ߬ߕߏ߬ ߞߐߜߍ ߘߏ߫ ߘߐ߫߸ ߡߍ߲ ߕߴߦߋ߲߬ ߡߎߣߎ߲߬.\nߣߵߌ ߦߴߊ߬ ߝߍ߫ ߞߊ߬ ߞߐߜߍ ߘߏ߫ ߟߊߘߊ߲߫߸ ߛߓߍߟߌ ߘߊߡߌ߬ߣߊ߬ ߘߎ߰ߟߊ߬ߘߐ߫ ߞߏ߲ߘߏ ߘߐ߫ (ߞߊ߬ [$1 ߘߍ߬ߡߍ߲߬ߠߌ߲ ߞߐߜߍ] ߦߋ߫߸ ߖߐ߲߬ߛߊ߬ ߌ ߘߌ߫ ߞߌ߬ߓߊ߬ߙߏ߬ ߖߐ߲ߖߐ߲ ߛߐ߬ߘߐ߲߬). ߣߵߌ ߘߏ߲߬ ߞߍ߫ ߘߊ߫ ߦߊ߲߬ ߝߎ߬ߕߎ߲߬ߕߌ߬ ߓߟߏߡߊ߬߸ ߌ ߟߊ߫ ߛߏ߲߯ߓߊߟߊ߲ <strong>back</strong> ߛߐ߲߬ߞߌ߲߫.",
"anontalkpagetext": "----\n<em>ߓߊ߬ߘߏ߬ ߞߐߜߍ ߣߌ߲߬ ߦߋ߫ ߟߊߓߊ߯ߙߟߊ߫ ߟߐ߲ߓߊߟߌ ߟߋ߬ ߓߟߏ߫ ߡߍ߲ ߡߊ߫ ߖߊ߬ߕߋ߬ߘߊ߬ ߛߌ߲ߘߌ߫ ߡߎߣߎ߲߬ ߥߟߴߊ߬ ߕߍ߫ ߖߊ߬ߕߋ߬ߘߊ ߏ߬ ߟߊߓߊ߯ߙߊ߫ ߟߊ߫;</em>\nߏ߬ ߞߏߛߐ߲߬ ߊ߲ ߞߊ߫ ߞߊ߲߫ ߞߵߊ߬ ߟߊ߫ ߓߡ (ߓߟߐߟߐ ߡߛߍ߬ߞߍ߬ߡߛߍߞߍ) ߛߊ߲߬ߓߊ߬ߕߐ߮ ߟߊߓߊ߯ߙߴߊ߬ ߡߊߟߐ߲߫ ߞߊߡߊ߬߸ ߟߊߓߊ߯ߙߟߊ߫ ߛߌߦߊߡߊ߲߫ ߓߴߛߋ߫ ߞߊ߬ ߘߍ߬ ߓߡ ߛߊ߲߬ߓߊ߬ߕߐ߮ ߣߌ߲߬ ߢߐ߲߰ ߠߊ߫.\nߣߴߌ ߞߍ߫ ߘߊ߫ ߟߊߓߊ߯ߙߟߊ߫ ߡߊߝߟߌ߬ߣߍ߲߫ ߘߌ߫ ߞߵߊ߬ ߛߏ߬ߓߌ߬ ߞߏ߫ ߌ ߟߊ߫ ߞߊ߲߬ߞߎߡߊ ߟߎ߬ ߕߴߌ ߕߊ߫ ߘߌ߫ ߊ߬ ߘߌ߫ ߟߐ߬ ߌ ߡߊ߬ ߌߞߘߐ߫߸ ߌ ߖߏ߫ ߞߊ߬ [[Special:CreateAccount|ߖߊ߬ߕߋ߬ߘߊ ߘߏ߫ ߘߊߦߟߍ߬]] ߥߟߊ߫ [[Special:UserLogin|ߞߊ߬ ߘߏ߲߬ߕߐ߰ߟߊ߬ߘߏ߲ ߞߍ߫]] ߖߐ߲߬ߛߊ߫ ߟߏ߲ߘߐ߬ ߓߊߛߌ߯ߓߊߟߌߦߊ ߘߌ߫ ߡߟߊ߫ ߟߊߓߊ߯ߙߟߊ߫ ߡߊߟߐ߲ߓߊߟߌ߫ ߜߘߍ ߟߎ߬ ߓߟߏ߫.",
- "noarticletext": "ß\9bß\93ß\8dß\9fß\8cß« ß\9bß\8cß« ß\95ß\8dß« ß\9eß\90ß\9cß\8d ߣß\8cß²ß ß\9eß\8a߲߬ ß\95ß\8b߲߫. ß\8c ß\98ß\8cß« ß\9bß\8bß« ß\9eß\90ß\9cß\8d ߣß\8c߲߬ \n [[Special:Search/{{PAGENAME}}|search for this page title]] ß\95ß\90ß® ߢß\8cߣß\8c߲߫ ß ß\8aß« ß\9eß\90ß\9cß\8d ß\95ß\90ß ß\9fß\8e߬ ß\98ß\90ß«߸ \n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
+ "noarticletext": "ß\9bß\93ß\8dß\9fß\8cß« ß\9bß\8cß« ß\95ß\8dß« ß\9eß\90ß\9cß\8d ߣß\8cß²ß ß\9eß\8a߲߬ ß\95ß\8b߲߬. ß\8c ß\98ß\8cß« ß\9bß\8bß« ß\9eß\90ß\9cß\8d ߣß\8c߲߬.\n[[Special:Search/{{PAGENAME}}|search for this page title]] ß\95ß\90ß® ߢß\8cߣß\8c߲߫ ß ß\8aß« ß\9eß\90ß\9cß\8d ß\95ß\90ß ß\9fß\8e߬ ߢß\8aß\9dß\8d߬߸ \n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} create this page]</span>.",
"noarticletext-nopermission": "ߛߓߍߟߌ߫ ߛߌ߫ ߕߍ߫ ߞߐߜߍ ߣߌ߲߭ ߞߊ߲߬ ߕߋ߲߫.\nߌ ߘߌ߫ ߛߋ߫ [[Special:Search/{{PAGENAME}}|search for this page title]] ߢߌߣߌ߲߫ ߠߊ߫ ߞߐߜߍ ߕߐ߭ ߟߎ߬ ߘߐ߫߸ ߥߟߊ߫ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span> ߞߏ߬ߣߌ߲߬ ߘߌ߬ߢߍ߬ ߞߍߣߍ߲߫ ߕߴߌ ߡߊ߬ ߞߐߜߍ߫ ߣߌ߲߬ ߠߊߞߊ߭ ߘߐ߫.",
"userpage-userdoesnotexist": "ߖߊ߬ߕߋ߬ߘߊ߬ ߟߊߓߊ߯ߙߕߊ \"$1\" ߛߌ߲ߘߌߣߍ߲߫ ߕߍ߫. \nߝߛߍ߬ߝߛߍ߬ߟߌ ߞߍ߫߸ ߣߴߌ ߦߴߊ߬ ߝߍ߬ ߞߊ߬ ߞߐߜߍ ߣߌ߲߬ ߛߌ߲ߘߌ߫/ߡߊߦߟߍ߬ߡߊ߲߫.",
"userpage-userdoesnotexist-view": "ߟߊ߬ߓߊ߰ߙߊ߬ ߖߊߕߋߘߊ \"$1\" ߟߊߞߎ߲߬ߘߎ߬ߣߍ߲߫ ߕߍ߫.",
"recentchanges-label-unpatrolled": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߣߌ߲߬ ߡߊ߫ ߓߍ߬ߙߍ߲߬ߓߍ߬ߙߍ߲߬ ߡߎߣߎ߲߬",
"recentchanges-label-plusminus": "ߞߐߜߍ ߢߊ߲ߞߊ߲ ߓߘߊ߫ ߡߊߦߟߍ߬ߡߊ߲߫ ߞߵߊ߬ ߝߌ߬ߘߊ߲ ߦߙߌߞߊ ߣߌ߲߬ ߘߌ߫",
"recentchanges-legend-heading": "<strong>ߡߊ߬ߛߙߋ:</strong>",
- "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ߣß\8c߲߬ ß\9dߣß\8aß« ߦß\8bß« \n[[Special:NewPages|list of new pages]])",
+ "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ߣß\8c߲߬ ß\9dߣß\8aß« ß\93ߴߦß\8b߲߬ [[Special:NewPages|list of new pages]])",
"recentchanges-submit": "ߊ߬ ߦߌ߬ߘߊ߬",
"rcfilters-tag-remove": "$1 ߛߋ߲߬ߓߐ߫",
"rcfilters-legend-heading": "<strong>ߟߊ߬ߘߛߏ߬ߟߌ ߛߙߍߘߍ</strong>",
"perfcached": "Like {{msg-mw|perfcachedts}} but used when we do not know how long ago page was cached (unlikely to happen).\n\nParameters:\n* $1 - the max result cut off ($wgQueryCacheLimit)",
"perfcachedts": "Used on pages that list page lists for which the displayed data is cached. Parameters:\n* $1 - a time stamp (date and time combined)\n* $2 - a date (optional)\n* $3 - a time (optional)\n* $4 - the cut off limit for cached results ($wgQueryCacheLimit). If there are more then this many results for the query, only the first $4 of those will be listed on the page. Usually $4 is about 1000.",
"querypage-no-updates": "Text on some special pages, e.g. [[Special:FewestRevisions]].",
+ "querypage-updates-periodical": "Text on some special pages which are configurated with a periodical run of a maintenance script.\n\nSee also {{msg-mw|querypage-no-updates}}.",
"viewsource": "The text displayed in place of the {{msg-mw|Edit}} tab when the user has no permission to edit the page.\n\nSee also:\n* {{msg-mw|Viewsource}}\n* {{msg-mw|Accesskey-ca-viewsource}}\n* {{msg-mw|Tooltip-ca-viewsource}}\n{{Identical|View source}}",
"viewsource-title": "Page title shown when trying to edit a protected page. Parameters:\n* $1 - the name of the page",
"actionthrottled": "This is the title of an error page. Read it in combination with {{msg-mw|actionthrottledtext}}.",
--- /dev/null
+-- T233221: The index on `archive` variously known as `ar_usertext_timestamp`
+-- and `usertext_timestamp` has a long and sordid history. We're dropping the
+-- `ar_user_text` column entirely now (see patch-drop-user-fields.sql), but
+-- this index needs special care thanks to said history.
+
+-- Do not use the /*i*/ thing here!
+DROP INDEX ar_usertext_timestamp ON /*_*/archive;
--- /dev/null
+-- T233221: The index on `archive` variously known as `ar_usertext_timestamp`
+-- and `usertext_timestamp` has a long and sordid history. We're dropping the
+-- `ar_user_text` column entirely now (see patch-drop-user-fields.sql), but
+-- this index needs special care thanks to said history.
+
+-- Do not use the /*i*/ thing here!
+DROP INDEX usertext_timestamp ON /*_*/archive;
-- T188327. Drop old xx_user and xx_user_text fields, and defaults from xx_actor fields.
ALTER TABLE /*_*/archive
- DROP INDEX /*i*/ar_usertext_timestamp,
DROP COLUMN ar_user,
DROP COLUMN ar_user_text,
ALTER COLUMN ar_actor DROP DEFAULT;
--- /dev/null
+-- T233240: The indexes on `user_newtalk` may be named `un_user_id`/`un_user_ip`
+-- or `user_id`/`user_ip`. At least it won't be both or mixed. Rename them to
+-- the former.
+
+-- Do not use the /*i*/ hack here!
+ALTER TABLE /*_*/user_newtalk
+ DROP INDEX user_id,
+ DROP INDEX user_ip,
+ ADD INDEX un_user_id (user_id),
+ ADD INDEX un_user_ip (user_ip);
public $numProcs = 1;
public $numBatches = 0;
public $pageBlobClass, $orphanBlobClass;
- public $replicaPipes, $replicaProcs, $prevReplicaId;
+ public $childPipes, $childProcs, $prevChildId;
public $copyOnly = false;
public $isChild = false;
- public $replicaId = false;
+ public $childId = false;
public $noCount = false;
public $debugLog, $infoLog, $criticalLog;
/** @var ExternalStoreDB */
private static $optionsWithArgs = [
'procs',
- 'replica-id',
+ 'child-id',
'debug-log',
'info-log',
'critical-log'
'procs' => 'numProcs',
'copy-only' => 'copyOnly',
'child' => 'isChild',
- 'replica-id' => 'replicaId',
+ 'child-id' => 'childId',
'debug-log' => 'debugLog',
'info-log' => 'infoLog',
'critical-log' => 'criticalLog',
$this->store = $esFactory->getStore( 'DB' );
if ( !$this->isChild ) {
$GLOBALS['wgDebugLogPrefix'] = "RCT M: ";
- } elseif ( $this->replicaId !== false ) {
- $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->replicaId}: ";
+ } elseif ( $this->childId !== false ) {
+ $GLOBALS['wgDebugLogPrefix'] = "RCT {$this->childId}: ";
}
$this->pageBlobClass = function_exists( 'xdiff_string_bdiff' ) ?
DiffHistoryBlob::class : ConcatenatedGzipHistoryBlob::class;
function logToFile( $msg, $file ) {
$header = '[' . date( 'd\TH:i:s' ) . '] ' . wfHostname() . ' ' . posix_getpid();
- if ( $this->replicaId !== false ) {
- $header .= "({$this->replicaId})";
+ if ( $this->childId !== false ) {
+ $header .= "({$this->childId})";
}
$header .= ' ' . WikiMap::getCurrentWikiDbDomain()->getId();
LegacyLogger::emit( sprintf( "%-50s %s\n", $header, $msg ), $file );
}
$this->syncDBs();
- $this->startReplicaProcs();
+ $this->startChildProcs();
$this->doAllPages();
$this->doAllOrphans();
- $this->killReplicaProcs();
+ $this->killChildProcs();
}
/**
* This necessary because text recompression is slow: loading, compressing and
* writing are all slow.
*/
- function startReplicaProcs() {
+ function startChildProcs() {
$wiki = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
$cmd = 'php ' . Shell::escape( __FILE__ );
foreach ( self::$cmdLineOptionMap as $cmdOption => $classOption ) {
- if ( $cmdOption == 'replica-id' ) {
+ if ( $cmdOption == 'child-id' ) {
continue;
} elseif ( in_array( $cmdOption, self::$optionsWithArgs ) && isset( $this->$classOption ) ) {
$cmd .= " --$cmdOption " . Shell::escape( $this->$classOption );
' --wiki ' . Shell::escape( $wiki ) .
' ' . Shell::escape( ...$this->destClusters );
- $this->replicaPipes = $this->replicaProcs = [];
+ $this->childPipes = $this->childProcs = [];
for ( $i = 0; $i < $this->numProcs; $i++ ) {
$pipes = [];
$spec = [
[ 'file', 'php://stderr', 'w' ]
];
Wikimedia\suppressWarnings();
- $proc = proc_open( "$cmd --replica-id $i", $spec, $pipes );
+ $proc = proc_open( "$cmd --child-id $i", $spec, $pipes );
Wikimedia\restoreWarnings();
if ( !$proc ) {
- $this->critical( "Error opening replica DB process: $cmd" );
+ $this->critical( "Error opening child process: $cmd" );
exit( 1 );
}
- $this->replicaProcs[$i] = $proc;
- $this->replicaPipes[$i] = $pipes[0];
+ $this->childProcs[$i] = $proc;
+ $this->childPipes[$i] = $pipes[0];
}
- $this->prevReplicaId = -1;
+ $this->prevChildId = -1;
}
/**
* Gracefully terminate the child processes
*/
- function killReplicaProcs() {
- $this->info( "Waiting for replica DB processes to finish..." );
+ function killChildProcs() {
+ $this->info( "Waiting for child processes to finish..." );
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $this->dispatchToReplica( $i, 'quit' );
+ $this->dispatchToChild( $i, 'quit' );
}
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $status = proc_close( $this->replicaProcs[$i] );
+ $status = proc_close( $this->childProcs[$i] );
if ( $status ) {
$this->critical( "Warning: child #$i exited with status $status" );
}
}
/**
- * Dispatch a command to the next available replica DB.
- * This may block until a replica DB finishes its work and becomes available.
+ * Dispatch a command to the next available child process.
+ * This may block until a child process finishes its work and becomes available.
* @param array|string ...$args
*/
function dispatch( ...$args ) {
- $pipes = $this->replicaPipes;
+ $pipes = $this->childPipes;
$x = [];
$y = [];
$numPipes = stream_select( $x, $pipes, $y, 3600 );
if ( !$numPipes ) {
- $this->critical( "Error waiting to write to replica DBs. Aborting" );
+ $this->critical( "Error waiting to write to child process. Aborting" );
exit( 1 );
}
for ( $i = 0; $i < $this->numProcs; $i++ ) {
- $replicaId = ( $i + $this->prevReplicaId + 1 ) % $this->numProcs;
- if ( isset( $pipes[$replicaId] ) ) {
- $this->prevReplicaId = $replicaId;
- $this->dispatchToReplica( $replicaId, $args );
+ $childId = ( $i + $this->prevChildId + 1 ) % $this->numProcs;
+ if ( isset( $pipes[$childId] ) ) {
+ $this->prevChildId = $childId;
+ $this->dispatchToChild( $childId, $args );
return;
}
}
/**
- * Dispatch a command to a specified replica DB
- * @param int $replicaId
+ * Dispatch a command to a specified child process
+ * @param int $childId
* @param array|string $args
*/
- function dispatchToReplica( $replicaId, $args ) {
+ function dispatchToChild( $childId, $args ) {
$args = (array)$args;
$cmd = implode( ' ', $args );
- fwrite( $this->replicaPipes[$replicaId], "$cmd\n" );
+ fwrite( $this->childPipes[$childId], "$cmd\n" );
}
/**
}
public function execute() {
- global $wgQueryCacheLimit, $wgDisableQueryPageUpdate;
+ global $wgQueryCacheLimit;
$dbw = $this->getDB( DB_MASTER );
$this->doSpecialPageCacheUpdates( $dbw );
+ $disabledQueryPages = QueryPage::getDisabledQueryPages( $this->getConfig() );
foreach ( QueryPage::getPages() as $page ) {
list( , $special ) = $page;
$limit = $page[2] ?? null;
}
if ( !$this->hasOption( 'override' )
- && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate )
+ && isset( $disabledQueryPages[$special] )
) {
$this->output( sprintf( "%-30s [QueryPage] disabled\n", $special ) );
continue;
/** @var Revision $rev1 */
$rev1 = $editStatus->getValue()['revision'];
- $this->setExpectedException( InvalidArgumentException::class );
- MediaWikiServices::getInstance()->getRevisionStore()
+ $status = MediaWikiServices::getInstance()->getRevisionStore()
->newRevisionsFromBatch( [ $this->revisionToRow( $rev1 ), $this->revisionToRow( $rev1 ) ] );
+
+ $this->assertFalse( $status->isGood() );
+ $this->assertTrue( $status->hasMessage( 'internalerror' ) );
}
}
$this->assertFalse( $this->cache->get( $key ), "Stale set() value ignored" );
}
+ /**
+ * @covers WANObjectCache::getWithSetCallback
+ */
+ public function testProcessCacheTTL() {
+ $cache = $this->cache;
+ $mockWallClock = 1549343530.2053;
+ $cache->setMockTime( $mockWallClock );
+
+ $key = "mykey-" . wfRandomString();
+
+ $hits = 0;
+ $callback = function ( $oldValue, &$ttl, &$setOpts ) use ( &$hits ) {
+ ++$hits;
+ return 42;
+ };
+
+ $cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+ $cache->delete( $key, $cache::HOLDOFF_NONE ); // clear persistent cache
+ $cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+ $this->assertEquals( 1, $hits, "Value process cached" );
+
+ $mockWallClock += 6;
+ $cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+ $this->assertEquals( 2, $hits, "Value expired in process cache" );
+ }
+
/**
* @covers WANObjectCache::getWithSetCallback
*/