// may still be a wikipage redirect to another article or URL.
$article = $this->initializeArticle();
if ( is_object( $article ) ) {
+ $url = $request->getFullRequestURL(); // requested URL
+ if (
+ $request->getMethod() === 'GET' &&
+ $url === $article->getTitle()->getCanonicalURL() &&
+ $article->checkTouched() &&
+ $output->checkLastModified( $article->getTouched() )
+ ) {
+ wfDebug( __METHOD__ . ": done 304\n" );
+ return;
+ }
$this->performAction( $article, $requestTitle );
} elseif ( is_string( $article ) ) {
$output->redirect( $article );
/** @var int[] */
private static $pageCount = [];
+ static function unload() {
+ self::$loaded = false;
+ }
+
static function recache() {
self::load( true );
}
: self::LIMIT_SML1;
if ( self::truncateArray( $valuesList, $sizeLimit ) ) {
+ $this->logFeatureUsage( "too-many-$valueName-for-{$this->getModulePath()}" );
$this->setWarning( "Too many values supplied for parameter '$valueName': " .
"the limit is $sizeLimit" );
}
"apihelp-linkaccount-example-link": "Iniciar el proceso de vincular a una cuenta de <kbd>Ejemplo</kbd>.",
"apihelp-login-description": "Iniciar sesión y obtener las cookies de autenticación.\n\nEsta acción solo se debe utilizar en combinación con [[Special:BotPasswords]]; para la cuenta de inicio de sesión no se utiliza y puede fallar sin previo aviso. Para iniciar la sesión de forma segura a la cuenta principal, utilice <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
"apihelp-login-description-nobotpasswords": "Iniciar sesión y obtener las cookies de autenticación.\n\nEsta acción esta obsoleta y puede fallar sin previo aviso. Para conectarse de forma segura, utilice <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
- "apihelp-login-description-nonauthmanager": "Iniciar sesión y obtener cookies de autenticación.\n\nSi inicias sesión sin problemas, las cookies necesarias se incluirán en los encabezados de respuesta HTTP. Si se produce algún error al iniciar sesión y este persiste, se puede regular para evitar los ataques masivos automatizados de adivinar contraseñas.",
"apihelp-login-param-name": "Nombre de usuario.",
"apihelp-login-param-password": "Contraseña.",
"apihelp-login-param-domain": "Dominio (opcional).",
"apihelp-query+alllinks-example-unique-generator": "Obtiene todos los títulos enlazados, marcando los que falten.",
"apihelp-query+alllinks-example-generator": "Obtiene páginas que contienen los enlaces.",
"apihelp-query+allmessages-description": "Devolver los mensajes de este sitio.",
+ "apihelp-query+allmessages-param-messages": "Qué mensajes mostrar. <kbd>*</kbd> (por defecto) significa todos los mensajes.",
"apihelp-query+allmessages-param-prop": "Qué propiedades se obtendrán.",
+ "apihelp-query+allmessages-param-enableparser": "Establecer para habilitar el analizador, se preprocesará el wikitexto del mensaje (sustitución de palabras mágicas, uso de plantillas, etc.).",
"apihelp-query+allmessages-param-nocontent": "Si se establece, no incluya el contenido de los mensajes en la salida.",
"apihelp-query+allmessages-param-args": "Los argumentos que se sustituyen en el mensaje.",
"apihelp-query+allmessages-param-filter": "Devolver solo mensajes con nombres que contengan esta cadena.",
"apihelp-query+mystashedfiles-description": "Obtener una lista de archivos en la corriente de carga de usuarios.",
"apihelp-query+mystashedfiles-param-prop": "Propiedades a buscar para los archivos.",
"apihelp-query+mystashedfiles-paramvalue-prop-size": "Buscar el tamaño del archivo y las dimensiones de la imagen.",
+ "apihelp-query+mystashedfiles-paramvalue-prop-type": "Obtener el tipo MIME y tipo multimedia del archivo.",
"apihelp-query+mystashedfiles-param-limit": "Cuántos archivos obtener.",
"apihelp-query+alltransclusions-param-from": "El título de la transclusión por la que empezar la enumeración.",
"apihelp-query+alltransclusions-param-to": "El título de la transclusión por la que terminar la enumeración.",
"apihelp-query+alltransclusions-param-limit": "Número de elementos que se desea obtener.",
"apihelp-query+alltransclusions-example-unique": "Listar títulos transcluidos de forma única.",
"apihelp-query+alltransclusions-example-unique-generator": "Obtiene todos los títulos transcluidos, marcando los que faltan.",
+ "apihelp-query+alltransclusions-example-generator": "Obtiene las páginas que contienen las transclusiones.",
"apihelp-query+allusers-description": "Enumerar todos los usuarios registrados.",
"apihelp-query+allusers-param-prefix": "Buscar todos los usuarios que empiecen con este valor.",
"apihelp-query+allusers-param-group": "Incluir solo usuarios en los grupos dados.",
"apihelp-query+allusers-paramvalue-prop-blockinfo": "Añade información sobre un bloque actual al usuario.",
"apihelp-query+allusers-paramvalue-prop-groups": "Lista los grupos a los que el usuario pertenece. Esto utiliza más recursos del servidor y puede devolver menos resultados que el límite.",
"apihelp-query+allusers-paramvalue-prop-rights": "Lista los permisos que tiene el usuario.",
+ "apihelp-query+allusers-paramvalue-prop-editcount": "Añade el número de ediciones del usuario.",
+ "apihelp-query+allusers-paramvalue-prop-registration": "Añade la marca de tiempo del momento en que el usuario se registró, si está disponible (puede estar en blanco).",
"apihelp-query+allusers-param-limit": "Cuántos nombres de usuario se devolverán.",
"apihelp-query+allusers-param-activeusers": "Solo listar usuarios activos en {{PLURAL:$1|el último día|los $1 últimos días}}.",
"apihelp-query+allusers-example-Y": "Listar usuarios que empiecen por <kbd>Y</kbd>.",
"apihelp-query+filerepoinfo-example-login": "Captura de las solicitudes que puede ser utilizadas al comienzo de inicio de sesión.",
+ "apihelp-query+backlinks-description": "Encuentra todas las páginas que enlazan a la página dada.",
"apihelp-query+backlinks-param-pageid": "Identificador de página que buscar. No puede usarse junto con <var>$1title</var>",
"apihelp-query+backlinks-param-filterredir": "Cómo filtrar redirecciones. Si se establece a <kbd>nonredirects</kbd> cuando está activo <var>$1redirect</var>, esto sólo se aplica al segundo nivel.",
"apihelp-query+backlinks-param-limit": "Cuántas páginas en total se devolverán. Si está activo <var>$1redirect</var>, el límite aplica a cada nivel por separado (lo que significa que se pueden devolver hasta 2 * <var>$1limit</var> resultados).",
"apihelp-query+blocks-paramvalue-prop-reason": "Añade la razón dada para el bloqueo.",
"apihelp-query+blocks-example-simple": "Listar bloques.",
"apihelp-query+categories-param-prop": "Qué propiedades adicionales obtener para cada categoría:",
+ "apihelp-query+categories-paramvalue-prop-timestamp": "Añade la marca de tiempo del momento en que se añadió la categoría.",
"apihelp-query+categories-param-show": "Qué tipo de categorías mostrar.",
"apihelp-query+categories-param-limit": "Cuántas categorías se devolverán.",
"apihelp-query+categories-example-generator": "Obtener información acerca de todas las categorías utilizadas en la página <kbd>Albert Einstein</kbd>.",
"apihelp-query+categoryinfo-description": "Devuelve información acerca de las categorías dadas.",
"apihelp-query+categoryinfo-example-simple": "Obtener información acerca de <kbd>Category:Foo</kbd> y <kbd>Category:Bar</kbd>",
+ "apihelp-query+categorymembers-description": "Lista todas las páginas en una categoría dada.",
"apihelp-query+categorymembers-param-prop": "Qué piezas de información incluir:",
"apihelp-query+categorymembers-paramvalue-prop-ids": "Añade el identificador de página.",
"apihelp-query+categorymembers-paramvalue-prop-title": "Agrega el título y el identificador del espacio de nombres de la página.",
"apihelp-query+categorymembers-paramvalue-prop-type": "Añade el tipo en el que se categorizó la página (<samp>page</samp>, <samp>subcat</samp> or <samp>file</samp>).",
+ "apihelp-query+categorymembers-paramvalue-prop-timestamp": "Añade la marca de tiempo del momento en que se incluyó la página.",
"apihelp-query+categorymembers-param-sort": "Propiedad por la que realizar la ordenación.",
"apihelp-query+categorymembers-param-dir": "Dirección en la que desea ordenar.",
"apihelp-query+categorymembers-param-startsortkey": "Utilizar $1starthexsortkey en su lugar.",
"apihelp-query+filearchive-param-to": "El título de imagen para detener la enumeración.",
"apihelp-query+filearchive-param-prefix": "Buscar todos los títulos de las imágenes que comiencen con este valor.",
"apihelp-query+filearchive-param-prop": "Qué información de imagen se obtendrá:",
+ "apihelp-query+filearchive-paramvalue-prop-timestamp": "Añade la marca de tiempo de la versión subida.",
+ "apihelp-query+filearchive-paramvalue-prop-user": "Agrega el usuario que subió la versión de la imagen.",
"apihelp-query+filearchive-paramvalue-prop-size": "Agrega el tamaño de la imagen en bytes y la altura, la anchura y el número de páginas (si es aplicable).",
"apihelp-query+filearchive-paramvalue-prop-dimensions": "Alias del tamaño.",
"apihelp-query+filearchive-paramvalue-prop-description": "Añade la descripción de la versión de la imagen.",
"apihelp-query+imageinfo-param-extmetadatafilter": "Si se especifica y no vacío, sólo estas claves serán devueltos por $1prop=extmetadata.",
"apihelp-query+imageinfo-param-urlparam": "Un controlador específico de la cadena de parámetro. Por ejemplo, los archivos Pdf pueden utilizar <kbd>page15-100px</kbd>. <var>$1urlwidth</var> debe ser utilizado y debe ser consistente con <var>$1urlparam</var>.",
"apihelp-query+imageinfo-param-localonly": "Buscar solo archivos en el repositorio local.",
+ "apihelp-query+imageinfo-example-simple": "Obtener información sobre la versión actual de [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageinfo-example-dated": "Obtener información sobre las versiones de [[:File:Test.jpg]] a partir de 2008.",
"apihelp-query+images-description": "Devuelve todos los archivos contenidos en las páginas dadas.",
"apihelp-query+images-param-limit": "Cuántos archivos se devolverán.",
"apihelp-query+images-example-simple": "Obtener una lista de los archivos usados en la [[Main Page|Portada]].",
"apihelp-query+info-example-protection": "Obtén información general y protección acerca de la página <kbd>Main Page</kbd>.",
"apihelp-query+iwbacklinks-param-limit": "Cuántas páginas se devolverán.",
"apihelp-query+iwbacklinks-param-prop": "Qué propiedades se obtendrán:",
+ "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Añade el título del interwiki.",
"apihelp-query+iwbacklinks-example-simple": "Obtener las páginas enlazadas a [[wikibooks:Test]]",
+ "apihelp-query+iwlinks-description": "Devuelve todos los enlaces interwiki de las páginas dadas.",
"apihelp-query+iwlinks-param-prop": "Qué propiedades adicionales obtener para cada enlace interlingüe:",
"apihelp-query+iwlinks-paramvalue-prop-url": "Añade el URL completo.",
+ "apihelp-query+iwlinks-param-limit": "Cuántos enlaces interwiki se desea devolver.",
+ "apihelp-query+iwlinks-param-prefix": "Devolver únicamente enlaces interwiki con este prefijo.",
"apihelp-query+langbacklinks-param-lang": "Idioma del enlace de idioma.",
"apihelp-query+langbacklinks-param-limit": "Cuántas páginas en total se devolverán.",
"apihelp-query+langbacklinks-param-prop": "Qué propiedades se obtendrán:",
"apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Añade el título del enlace de idioma.",
"apihelp-query+langbacklinks-example-simple": "Obtener las páginas enlazadas a [[:fr:Test]]",
"apihelp-query+langbacklinks-example-generator": "Obtener información acerca de las páginas enlazadas a [[:fr:Test]].",
+ "apihelp-query+langlinks-param-url": "Obtener la URL completa o no (no se puede usar con <var>$1prop</var>).",
"apihelp-query+langlinks-param-prop": "Qué propiedades adicionales obtener para cada enlace interlingüe:",
"apihelp-query+langlinks-paramvalue-prop-url": "Añade el URL completo.",
"apihelp-query+langlinks-paramvalue-prop-autonym": "Añade el nombre del idioma nativo.",
"apihelp-query+recentchanges-param-excludeuser": "No listar cambios de este usuario.",
"apihelp-query+recentchanges-param-tag": "Listar solo los cambios con esta etiqueta.",
"apihelp-query+recentchanges-param-prop": "Incluir piezas adicionales de información:",
+ "apihelp-query+recentchanges-paramvalue-prop-comment": "Añade el comentario de la edición.",
"apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "Añade el comentario analizado para la edición.",
"apihelp-query+recentchanges-paramvalue-prop-flags": "Añade marcas para la edición.",
+ "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Añade la marca de tiempo de la edición.",
+ "apihelp-query+recentchanges-paramvalue-prop-title": "Añade el título de la página de la edición.",
+ "apihelp-query+recentchanges-paramvalue-prop-ids": "Añade los códigos ID de la página, de los cambios recientes y de las revisiones antigua y nueva.",
+ "apihelp-query+recentchanges-paramvalue-prop-sizes": "Añade la longitud antigua y la longitud nueva de la página en bytes.",
+ "apihelp-query+recentchanges-paramvalue-prop-redirect": "Etiqueta la edición si la página es una redirección.",
"apihelp-query+recentchanges-paramvalue-prop-patrolled": "Etiqueta ediciones verificables como verificadas o no verificadas.",
"apihelp-query+recentchanges-param-token": "Usa <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> en su lugar.",
"apihelp-query+recentchanges-param-limit": "Cuántos cambios en total se devolverán.",
"apihelp-query+redirects-paramvalue-prop-pageid": "Identificador de página de cada redirección.",
"apihelp-query+redirects-paramvalue-prop-title": "Título de cada redirección.",
"apihelp-query+redirects-paramvalue-prop-fragment": "Fragmento de cada redirección, si los hubiere.",
+ "apihelp-query+redirects-param-namespace": "Incluir solo páginas de estos espacios de nombres.",
"apihelp-query+redirects-param-limit": "Cuántas redirecciones se devolverán.",
"apihelp-query+redirects-example-simple": "Mostrar una lista de las redirecciones a la [[Main Page|Portada]]",
+ "apihelp-query+redirects-example-generator": "Obtener información sobre todas las redirecciones a la [[Main Page|Portada]]",
+ "apihelp-query+revisions-param-end": "Enumerar hasta esta marca de tiempo.",
+ "apihelp-query+revisions-param-user": "Incluir solo las revisiones realizadas por el usuario.",
+ "apihelp-query+revisions-param-excludeuser": "Excluir las revisiones realizadas por el usuario.",
"apihelp-query+revisions-example-last5": "Mostrar las últimas 5 revisiones de la <kbd>Main Page</kbd>.",
"apihelp-query+revisions+base-param-prop": "Las propiedades que se obtendrán para cada revisión:",
"apihelp-query+revisions+base-paramvalue-prop-ids": "El identificador de la revisión.",
return $this->__call( __FUNCTION__, func_get_args() );
}
- public function setFlag( $flag ) {
+ public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
return $this->__call( __FUNCTION__, func_get_args() );
}
- public function clearFlag( $flag ) {
+ public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
+ return $this->__call( __FUNCTION__, func_get_args() );
+ }
+
+ public function restoreFlags( $state = self::RESTORE_PRIOR ) {
return $this->__call( __FUNCTION__, func_get_args() );
}
/** @var float UNIX timestamp */
protected $lastPing = 0.0;
+ /** @var int[] Prior mFlags values */
+ private $priorFlags = [];
+
/** @var TransactionProfiler */
protected $trxProfiler;
return $this->mOpened;
}
- public function setFlag( $flag ) {
+ public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
+ if ( $remember === self::REMEMBER_PRIOR ) {
+ array_push( $this->priorFlags, $this->mFlags );
+ }
$this->mFlags |= $flag;
}
- public function clearFlag( $flag ) {
+ public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
+ if ( $remember === self::REMEMBER_PRIOR ) {
+ array_push( $this->priorFlags, $this->mFlags );
+ }
$this->mFlags &= ~$flag;
}
+ public function restoreFlags( $state = self::RESTORE_PRIOR ) {
+ if ( !$this->priorFlags ) {
+ return;
+ }
+
+ if ( $state === self::RESTORE_INITIAL ) {
+ $this->mFlags = reset( $this->priorFlags );
+ $this->priorFlags = [];
+ } else {
+ $this->mFlags = array_pop( $this->priorFlags );
+ }
+ }
+
public function getFlag( $flag ) {
return !!( $this->mFlags & $flag );
}
protected $lagDetectionOptions = [];
/** @var bool bool Whether to use GTID methods */
protected $useGTIDs = false;
-
+ /** @var string|null */
+ protected $sslKeyPath;
+ /** @var string|null */
+ protected $sslCertPath;
+ /** @var string|null */
+ protected $sslCAPath;
+ /** @var string[]|null */
+ protected $sslCiphers;
/** @var string|null */
private $serverVersion = null;
* ID of this server's master will be used. Set the "conds" field to
* override the query conditions, e.g. ['shard' => 's1'].
* - useGTIDs : use GTID methods like MASTER_GTID_WAIT() when possible.
+ * - sslKeyPath : path to key file [default: null]
+ * - sslCertPath : path to certificate file [default: null]
+ * - sslCAPath : parth to certificate authority PEM files [default: null]
+ * - sslCiphers : array list of allowable ciphers [default: null]
* @param array $params
*/
function __construct( array $params ) {
? $params['lagDetectionOptions']
: [];
$this->useGTIDs = !empty( $params['useGTIDs' ] );
+ foreach ( [ 'KeyPath', 'CertPath', 'CAPath', 'Ciphers' ] as $name ) {
+ $var = "ssl{$name}";
+ if ( isset( $params[$var] ) ) {
+ $this->$var = $params[$var];
+ }
+ }
}
/**
$socket = $hostAndSocket[1];
}
+ $mysqli = mysqli_init();
+
$connFlags = 0;
if ( $this->mFlags & DBO_SSL ) {
$connFlags |= MYSQLI_CLIENT_SSL;
+ $mysqli->ssl_set(
+ $this->sslKeyPath,
+ $this->sslCertPath,
+ null,
+ $this->sslCAPath,
+ $this->sslCiphers
+ );
}
if ( $this->mFlags & DBO_COMPRESS ) {
$connFlags |= MYSQLI_CLIENT_COMPRESS;
$realServer = 'p:' . $realServer;
}
- $mysqli = mysqli_init();
if ( $wgDBmysql5 ) {
// Tell the server we're communicating with it in UTF-8.
// This may engage various charset conversions.
/** @var string Transaction operation comes from the database class internally */
const FLUSHING_INTERNAL = 'flush';
+ /** @var string No not remember the prior flags */
+ const REMEMBER_NOTHING = '';
+ /** @var string Remember the prior flags */
+ const REMEMBER_PRIOR = 'remember';
+ /** @var string Restore to the prior flag state */
+ const RESTORE_PRIOR = 'prior';
+ /** @var string Restore to the initial flag state */
+ const RESTORE_INITIAL = 'initial';
+
/**
* A string describing the current software version, and possibly
* other details in a user-friendly way. Will be listed on Special:Version, etc.
* - DBO_DEFAULT: automatically sets DBO_TRX if not in command line mode
* and removes it in command line mode
* - DBO_PERSISTENT: use persistant database connection
+ * @param string $remember IDatabase::REMEMBER_* constant [default: REMEMBER_NOTHING]
*/
- public function setFlag( $flag );
+ public function setFlag( $flag, $remember = self::REMEMBER_NOTHING );
/**
* Clear a flag for this connection
* - DBO_DEFAULT: automatically sets DBO_TRX if not in command line mode
* and removes it in command line mode
* - DBO_PERSISTENT: use persistant database connection
+ * @param string $remember IDatabase::REMEMBER_* constant [default: REMEMBER_NOTHING]
+ */
+ public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING );
+
+ /**
+ * Restore the flags to their prior state before the last setFlag/clearFlag call
+ *
+ * @param string $state IDatabase::RESTORE_* constant. [default: RESTORE_PRIOR]
+ * @since 1.28
*/
- public function clearFlag( $flag );
+ public function restoreFlags( $state = self::RESTORE_PRIOR );
/**
* Returns a boolean whether the flag $flag is set for this connection
);
}
+ /**
+ * Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
+ *
+ * The DBO_TRX setting will be reverted to the default in each of these methods:
+ * - commitMasterChanges()
+ * - rollbackMasterChanges()
+ * - commitAll()
+ * This allows for custom transaction rounds from any outer transaction scope.
+ *
+ * @param string $fname
+ * @since 1.28
+ */
+ public function beginMasterChanges( $fname = __METHOD__ ) {
+ $this->forEachLBCallMethod( 'beginMasterChanges', [ $fname ] );
+ }
+
/**
* Commit on all connections. Done for two reasons:
* 1. To commit changes to the masters.
*/
public function commitAll( $fname = __METHOD__ ) {
$this->forEachOpenConnection( function ( DatabaseBase $conn ) use ( $fname ) {
- $conn->commit( $fname, IDatabase::FLUSHING_ALL_PEERS );
+ $conn->commit( $fname, $conn::FLUSHING_ALL_PEERS );
} );
}
} );
}
+ /**
+ * Flush any master transaction snapshots and set DBO_TRX (if DBO_DEFAULT is set)
+ *
+ * The DBO_TRX setting will be reverted to the default in each of these methods:
+ * - commitMasterChanges()
+ * - rollbackMasterChanges()
+ * - commitAll()
+ * This allows for custom transaction rounds from any outer transaction scope.
+ *
+ * @param string $fname
+ * @since 1.28
+ */
+ public function beginMasterChanges( $fname = __METHOD__ ) {
+ $this->forEachOpenMasterConnection( function ( DatabaseBase $conn ) use ( $fname ) {
+ if ( $conn->writesOrCallbacksPending() ) {
+ throw new DBTransactionError(
+ $conn,
+ "Transaction with pending writes still active."
+ );
+ } elseif ( $conn->trxLevel() ) {
+ $conn->commit( $fname, $conn::FLUSHING_ALL_PEERS );
+ }
+ if ( $conn->getFlag( DBO_DEFAULT ) ) {
+ // DBO_TRX is controlled entirely by CLI mode presence with DBO_DEFAULT.
+ // Force DBO_TRX even in CLI mode since a commit round is expected soon.
+ $conn->setFlag( DBO_TRX, $conn::REMEMBER_PRIOR );
+ $conn->onTransactionResolution( function () use ( $conn ) {
+ $conn->restoreFlags( $conn::RESTORE_PRIOR );
+ } );
+ } else {
+ // Config has explicitly requested DBO_TRX be either on or off; respect that.
+ // This is useful for things like blob stores which use auto-commit mode.
+ }
+ } );
+ }
+
/**
* Issue COMMIT on all master connections where writes where done
* @param string $fname Caller name
public function commitMasterChanges( $fname = __METHOD__ ) {
$this->forEachOpenMasterConnection( function ( DatabaseBase $conn ) use ( $fname ) {
if ( $conn->writesOrCallbacksPending() ) {
- $conn->commit( $fname, IDatabase::FLUSHING_ALL_PEERS );
+ $conn->commit( $fname, $conn::FLUSHING_ALL_PEERS );
}
} );
}
*/
public function runMasterPostCommitCallbacks() {
$e = null; // first exception
- $this->forEachOpenMasterConnection( function ( DatabaseBase $db ) use ( &$e ) {
- $db->setPostCommitCallbackSupression( false );
+ $this->forEachOpenMasterConnection( function ( DatabaseBase $conn ) use ( &$e ) {
+ $conn->setPostCommitCallbackSupression( false );
try {
- $db->runOnTransactionIdleCallbacks( IDatabase::TRIGGER_COMMIT );
+ $conn->runOnTransactionIdleCallbacks( $conn::TRIGGER_COMMIT );
} catch ( Exception $ex ) {
$e = $e ?: $ex;
}
foreach ( $conns2[$masterIndex] as $conn ) {
if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
try {
- $conn->rollback( $fname, IDatabase::FLUSHING_ALL_PEERS );
+ $conn->rollback( $fname, $conn::FLUSHING_ALL_PEERS );
} catch ( DBError $e ) {
MWExceptionHandler::logException( $e );
$failedServers[] = $conn->getServer();
// Commit the updates and unlock the table
$dbw->unlock( $lockKey, __METHOD__ );
}
+
+ // Invalid cache used by parser functions
+ SiteStats::unload();
}
/**
__METHOD__
);
+ // Invalid cache used by parser functions
+ SiteStats::unload();
+
return $activeUsers;
}
"Matiia",
"AlvaroMolina",
"Indiralena",
- "Peter Bowman"
+ "Peter Bowman",
+ "Dgstranz"
]
},
"config-desc": "El instalador de MediaWiki",
"config-subscribe": "Suscribirse a la [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce lista de correo de anuncios de versiones].",
"config-subscribe-help": "Esta es una lista de divulgación de bajo volumen para anuncios de lanzamiento de versiones nuevas, incluyendo anuncios de seguridad importantes.\nTe recomendamos suscribirte y actualizar tu instalación MediaWiki cada vez que se lance una nueva versión.",
"config-subscribe-noemail": "Has intentado suscribirte a la lista de correo de anuncios de nuevos lanzamientos sin proporcionar una dirección de correo electrónico.\nProporciona una dirección de correo electrónico si quieres suscribirte a la lista de correo.",
+ "config-pingback": "Compartir datos sobre esta instalación con los desarrolladores de MediaWiki.",
+ "config-pingback-help": "Si seleccionas esta opción, MediaWiki enviará periódicamente a https://www.mediawiki.org datos básicos sobre esta instancia de MediaWiki. Se trata de datos tales como el tipo de sistema, la versión de PHP y la base de datos elegida. La Fundación Wikimedia comparte estos datos con los desarrolladores de MediaWiki para ayudar a guiar el desarrollo futuro. Se enviarán los siguientes datos para tu sistema:\n<pre>$1</pre>",
"config-almost-done": "¡Ya casi has terminado!\nAhora puedes saltarte el resto de los pasos e instalar el wiki ya.",
"config-optional-continue": "Hazme más preguntas.",
"config-optional-skip": "Ya estoy aburrido, sólo instala el wiki.",
}
}
- # Is it client cached?
- if ( $outputPage->checkLastModified( $timestamp ) ) {
- wfDebug( __METHOD__ . ": done 304\n" );
-
- return;
- # Try file cache
- } elseif ( $wgUseFileCache && $this->tryFileCache() ) {
+ # Try to stream the output from file cache
+ if ( $wgUseFileCache && $this->tryFileCache() ) {
wfDebug( __METHOD__ . ": done file cache\n" );
# tell wgOut that output is taken care of
$outputPage->disable();
/**
* Loads page_touched and returns a value indicating if it should be used
- * @return bool True if not a redirect
+ * @return bool True if this page exists and is not a redirect
*/
public function checkTouched() {
if ( !$this->mDataLoaded ) {
$this->loadPageData();
}
- return !$this->mIsRedirect;
+ return ( $this->mId && !$this->mIsRedirect );
}
/**
protected $moduleInfos = [];
/** @var Config $config */
- private $config;
+ protected $config;
/**
* Associative array mapping framework ids to a list of names of test suite modules
* Register sources with the given IDs and properties.
*
* @param string $id Source ID
- * @param array $properties Source properties (see addSource())
+ * @param string $loadUrl load.php url
* @return string
*/
- public static function makeLoaderSourcesScript( $id, $properties = null ) {
+ public static function makeLoaderSourcesScript( $id, $loadUrl = null ) {
if ( is_array( $id ) ) {
return Xml::encodeJsCall(
'mw.loader.addSource',
} else {
return Xml::encodeJsCall(
'mw.loader.addSource',
- [ $id, $properties ],
+ [ $id, $loadUrl ],
ResourceLoader::inDebugMode()
);
}
}
/**
- * Returns true if the form built from the given AuthenticationRequests has fields which take
- * values. If all available providers use the redirect flow, the form might contain nothing
- * but submit buttons, in which case we should not add an extra submit button which does nothing.
+ * Returns true if the form built from the given AuthenticationRequests needs a submit button.
+ * Providers using redirect flow (e.g. Google login) need their own submit buttons; if using
+ * one of those custom buttons is the only way to proceed, there is no point in displaying the
+ * default button which won't do anything useful.
*
* @param AuthenticationRequest[] $requests An array of AuthenticationRequests from which the
* form will be built
* @return bool
*/
protected function needsSubmitButton( array $requests ) {
+ $customSubmitButtonPresent = false;
+
+ // Secondary and preauth providers always need their data; they will not care what button
+ // is used, so they can be ignored. So can OPTIONAL buttons createdby primary providers;
+ // that's the point in being optional. Se we need to check whether all primary providers
+ // have their own buttons and whether there is at least one button present.
foreach ( $requests as $req ) {
- if ( $req->required === AuthenticationRequest::PRIMARY_REQUIRED &&
- $this->doesRequestNeedsSubmitButton( $req )
- ) {
- return true;
+ if ( $req->required === AuthenticationRequest::PRIMARY_REQUIRED ) {
+ if ( $this->hasOwnSubmitButton( $req ) ) {
+ $customSubmitButtonPresent = true;
+ } else {
+ return true;
+ }
}
}
- return false;
+ return !$customSubmitButtonPresent;
}
/**
- * Checks if the given AuthenticationRequest needs a submit button or not.
- *
- * @param AuthenticationRequest $req The request to check
+ * Checks whether the given AuthenticationRequest has its own submit button.
+ * @param AuthenticationRequest $req
* @return bool
*/
- protected function doesRequestNeedsSubmitButton( AuthenticationRequest $req ) {
+ protected function hasOwnSubmitButton( AuthenticationRequest $req ) {
foreach ( $req->getFieldInfo() as $field => $info ) {
if ( $info['type'] === 'button' ) {
- return false;
+ return true;
}
}
- return true;
+ return false;
}
/**
"linkaccounts-submit": "Benutzerkonten verknüpfen",
"unlinkaccounts": "Benutzerkonten trennen",
"unlinkaccounts-success": "Das Benutzerkonto wurde getrennt.",
- "authenticationdatachange-ignored": "Die Änderung der Authentifizierungsdaten wurde nicht bearbeitet. Vielleicht wurde kein Anbieter konfiguriert?"
+ "authenticationdatachange-ignored": "Die Änderung der Authentifizierungsdaten wurde nicht bearbeitet. Vielleicht wurde kein Anbieter konfiguriert?",
+ "userjsispublic": "Bitte beachten: JavaScript-Unterseiten sollten keine vertraulichen Daten enthalten, da sie von anderen Benutzern eingesehen werden können.",
+ "usercssispublic": "Bitte beachten: CSS-Unterseiten sollten keine vertraulichen Daten enthalten, da sie von anderen Benutzern eingesehen werden können."
}
"undo-summary": "Vırnayışê $1'i [[Special:Contributions/$2|$2i]] ([[User talk:$2|Werênayış]]) peyser gırot",
"undo-summary-username-hidden": "Rewizyona veri $1'i hewada",
"cantcreateaccount-text": "Hesabvıraştışê na IP adrese ('''$1''') terefê [[User:$3|$3]] kılit biyo.\n\nSebebo ke terefê $3 ra diyao ''$2''",
- "viewpagelogs": "Qeydanê ena perer bıvin",
+ "viewpagelogs": "Qeydanê na pele bımocne",
"nohistory": "Verê vurnayışanê na pele çıniyo.",
"currentrev": "Çımraviyarnayışo rocane",
"currentrev-asof": "$1 ra tepya mewcud weziyeta pela",
"last": "peyên",
"page_first": "verên",
"page_last": "peyên",
- "histlegend": "Ferqê weçinıtışi: Qutiya versiyonan qandé pêver sanayış işaret ke u dest be ''enter''i ya zi gocega cêrêne ro ne.<br />\nCedwel: <strong>({{int:ferq}})</strong> = ferqê versiyonê peyêni, <strong>({{int:peyên}})</strong> = ferqê versiyonê verêni, <strong>{{int:q}}</strong> = vurnayışo werdi.",
+ "histlegend": "Ferqê weçinıtışi: Qutiya versiyonan seba têversanayış işaret ke û dest be ''enter''i ya zi gocega cêrêne ro ne.<br />\nCedwel: <strong>({{int:ferq}})</strong> = ferqê verziyonê peyêni, <strong>({{int:peyên}})</strong> = ferqê versiyonê verêni, <strong>{{int:q}}</strong> = vurnayışo werdi.",
"history-fieldset-title": "Tarixi bıvêne",
"history-show-deleted": "Tenya esterıtey",
"histfirst": "Verênêr",
"lineno": "Xeta $1:",
"compareselectedversions": "Rewizyonanê weçineyan pêver ke",
"showhideselectedversions": "Revizyonanê weçinıtan bımocne/bınımne",
- "editundo": "peyser bıya",
+ "editundo": "peyser biya",
"diff-empty": "(Babetna niyo)",
"diff-multi-sameuser": "(Terefê eyni karberi ra {{PLURAL:$1|yew revizyono miyanên nêmocno|$1 revizyonê miyanêni nêmocnê}})",
"diff-multi-otherusers": "(Terefê {{PLURAL:$2|yew karberi|$2 karberan}} ra {{PLURAL:$1|yew revizyono miyanên nêmocno|$1 revizyonê miyanêni nêmocnê}})",
"recentchanges-summary": "Wiki sero vurriyayışê peyêni asenê.",
"recentchanges-noresult": "Goreyê kriteranê kıfşkerdeyan ra qet yew vurnayış nêvêniya.",
"recentchanges-feed-description": "Ena feed dı vurnayişanê tewr peniyan teqip bık.",
- "recentchanges-label-newpage": "Pera newiy vıraziya ya",
+ "recentchanges-label-newpage": "Enê vurnayışi ra yew pela newiye vıraziye",
"recentchanges-label-minor": "Vurriyayışo werdiyo",
- "recentchanges-label-bot": "Ena vırnayışa boti ya",
+ "recentchanges-label-bot": "Eno vurnayış terefê yew boti ra vıraziyo",
"recentchanges-label-unpatrolled": "Eno vurnayış hewna dewriya nêbiyo",
- "recentchanges-label-plusminus": "No nımre erca ebata perer asıneno (maypuşt)",
+ "recentchanges-label-plusminus": "Ebadê pele de bazê bayti de vayeyê cı",
"recentchanges-legend-heading": "<strong>Kıtabekê Vurriyayışê peyêni:</strong>",
"recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|Lista pelanê neweyan]] zi bıvêne)",
"recentchanges-legend-plusminus": "''(±123)''",
"recentchangeslinked-summary": "Lista cêrêne, pela bêlikerdiye rê (ya zi karberanê kategoriya bêlikerdiye rê) pelanê gırêdayoğan de lista de vurnayışê peyênana.\n[[Special:Watchlist|Lista şımaya seyrkedışi de]] peli be nuşteyo '''qolınd''' bêli kerdê.",
"recentchangeslinked-page": "Nameyê pele:",
"recentchangeslinked-to": "Heruna pela ke yena dayene, vurnayışanê pelanê ke daye ra gırêdayiyê inan bımocne",
- "recentchanges-page-added-to-category": "[[:$1]] de kerd kategori miyan",
+ "recentchanges-page-added-to-category": "[[:$1]] kerd kategoriye miyan",
"recentchanges-page-removed-from-category": "[[:$1]] kategoriye ra vet",
"autochange-username": "MediaWiki vurnayışo otomatik",
"upload": "Dosya bar ke",
"grant-viewdeleted": "नयाँ फाइलहरू अपलोड\nसम्पादन गर",
"grant-viewmywatchlist": "आफनो अबलोकन सुची हेर",
"newuserlogpage": "प्रयोगकर्ता श्रृजना लग",
+ "action-move": "ये पानालाई अर्खिठौर सार",
"action-move-subpages": "यै पानाको रे यैका उपपानाको नाम बदल्न्या",
+ "action-move-rootuserpages": "मूल प्रयोगकर्ता पृष्ठहरू सार्ने",
+ "action-move-categorypages": "श्रेणी पृष्ठ सार",
+ "action-movefile": "ये फाईललाइ सार",
+ "action-upload": "ये फाइल अपलोड गर",
"action-unwatchedpages": "कसैले ध्यान नराख्याका पाननको सूची हेद्या",
"action-userrights-interwiki": "अन्य विकिका प्रयोगकर्तानको प्रयोगकर्ता अधिकार सम्पादन गद्या",
"action-applychangetags": "तमरो परिवर्तनसँगै ट्यागहरू लागु गर्न्या",
"permissionserrors": "Error de permisos",
"permissionserrorstext": "No tienes permiso para hacer eso, por {{PLURAL:$1|el siguiente motivo|los siguientes motivos}}:",
"permissionserrorstext-withaction": "No tienes permiso para $2, por {{PLURAL:$1|el siguiente motivo|los siguientes motivos}}:",
- "contentmodelediterror": "No puedes editar esta revisión porque su modelo de contenido es <code>$1</code>, la cual difiere del modelo actual de la página <code>$2</code>.",
+ "contentmodelediterror": "No puedes editar esta revisión porque su modelo de contenido es <code>$1</code>, que difiere del modelo actual de contenido de la página <code>$2</code>.",
"recreate-moveddeleted-warn": "<strong>Atención: estás volviendo a crear una página que ha sido borrada anteriormente.</strong>\n\nPiensa si es adecuado continuar editando la página.\nA continuación, se proporciona el registro de borrado y traslados de esta página para más información:",
"moveddeleted-notice": "Esta página ha sido borrada.\nA continuación, se proporciona el registro de borrados y traslados de la página para más información.",
- "moveddeleted-notice-recent": "Esta página se ha eliminado recientemente (dentro de las últimas 24 horas).\nEl registro de eliminación y traslado de la página se muestran a continuación como referencia.",
+ "moveddeleted-notice-recent": "Esta página se ha eliminado recientemente (durante las últimas 24 horas).\nEl registro de eliminación y traslado de la página se muestran a continuación como referencia.",
"log-fulllog": "Ver el registro completo",
"edit-hook-aborted": "Una extensión ha evitado la edición.\nNo hay explicación disponible.",
"edit-gone-missing": "No se ha podido actualizar la página.\nParece haber sido borrada.",
"content-json-empty-object": "Objeto vacío",
"content-json-empty-array": "Matriz vacía",
"deprecated-self-close-category": "Páginas que utilizan etiquetas HTML autocerradas no válidas",
- "deprecated-self-close-category-desc": "Esta página contiene etiquetas HTML de auto-cierre invalidas, tales como <code><b/></code> o <code><span/></code>. El comportamiento de estas en cambiará pronto para ser coherente con la especificación de HTML5, por lo que su utilización en wikitext está en desuso.",
+ "deprecated-self-close-category-desc": "Esta página contiene etiquetas HTML de autocierre inválidas, tales como <code><b/></code> o <code><span/></code>. El comportamiento de estas cambiará pronto para ser coherente con la especificación de HTML5, por lo que su utilización en el wikitexto está en desuso.",
"duplicate-args-warning": "<strong>Aviso:</strong> [[:$1]] llama a [[:$2]] con más de un valor para el parámetro «$3». Se usará solo el último valor proporcionado.",
"duplicate-args-category": "Páginas que usan argumentos duplicados en invocaciones de plantillas",
"duplicate-args-category-desc": "La página contiene invocaciones de plantillas que utilizan argumentos duplicados, como <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> o <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
"expensive-parserfunction-warning": "<strong>Advertencia:</strong> esta página contiene demasiadas llamadas a funciones sintácticas costosas.\n\nTiene {{PLURAL:$1|una llamada|$1 llamadas}}, pero debería tener menos de {{PLURAL:$2|una|$2}}.",
- "expensive-parserfunction-category": "Páginas con llamadas a funciones sintácticas demasiado costosas",
+ "expensive-parserfunction-category": "Páginas con demasiadas llamadas a funciones sintácticas costosas",
"post-expand-template-inclusion-warning": "<strong>Aviso:</strong> El tamaño de las plantillas incluidas es muy grande.\nAlgunas de ellas no se incluirán.",
"post-expand-template-inclusion-category": "Páginas con sobrecarga de plantillas",
"post-expand-template-argument-warning": "Aviso: Esta página contiene al menos un parámetro de plantilla con un tamaño de expansión demasiado grande.\nSe han descartado esos parámetros.",
"grant-group-high-volume": "Realizar actividad de volumen alto",
"grant-group-customization": "Personalización y preferencias",
"grant-group-administration": "Realizar acciones administrativas",
+ "grant-group-private-information": "Acceder a información privada sobre ti",
"grant-group-other": "Actividades diversas",
"grant-blockusers": "Bloquear y desbloquear usuarios",
"grant-createaccount": "Crear cuentas",
"grant-highvolume": "Gran cantidad de ediciones",
"grant-oversight": "Ocultar a los usuarios y suprimir las revisiones",
"grant-patrol": "Verificar cambios a páginas",
+ "grant-privateinfo": "Acceder a información privada",
"grant-protect": "Proteger y desproteger páginas",
"grant-rollback": "Revertir cambios a páginas",
"grant-sendemail": "Enviar un correo electrónico a otros usuarios",
"linkaccounts-submit": "Vincular cuentas",
"unlinkaccounts": "Desvincular cuentas",
"unlinkaccounts-success": "Se ha desvinculado la cuenta.",
- "authenticationdatachange-ignored": "El cambio den los datos de autentificacion no fue realizado. ¿Tal vez, no se configuró un proveedor?"
+ "authenticationdatachange-ignored": "El cambio den los datos de autentificacion no fue realizado. ¿Tal vez, no se configuró un proveedor?",
+ "userjsispublic": "Recuerda: Las subpáginas JavaScript no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
+ "usercssispublic": "Recuerda: Las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver."
}
"linkaccounts-submit": "Lier les comptes",
"unlinkaccounts": "Dissocier les comptes",
"unlinkaccounts-success": "Le compte a été dissocié.",
- "authenticationdatachange-ignored": "Les modifications de données d’authentification n’ont pas été gérées. Peut-être aucun fournisseur n’a-t-il été configuré ?"
+ "authenticationdatachange-ignored": "Les modifications de données d’authentification n’ont pas été gérées. Peut-être aucun fournisseur n’a-t-il été configuré ?",
+ "userjsispublic": "Veuillez noter: les sous-pages JavaScript ne doivent pas contenir de données confidentielles parce qu'elles sont visibles des autres utilisateurs.",
+ "usercssispublic": "Veuillez noter: les sous-pages CSS ne doivent pas contenir de données confidentielles parce qu'elles sont visibles des autres utilisateurs."
}
"តឹក ប៊ុនលី",
"វ័ណថារិទ្ធ",
"아라",
- "Macofe"
+ "Macofe",
+ "Dcljr"
]
},
"tog-underline": "គូសបន្ទាត់ក្រោមតំណភ្ជាប់៖",
"passwordreset-emailtext-user": "អ្នកប្រើប្រាស់ $1 នៅក្នុង {{SITENAME}} បានស្នើសុំស្ដារពាក្យសម្ងាត់របស់អ្នកនៅក្នុង {{SITENAME}} ($4)។\n {{PLURAL:$3|គណនី|គណនី}}អ្នកប្រើប្រាស់ដូចតទៅនេះមានជាប់ទាក់ទិននឹងអាសយដ្ឋានអ៊ីមែលនេះ៖\n\n$2\n\n{{PLURAL:$3|ពាក្យសម្ងាត់បណ្ដោះអាសន្ននេះ|ពាក្យសម្ងាត់បណ្ដោះអាសន្នទាំងនេះ}} និងហួសសុពលភាពក្នុងរយៈពេល {{PLURAL:$5|មួយថ្ងៃ|$5 ថ្ងៃ}}។\nយកល្អអ្នកគួរតែកត់ឈ្មោះចូលរួចជ្រើសរើសពាក្យសម្ងាត់ថ្មីមួយ។ ប្រសិនបើមាននរណាម្នាក់ផ្សេងធ្វើការស្នើសុំនេះ \nឬប្រសិនបើអ្នកនឹកឃើញពាក្យសម្ងាត់ដើមរបស់អ្នក ហើយអ្នកមិនប្រាថ្នាផ្លាស់ប្ដូរវាទៀតទេនោះ អ្នកគ្រាន់តែ\nបំភ្លេចអំពីសារមួយនេះ ហើយបន្តប្រើប្រាស់ពាក្យសម្ងាត់ចាស់របស់អ្នកទៅបានហើយ។",
"passwordreset-emailelement": "អត្តនាម៖ \n$1\n\nពាក្យសម្ងាត់បណ្ដោះអាសន្ន៖ \n$2",
"passwordreset-emailsentemail": "បើសិនជានេះអាសយដ្ឋានអ៊ីមែលដែលត្រូវបានចុះឈ្មោះសម្រាប់គណនីរបស់អ្នក នោះអ៊ីមែលសម្រាប់ស្ដារពាក្យសម្ងាត់មួយនឹងត្រូវបានផ្ញើទៅ។",
- "passwordreset-emailsent-capture": "អ៊ីមែលស្ដារពាក្យសម្ងាត់មួយដូចបង្ហាញខាងក្រោមត្រូវបានផ្ញើទៅហើយ។",
- "passwordreset-emailerror-capture": "អ៊ីមែលស្ដារពាក្យសម្ងាត់មួយដូចបង្ហាញខាងក្រោមត្រូវបានបង្កើតហើយ ប៉ុន្តែការផ្ញើទៅកាន់ {{GENDER:$2|អ្នកប្រើប្រាស់}}មិនបានសំរេចទេ៖ $1",
"changeemail": "ផ្លាស់ប្ដូរឬលុបអាសយដ្ឋានអ៊ីមែល",
"changeemail-header": "សូមបំពេញសំណុំបែបបទនេះដើម្បីផ្លាស់ប្ដូរអាសយដ្ឋានអ៊ីមែល។ បើសិនជាអ្នកចង់លុបការតភ្ជាប់អាសយដ្ឋានអ៊ីមែលពីគណនីរបស់អ្នក សូមដាក់ប្រឡោះអាសយដ្ឋានថ្មីអោយនៅទំនេរពេលសម្រេចដាក់សំណុំបែបបទ។",
"changeemail-no-info": "អ្នកចាំបាច់ត្រូវតែកត់ឈ្មោះចូល ដើម្បីចូលទៅកាន់ទំព័រនេះដោយផ្ទាល់។",
"undo-norev": "កំណែមិនអាចមិនធ្វើឡើងវិញបានទេ ពីព្រោះវាមិនមានឬត្រូវបានលុបបាត់ទៅហើយ។",
"undo-summary": "មិនធ្វើវិញនូវកំណែប្រែ $1 ដោយ [[Special:Contributions/$2|$2]] ([[User talk:$2|ការពិភាក្សា]])",
"undo-summary-username-hidden": "មិនធ្វើវិញនូវកំណែប្រែ $1 ដោយអ្នកប្រើប្រាស់លាក់ឈ្មោះ",
- "cantcreateaccounttitle": "មិនអាចបង្កើតគណនីបានទេ",
"cantcreateaccount-text": "ការបង្កើតគណនីពីអាសយដ្ឋាន IP ('''$1''') នេះ ត្រូវបានរារាំងដោយ [[User:$3|$3]]។\n\nហេតុផលដែលត្រូវលើកឡើងដោយ $3 គឺ ''$2''",
"viewpagelogs": "មើលកំណត់ហេតុសម្រាប់ទំព័រនេះ",
"nohistory": "មិនមានប្រវត្តិកំណែប្រែចំពោះទំព័រនេះ។",
"enotif_subject_moved": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|ប្ដូរទីតាំង}} ដោយ $2",
"enotif_subject_restored": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|ស្ដារឡើងវិញ}} ដោយ $2",
"enotif_subject_changed": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|ផ្លាស់ប្ដូរ}} ដោយ $2",
- "enotif_body_intro_deleted": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|លុបចោល}} នៅ $PAGEEDITDATE ដោយ $2។ សូមអាន $3។",
+ "enotif_body_intro_deleted": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|លុបចោល}} នៅ $PAGEEDITDATE ដោយ $2 ។ សូមអាន $3 ។",
"enotif_body_intro_created": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|បង្កើត}} នៅ $PAGEEDITDATE ដោយ $2។ សូមអាន $3 សម្រាប់កំណែបច្ចុប្បន្ន។",
"enotif_body_intro_moved": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|ប្ដូរទីតាំង}} នៅ $PAGEEDITDATE ដោយ $2។ សូមអាន $3 សម្រាប់កំណែបច្ចុប្បន្ន។",
"enotif_body_intro_restored": "ទំព័រ {{SITENAME}} មានចំណងជើងថា $1 ត្រូវបាន {{GENDER:$2|ស្ដារឡើងវិញ}} នៅ $PAGEEDITDATE ដោយ $2។ សូមអាន $3 សម្រាប់កំណែបច្ចុប្បន្ន។",
"special-characters-title-minus": "សញ្ញាដក",
"mw-widgets-dateinput-no-date": "គ្មានកាលបរិច្ឆេទត្រូវបានជ្រើសរើស",
"mw-widgets-titleinput-description-new-page": "ទំព័រមិនទាន់មាននៅឡើយទេ",
- "mw-widgets-titleinput-description-redirect": "បញ្ជូនបន្តទៅ $1",
- "api-error-blacklisted": "សូមជ្រើសរើសឈ្មោះផ្សេងដែលក្បោះក្បាយជាង។"
+ "mw-widgets-titleinput-description-redirect": "បញ្ជូនបន្តទៅ $1"
}
"linkaccounts-submit": "계정 연결",
"unlinkaccounts": "계정 연결 해제",
"unlinkaccounts-success": "계정의 연결이 해제되었습니다.",
- "authenticationdatachange-ignored": "인증 데이터 변경을 처리하지 못했습니다. 제공자를 설정하지 않으셨습니까?"
+ "authenticationdatachange-ignored": "인증 데이터 변경을 처리하지 못했습니다. 제공자를 설정하지 않으셨습니까?",
+ "userjsispublic": "주목해 주십시오: 자바스크립트의 하위 문서들은 다른 사용자들이 볼 수 있기 때문에 기밀 데이터를 포함해서는 안 됩니다.",
+ "usercssispublic": "주목해 주십시오: CSS의 하위 문서들은 다른 사용자들이 볼 수 있기 때문에 기밀 데이터를 포함해서는 안 됩니다."
}
"linkaccounts-submit": "Поврзи сметки",
"unlinkaccounts": "Одврзи сметки",
"unlinkaccounts-success": "Сметката е одврзана.",
- "authenticationdatachange-ignored": "Промената на податоците во заверката не е обработена. Можеби не е поставен услужник?"
+ "authenticationdatachange-ignored": "Промената на податоците во заверката не е обработена. Можеби не е поставен услужник?",
+ "userjsispublic": "Напомена: потстраниците со JavaScript не треба да содржат дсоверливи податоци бидејќи истите се видливи и за други корисници.",
+ "usercssispublic": "Напомена: потстраниците со CSS не треба да содржат дсоверливи податоци бидејќи истите се видливи и за други корисници."
}
"minoredit": "Aquò es un cambiament menor",
"watchthis": "Seguir aquesta pagina",
"savearticle": "Salvar",
+ "publishpage": "Publicar la pagina",
"publishchanges": "Publicar las modificacions",
"preview": "Previsualizar",
"showpreview": "Previsualizar",
"linkaccounts-submit": "Text of the main submit button on [[Special:LinkAccounts]] (when there is one)",
"unlinkaccounts": "Title of the special page [[Special:UnlinkAccounts]] which allows the user to remove linked remote accounts.",
"unlinkaccounts-success": "Account unlinking form success message",
- "authenticationdatachange-ignored": "Shown when authentication data change was unsuccessful due to configuration problems.\n\nCf. e.g. {{msg-mw|Passwordreset-ignored}}."
+ "authenticationdatachange-ignored": "Shown when authentication data change was unsuccessful due to configuration problems.\n\nCf. e.g. {{msg-mw|Passwordreset-ignored}}.",
+ "userjsispublic": "A reminder to users that Javascript subpages are not preferences but normal pages, and thus can be viewed by other users and the general public. This message is shown to a user whenever they are editing a subpage in their own user-space that ends in .js. See also {{msg-mw|usercssispublic}}.",
+ "usercssispublic": "A reminder to users that CSS subpages are not preferences but normal pages, and thus can be viewed by other users and the general public. This message is shown to a user whenever they are editing a subpage in their own user-space that ends in .css. See also {{msg-mw|userjsispublic}}"
}
"linkaccounts-submit": "Poveži račune",
"unlinkaccounts": "Razveži račune",
"unlinkaccounts-success": "Račun smo razvezali.",
- "authenticationdatachange-ignored": "Sprememba overitvenih podatkov ni bila obdelana. Morda ni bil konfiguriran noben ponudnik?"
+ "authenticationdatachange-ignored": "Sprememba overitvenih podatkov ni bila obdelana. Morda ni bil konfiguriran noben ponudnik?",
+ "userjsispublic": "Pomnite: Podstrani JavaScript naj ne vsebujejo zaupnih podatkov, saj so vidne tudi drugim uporabnikom.",
+ "usercssispublic": "Pomnite: Podstrani CSS naj ne vsebujejo zaupnih podatkov, saj so vidne tudi drugim uporabnikom."
}
"linkaccounts-submit": "Länka konton",
"unlinkaccounts": "Avlänka konton",
"unlinkaccounts-success": "Kontot avlänkades.",
- "authenticationdatachange-ignored": "Ändringen av autentiseringsdata hanterades inte. Kanske ingen tillhandahållare har konfigurerats?"
+ "authenticationdatachange-ignored": "Ändringen av autentiseringsdata hanterades inte. Kanske ingen tillhandahållare har konfigurerats?",
+ "userjsispublic": "Observera: JavaScript-undersidor bör inte innehålla konfidentiella uppgifter eftersom de kan ses av andra användare.",
+ "usercssispublic": "Observera: CSS-undersidor bör inte innehålla konfidentiella uppgifter eftersom de kan ses av andra användare."
}
"filesource": "ಮೂಲ",
"savefile": "ಕಡತನ್ ಒರಿಪಾಲೆ",
"upload-source": "ಮೂಲ ಕಡತ",
+ "upload-options": "ಅಪ್ಲೋಡ್ ಆಯ್ಕೆಲು",
+ "watchthisupload": "ಈ ಪುಟೊನು ತೂಲೆ",
"upload-file-error": "ಆ೦ತರಿಕ ದೋಷ",
+ "upload-dialog-title": "ಫೈಲ್ ಅಪ್ಲೋಡ್",
"upload-dialog-button-cancel": "ವಜಾ ಮಲ್ಪುಲೆ",
"upload-dialog-button-done": "ಆಂಡ್",
"upload-dialog-button-save": "ಒರಿಪಾಲೆ",
"listfiles_size": "ಗಾತ್ರೊ",
"listfiles_description": "ವಿವರಣೆ",
"listfiles_count": "ಆವೃತ್ತಿಲು",
+ "listfiles-latestversion": "ಪ್ರಸಕ್ತ ಆವೃತ್ತಿ",
"listfiles-latestversion-yes": "ಅಂದ್",
"listfiles-latestversion-no": "ಅತ್ತ್",
"file-anchor-link": "ಫೈಲ್",
"filehist-datetime": "ದಿನೊ/ಪೊರ್ತು",
"filehist-thumb": "ಎಲ್ಯಚಿತ್ರೊ",
"filehist-thumbtext": "$1ತ ಆವೃತ್ತಿದ ಎಲ್ಯಚಿತ್ರೊ",
+ "filehist-nothumb": "ಎಲ್ಯಚಿತ್ರೊ ಇಜ್ಜಿ",
"filehist-user": "ಬಳಕೆದಾರೆರ್",
"filehist-dimensions": "ಆಯಾಮೊಲು",
"filehist-filesize": "ಫೈಲ್’ದ ಗಾತ್ರ",
"upload-disallowed-here": "ಈರ್ ಈ ಫೈಲ್ನ್ ಕುಡೊರೊ ಬರೆವರೆ ಸಾದ್ಯೊ ಇದ್ದಿ.",
"filerevert-comment": "ಕಾರಣ:",
"filerevert-submit": "ದುಂಬುದ ಲೆಕ ಮಲ್ಪುಲೆ",
+ "filedelete-legend": "ಕಡತನ್ ಮಾಜಾಲೆ",
"filedelete-comment": "ಕಾರಣ",
"filedelete-submit": "ಮಾಜಾಲೆ",
"filedelete-reason-otherlist": "ಬೇತೆ ಕಾರಣ",
"download": "ಡೌನ್ಲೋಡ್",
"randompage": "ಯಾದೃಚ್ಛಿಕ ಪುಟೊ",
+ "randomincategory-category": "ವರ್ಗೊ:",
"randomincategory-submit": "ಪೋಲೆ",
"statistics": "ಅಂಕಿ ಅಂಶೊಲು",
"statistics-header-pages": "ಪುಟೊತ ಅಂಕಿ ಅಂಶಲು",
"statistics-pages": "ಪುಟಕುಲು",
+ "statistics-users-active": "ಸಕ್ರಿಯ ಬಳಕೆದಾರೆರ್",
"pageswithprop-submit": "ಪೋಲೆ",
"brokenredirects-edit": "ಸಂಪೊಲಿಪುಲೆ",
"brokenredirects-delete": "ಮಾಜಾಲೆ",
"wantedfiles": "ಬೋಡಾಯಿನ ಕಡತೊಲು",
"prefixindex": "ಪೂರ್ವನಾಮೊಲ್ದ ಸೂಚಿಕೆ",
"prefixindex-submit": "ತೋಜಾಲೆ",
+ "shortpages": "ಎಲ್ಯ ಪುಟೊಕುಲು",
+ "longpages": "ಉದ್ದ ಪುಟೊಕುಲು",
+ "protectedpages": "ಸಂರಕ್ಷಿತ ಪುಟೊ",
"protectedpages-page": "ಪುಟೊ",
"protectedpages-reason": "ಕಾರಣೊ",
"protectedpages-unknown-timestamp": "ಗೊತ್ತಿಜ್ಜಾಂದಿನ",
+ "protectedpages-unknown-performer": "ಅಜ್ಞಾತ ಬಳಕೆದಾರೆ",
+ "protectedtitles": "ಸಂರಕ್ಷಿತ ಶೀರ್ಷಿಕೆಲು",
"listusers": "ಬಳಕೆದಾರರೆನ ತಖ್ತೆ",
"newpages": "ಪೊಸ ಪುಟೊಲು",
"newpages-submit": "ತೋಜಾಲೆ",
"emailsend": "ಕಡಪುಡುಲೆ",
"watchlist": "ವೀಕ್ಷಣಾ ಪಟ್ಟಿ",
"mywatchlist": "ಎನ್ನ ವೀಕ್ಷಣಾಪಟ್ಟಿ",
+ "watchnologin": "ಲಾಗಿನ್ ಆತ್ಜರ್",
"watch": "ತೂಲೆ",
"watchthispage": "ಈ ಪುಟೊನು ತೂಲೆ",
"unwatch": "ವೀಕ್ಷಣಾಪಟ್ಟಿರ್ದ್ ದೆಪ್ಪು",
"watchlist-hide": "ಅಡೆಂಗಾವು",
"watchlist-submit": "ತೋಜಾವು",
"wlshowhideminor": "ಎಲ್ಯೆಲ್ಯ ಬದಲಾವಣೆಲು",
+ "wlshowhideliu": "ನೋಂದವಣೆ ಆತಿನಂಚಿನ ಸದಸ್ಯೆರ್",
+ "wlshowhideanons": "ಪುದರ್ ಇದ್ಯಾಂದಿನ ಸದಸ್ಯೆರ್",
"watchlist-options": "ವೀಕ್ಷಣಾಪಟ್ಟಿ ಆಯ್ಕೆಲು",
"watching": "ವೀಕ್ಷಣಾಪಟ್ಟಿಗ್ ಸೇರ್ಪಾವೊಂದುಂಡು...",
"unwatching": "ವೀಕ್ಷಣಾಪಟ್ಟಿರ್ದ್ ದೆತ್ತೊಂದುಂಡು...",
+ "deletepage": "ಪುಟೊಕುಲೆನ್ ಮಾಜಾಲೆ",
"confirm": "ಗಟ್ಟಿಮಲ್ಪುಲೆ",
"delete-legend": "ಮಾಜಾಲೆ",
"historyaction-submit": "ತೋಜಾಲೆ",
"actioncomplete": "ಕಾರ್ಯ ಸಂಪೂರ್ಣ",
"dellogpage": "ಡಿಲೀಟ್ ಮಲ್ತಿನ ಫೈಲ್ದ ದಾಕಲೆ",
+ "deletionlog": "ಡಿಲೀಟ್ ಮಲ್ತಿನ ಫೈಲ್ದ ದಾಕಲೆ",
"deletecomment": "ಕಾರಣ:",
"deletereasonotherlist": "ಬೇತೆ ಕಾರಣ",
+ "delete-edit-reasonlist": "ಮಾಜಾಯಿನ ಕಾರಣೊಲೆನ್ ಸಂಪಾದನೆ ಮಲ್ಪುಲೆ",
"rollbacklink": "ಪುಡತ್ತ್ ಪಾಡ್",
"rollbacklinkcount": "ಪಿರ ದೆತೊನ್ಲೆ $1 {{PLURAL:$1|edit|ಸಂಪದನೆಲು}}",
+ "changecontentmodel-title-label": "ಪುಟೊದ ಪುದರ್",
"changecontentmodel-reason-label": "ಕಾರಣ:",
"changecontentmodel-submit": "ಬದಲಾವಣೆ",
"logentry-contentmodel-change-revertlink": "ದುಂಬುದ ಲೆಕ ಮಲ್ಪುಲೆ",
"ipbreason": "ಕಾರಣೊ:",
"ipboptions": "2 ಗಂಟೆಲು:2 hours,1 ದಿನ:1 day,3 ದಿನೊಲು:3 days,1 ವಾರ:1 week,2 ವಾರೊಲು:2 weeks,1 ತಿಂಗೊಲು:1 month,3 ತಿಂಗೊಲು:3 months,6 ತಿಂಗೊಲು:6 months,1 ವರ್ಷ:1 year,ಅನಿರ್ಧಿಷ್ಟ:infinite",
"ipblocklist": "ತಡೆಪತ್ತ್’ದಿನ ಐ.ಪಿ ವಿಳಾಸೊಲು ಅಂಚೆನೆ ಬಳಕೆದ ಪುದರ್’ಲು",
+ "blocklist-target": "ಗುರಿ",
+ "blocklist-reason": "ಕಾರಣೊ",
+ "ipblocklist-submit": "ನಾಡ್ಲೆ",
"blocklink": "ಅಡ್ಡ ಪತ್ತ್ಲೆ",
"unblocklink": "ಅಡ್ಡನ್ ದೆಪ್ಪುಲೆ",
"change-blocklink": "ಬ್ಲಾಕ್’ನ್ ಬದಲಾಲೆ",
"contribslink": "ಕಾಣಿಕೆಲು",
+ "emaillink": "ಇ-ಅಂಚೆ ಕಡಪುಡುಲೆ",
"blocklogpage": "ತಡೆಪತ್ತ್’ದ್’ನ ಸದಸ್ಯೆರ್ನ ದಿನಚರಿ",
"blocklogentry": "[[$1]] ಖಾತೆನ್ $2 $3 ಮುಟ್ಟ ತಡೆಪತ್ತ್’ದ್’ನ್ಡ್",
"unblocklogentry": "$1 ಖಾತೆನ್ ಅನ್-ಬ್ಲಾಕ್ ಮಲ್ತ್’ನ್ಡ್",
"block-log-flags-nocreate": "ಖಾತೆ ಸೃಷ್ಟಿನ್ ತಡೆಪತ್ತ್’ದ್’ನ್ಡ್",
"movelogpage": "ಸ್ತಲಾಂತರೊದ ದಾಕಲೆ",
+ "movereason": "ಕಾರಣೊ:",
"revertmove": "ದುಂಬುದ ಲೆಕೆ ಮಲ್ಪುಲೆ",
"export": "ಪುಟೊಲೆನ್ ಕಡಪುಡ್ಲೆ",
+ "export-submit": "ರಫ್ತು ಮಲ್ಪುಲೆ",
+ "export-addcat": "ಸೇರಾಲೆ",
+ "export-addns": "ಸೇರಾಲೆ",
+ "export-download": "ಕಡತನ್ ಒರಿಪಾಲೆ",
"allmessagesname": "ಪುದರ್",
+ "allmessages-filter-legend": "ಅರಿಪೆ",
+ "allmessages-filter-all": "ಮಾತಾ",
+ "allmessages-filter-modified": "ಬದಲಾಯಿನ",
+ "allmessages-language": "ಬಾಸೆ:",
+ "allmessages-filter-submit": "ಪೋ",
+ "allmessages-filter-translate": "ಭಾಷಾಂತರ ಮಲ್ಪುಲೆ",
"thumbnail-more": "ಮಲ್ಲೆ ಮಲ್ಪುಲೆ",
"thumbnail_error": "ಮುನ್ನೋಟ ಚಿತ್ರೊನು ಸೃಷ್ಟಿ ಮನ್ಪುನಗ ದೋಷ: $1",
+ "import": "ಪುಟೊಲೆನ್ ಕಡಪುಡ್ಲೆ",
+ "import-interwiki-sourcepage": "ಮೂಲ ಪುಟ",
+ "import-interwiki-submit": "ಆಮದು",
+ "import-upload-filename": "ಕಡತದ ಪುದರ್:",
+ "import-comment": "ಅಭಿಪ್ರಾಯೊ:",
"tooltip-pt-userpage": "{{GENDER:|ಎನ್ನ ಸದಸ್ಯ}} ಪುಟೊ",
"tooltip-pt-mytalk": "{{GENDER:|ಎನ್ನ}} ಚರ್ಚೆ ಪುಟೊ",
"tooltip-pt-preferences": "{{GENDER:|ಎನ್ನ}} ಇಸ್ಟೊಲು",
"tooltip-undo": "\"ವಜಾ ಮಲ್ಪುಲೆ\" ಈ ಬದಲಾವಣೆನ್ ದೆತೊನುಜಿ ಬುಕ್ಕೊ ಪ್ರಿವ್ಯೂ ಮೋಡ್ಡ್ ಬದಲಾವಣೆ ಮಲ್ಪೆರ್ ಕೊನೊಪು೦ಡು. ಅ೦ಚೆನೆ ಸಾರಾಂಸೊಡು ಬದಲಾವಣೆಗ್ ಕಾರಣ ಸೇರಾಯರ ಆಪು೦ಡು.",
"tooltip-summary": "ಒಂಜಿ ಎಲ್ಯ ಸಾರಾಂಸೊ ಕೊರ್ಲೆ",
"simpleantispam-label": "ಯಾಂಟಿ-ಸ್ಪಾಮ್ ಚೆಕ್.\nಮುಲ್ಪ <strong>ದಿಂಜಾವೊಡ್ಚಿ</strong>",
+ "pageinfo-article-id": "ಪುಟೊದ ಐಡಿ",
"pageinfo-toolboxlink": "ಪುಟೊದ ಮಾಹಿತಿ",
+ "pageinfo-contentpage-yes": "ಅಂದ್",
+ "pageinfo-protect-cascading-yes": "ಅಂದ್",
+ "pageinfo-category-pages": "ಪುಟೊಕುಲೆ ಸಂಕ್ಯೆ",
"previousdiff": "← ದುಂಬುದ ಸಂಪದನೆ",
"nextdiff": "ಬುಕ್ಕೊದ ಸಂಪದನೆ →",
+ "thumbsize": "ಕಿರುನೋಟದ ಗಾತ್ರೊ:",
"file-info-size": "$1 × $2 ಚಿತ್ರಬಿಂದುಲು, ಫೈಲ್ದ ಗಾತ್ರೊ: $3, MIME ಪ್ರಕಾರೊ: $4",
"file-nohires": "ಇಂದೆರ್ದ್ ಜಾಸ್ತಿ ರೆಸಲ್ಯೂಶನ್ ಇದ್ದಿ,",
"svg-long-desc": "ಎಸ್.ವಿ.ಜಿ ಫೈಲ್, ಸುಮಾರಾದ್ $1 × $2 ಚಿತ್ರೊಬಿಂದು, ಫೈಲ್ದ ಗಾತ್ರ: $3",
"show-big-image-preview": "ಪಿರವುದ ಪುಟೊದ ಗಾತ್ರೊ: $1.",
"show-big-image-other": "ಬೇತೆ{{PLURAL:$2|resolution|ನಿರ್ನಯೊಲು}}: $1.",
"show-big-image-size": "$1 × $2 ಚಿತ್ರೊಬಿಂದುಲು",
+ "newimages-legend": "ಅರಿಪೆ",
+ "ilsubmit": "ನಾಡ್ಲೆ",
"bad_image_list": "ವ್ಯವಸ್ಥೆದ ಆಕಾರ ಈ ರೀತಿ ಉಂಡು:\n\nಪಟ್ಟಿಡುಪ್ಪುನಂಚಿನ ದಾಖಲೆಲೆನ್ (* ರ್ದ್ ಶುರು ಆಪುನ ಸಾಲ್’ಲು) ಮಾತ್ರ ಪರಿಗಣನೆಗ್ ದೆತೊನೆರಾಪುಂಡು.\nಪ್ರತಿ ಸಾಲ್’ದ ಶುರುತ ಲಿಂಕ್ ಒಂಜಿ ದೋಷ ಉಪ್ಪುನಂಚಿನ ಫೈಲ್’ಗ್ ಲಿಂಕಾದುಪ್ಪೊಡು.\nಅವ್ವೇ ಸಾಲ್’ದ ಶುರುತ ಪೂರಾ ಲಿಂಕ್’ಲೆನ್ ಪರಿಗನೆರ್ದ್ ದೆಪ್ಪೆರಾಪುಂಡು, ಪಂಡ ಓವು ಪುಟೊಲೆಡ್ ಫೈಲ್’ದ ಬಗ್ಗೆ ಬರ್ಪುಂಡೋ ಔಲು.",
"metadata": "ಮೆಟಾಡೇಟಾ",
"metadata-help": "ಈ ಪೈಲ್ಡ್ ಜಾಸ್ತಿ ಮಾಹಿತಿ ಉಂಡು. ಹೆಚ್ಚಿನಂಸೊ ಪೈಲ್ನ್ ಉಂಡು ಮಲ್ಪೆರೆ ಉಪಯೋಗ ಮಲ್ತಿನ ಡಿಜಿಟಲ್ ಕ್ಯಾಮೆರರ್ದ್ ಅತ್ತ್ಂಡ ಸ್ಕ್ಯಾನರ್ರ್ದ್ ಈ ಮಾಹಿತಿ ಬತ್ತ್ಂಡ್.\nಮೂಲಪ್ರತಿರ್ದ್ ಈ ಪೈಲ್ ಬದಲಾದಿತ್ತ್ಂಡ್, ಈ ಮಾಹಿತಿ ಬದಲಾತಿನ ಪೈಲ್ದ ವಿವರೊಲೆಗ್ ಸರಿಯಾದ್ ಹೊಂದಂದೆ ಉಪ್ಪು.",
"metadata-expand": "ವಿಸ್ತಾರವಾಯಿನ ವಿವರೊಲೆನ್ ತೊಜ್ಪಾವು",
"metadata-collapse": "ವಿಸ್ತಾರವಾಯಿನ ವಿವರೊಲೆನ್ ದೆಂಗಾವು",
"metadata-fields": "ಈ ಸಂದೇಸೊಡು ಪಟ್ಟಿ ಮಲ್ತಿನಂಚಿನ EXIF ಮಿತ್ತ ದರ್ಜೆದ ಮಾಹಿತಿನ್ ಚಿತ್ರೊ ಪುಟೊಕು ಸೇರ್ಪಾಯೆರೆ ಆವೊಂದುಂಡು. ಪುಟೊಟು ಮಿತ್ತ ದರ್ಜೆ ಮಾಹಿತಿದ ಪಟ್ಟಿನ್ ದೆಪ್ಪುನಗ ಉಂದು ತೋಜುಂಡು.\nಒರಿದನವು ಮೂಲೊ ಸ್ಥಿತಿಟ್ ಅಡೆಂಗ್ದುಂಡು.\n*ಮಲ್ಪುಲೆ\n*ಮಾದರಿ\n*ದಿನೊ ಪೊರ್ತು ಮೂಲೊ\n*ಮಾನಾದಿಗೆದ ಸಮಯೊ\n*ಫ್ಸಂಖ್ಯೆ\n*ಐಎಸ್ಒ ವೇಗೊದ ರೇಟಿಂಗ್\n*ತೂಪಿನ ಜಾಗೆದ ದೂರ\n*ಕಲಾವಿದೆ\n*ಕೃತಿಸ್ವಾಮ್ಯೊ\n*ಚಿತ್ರೊ ವಿವರಣೆ\n*ಜಿಪಿಎಸ್ ಅಕ್ಷಾಂಸೊ\n*ಜಿಪಿಎಸ್ ರೇಖಾಂಸೊ\n*ಜಿಪಿಎಸ್ ಎತ್ತರೊ",
+ "exif-imagewidth": "ಅಗೆಲ",
+ "exif-imagelength": "ಎತ್ತರೊ",
"exif-orientation": "ದಿಕ್ಕ್ ದಿಸೆ",
"exif-xresolution": "ಅಡ್ಡಗಲೊದ ರೆಜ಼ಲ್ಯೂಶನ್",
"exif-yresolution": "ಉದ್ದೊದ ರೆಜ಼ಲ್ಯೂಶನ್",
"exif-make": "ಕ್ಯಾಮರೊದ ತಯಾರೆಕೆರ್",
"exif-model": "ಕ್ಯಾಮರೊದ ಮಾದರಿ",
"exif-software": "ಉಪಯೋಗೊ ಮಲ್ತಿನ ತಂತ್ರಾಂಸೊ",
+ "exif-artist": "ಬರೆತಿನಾರ್",
+ "exif-copyright": "ಹಕ್ಕುದಾರೆ",
"exif-exifversion": "Exif ಆವೃತ್ತಿ",
"exif-colorspace": "ಬಣ್ಣೊದ ಜಾಗೆ",
"exif-datetimeoriginal": "ಮಾಹಿತಿ ಸ್ರಿಸ್ಟಿಸಯಿನ ದಿನೊ ಬೊಕ್ಕ ಪೊರ್ತು",
"exif-datetimedigitized": "ಗಣಕೀಕರಣೊದ ದಿನೊ ಬೊಕ್ಕ ಪೊರ್ತು",
+ "exif-flash": "ಫ್ಲ್ಯಾಶ್",
+ "exif-source": "ಮೂಲೊ",
+ "exif-languagecode": "ಭಾಸೆ",
+ "exif-iimcategory": "ವರ್ಗೊ",
+ "exif-label": "ಗುರುತು ಪಟ್ಟಿ",
"exif-orientation-1": "ಸಾದಾರನೊ",
+ "exif-meteringmode-1": "ಸರಾಸರಿ",
+ "exif-meteringmode-255": "ಇತರೊ",
+ "exif-lightsource-0": "ಗೊತ್ತಿಜ್ಜಾಂದಿನ",
+ "exif-lightsource-4": "ಫ್ಲ್ಯಾಶ್",
+ "exif-contrast-0": "ಸಾದಾರನೊ",
+ "exif-saturation-0": "ಸಾದಾರನೊ",
+ "exif-subjectdistancerange-0": "ಗೊತ್ತಿಜ್ಜಾಂದಿನ",
+ "exif-iimcategory-hth": "ಆರೋಗ್ಯ",
"namespacesall": "ಮಾತ",
"monthsall": "ಮಾತ",
+ "confirm_purge_button": "ಸರಿ",
+ "confirm-watch-button": "ಸರಿ",
+ "confirm-unwatch-button": "ಸರಿ",
+ "confirm-rollback-button": "ಸರಿ",
+ "quotation-marks": "\"$1\"",
+ "imgmultipageprev": "← ದುಂಬುತ ಪುಟೊ",
+ "imgmultipagenext": "ನನತಾ ಪುಟ →",
+ "img-lang-go": "ಪೋಲೆ",
+ "table_pager_next": "ನನತಾ ಪುಟ",
+ "table_pager_prev": "ದುಂಬುತ ಪುಟೊ",
+ "table_pager_first": "ಸುರುತ ಪುಟೊ",
+ "table_pager_last": "ಕಡೆತ ಪುಟೊ",
+ "table_pager_limit_submit": "ಪೋಲೆ",
+ "watchlistedit-raw-titles": "ತರೆಬರವು:",
"watchlistedit-clear-title": "ತುಯಿನೇನ್ ಮಾಜಾಲೇ",
+ "watchlistedit-clear-legend": "ತುಯಿನೇನ್ ಮಾಜಾಲೇ",
+ "watchlistedit-clear-titles": "ತರೆಬರವು:",
"watchlisttools-view": "ಪ್ರಸ್ತುತ ಬದಲಾವಣೆಲ್ ತೋಜಾಲೆ",
"watchlisttools-edit": "ವೀಕ್ಷಣಾಪಟ್ಟಿನ್ ತೂಲೆ ಬೊಕ್ಕ ಎಡಿಟ್ ಮಲ್ಪುಲೆ",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ಪಾತೆರ್ಲೆ]])",
+ "version": "ಆವೃತ್ತಿ",
+ "version-specialpages": "ವಿಸೇಸೊ ಪುಟೊಲು",
+ "version-other": "ಇತರೊ",
+ "version-ext-license": "ಪರವಾನಗಿ",
+ "version-ext-colheader-name": "ವಿಸ್ತರಣೆ",
+ "version-skin-colheader-name": "ಸ್ಕಿನ್",
+ "version-ext-colheader-version": "ಆವೃತ್ತಿ",
+ "version-ext-colheader-license": "ಪರವಾನಗಿ",
+ "version-ext-colheader-description": "ವಿವರಣೆ",
+ "version-ext-colheader-credits": "ಲೇಖಕೆರ್",
+ "version-poweredby-others": "ಇತರೊ",
+ "version-software-product": "ಉತ್ಪನ್ನ",
+ "version-software-version": "ಆವೃತ್ತಿ",
+ "version-libraries-library": "ಗ್ರಂಥಾಲಯೊ",
+ "version-libraries-version": "ಆವೃತ್ತಿ",
+ "version-libraries-license": "ಪರವಾನಗಿ",
+ "version-libraries-description": "ವಿವರಣೆ",
+ "version-libraries-authors": "ಲೇಖಕೆರ್",
+ "redirect-submit": "ಪೋಲೆ",
+ "redirect-value": "ಮೌಲ್ಯ:",
+ "redirect-user": "ಬಳಕೆದಾರೆರ ID",
+ "redirect-page": "ಪುಟೊದ ಐಡಿ",
+ "redirect-file": "ಕಡತದ ಪುದರ್",
+ "fileduplicatesearch-filename": "ಕಡತದ ಪುದರ್:",
+ "fileduplicatesearch-submit": "ನಾಡ್ಲೆ",
"specialpages": "ವಿಸೇಸೊ ಪುಟೊಲು",
+ "blankpage": "ಖಾಲಿ ಪುಟ",
"tag-filter": "[[Special:Tags|ಟ್ಯಾಗ್]]ಅರಿಪೆ:",
+ "tag-filter-submit": "ಅರಿಪೆ",
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|ಟ್ಯಾಗುಲು}}]]:$2)",
+ "tags-title": "ತೂಗು ಪಟ್ಟಿಲು",
+ "tags-source-header": "ಮೂಲೊ",
+ "tags-active-header": "ಸಕ್ರಿಯ?",
+ "tags-actions-header": "ಕ್ರಿಯೆಕ್ಕುಲು",
+ "tags-active-yes": "ಅಂದ್",
+ "tags-active-no": "ಅತ್ತ್",
+ "tags-edit": "ಸಂಪೊಲಿಪುಲೆ",
+ "tags-delete": "ಮಾಜಾಲೆ",
+ "tags-create-reason": "ಕಾರಣ:",
+ "tags-create-submit": "ಸೃಷ್ಟಿಸಾಲೆ",
+ "tags-delete-reason": "ಕಾರಣ:",
+ "tags-deactivate-reason": "ಕಾರಣ:",
"logentry-delete-delete": "$1{{GENDER:$2|ಮಾಜಾದ್ಂಡ್}}ಪುಟೊ $3",
"logentry-move-move": "$1 {{GENDER:$2|ಜಾರಲೆ}} ಪುಟೊ $3 ಡ್ದ್ $4",
"logentry-newusers-create": "ಬಳಕೆದಾರೆರೆ ಕಾತೆ $1 ನ್ನು {{GENDER:$2|ಸ್ರಿಸ್ಟಿ ಮಲ್ತಾಂಡ್}}",
"linkaccounts-submit": "Пов'язати облікові записи",
"unlinkaccounts": "Відв'язати облікові записи",
"unlinkaccounts-success": "Обліковий запис було відв'язано.",
- "authenticationdatachange-ignored": "Неопрацьована зміна облікових даних. Можливо, жоден з провайдерів не був налаштований?"
+ "authenticationdatachange-ignored": "Неопрацьована зміна облікових даних. Можливо, жоден з провайдерів не був налаштований?",
+ "userjsispublic": "Будь ласка, зверніть увагу: підсторінки JavaScript не повинні містити конфіденційних даних, бо їх можуть бачити інші користувачі.",
+ "usercssispublic": "Будь ласка, зверніть увагу: підсторінки CSS не повинні містити конфіденційних даних, бо їх можуть бачити інші користувачі."
}
'ResourceLoaderTestCase' => "$testDir/phpunit/ResourceLoaderTestCase.php",
'ResourceLoaderTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
'ResourceLoaderFileModuleTestModule' => "$testDir/phpunit/ResourceLoaderTestCase.php",
+ 'EmptyResourceLoader' => "$testDir/phpunit/ResourceLoaderTestCase.php",
'TestUser' => "$testDir/phpunit/includes/TestUser.php",
'TestUserRegistry' => "$testDir/phpunit/includes/TestUserRegistry.php",
'LessFileCompilationTest' => "$testDir/phpunit/LessFileCompilationTest.php",
<?php
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
/**
* @param string $lang
class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {
}
+
+class EmptyResourceLoader extends ResourceLoader {
+ // TODO: This won't be needed once ResourceLoader is empty by default
+ // and default registrations are done from ServiceWiring instead.
+ public function __construct( Config $config = null, LoggerInterface $logger = null ) {
+ $this->setLogger( $logger ?: new NullLogger() );
+ $this->config = $config ?: ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+ $this->setMessageBlobStore( new MessageBlobStore( $this, $this->getLogger() ) );
+ }
+}
$this->dropFunctions();
$this->functionTest = false;
}
+ $this->db->restoreFlags( IDatabase::RESTORE_INITIAL );
}
/**
* @covers DatabaseBase::dropTable
$db->begin( __METHOD__ );
throw new RunTimeException( "Uh oh!" );
}
+
+ /**
+ * @covers DatabaseBase::getFlag(
+ * @covers DatabaseBase::setFlag()
+ * @covers DatabaseBase::restoreFlags()
+ */
+ public function testFlagSetting() {
+ $db = $this->db;
+ $origTrx = $db->getFlag( DBO_TRX );
+ $origSsl = $db->getFlag( DBO_SSL );
+
+ if ( $origTrx ) {
+ $db->clearFlag( DBO_TRX, $db::REMEMBER_PRIOR );
+ } else {
+ $db->setFlag( DBO_TRX, $db::REMEMBER_PRIOR );
+ }
+ $this->assertEquals( !$origTrx, $db->getFlag( DBO_TRX ) );
+
+ if ( $origSsl ) {
+ $db->clearFlag( DBO_SSL, $db::REMEMBER_PRIOR );
+ } else {
+ $db->setFlag( DBO_SSL, $db::REMEMBER_PRIOR );
+ }
+ $this->assertEquals( !$origSsl, $db->getFlag( DBO_SSL ) );
+
+ $db2 = clone $db;
+ $db2->restoreFlags( $db::RESTORE_INITIAL );
+ $this->assertEquals( $origTrx, $db2->getFlag( DBO_TRX ) );
+ $this->assertEquals( $origSsl, $db2->getFlag( DBO_SSL ) );
+
+ $db->restoreFlags();
+ $this->assertEquals( $origSsl, $db->getFlag( DBO_SSL ) );
+ $this->assertEquals( !$origTrx, $db->getFlag( DBO_TRX ) );
+
+ $db->restoreFlags();
+ $this->assertEquals( $origSsl, $db->getFlag( DBO_SSL ) );
+ $this->assertEquals( $origTrx, $db->getFlag( DBO_TRX ) );
+ }
}
function __construct() {
}
- function clearFlag( $arg ) {
+ function clearFlag( $arg, $remember = self::REMEMBER_NOTHING ) {
}
- function setFlag( $arg ) {
+ function setFlag( $arg, $remember = self::REMEMBER_NOTHING ) {
}
public function insert( $table, $a, $fname = __METHOD__, $options = [] ) {
* @dataProvider provideGetModuleRegistrations
* @covers ResourceLoaderStartUpModule::compileUnresolvedDependencies
* @covers ResourceLoaderStartUpModule::getModuleRegistrations
- * @covers ResourceLoader::makeLoaderSourcesScript
* @covers ResourceLoader::makeLoaderRegisterScript
*/
public function testGetModuleRegistrations( $case ) {
] );
}
- public static function provideValidModules() {
- return [
- [ 'TEST.validModule1', new ResourceLoaderTestModule() ],
- ];
- }
-
/**
- * Ensures that the ResourceLoaderRegisterModules hook is called when a new
- * ResourceLoader object is constructed.
+ * Ensure the ResourceLoaderRegisterModules hook is called.
+ *
* @covers ResourceLoader::__construct
*/
- public function testCreatingNewResourceLoaderCallsRegistrationHook() {
+ public function testConstructRegistrationHook() {
$resourceLoaderRegisterModulesHook = false;
$this->setMwGlobals( 'wgHooks', [
]
] );
- $resourceLoader = new ResourceLoader();
+ $unused = new ResourceLoader();
$this->assertTrue(
$resourceLoaderRegisterModulesHook,
'Hook ResourceLoaderRegisterModules called'
);
-
- return $resourceLoader;
}
/**
- * @dataProvider provideValidModules
- * @depends testCreatingNewResourceLoaderCallsRegistrationHook
* @covers ResourceLoader::register
* @covers ResourceLoader::getModule
*/
- public function testRegisteredValidModulesAreAccessible(
- $name, ResourceLoaderModule $module, ResourceLoader $resourceLoader
- ) {
- $resourceLoader->register( $name, $module );
- $this->assertEquals( $module, $resourceLoader->getModule( $name ) );
+ public function testRegisterValid() {
+ $module = new ResourceLoaderTestModule();
+ $resourceLoader = new EmptyResourceLoader();
+ $resourceLoader->register( 'test', $module );
+ $this->assertEquals( $module, $resourceLoader->getModule( 'test' ) );
}
/**
- * @covers ResourceLoaderFileModule::compileLessFile
+ * @covers ResourceLoader::register
*/
- public function testLessFileCompilation() {
- $context = $this->getResourceLoaderContext();
- $basePath = __DIR__ . '/../../data/less/module';
- $module = new ResourceLoaderFileModule( [
- 'localBasePath' => $basePath,
- 'styles' => [ 'styles.less' ],
- ] );
- $module->setName( 'test.less' );
- $styles = $module->getStyles( $context );
- $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] );
+ public function testRegisterInvalidName() {
+ $resourceLoader = new EmptyResourceLoader();
+ $this->setExpectedException( 'MWException', "name 'test!invalid' is invalid" );
+ $resourceLoader->register( 'test!invalid', new ResourceLoaderTestModule() );
}
/**
- * Strip @noflip annotations from CSS code.
- * @param string $css
- * @return string
+ * @covers ResourceLoader::register
*/
- private static function stripNoflip( $css ) {
- return str_replace( '/*@noflip*/ ', '', $css );
+ public function testRegisterInvalidType() {
+ $resourceLoader = new EmptyResourceLoader();
+ $this->setExpectedException( 'MWException', 'ResourceLoader module info type error' );
+ $resourceLoader->register( 'test', new stdClass() );
}
/**
- * @dataProvider providePackedModules
- * @covers ResourceLoader::makePackedModulesString
+ * @covers ResourceLoader::getModuleNames
*/
- public function testMakePackedModulesString( $desc, $modules, $packed ) {
- $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc );
+ public function testGetModuleNames() {
+ // Use an empty one so that core and extension modules don't get in.
+ $resourceLoader = new EmptyResourceLoader();
+ $resourceLoader->register( 'test.foo', new ResourceLoaderTestModule() );
+ $resourceLoader->register( 'test.bar', new ResourceLoaderTestModule() );
+ $this->assertEquals(
+ [ 'test.foo', 'test.bar' ],
+ $resourceLoader->getModuleNames()
+ );
}
/**
- * @dataProvider providePackedModules
- * @covers ResourceLoaderContext::expandModuleNames
+ * @covers ResourceLoader::isModuleRegistered
*/
- public function testexpandModuleNames( $desc, $modules, $packed ) {
- $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc );
+ public function testIsModuleRegistered() {
+ $rl = new EmptyResourceLoader();
+ $rl->register( 'test', new ResourceLoaderTestModule() );
+ $this->assertTrue( $rl->isModuleRegistered( 'test' ) );
+ $this->assertFalse( $rl->isModuleRegistered( 'test.unknown' ) );
+ }
+
+ /**
+ * @covers ResourceLoader::getModule
+ */
+ public function testGetModuleUnknown() {
+ $rl = new EmptyResourceLoader();
+ $this->assertSame( null, $rl->getModule( 'test' ) );
+ }
+
+ /**
+ * @covers ResourceLoader::getModule
+ */
+ public function testGetModuleClass() {
+ $rl = new EmptyResourceLoader();
+ $rl->register( 'test', [ 'class' => ResourceLoaderTestModule::class ] );
+ $this->assertInstanceOf(
+ ResourceLoaderTestModule::class,
+ $rl->getModule( 'test' )
+ );
+ }
+
+ /**
+ * @covers ResourceLoader::getModule
+ */
+ public function testGetModuleClassDefault() {
+ $rl = new EmptyResourceLoader();
+ $rl->register( 'test', [] );
+ $this->assertInstanceOf(
+ ResourceLoaderFileModule::class,
+ $rl->getModule( 'test' ),
+ 'Array-style module registrations default to FileModule'
+ );
+ }
+
+ /**
+ * @covers ResourceLoaderFileModule::compileLessFile
+ */
+ public function testLessFileCompilation() {
+ $context = $this->getResourceLoaderContext();
+ $basePath = __DIR__ . '/../../data/less/module';
+ $module = new ResourceLoaderFileModule( [
+ 'localBasePath' => $basePath,
+ 'styles' => [ 'styles.less' ],
+ ] );
+ $module->setName( 'test.less' );
+ $styles = $module->getStyles( $context );
+ $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] );
}
public static function providePackedModules() {
];
}
+ /**
+ * @dataProvider providePackedModules
+ * @covers ResourceLoader::makePackedModulesString
+ */
+ public function testMakePackedModulesString( $desc, $modules, $packed ) {
+ $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc );
+ }
+
+ /**
+ * @dataProvider providePackedModules
+ * @covers ResourceLoaderContext::expandModuleNames
+ */
+ public function testexpandModuleNames( $desc, $modules, $packed ) {
+ $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc );
+ }
+
public static function provideAddSource() {
return [
- [ 'examplewiki', '//example.org/w/load.php', 'examplewiki' ],
- [ 'example2wiki', [ 'loadScript' => '//example.com/w/load.php' ], 'example2wiki' ],
+ [ 'foowiki', 'https://example.org/w/load.php', 'foowiki' ],
+ [ 'foowiki', [ 'loadScript' => 'https://example.org/w/load.php' ], 'foowiki' ],
[
- [ 'foowiki' => '//foo.org/w/load.php', 'bazwiki' => '//baz.org/w/load.php' ],
+ [
+ 'foowiki' => 'https://example.org/w/load.php',
+ 'bazwiki' => 'https://example.com/w/load.php',
+ ],
null,
[ 'foowiki', 'bazwiki' ]
- ],
- [
- [ 'foowiki' => '//foo.org/w/load.php' ],
- null,
- false,
- ],
+ ]
];
}
*/
public function testAddSource( $name, $info, $expected ) {
$rl = new ResourceLoader;
- if ( $expected === false ) {
- $this->setExpectedException( 'MWException', 'ResourceLoader duplicate source addition error' );
- $rl->addSource( $name, $info );
- }
$rl->addSource( $name, $info );
if ( is_array( $expected ) ) {
foreach ( $expected as $source ) {
}
}
- public static function fakeSources() {
- return [
- 'examplewiki' => [
- 'loadScript' => '//example.org/w/load.php',
- 'apiScript' => '//example.org/w/api.php',
- ],
- 'example2wiki' => [
- 'loadScript' => '//example.com/w/load.php',
- 'apiScript' => '//example.com/w/api.php',
- ],
- ];
+ /**
+ * @covers ResourceLoader::addSource
+ */
+ public function testAddSourceDupe() {
+ $rl = new ResourceLoader;
+ $this->setExpectedException( 'MWException', 'ResourceLoader duplicate source addition error' );
+ $rl->addSource( 'foo', 'https://example.org/w/load.php' );
+ $rl->addSource( 'foo', 'https://example.com/w/load.php' );
+ }
+
+ /**
+ * @covers ResourceLoader::addSource
+ */
+ public function testAddSourceInvalid() {
+ $rl = new ResourceLoader;
+ $this->setExpectedException( 'MWException', 'with no "loadScript" key' );
+ $rl->addSource( 'foo', [ 'x' => 'https://example.org/w/load.php' ] );
}
public static function provideLoaderImplement() {
'name' => 'test.example',
'scripts' => 'mw.example();',
'styles' => [],
- 'messages' => new XmlJsCode( '{}' ),
- 'templates' => [],
'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery, require, module ) {
mw.example();
'scripts' => [],
'styles' => [ 'css' => [ '.mw-example {}' ] ],
'messages' => new XmlJsCode( '{}' ),
- 'templates' => [],
'expected' => 'mw.loader.implement( "test.example", [], {
"css": [
'name' => 'test.example',
'scripts' => 'mw.example();',
- 'styles' => [],
'messages' => [ 'example' => '' ],
- 'templates' => [],
'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery, require, module ) {
mw.example();
'name' => 'test.example',
'scripts' => 'mw.example();',
- 'styles' => [],
- 'messages' => new XmlJsCode( '{}' ),
'templates' => [ 'example.html' => '' ],
'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery, require, module ) {
"example.html": ""
} );',
] ],
+ [ [
+ 'title' => 'Implement unwrapped user script',
+
+ 'name' => 'user',
+ 'scripts' => 'mw.example( 1 );',
+
+ 'expected' => 'mw.loader.implement( "user", "mw.example( 1 );" );',
+ ] ],
+ [ [
+ 'title' => 'Implement unwrapped user script',
+ 'debug' => false,
+
+ 'name' => 'user',
+ 'scripts' => 'mw.example( 1 );',
+
+ 'expected' => 'mw.loader.implement("user","mw.example(1);");',
+ ] ],
];
}
/**
* @dataProvider provideLoaderImplement
* @covers ResourceLoader::makeLoaderImplementScript
+ * @covers ResourceLoader::trimArray
*/
public function testMakeLoaderImplementScript( $case ) {
+ $case += [
+ 'styles' => [], 'templates' => [], 'messages' => new XmlJsCode( '{}' ),
+ 'debug' => true
+ ];
+ ResourceLoader::clearCache();
+ $this->setMwGlobals( 'wgResourceLoaderDebug', $case['debug'] );
+
$this->assertEquals(
$case['expected'],
ResourceLoader::makeLoaderImplementScript(
);
}
+ /**
+ * @covers ResourceLoader::makeLoaderImplementScript
+ */
+ public function testMakeLoaderImplementScriptInvalid() {
+ $this->setExpectedException( 'MWException', 'Invalid scripts error' );
+ ResourceLoader::makeLoaderImplementScript(
+ 'test', // name
+ 123, // scripts
+ null, // styles
+ null, // messages
+ null // templates
+ );
+ }
+
+ /**
+ * @covers ResourceLoader::makeLoaderSourcesScript
+ */
+ public function testMakeLoaderSourcesScript() {
+ $this->assertEquals(
+ 'mw.loader.addSource( "local", "/w/load.php" );',
+ ResourceLoader::makeLoaderSourcesScript( 'local', '/w/load.php' )
+ );
+ $this->assertEquals(
+ 'mw.loader.addSource( {
+ "local": "/w/load.php"
+} );',
+ ResourceLoader::makeLoaderSourcesScript( [ 'local' => '/w/load.php' ] )
+ );
+ $this->assertEquals(
+ 'mw.loader.addSource( {
+ "local": "/w/load.php",
+ "example": "https://example.org/w/load.php"
+} );',
+ ResourceLoader::makeLoaderSourcesScript( [
+ 'local' => '/w/load.php',
+ 'example' => 'https://example.org/w/load.php'
+ ] )
+ );
+ $this->assertEquals(
+ 'mw.loader.addSource( [] );',
+ ResourceLoader::makeLoaderSourcesScript( [] )
+ );
+ }
+
+ private static function fakeSources() {
+ return [
+ 'examplewiki' => [
+ 'loadScript' => '//example.org/w/load.php',
+ 'apiScript' => '//example.org/w/api.php',
+ ],
+ 'example2wiki' => [
+ 'loadScript' => '//example.com/w/load.php',
+ 'apiScript' => '//example.com/w/api.php',
+ ],
+ ];
+ }
+
/**
* @covers ResourceLoader::getLoadScript
*/
$this->assertTrue( true );
}
}
-
- /**
- * @covers ResourceLoader::isModuleRegistered
- */
- public function testIsModuleRegistered() {
- $rl = new ResourceLoader();
- $rl->register( 'test.module', new ResourceLoaderTestModule() );
- $this->assertTrue( $rl->isModuleRegistered( 'test.module' ) );
- $this->assertFalse( $rl->isModuleRegistered( 'test.modulenotregistered' ) );
- }
}