From: jenkins-bot Date: Wed, 31 Jan 2018 15:53:51 +0000 (+0000) Subject: Merge "jquery.textSelection: Remove code supporting IE 6 selection APIs" X-Git-Tag: 1.31.0-rc.0~751 X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dcompta/comptes/journal.php?a=commitdiff_plain;h=199df046c48a29c9ae2ea6194dad664ffc8fb9f8;hp=1430ca85dcf9cb3f77a92bee6a915473e465f649;p=lhc%2Fweb%2Fwiklou.git Merge "jquery.textSelection: Remove code supporting IE 6 selection APIs" --- diff --git a/includes/EditPage.php b/includes/EditPage.php index d49f2051e9..6bf3c89213 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -2472,12 +2472,22 @@ ERROR; $displayTitle = $contextTitle->getPrefixedText(); } $out->setPageTitle( $this->context->msg( $msg, $displayTitle ) ); + + $config = $this->context->getConfig(); + # Transmit the name of the message to JavaScript for live preview # Keep Resources.php/mediawiki.action.edit.preview in sync with the possible keys $out->addJsConfigVars( [ 'wgEditMessage' => $msg, - 'wgAjaxEditStash' => $this->context->getConfig()->get( 'AjaxEditStash' ), + 'wgAjaxEditStash' => $config->get( 'AjaxEditStash' ), ] ); + + // Add whether to use 'save' or 'publish' messages to JavaScript for post-edit, other + // editors, etc. + $out->addJsConfigVars( + 'wgEditSubmitButtonLabelPublish', + $config->get( 'EditSubmitButtonLabelPublish' ) + ); } /** diff --git a/includes/Storage/RevisionStore.php b/includes/Storage/RevisionStore.php index b6a751b4b8..79ecec691f 100644 --- a/includes/Storage/RevisionStore.php +++ b/includes/Storage/RevisionStore.php @@ -1484,13 +1484,29 @@ class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup * @throws MWException */ private function checkDatabaseWikiId( IDatabase $db ) { - $storeWiki = $this->loadBalancer->getLocalDomainID(); + $storeWiki = $this->wikiId; $dbWiki = $db->getDomainID(); if ( $dbWiki === $storeWiki ) { return; } + // XXX: we really want the default database ID... + $storeWiki = $storeWiki ?: wfWikiID(); + $dbWiki = $dbWiki ?: wfWikiID(); + + if ( $dbWiki === $storeWiki ) { + return; + } + + // HACK: counteract encoding imposed by DatabaseDomain + $storeWiki = str_replace( '?h', '-', $storeWiki ); + $dbWiki = str_replace( '?h', '-', $dbWiki ); + + if ( $dbWiki === $storeWiki ) { + return; + } + throw new MWException( "RevisionStore for $storeWiki " . "cannot be used with a DB connection for $dbWiki" ); } diff --git a/includes/api/i18n/de.json b/includes/api/i18n/de.json index 218454d5a1..4da95097d5 100644 --- a/includes/api/i18n/de.json +++ b/includes/api/i18n/de.json @@ -22,7 +22,7 @@ "Tacsipacsi" ] }, - "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentation]]\n* [[mw:Special:MyLanguage/API:FAQ|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n
\nStatus: Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\nFehlerhafte Anfragen: Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Fehler und Warnungen]].\n\nTesten: Zum einfachen Testen von API-Anfragen, siehe [[Special:ApiSandbox]].", + "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentation]]\n* [[mw:Special:MyLanguage/API:FAQ|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n
\nStatus: Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\nFehlerhafte Anfragen: Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Fehler und Warnungen]].\n\n

Testen: Zum einfachen Testen von API-Anfragen, siehe [[Special:ApiSandbox]].

", "apihelp-main-param-action": "Auszuführende Aktion.", "apihelp-main-param-format": "Format der Ausgabe.", "apihelp-main-param-maxlag": "maxlag kann verwendet werden, wenn MediaWiki auf einem datenbankreplizierten Cluster installiert ist. Um weitere Replikationsrückstände zu verhindern, lässt dieser Parameter den Client warten, bis der Replikationsrückstand kleiner als der angegebene Wert (in Sekunden) ist. Bei einem größerem Rückstand wird der Fehlercode maxlag zurückgegeben mit einer Nachricht wie Waiting for $host: $lag seconds lagged.
Siehe [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Handbuch: Maxlag parameter]] für weitere Informationen.", diff --git a/includes/api/i18n/fr.json b/includes/api/i18n/fr.json index 2f27b58110..d72b218359 100644 --- a/includes/api/i18n/fr.json +++ b/includes/api/i18n/fr.json @@ -33,7 +33,7 @@ "Kenjiraw" ] }, - "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n
\nÉtat : Toutes les fonctionnalités affichées sur cette page devraient fonctionner, mais l’API est encore en cours de développement et peut changer à tout moment. Inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\nRequêtes erronées : Si des requêtes erronées sont envoyées à l’API, un entête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet entête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\nTest : Pour faciliter le test des requêtes de l’API, voyez [[Special:ApiSandbox]].", + "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n
\nÉtat : Toutes les fonctionnalités affichées sur cette page devraient fonctionner, mais l’API est encore en cours de développement et peut changer à tout moment. Inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\nRequêtes erronées : Si des requêtes erronées sont envoyées à l’API, un entête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet entête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n

Test : Pour faciliter le test des requêtes de l’API, voyez [[Special:ApiSandbox]].

", "apihelp-main-param-action": "Quelle action effectuer.", "apihelp-main-param-format": "Le format de sortie.", "apihelp-main-param-maxlag": "La latence maximale peut être utilisée quand MédiaWiki est installé sur un cluster de base de données répliqué. Pour éviter des actions provoquant un supplément de latence de réplication de site, ce paramètre peut faire attendre le client jusqu’à ce que la latence de réplication soit inférieure à une valeur spécifiée. En cas de latence excessive, le code d’erreur maxlag est renvoyé avec un message tel que Attente de $host : $lag secondes de délai.
Voyez [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manuel: Maxlag parameter]] pour plus d’information.", diff --git a/includes/api/i18n/it.json b/includes/api/i18n/it.json index 568203622f..25da0e6e4b 100644 --- a/includes/api/i18n/it.json +++ b/includes/api/i18n/it.json @@ -19,7 +19,7 @@ "Margherita.mignanelli" ] }, - "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentazione]] (in inglese)\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]] (in inglese)\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n
\nStato: tutte le funzioni e caratteristiche mostrate su questa pagina dovrebbero funzionare, ma le API sono ancora in fase attiva di sviluppo, e potrebbero cambiare in qualsiasi momento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la mailing list sugli annunci delle API MediaWiki] per essere informato sugli aggiornamenti.\n\nIstruzioni sbagliate: quando vengono impartite alle API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e, sia il valore dell'intestazione, sia il codice d'errore, verranno impostati con lo stesso valore. Per maggiori informazioni leggi [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Errori ed avvertimenti]] (in inglese).\n\nTest: per testare facilmente le richieste API, vedi [[Special:ApiSandbox]].", + "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentazione]] (in inglese)\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]] (in inglese)\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n
\nStato: tutte le funzioni e caratteristiche mostrate su questa pagina dovrebbero funzionare, ma le API sono ancora in fase attiva di sviluppo, e potrebbero cambiare in qualsiasi momento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la mailing list sugli annunci delle API MediaWiki] per essere informato sugli aggiornamenti.\n\nIstruzioni sbagliate: quando vengono impartite alle API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e, sia il valore dell'intestazione, sia il codice d'errore, verranno impostati con lo stesso valore. Per maggiori informazioni leggi [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Errori ed avvertimenti]] (in inglese).\n\n

Test: per testare facilmente le richieste API, vedi [[Special:ApiSandbox]].

", "apihelp-main-param-action": "Azione da compiere.", "apihelp-main-param-format": "Formato dell'output.", "apihelp-main-param-assert": "Verifica che l'utente abbia effettuato l'accesso se si è impostato user, o che abbia i permessi di bot se si è impostato bot.", diff --git a/includes/api/i18n/pt.json b/includes/api/i18n/pt.json index f4a4662c63..aa697fbdb9 100644 --- a/includes/api/i18n/pt.json +++ b/includes/api/i18n/pt.json @@ -8,13 +8,14 @@ "Hamilton Abreu", "Mansil", "Felipe L. Ewald", - "Athena in Wonderland" + "Athena in Wonderland", + "Waldir" ] }, - "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentação]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e pedidos]\n
\nEstado: Todas as funcionalidades mostradas nesta página devem ter o comportamento documentado, mas a API ainda está em desenvolvimento ativo e pode ser alterada a qualquer momento. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das atualizações.\n\nPedidos incorretos: Quando são enviados pedidos incorretos à API, será devolvido um cabeçalho HTTP com a chave \"MediaWiki-API-Error\" e depois tanto o valor desse cabeçalho como o código de erro devolvido serão definidos com o mesmo valor. Para mais informação, consulte [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Erros e avisos]].\n\nTestes: Para testar facilmente pedidos à API, visite [[Special:ApiSandbox|Testes da API]].", + "apihelp-main-extended-description": "
\n* [[mw:Special:MyLanguage/API:Main_page|Documentação]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e pedidos]\n
\nEstado: Todas as funcionalidades mostradas nesta página devem ter o comportamento documentado, mas a API ainda está em desenvolvimento ativo e pode ser alterada a qualquer momento. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das atualizações.\n\nPedidos incorretos: Quando são enviados pedidos incorretos à API, será devolvido um cabeçalho HTTP com a chave \"MediaWiki-API-Error\" e depois tanto o valor desse cabeçalho como o código de erro devolvido serão definidos com o mesmo valor. Para mais informação, consulte [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Erros e avisos]].\n\n

\nTestes: Para testar facilmente pedidos à API, visite [[Special:ApiSandbox|Testes da API]].\n

", "apihelp-main-param-action": "A operação a ser realizada.", "apihelp-main-param-format": "O formato do resultado.", - "apihelp-main-param-maxlag": "O atraso máximo pode ser usado quando o MediaWiki é instalado num ''cluster'' de bases de dados replicadas. Para impedir que as operações causem ainda mais atrasos de replicação do ''site'', este parâmetro pode fazer o cliente aguardar até que o atraso de replicação seja inferior ao valor especificado. Caso o atraso atual exceda esse valor, o código de erro maxlag é devolvido com uma mensagem como À espera do servidor $host: $lag segundos de atraso.
Consulte [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: Parâmetro maxlag]] para mais informações.", + "apihelp-main-param-maxlag": "O atraso máximo pode ser usado quando o MediaWiki é instalado num ''cluster'' de bases de dados replicadas. Para impedir que as operações causem ainda mais atrasos de replicação do sítio, este parâmetro pode fazer o cliente aguardar até que o atraso de replicação seja inferior ao valor especificado. Caso o atraso atual exceda esse valor, o código de erro maxlag é devolvido com uma mensagem como À espera do servidor $host: $lag segundos de atraso.
Consulte [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: Parâmetro maxlag]] para mais informações.", "apihelp-main-param-smaxage": "Definir no cabeçalho HTTP s-maxage de controlo da cache este número de segundos. Os erros nunca são armazenados na cache.", "apihelp-main-param-maxage": "Definir no cabeçalho HTTP max-age de controlo da cache este número de segundos. Os erros nunca são armazenados na cache.", "apihelp-main-param-assert": "Se definido com o valor user, verificar que o utilizador está autenticado. Se definido com o valor bot, verificar que o utilizador tem o privilégio de conta robô.", @@ -303,7 +304,7 @@ "apihelp-opensearch-example-te": "Encontrar as páginas que começam por Te.", "apihelp-options-summary": "Alterar as preferências do utilizador atual.", "apihelp-options-extended-description": "Só podem ser definidas as opções que estão registadas no núcleo do MediaWiki ou numa das extensões instaladas, ou opções cuja chave tem o prefixo userjs- (que são supostas ser usadas por ''scripts'' de utilizador).", - "apihelp-options-param-reset": "Reiniciar preferências para os valores por omissão do ''site''.", + "apihelp-options-param-reset": "Reiniciar preferências para os valores por omissão do sítio.", "apihelp-options-param-resetkinds": "Lista dos tipos de opções a reiniciar quando a opção $1reset está definida.", "apihelp-options-param-change": "Listas das alterações, na forma nome=valor (isto é, skin=vector). Se não for fornecido nenhum valor (nem sequer um sinal de igualdade), por exemplo, nomedaopção|outraopção|..., a opção será reiniciada para o seu valor por omissão. Se qualquer dos valores passados contém uma barra vertical (|), use um [[Special:ApiHelp/main#main/datatypes|separador alternativo para valores múltiplos]] de forma a obter o comportamento correto.", "apihelp-options-param-optionname": "O nome da opção que deve ser configurada com o valor dado por $1optionvalue.", @@ -401,7 +402,7 @@ "apihelp-purge-example-simple": "Purgar as páginas Main Page e API.", "apihelp-purge-example-generator": "Purgar as primeiras 10 páginas no espaço nominal principal.", "apihelp-query-summary": "Obter dados de, e sobre, o MediaWiki.", - "apihelp-query-extended-description": "Todas as modificações de dados terão primeiro que usar uma consulta para adquirir uma chave, o que visa impedir abusos de sites maliciosos.", + "apihelp-query-extended-description": "Todas as modificações de dados terão primeiro que usar uma consulta para adquirir uma chave, o que visa impedir abusos de sítios maliciosos.", "apihelp-query-param-prop": "As propriedades a serem obtidas para as páginas consultadas.", "apihelp-query-param-list": "As listas a serem obtidas.", "apihelp-query-param-meta": "Os metadados a serem obtidos.", @@ -410,7 +411,7 @@ "apihelp-query-param-exportnowrap": "Devolver o XML de exportação sem envolvê-lo num resultado XML (o mesmo formato que [[Special:Export]]). Só pode ser usado com $1export.", "apihelp-query-param-iwurl": "Indica se deve ser obtido o URL completo quando o título é uma hiperligação interwikis.", "apihelp-query-param-rawcontinue": "Devolver os dados em bruto de query-continue para continuar.", - "apihelp-query-example-revisions": "Obter [[Special:ApiHelp/query+siteinfo|informação do ''site'']] e as [[Special:ApiHelp/query+revisions|revisões]] da página Main Page.", + "apihelp-query-example-revisions": "Obter [[Special:ApiHelp/query+siteinfo|informação do sítio]] e as [[Special:ApiHelp/query+revisions|revisões]] da página Main Page.", "apihelp-query-example-allpages": "Obter as revisões das páginas que começam por API/.", "apihelp-query+allcategories-summary": "Enumerar todas as categorias.", "apihelp-query+allcategories-param-from": "A categoria a partir da qual será começada a enumeração.", @@ -490,7 +491,7 @@ "apihelp-query+alllinks-example-unique": "Listar os títulos únicos para os quais existem hiperligações.", "apihelp-query+alllinks-example-unique-generator": "Obtém todos os títulos para os quais existem hiperligações, marcando aqueles em falta.", "apihelp-query+alllinks-example-generator": "Obtém as páginas que contêm as ligações.", - "apihelp-query+allmessages-summary": "Devolver as mensagens deste ''site''.", + "apihelp-query+allmessages-summary": "Devolver as mensagens deste sítio.", "apihelp-query+allmessages-param-messages": "Mensagens a serem produzidas no resultado. * (o valor por omissão) significa todas as mensagens.", "apihelp-query+allmessages-param-prop": "As propriedades a serem obtidas:", "apihelp-query+allmessages-param-enableparser": "Definir para ativar o analisador sintático; irá pré-processar o texto wiki da mensagem (substituir palavras mágicas, processar predefinições, etc.).", @@ -719,7 +720,7 @@ "apihelp-query+embeddedin-example-simple": "Mostrar as páginas que transcluem Template:Stub.", "apihelp-query+embeddedin-example-generator": "Obter informação sobre as páginas que transcluem Template:Stub.", "apihelp-query+extlinks-summary": "Devolve todos os URL externos (que não sejam interwikis) das páginas especificadas.", - "apihelp-query+extlinks-param-limit": "O número de ''links'' a serem devolvidos.", + "apihelp-query+extlinks-param-limit": "O número de hiperligações a serem devolvidas.", "apihelp-query+extlinks-param-protocol": "Protocolo do URL. Se vazio e $1query está definido, o protocolo é http. Deixe este parâmetro e $1query vazios para listar todas as hiperligações externas.", "apihelp-query+extlinks-param-query": "Texto de pesquisa sem protocolo. Útil para verificar se uma determinada página contém um determinado URL externo.", "apihelp-query+extlinks-param-expandurl": "Expandir os URL relativos a protocolo com o protocolo canónico.", @@ -839,7 +840,7 @@ "apihelp-query+info-param-token": "Em substituição, usar [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].", "apihelp-query+info-example-simple": "Obter informações sobre a página Main Page.", "apihelp-query+info-example-protection": "Obter informação geral e de proteção sobre a página Main Page.", - "apihelp-query+iwbacklinks-summary": "Encontrar todas as páginas que contêm ''links'' para as páginas indicadas.", + "apihelp-query+iwbacklinks-summary": "Encontrar todas as páginas que contêm hiperligações para as páginas indicadas.", "apihelp-query+iwbacklinks-extended-description": "Pode ser usado para encontrar todas as hiperligações com um prefixo, ou todas as hiperligações para um título (com um prefixo especificado). Se nenhum dos parâmetros for usado, isso efetivamente significa \"todas as hiperligações interwikis\".", "apihelp-query+iwbacklinks-param-prefix": "O prefixo interwikis.", "apihelp-query+iwbacklinks-param-title": "A hiperligação interwikis a ser procurada. Tem de ser usado em conjunto com $1blprefix.", @@ -884,10 +885,10 @@ "apihelp-query+langlinks-example-simple": "Obter as hiperligações interlínguas da página Main Page.", "apihelp-query+links-summary": "Devolve todas as hiperligações das páginas indicadas.", "apihelp-query+links-param-namespace": "Mostrar apenas as hiperligações destes espaços nominais.", - "apihelp-query+links-param-limit": "O número de ''links'' a serem devolvidos.", + "apihelp-query+links-param-limit": "O número de hiperligações a serem devolvidas.", "apihelp-query+links-param-titles": "Listar só as hiperligações para estes títulos. Útil para verificar se uma determinada página contém hiperligações para um determinado título.", "apihelp-query+links-param-dir": "A direção de listagem.", - "apihelp-query+links-example-simple": "Obter os ''links'' da página Main Page.", + "apihelp-query+links-example-simple": "Obter as hiperligações da página Main Page.", "apihelp-query+links-example-generator": "Obter informação sobre as páginas ligadas na página Main Page.", "apihelp-query+links-example-namespaces": "Obter as hiperligações da página Main Page nos espaços nominais {{ns:user}} e {{ns:template}}.", "apihelp-query+linkshere-summary": "Encontrar todas as páginas que contêm hiperligações para as páginas indicadas.", @@ -1083,14 +1084,14 @@ "apihelp-query+search-example-simple": "Pesquisar meaning.", "apihelp-query+search-example-text": "Pesquisar meaning nos textos.", "apihelp-query+search-example-generator": "Obter informação sobre as páginas devolvidas por uma pesquisa do termo meaning.", - "apihelp-query+siteinfo-summary": "Devolver informação geral sobre o ''site''.", + "apihelp-query+siteinfo-summary": "Devolver informação geral sobre o sítio.", "apihelp-query+siteinfo-param-prop": "A informação a ser obtida:", "apihelp-query+siteinfo-paramvalue-prop-general": "Informação global do sistema.", "apihelp-query+siteinfo-paramvalue-prop-namespaces": "Uma lista dos espaços nominais registados e dos seus nomes canónicos.", "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "Uma lista dos nomes alternativos dos espaços nominais registados.", "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "Uma lista dos nomes alternativos das páginas especiais.", "apihelp-query+siteinfo-paramvalue-prop-magicwords": "Uma lista das palavras mágicas e dos seus nomes alternativos.", - "apihelp-query+siteinfo-paramvalue-prop-statistics": "Devolve as estatísticas do ''site''.", + "apihelp-query+siteinfo-paramvalue-prop-statistics": "Devolve as estatísticas do sítio.", "apihelp-query+siteinfo-paramvalue-prop-interwikimap": "Devolve o mapa de interwikis (opcionalmente filtrado, opcionalmente localizado usando $1inlanguagecode).", "apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "Devolve o servidor da base de dados com o maior atraso de replicação.", "apihelp-query+siteinfo-paramvalue-prop-usergroups": "Devolve os grupos de utilizadores e as permissões associadas.", @@ -1106,14 +1107,14 @@ "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "Devolve uma lista dos ''hooks'' de funções do analisador sintático.", "apihelp-query+siteinfo-paramvalue-prop-showhooks": "Devolve uma lista de todos os ''hooks'' subscritos (conteúdo de [[mw:Special:MyLanguage/Manual:$wgHooks|$wgHooks]]).", "apihelp-query+siteinfo-paramvalue-prop-variables": "Devolve uma lista de identificadores de variáveis.", - "apihelp-query+siteinfo-paramvalue-prop-protocols": "Devolve uma lista dos protocolos permitidos nos ''links'' externos.", + "apihelp-query+siteinfo-paramvalue-prop-protocols": "Devolve uma lista dos protocolos permitidos nas hiperligações externas.", "apihelp-query+siteinfo-paramvalue-prop-defaultoptions": "Devolve os valores padrão para as preferências dos utilizadores.", "apihelp-query+siteinfo-paramvalue-prop-uploaddialog": "Devolve a configuração do diálogo de carregamento.", "apihelp-query+siteinfo-param-filteriw": "Devolver só as entradas locais, ou só as não locais, do mapa de interwikis.", "apihelp-query+siteinfo-param-showalldb": "Listar todos os servidores da base de dados, não só aquele que tem maior atraso.", "apihelp-query+siteinfo-param-numberingroup": "Lista o número de utilizadores nos grupos de utilizadores.", "apihelp-query+siteinfo-param-inlanguagecode": "O código de língua dos nomes localizados (o melhor possível) das línguas e dos temas.", - "apihelp-query+siteinfo-example-simple": "Obter as informações do ''site''.", + "apihelp-query+siteinfo-example-simple": "Obter as informações do sítio.", "apihelp-query+siteinfo-example-interwiki": "Obter uma lista dos prefixos interwikis locais.", "apihelp-query+siteinfo-example-replag": "Verificar o atraso de replicação atual.", "apihelp-query+stashimageinfo-summary": "Devolve informações dos ficheiros escondidos.", diff --git a/includes/changetags/ChangeTags.php b/includes/changetags/ChangeTags.php index 95848ea085..7e4dd006ac 100644 --- a/includes/changetags/ChangeTags.php +++ b/includes/changetags/ChangeTags.php @@ -408,19 +408,24 @@ class ChangeTags { sort( $prevTags ); sort( $newTags ); if ( $prevTags == $newTags ) { - // No change. return false; } if ( !$newTags ) { - // no tags left, so delete the row altogether + // No tags left, so delete the row altogether $dbw->delete( 'tag_summary', $tsConds, __METHOD__ ); } else { - $dbw->replace( 'tag_summary', - [ 'ts_rev_id', 'ts_rc_id', 'ts_log_id' ], - array_filter( array_merge( $tsConds, [ 'ts_tags' => implode( ',', $newTags ) ] ) ), - __METHOD__ - ); + // Specify the non-DEFAULT value columns in the INSERT/REPLACE clause + $row = array_filter( [ 'ts_tags' => implode( ',', $newTags ) ] + $tsConds ); + // Check the unique keys for conflicts, ignoring any NULL *_id values + $uniqueKeys = []; + foreach ( [ 'ts_rev_id', 'ts_rc_id', 'ts_log_id' ] as $uniqueColumn ) { + if ( isset( $row[$uniqueColumn] ) ) { + $uniqueKeys[] = [ $uniqueColumn ]; + } + } + + $dbw->replace( 'tag_summary', $uniqueKeys, $row, __METHOD__ ); } return true; diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php index e2feb1fa7c..90fabaf5c4 100644 --- a/includes/db/DatabaseOracle.php +++ b/includes/db/DatabaseOracle.php @@ -354,7 +354,7 @@ class DatabaseOracle extends Database { return $e['code']; } - function affectedRows() { + protected function fetchAffectedRowCount() { return $this->mAffectedRows; } diff --git a/includes/installer/i18n/pt.json b/includes/installer/i18n/pt.json index 760986d01d..228064452a 100644 --- a/includes/installer/i18n/pt.json +++ b/includes/installer/i18n/pt.json @@ -67,7 +67,7 @@ "config-env-php": "O PHP $1 está instalado.", "config-env-hhvm": "HHVM $1 está instalado.", "config-unicode-using-intl": "A usar a [http://pecl.php.net/intl extensão intl PECL] para a normalização Unicode.", - "config-unicode-pure-php-warning": "Aviso: A [http://pecl.php.net/intl extensão intl PECL] não está disponível para efetuar a normalização Unicode. Irá recorrer-se à implementação em PHP puro, que é mais lenta.\nSe o seu site tem alto volume de tráfego, devia informar-se um pouco sobre a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations/pt normalização Unicode].", + "config-unicode-pure-php-warning": "Aviso: A [http://pecl.php.net/intl extensão intl PECL] não está disponível para efetuar a normalização Unicode. Irá recorrer-se à implementação em PHP puro, que é mais lenta.\nSe o seu sítio tem alto volume de tráfego, devia informar-se um pouco sobre a [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations/pt normalização Unicode].", "config-unicode-update-warning": "Aviso: A versão instalada do wrapper de normalização Unicode usa uma versão mais antiga da biblioteca do [http://site.icu-project.org/ projeto ICU].\nDevia [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations atualizá-la] se tem quaisquer preocupações sobre o uso do Unicode.", "config-no-db": "Não foi possível encontrar um controlador apropriado da base de dados! Precisa de instalar um controlador da base de dados para o PHP. {{PLURAL:$2|É aceite o seguinte tipo|São aceites os seguintes tipos}} de base de dados: $1.\n\nSe fez a compilação do PHP, reconfigure-o com um cliente de base de dados ativado; por exemplo, usando ./configure --with-mysqli.\nSe instalou o PHP a partir de um pacote Debian ou Ubuntu, então precisa de instalar também, por exemplo, o pacote php5-mysql.", "config-outdated-sqlite": "Aviso: Tem a versão $1 do SQLite, que é anterior à versão mínima necessária, a $2. O SQLite não estará disponível.", @@ -193,7 +193,7 @@ "config-mssql-windowsauth": "Autenticação do Windows", "config-site-name": "Nome da wiki:", "config-site-name-help": "Este nome aparecerá no título da janela do seu navegador e em vários outros sítios.", - "config-site-name-blank": "Introduza o nome do site.", + "config-site-name-blank": "Introduza o nome do sítio.", "config-project-namespace": "Espaço nominal do projeto:", "config-ns-generic": "Projeto", "config-ns-site-name": "O mesmo que o nome da wiki: $1", @@ -261,13 +261,13 @@ "config-logo": "URL do logótipo:", "config-logo-help": "O tema padrão do MediaWiki inclui espaço para um logótipo de 135x160 píxeis acima do menu da barra lateral.\nColoque na wiki uma imagem com estas dimensões e introduza aqui o URL dessa imagem.\n\nSe não pretende usar um logótipo, deixe este campo em branco.", "config-instantcommons": "Ativar Instant Commons", - "config-instantcommons-help": "O [https://www.mediawiki.org/wiki/InstantCommons Instant Commons] é uma funcionalidade que permite que as wikis usem imagens, áudio e outros ficheiros multimédia disponíveis no site [https://commons.wikimedia.org/ Wikimedia Commons].\nPara poder usá-los, o MediaWiki necessita de acesso à Internet.\n\nPara mais informações sobre esta funcionalidade, incluindo instruções sobre como configurá-la para usar outras wikis em vez da Wikimedia Commons, consulte o [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos Manual Técnico].", + "config-instantcommons-help": "O [https://www.mediawiki.org/wiki/InstantCommons Instant Commons] é uma funcionalidade que permite que as wikis usem imagens, áudio e outros ficheiros multimédia disponíveis no sítio [https://commons.wikimedia.org/ Wikimedia Commons].\nPara poder usá-los, o MediaWiki necessita de acesso à Internet.\n\nPara mais informações sobre esta funcionalidade, incluindo instruções sobre como configurá-la para usar outras wikis em vez da Wikimedia Commons, consulte o [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos Manual Técnico].", "config-cc-error": "O auxiliar de escolha de licenças da Creative Commons não produziu resultados.\nIntroduza o nome da licença manualmente.", "config-cc-again": "Escolha outra vez...", "config-cc-not-chosen": "Escolha a licença da Creative Commons que pretende e clique \"proceed\".", "config-advanced-settings": "Configuração avançada", "config-cache-options": "Configuração da cache de objetos:", - "config-cache-help": "A cache de objetos é usada para melhorar o desempenho do MediaWiki. Armazena dados usados com frequência.\nSites de tamanho médio ou grande são altamente encorajados a ativar esta funcionalidade e os sites pequenos também terão alguns benefícios em fazê-lo.", + "config-cache-help": "A cache de objetos é usada para melhorar o desempenho do MediaWiki. Armazena dados usados com frequência.\nSítios de tamanho médio ou grande são altamente encorajados a ativar esta funcionalidade e os sítios pequenos também terão alguns benefícios em fazê-lo.", "config-cache-none": "Sem cache (não é removida nenhuma funcionalidade, mas a velocidade de operação pode ser afectada nas wikis grandes)", "config-cache-accel": "Cache de objetos do PHP (APC, APCu, XCache ou WinCache)", "config-cache-memcached": "Usar Memcached (requer instalação e configurações adicionais)", diff --git a/includes/libs/objectcache/WANObjectCache.php b/includes/libs/objectcache/WANObjectCache.php index 409f507969..08424c9c8a 100644 --- a/includes/libs/objectcache/WANObjectCache.php +++ b/includes/libs/objectcache/WANObjectCache.php @@ -419,6 +419,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { * * Setting 'lag' and 'since' help avoids keys getting stuck in stale states. * + * Be aware that this does not update the process cache for getWithSetCallback() + * callers. Keys accessed via that method are not generally meant to also be set + * using this primitive method. + * + * Do not use this method on versioned keys accessed via getWithSetCallback(). + * * Example usage: * @code * $dbr = wfGetDB( DB_REPLICA ); @@ -535,6 +541,10 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { * * Note that set() can also be lag-aware and lower the TTL if it's high. * + * Be aware that this does not clear the process cache. Even if it did, callbacks + * used by getWithSetCallback() might still return stale data in the case of either + * uncommitted or not-yet-replicated changes (callback generally use replica DBs). + * * When using potentially long-running ACID transactions, a good pattern is * to use a pre-commit hook to issue the delete. This means that immediately * after commit, callers will see the tombstone in cache upon purge relay. diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php index 1efa9a1f2e..f3877fbe1e 100644 --- a/includes/libs/rdbms/database/Database.php +++ b/includes/libs/rdbms/database/Database.php @@ -126,6 +126,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware protected $delimiter = ';'; /** @var DatabaseDomain */ protected $currentDomain; + /** @var integer|null Rows affected by the last query to query() or its CRUD wrappers */ + protected $affectedRowCount; /** * Either 1 if a transaction is active or 0 otherwise. @@ -1002,8 +1004,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } /** - * Helper method for query() that handles profiling and logging and sends - * the query to doQuery() + * Wrapper for query() that also handles profiling, logging, and affected row count updates * * @param string $sql Original SQL query * @param string $commentedSql SQL query with debugging/trace comment @@ -1029,7 +1030,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware if ( $this->profiler ) { call_user_func( [ $this->profiler, 'profileIn' ], $queryProf ); } + $this->affectedRowCount = null; $ret = $this->doQuery( $commentedSql ); + $this->affectedRowCount = $this->affectedRows(); if ( $this->profiler ) { call_user_func( [ $this->profiler, 'profileOut' ], $queryProf ); } @@ -2238,51 +2241,49 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } public function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) { - $quotedTable = $this->tableName( $table ); - if ( count( $rows ) == 0 ) { return; } - # Single row case + // Single row case if ( !is_array( reset( $rows ) ) ) { $rows = [ $rows ]; } - // @FXIME: this is not atomic, but a trx would break affectedRows() + $affectedRowCount = 0; foreach ( $rows as $row ) { - # Delete rows which collide - if ( $uniqueIndexes ) { - $sql = "DELETE FROM $quotedTable WHERE "; - $first = true; - foreach ( $uniqueIndexes as $index ) { - if ( $first ) { - $first = false; - $sql .= '( '; - } else { - $sql .= ' ) OR ( '; - } - if ( is_array( $index ) ) { - $first2 = true; - foreach ( $index as $col ) { - if ( $first2 ) { - $first2 = false; - } else { - $sql .= ' AND '; - } - $sql .= $col . '=' . $this->addQuotes( $row[$col] ); - } - } else { - $sql .= $index . '=' . $this->addQuotes( $row[$index] ); - } + // Delete rows which collide with this one + $indexWhereClauses = []; + foreach ( $uniqueIndexes as $index ) { + $indexColumns = (array)$index; + $indexRowValues = array_intersect_key( $row, array_flip( $indexColumns ) ); + if ( count( $indexRowValues ) != count( $indexColumns ) ) { + throw new DBUnexpectedError( + $this, + 'New record does not provide all values for unique key (' . + implode( ', ', $indexColumns ) . ')' + ); + } elseif ( in_array( null, $indexRowValues, true ) ) { + throw new DBUnexpectedError( + $this, + 'New record has a null value for unique key (' . + implode( ', ', $indexColumns ) . ')' + ); } - $sql .= ' )'; - $this->query( $sql, $fname ); + $indexWhereClauses[] = $this->makeList( $indexRowValues, LIST_AND ); + } + + if ( $indexWhereClauses ) { + $this->delete( $table, $this->makeList( $indexWhereClauses, LIST_OR ), $fname ); + $affectedRowCount += $this->affectedRows(); } - # Now insert the row + // Now insert the row $this->insert( $table, $row, $fname ); + $affectedRowCount += $this->affectedRows(); } + + $this->affectedRowCount = $affectedRowCount; } /** @@ -2347,6 +2348,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware $where = false; } + $affectedRowCount = 0; $useTrx = !$this->mTrxLevel; if ( $useTrx ) { $this->begin( $fname, self::TRANSACTION_INTERNAL ); @@ -2355,11 +2357,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware # Update any existing conflicting row(s) if ( $where !== false ) { $ok = $this->update( $table, $set, $where, $fname ); + $affectedRowCount += $this->affectedRows(); } else { $ok = true; } # Now insert any non-conflicting row(s) $ok = $this->insert( $table, $rows, $fname, [ 'IGNORE' ] ) && $ok; + $affectedRowCount += $this->affectedRows(); } catch ( Exception $e ) { if ( $useTrx ) { $this->rollback( $fname, self::FLUSHING_INTERNAL ); @@ -2369,6 +2373,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware if ( $useTrx ) { $this->commit( $fname, self::FLUSHING_INTERNAL ); } + $this->affectedRowCount = $affectedRowCount; return $ok; } @@ -3187,6 +3192,17 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } } + public function affectedRows() { + return ( $this->affectedRowCount === null ) + ? $this->fetchAffectedRowCount() // default to driver value + : $this->affectedRowCount; + } + + /** + * @return int Number of retrieved rows according to the driver + */ + abstract protected function fetchAffectedRowCount(); + /** * Take the result from a query, and wrap it in a ResultWrapper if * necessary. Boolean values are passed through as is, to indicate success diff --git a/includes/libs/rdbms/database/DatabaseMssql.php b/includes/libs/rdbms/database/DatabaseMssql.php index 53beb65f9a..832ed9e11e 100644 --- a/includes/libs/rdbms/database/DatabaseMssql.php +++ b/includes/libs/rdbms/database/DatabaseMssql.php @@ -353,7 +353,7 @@ class DatabaseMssql extends Database { /** * @return int */ - public function affectedRows() { + protected function fetchAffectedRowCount() { return $this->mAffectedRows; } diff --git a/includes/libs/rdbms/database/DatabaseMysqlBase.php b/includes/libs/rdbms/database/DatabaseMysqlBase.php index 82a78cab46..6a545ceb2d 100644 --- a/includes/libs/rdbms/database/DatabaseMysqlBase.php +++ b/includes/libs/rdbms/database/DatabaseMysqlBase.php @@ -889,8 +889,10 @@ abstract class DatabaseMysqlBase extends Database { return 0; // already reached this point for sure } + $useGTID = ( $this->useGTIDs && $pos->gtids ); + // Call doQuery() directly, to avoid opening a transaction if DBO_TRX is set - if ( $this->useGTIDs && $pos->gtids ) { + if ( $useGTID ) { // Wait on the GTID set (MariaDB only) $gtidArg = $this->addQuotes( implode( ',', $pos->gtids ) ); $res = $this->doQuery( "SELECT MASTER_GTID_WAIT($gtidArg, $timeout)" ); @@ -910,14 +912,17 @@ abstract class DatabaseMysqlBase extends Database { // Result can be NULL (error), -1 (timeout), or 0+ per the MySQL manual $status = ( $row[0] !== null ) ? intval( $row[0] ) : null; if ( $status === null ) { - // T126436: jobs programmed to wait on master positions might be referencing binlogs - // with an old master hostname. Such calls make MASTER_POS_WAIT() return null. Try - // to detect this and treat the replica DB as having reached the position; a proper master - // switchover already requires that the new master be caught up before the switch. - $replicationPos = $this->getReplicaPos(); - if ( $replicationPos && !$replicationPos->channelsMatch( $pos ) ) { - $this->lastKnownReplicaPos = $replicationPos; - $status = 0; + if ( !$useGTID ) { + // T126436: jobs programmed to wait on master positions might be referencing + // binlogs with an old master hostname; this makes MASTER_POS_WAIT() return null. + // Try to detect this case and treat the replica DB as having reached the given + // position (any master switchover already requires that the new master be caught + // up before the switch). + $replicationPos = $this->getReplicaPos(); + if ( $replicationPos && !$replicationPos->channelsMatch( $pos ) ) { + $this->lastKnownReplicaPos = $replicationPos; + $status = 0; + } } } elseif ( $status >= 0 ) { // Remember that this position was reached to save queries next time diff --git a/includes/libs/rdbms/database/DatabaseMysqli.php b/includes/libs/rdbms/database/DatabaseMysqli.php index c1a56988d5..09ea66cac8 100644 --- a/includes/libs/rdbms/database/DatabaseMysqli.php +++ b/includes/libs/rdbms/database/DatabaseMysqli.php @@ -172,7 +172,7 @@ class DatabaseMysqli extends DatabaseMysqlBase { /** * @return int */ - function affectedRows() { + protected function fetchAffectedRowCount() { $conn = $this->getBindingHandle(); return $conn->affected_rows; diff --git a/includes/libs/rdbms/database/DatabasePostgres.php b/includes/libs/rdbms/database/DatabasePostgres.php index 8c21d726b0..5bf845b1af 100644 --- a/includes/libs/rdbms/database/DatabasePostgres.php +++ b/includes/libs/rdbms/database/DatabasePostgres.php @@ -384,7 +384,7 @@ class DatabasePostgres extends Database { } } - public function affectedRows() { + protected function fetchAffectedRowCount() { if ( !is_null( $this->mAffectedRows ) ) { // Forced result for simulated queries return $this->mAffectedRows; diff --git a/includes/libs/rdbms/database/DatabaseSqlite.php b/includes/libs/rdbms/database/DatabaseSqlite.php index 2b0660707c..01772cf809 100644 --- a/includes/libs/rdbms/database/DatabaseSqlite.php +++ b/includes/libs/rdbms/database/DatabaseSqlite.php @@ -56,6 +56,9 @@ class DatabaseSqlite extends Database { /** @var FSLockManager (hopefully on the same server as the DB) */ protected $lockMgr; + /** @var array List of shared database already attached to this connection */ + private $alreadyAttached = []; + /** * Additional params include: * - dbDirectory : directory containing the DB and the lock file directory @@ -82,16 +85,7 @@ class DatabaseSqlite extends Database { parent::__construct( $p ); // Super doesn't open when $user is false, but we can work with $dbName if ( $p['dbname'] && !$this->isOpen() ) { - if ( $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ) ) { - $done = []; - foreach ( $this->tableAliases as $params ) { - if ( isset( $done[$params['dbname']] ) ) { - continue; - } - $this->attachDatabase( $params['dbname'] ); - $done[$params['dbname']] = 1; - } - } + $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ); } } @@ -302,6 +296,14 @@ class DatabaseSqlite extends Database { return parent::isWriteQuery( $sql ) && !preg_match( '/^(ATTACH|PRAGMA)\b/i', $sql ); } + protected function isTransactableQuery( $sql ) { + return parent::isTransactableQuery( $sql ) && !in_array( + $this->getQueryVerb( $sql ), + [ 'ATTACH', 'PRAGMA' ], + true + ); + } + /** * SQLite doesn't allow buffered results or data seeking etc, so we'll use fetchAll as the result * @@ -494,7 +496,7 @@ class DatabaseSqlite extends Database { /** * @return int */ - function affectedRows() { + protected function fetchAffectedRowCount() { return $this->mAffectedRows; } @@ -1033,6 +1035,17 @@ class DatabaseSqlite extends Database { return $this->query( $sql, $fName ); } + public function setTableAliases( array $aliases ) { + parent::setTableAliases( $aliases ); + foreach ( $this->tableAliases as $params ) { + if ( isset( $this->alreadyAttached[$params['dbname']] ) ) { + continue; + } + $this->attachDatabase( $params['dbname'] ); + $this->alreadyAttached[$params['dbname']] = true; + } + } + protected function requiresDatabaseUser() { return false; // just a file } diff --git a/includes/parser/Sanitizer.php b/includes/parser/Sanitizer.php index 8fee2c77c1..de7a6fa501 100644 --- a/includes/parser/Sanitizer.php +++ b/includes/parser/Sanitizer.php @@ -1171,7 +1171,9 @@ class Sanitizer { # Stupid hack $encValue = preg_replace_callback( '/((?i)' . wfUrlProtocols() . ')/', - [ self::class, 'armorLinksCallback' ], + function ( $matches ) { + return str_replace( ':', ':', $matches[1] ); + }, $encValue ); return $encValue; } @@ -1416,15 +1418,6 @@ class Sanitizer { return $html; } - /** - * Regex replace callback for armoring links against further processing. - * @param array $matches - * @return string - */ - private static function armorLinksCallback( $matches ) { - return str_replace( ':', ':', $matches[1] ); - } - /** * Return an associative array of attribute names and values from * a partial tag string. Attribute names are forced to lowercase, diff --git a/includes/resourceloader/ResourceLoader.php b/includes/resourceloader/ResourceLoader.php index 4a3e8af043..830dbb4a55 100644 --- a/includes/resourceloader/ResourceLoader.php +++ b/includes/resourceloader/ResourceLoader.php @@ -1227,7 +1227,11 @@ MESSAGE; $name, $scripts, $styles, $messages, $templates ) { if ( $scripts instanceof XmlJsCode ) { - $scripts = new XmlJsCode( "function ( $, jQuery, require, module ) {\n{$scripts->value}\n}" ); + if ( self::inDebugMode() ) { + $scripts = new XmlJsCode( "function ( $, jQuery, require, module ) {\n{$scripts->value}\n}" ); + } else { + $scripts = new XmlJsCode( 'function($,jQuery,require,module){'. $scripts->value . '}' ); + } } elseif ( !is_string( $scripts ) && !is_array( $scripts ) ) { throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' ); } diff --git a/includes/resourceloader/ResourceLoaderUserOptionsModule.php b/includes/resourceloader/ResourceLoaderUserOptionsModule.php index 458c44d6e7..ffa55c08ac 100644 --- a/includes/resourceloader/ResourceLoaderUserOptionsModule.php +++ b/includes/resourceloader/ResourceLoaderUserOptionsModule.php @@ -51,10 +51,12 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule { * @return string JavaScript code */ public function getScript( ResourceLoaderContext $context ) { - return Xml::encodeJsCall( 'mw.user.options.set', + // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960). + return ResourceLoader::FILTER_NOMIN . Xml::encodeJsCall( + 'mw.user.options.set', [ $context->getUserObj()->getOptions( User::GETOPTIONS_EXCLUDE_DEFAULTS ) ], ResourceLoader::inDebugMode() - ) . ResourceLoader::FILTER_NOMIN; + ); } /** diff --git a/includes/resourceloader/ResourceLoaderUserTokensModule.php b/includes/resourceloader/ResourceLoaderUserTokensModule.php index e933f1f34d..ae4fb67b8d 100644 --- a/includes/resourceloader/ResourceLoaderUserTokensModule.php +++ b/includes/resourceloader/ResourceLoaderUserTokensModule.php @@ -48,19 +48,16 @@ class ResourceLoaderUserTokensModule extends ResourceLoaderModule { } /** - * Generate the JavaScript content of this module. - * - * Add FILTER_NOMIN annotation to prevent needless minification and caching (T84960). - * * @param ResourceLoaderContext $context * @return string JavaScript code */ public function getScript( ResourceLoaderContext $context ) { - return Xml::encodeJsCall( + // Use FILTER_NOMIN annotation to prevent needless minification and caching (T84960). + return ResourceLoader::FILTER_NOMIN . Xml::encodeJsCall( 'mw.user.tokens.set', [ $this->contextUserTokens( $context ) ], ResourceLoader::inDebugMode() - ) . ResourceLoader::FILTER_NOMIN; + ); } /** diff --git a/includes/specials/SpecialExpandTemplates.php b/includes/specials/SpecialExpandTemplates.php index 0c18a483bc..73ca76bb97 100644 --- a/includes/specials/SpecialExpandTemplates.php +++ b/includes/specials/SpecialExpandTemplates.php @@ -164,7 +164,6 @@ class SpecialExpandTemplates extends SpecialPage { 'size' => 60, 'default' => $title, 'autofocus' => true, - 'cssclass' => 'mw-ui-input-inline', ], 'input' => [ 'type' => 'textarea', diff --git a/includes/specials/SpecialUserrights.php b/includes/specials/SpecialUserrights.php index fd066ac7f3..e62731fbf4 100644 --- a/includes/specials/SpecialUserrights.php +++ b/includes/specials/SpecialUserrights.php @@ -873,6 +873,10 @@ class UserrightsPage extends SpecialPage { } else { $expiryHtml = $this->msg( 'userrights-expiry-none' )->text(); } + // T171345: Add a hidden form element so that other groups can still be manipulated, + // otherwise saving errors out with an invalid expiry time for this group. + $expiryHtml .= Html::Hidden( "wpExpiry-$group", + $currentExpiry ? 'existing' : 'infinite' ); $expiryHtml .= "
\n"; } else { $expiryHtml = Xml::element( 'span', null, diff --git a/languages/i18n/ast.json b/languages/i18n/ast.json index de3b6af810..e96d46a511 100644 --- a/languages/i18n/ast.json +++ b/languages/i18n/ast.json @@ -1302,7 +1302,7 @@ "rcfilters-activefilters": "Filtros activos", "rcfilters-advancedfilters": "Filtros avanzaos", "rcfilters-limit-title": "Resultancies qu'amosar", - "rcfilters-limit-and-date-label": "{{PLURAL:$1|cambiu|$1 cambios}}, $2", + "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|cambiu|$1 cambios}}, $2", "rcfilters-date-popup-title": "Periodu de tiempu a buscar", "rcfilters-days-title": "Últimos díes", "rcfilters-hours-title": "Últimes hores", @@ -1640,7 +1640,7 @@ "lockmanager-fail-closelock": "Nun se pudo zarrar el ficheru de bloquéu pa \"$1\".", "lockmanager-fail-deletelock": "Non se pudo desaniciar el ficheru de bloquéu pa \"$1\".", "lockmanager-fail-acquirelock": "Nun se pudo adquirir el bloquéu pa \"$1\".", - "lockmanager-fail-openlock": "Nun se pudo abrir el ficheru de bloquéu pa \"$1\".", + "lockmanager-fail-openlock": "Nun se pudo abrir el ficheru de bloquéu pa \"$1\". Por favor comprueba que'l direutoriu de xubíes ta configuráu correutamente y que'l to sirvidor web tien permisos d'escritura nesi direutoriu. Ver https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory pa más información.", "lockmanager-fail-releaselock": "Nun se pudo lliberar el bloquéu pa \"$1\".", "lockmanager-fail-db-bucket": "Nun se pudo contautar con bloqueos de bases de datos bastantes nel conxuntu $1.", "lockmanager-fail-db-release": "Nun se pudieron lliberar los bloqueos na base de datos $1.", @@ -1831,7 +1831,7 @@ "doubleredirects": "Redireiciones dobles", "doubleredirectstext": "Esta páxina llista páxines que redireicionen a otres páxines de redireición.\nCada filera contien enllaces a la primera y segunda redireición, asina como al oxetivu de la segunda redireición, que de vezu ye la páxina oxetivu \"real\", onde tendría d'empobinar la primera redireición.\nLes entraes tachaes tan resueltes.", "double-redirect-fixed-move": "[[$1]] treslladóse.\nAnovóse automáticamente y agora redirixe haza [[$2]].", - "double-redirect-fixed-maintenance": "Iguando automáticamente la doble redireición de [[$1]] a [[$2]] nuna xera de mantenimientu.", + "double-redirect-fixed-maintenance": "Iguando automáticamente la doble redireición de [[$1]] a [[$2]] nuna xera de mantenimientu", "double-redirect-fixer": "Iguador de redireiciones", "brokenredirects": "Redireiciones frañaes", "brokenredirectstext": "Les redireiciones siguientes enllacien a páxines que nun esisten:", diff --git a/languages/i18n/be-tarask.json b/languages/i18n/be-tarask.json index a03318a133..607d11b271 100644 --- a/languages/i18n/be-tarask.json +++ b/languages/i18n/be-tarask.json @@ -1120,7 +1120,7 @@ "right-createtalk": "Стварэньне старонак абмеркаваньня", "right-createaccount": "Стварэньне новых рахункаў удзельнікаў", "right-autocreateaccount": "Аўтаматычны ўваход з вонкавага рахунку ўдзельніка", - "right-minoredit": "пазначэньне рэдагаваньняў як дробныя", + "right-minoredit": "Пазначэньне рэдагаваньняў як дробных", "right-move": "перанос старонак", "right-move-subpages": "перанос старонак разам зь іх падстаронкамі", "right-move-rootuserpages": "перанос карэнных старонак удзельнікаў", diff --git a/languages/i18n/bg.json b/languages/i18n/bg.json index a569fc9972..3f3f3e97aa 100644 --- a/languages/i18n/bg.json +++ b/languages/i18n/bg.json @@ -1561,7 +1561,7 @@ "zip-file-open-error": "Възникна грешка при отваряне на файла за проверка на ZIP.", "zip-wrong-format": "Указаният файл не е ZIP файл.", "zip-bad": "Файлът е повреден или е нечетим ZIP файл.\nСигурността му не може да бъде проверена.", - "zip-unsupported": "Файлът е ZIP файл, който използва ZIP компоненти, които не се поддържат от МедияУики.\nСигурността му не може да бъде коректно проверена.", + "zip-unsupported": "Файлът е ZIP файл, който използва функционалност, която не се поддържа от МедияУики.\nСигурността му не може да бъде коректно проверена.", "uploadstash": "Скрити качвания", "uploadstash-summary": "Тази страница предоставя достъп до файловете, които са качени (или са в процес на качване), но все още не са публикувани в уикито. Тези файлове не са достъпни само за потребителя, който ги е качил.", "uploadstash-clear": "Изчистване на скритите качвания", diff --git a/languages/i18n/de.json b/languages/i18n/de.json index 828804d48c..3a018c8d1a 100644 --- a/languages/i18n/de.json +++ b/languages/i18n/de.json @@ -788,6 +788,7 @@ "postedit-confirmation-created": "Die Seite wurde erstellt.", "postedit-confirmation-restored": "Die Seite wurde wiederhergestellt.", "postedit-confirmation-saved": "Deine Bearbeitung wurde gespeichert.", + "postedit-confirmation-published": "Deine Bearbeitung wurde veröffentlicht.", "edit-already-exists": "Die neue Seite konnte nicht erstellt werden, da sie bereits vorhanden ist.", "defaultmessagetext": "Standardtext", "content-failed-to-parse": "Parsen des Inhalts $2 für Modell $1 fehlgeschlagen: $3", diff --git a/languages/i18n/diq.json b/languages/i18n/diq.json index 745a4323ae..ca5672d5ea 100644 --- a/languages/i18n/diq.json +++ b/languages/i18n/diq.json @@ -2523,7 +2523,7 @@ "seconds-ago": "Verê $1 {{PLURAL:$1|saniya|saniyeyan}}", "monday-at": "Dışeme $1 de", "tuesday-at": "Sêşeme $1 de", - "wednesday-at": "Çarşeme $1 de", + "wednesday-at": "Çeharşeme $1 de", "thursday-at": "Pancşeme $1 de", "friday-at": "Êne $1 de", "saturday-at": "Şeme $1 de", diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 3726ae9ed5..a638833acf 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -745,6 +745,7 @@ "postedit-confirmation-created": "The page has been created.", "postedit-confirmation-restored": "The page has been restored.", "postedit-confirmation-saved": "Your edit was saved.", + "postedit-confirmation-published": "Your edit was published.", "edit-already-exists": "Could not create a new page.\nIt already exists.", "addsection-preload": "", "addsection-editintro": "", diff --git a/languages/i18n/es.json b/languages/i18n/es.json index 3bf879f77d..e112dcee6f 100644 --- a/languages/i18n/es.json +++ b/languages/i18n/es.json @@ -1793,7 +1793,7 @@ "lockmanager-fail-closelock": "No se pudo cerrar la referencia para el archivo de bloqueo de \"$1\".", "lockmanager-fail-deletelock": "No se pudo eliminar el archivo de bloqueo para \"$1\".", "lockmanager-fail-acquirelock": "No pudo adquirir el bloqueo para \"$1\".", - "lockmanager-fail-openlock": "No se pudo abrir el archivo de bloqueo para \"$1\". Por favor verifica que el directorio de subidas está configurado correctamente y que tu servidor web tiene permisos de escritura en ese directorio. Ver https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory para más información.", + "lockmanager-fail-openlock": "No se pudo abrir el archivo de bloqueo de «$1». Revisa que el directorio de cargas esté configurado correctamente y que tu servidor web tenga permisos de escritura en ese directorio. Consulta https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory para obtener más información.", "lockmanager-fail-releaselock": "No se pudo liberar el bloqueo de \"$1\".", "lockmanager-fail-db-bucket": "No se pudo contactar con las suficientes bases de datos del conjunto $1.", "lockmanager-fail-db-release": "No se pudieron liberar los bloqueos registrados en la base de datos $1.", @@ -2422,7 +2422,7 @@ "protect-otherreason": "Otra razón:", "protect-otherreason-op": "Otro motivo", "protect-dropdown": "*Razones de protección habituales\n**Vandalismo excesivo\n**Spam excesivo\n**Guerra de ediciones\n**Página muy visitada", - "protect-edit-reasonlist": "Editar las razones de protección", + "protect-edit-reasonlist": "Editar motivos de protección", "protect-expiry-options": "1 hora:1 hour,1 día:1 day,1 semana:1 week,2 semanas:2 weeks,1 mes:1 month,3 meses:3 months,6 meses:6 months,1 año:1 year,para siempre:infinite", "restriction-type": "Permiso:", "restriction-level": "Nivel de restricción:", diff --git a/languages/i18n/eu.json b/languages/i18n/eu.json index a92336b4ae..de219536dc 100644 --- a/languages/i18n/eu.json +++ b/languages/i18n/eu.json @@ -1653,7 +1653,7 @@ "lockmanager-fail-closelock": "Ezin izan da \"$1\" fitxategiaren giltza itxi.", "lockmanager-fail-deletelock": "Ezin izan da \"$1\" fitxategia desblokeatu.", "lockmanager-fail-acquirelock": "Ezin izan da \"$1\" blokeoa eskuratu.", - "lockmanager-fail-openlock": "Ezin izan da \"$1\" blokeo fitxategia ireki.", + "lockmanager-fail-openlock": "Ezin izan da \"$1\"-rentzako blokeo fitxategia ireki. Ziurtatu igoera direktorioa behar bezala konfiguratuta dagoela eta zure web zerbitzariak baimena duela idazteko. Ikusi informazio gehiagorako https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory.", "lockmanager-fail-releaselock": "Ezin izan da \"$1\" blokeoa askatu.", "lockmanager-fail-db-bucket": "Ezin izan dut $1 buketean datubase nahikoa ziurtatu.", "lockmanager-fail-db-release": "Ezin izan da $1 datubasean giltzaraporik askatu.", @@ -3978,6 +3978,8 @@ "restrictionsfield-badip": "Baliogabeko IP helbide edo eremua: $1", "restrictionsfield-label": "Onartutako IP eremuak:", "restrictionsfield-help": "Linea bakoitzeko IP helbide edo CIDR eremu bakarra. Guztia gaitzeko, erabili: \n
0.0.0.0/0\n::/0
", + "edit-error-short": "Akatsa: $1", + "edit-error-long": "Akatsak:\n\n$1", "revid": "$1 berrikusi", "pageid": "$1 orri IDa", "rawhtml-notallowed": "<html> etiketak ezin dira orri arruntetatik kanpo erabili.", diff --git a/languages/i18n/he.json b/languages/i18n/he.json index e79ee5f615..7bbbed5826 100644 --- a/languages/i18n/he.json +++ b/languages/i18n/he.json @@ -1663,7 +1663,7 @@ "lockmanager-fail-closelock": "לא הייתה אפשרות לסגור את קובץ הנעילה עבור \"$1\".", "lockmanager-fail-deletelock": "לא הייתה אפשרות למחוק את קובץ הנעילה עבור \"$1\".", "lockmanager-fail-acquirelock": "לא הייתה אפשרות לקבל נעילה עבור \"$1\".", - "lockmanager-fail-openlock": "לא הייתה אפשרות לפתוח את קובץ הנעילה עבור \"$1\".", + "lockmanager-fail-openlock": "לא הייתה אפשרות לפתוח את קובץ הנעילה עבור \"$1\". יש לוודא שתיקיית ההעלאות מוגדרת בצורה תקינה ושלשרת האינטרנט יש הרשאות לכתוב לתיקייה זו. [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory למידע נוסף].", "lockmanager-fail-releaselock": "לא הייתה אפשרות לשחרר את הנעילה עבור \"$1\".", "lockmanager-fail-db-bucket": "לא הייתה אפשרות לקבל מספיק מסדי נתונים של נעילות בדלי $1.", "lockmanager-fail-db-release": "לא הייתה אפשרות לשחרר נעילות על מסד הנתונים $1.", diff --git a/languages/i18n/hu.json b/languages/i18n/hu.json index 1a1353d416..58d3d17abe 100644 --- a/languages/i18n/hu.json +++ b/languages/i18n/hu.json @@ -989,7 +989,7 @@ "search-external": "Külső kereső", "searchdisabled": "Elnézésed kérjük, de a teljes szöveges keresés terhelési okok miatt átmenetileg nem használható. Ezidő alatt használhatod a lenti Google keresést, mely viszont lehetséges, hogy nem teljesen friss adatokkal dolgozik.", "search-error": "A keresés közben hiba történt: $1", - "search-warning": "$1 keresése közben hiba történt", + "search-warning": "Hiba történt a keresés közben: $1", "preferences": "Beállítások", "mypreferences": "Beállítások", "prefs-edits": "Szerkesztéseid száma:", diff --git a/languages/i18n/ja.json b/languages/i18n/ja.json index a50f7bc55d..367115c24d 100644 --- a/languages/i18n/ja.json +++ b/languages/i18n/ja.json @@ -1554,7 +1554,7 @@ "recentchangeslinked-feed": "関連ページの更新状況", "recentchangeslinked-toolbox": "関連ページの更新状況", "recentchangeslinked-title": "「$1」と関連する変更", - "recentchangeslinked-summary": "これは指定したページからリンクされている (または指定したカテゴリに含まれている) ページの最近の変更の一覧です。\n[[Special:Watchlist|自分のウォッチリスト]]にあるページは太字で表示されます。", + "recentchangeslinked-summary": "ページ名を入力すると、リンク関係 (そのページのリンク先もしくは他のページからのリンク) の最近の変更を調べることができます。 (下位カテゴリを参照するには、カテゴリ:カテゴリ名 (Category:Name of category) を入力)。[[Special:Watchlist|自分のウォッチリスト]]にあるページの変更は太字で表示されます。", "recentchangeslinked-page": "ページ名:", "recentchangeslinked-to": "このページへのリンク元での変更の表示に切り替え", "recentchanges-page-added-to-category": "[[:$1]]をカテゴリに追加", diff --git a/languages/i18n/jv.json b/languages/i18n/jv.json index 500e25ef78..9bb875aa37 100644 --- a/languages/i18n/jv.json +++ b/languages/i18n/jv.json @@ -279,7 +279,7 @@ "site-rss-feed": "$1 ''RSS Feed''", "site-atom-feed": "Lebon atom $1", "page-rss-feed": "\"$1\" ''RSS Feed''", - "page-atom-feed": "\"$1\" ''Atom Feed''", + "page-atom-feed": "Pakan atom \"$1\"", "red-link-title": "$1 (kaca ora ana)", "sort-descending": "Urutaké medhun", "sort-ascending": "Urutaké munggah", @@ -297,7 +297,7 @@ "nosuchaction": "Ora ana tumindak mangkono", "nosuchactiontext": "Tumindak sing dikarepaké déning URL ora trep.\nPanjenengan bokmanawa salah ngetik URL-é, utawa salah nurut pranala.\nIki bokmanawa uga nuduhaké yèn ana ama ing piranti alus sing dianggo déning {{SITENAME}}.", "nosuchspecialpage": "Ora ana kaca mirunggan mangkono", - "nospecialpagetext": "Panjenengan nyuwun kaca astaméwa sing ora sah. Daftar kaca astaméwa sing sah bisa dipirsani ing [[Special:SpecialPages|daftar kaca astaméwa]].", + "nospecialpagetext": "Panjenengan nyuwun kaca mirunggan sing ora sah.\n\nPratélan kaca mirunggan sing sah bisa tinemu ing [[Special:SpecialPages|{{int:specialpages}}]].", "error": "Masalah", "databaseerror": "Masalah sasana dhata", "databaseerror-text": "Ana kerusakan ing basis data (query error).\n\nMungkin ana masalah ing software-e.", @@ -869,7 +869,7 @@ "showingresults": "Ing ngisor iki dituduhaké {{PLURAL:$1|'''1''' kasil|'''$1''' kasil}}, wiwitané saking #$2.", "showingresultsinrange": "Nuduhaké nganti {{PLURAL:$1|1 kasil|$1 kasil}} sajeroning penthangan #$2 tekan #$3.", "search-showingresults": "{{PLURAL:$4|Asil $1 saka $3|Asil $1 – $2 saka $3}}", - "search-nonefound": "Ora ana kasil sing cocog karo pitakonan (''query'').", + "search-nonefound": "Ora ana kasil sing mathuk karo pitakoné.", "search-nonefound-thiswiki": "Ora ana kasil sing jumbuh karo panjalukan ing situs iki.", "powersearch-legend": "Panggolèkan sabanjuré (''advance search'')", "powersearch-ns": "Golèk ing mandala aran:", @@ -1198,7 +1198,7 @@ "recentchanges": "Owahan-owahan anyar", "recentchanges-legend": "Opsi owah-owahan anyar", "recentchanges-summary": "Lacak owah-owahan anyar wiki iki ing kaca iki.", - "recentchanges-noresult": "Ora ana pangowahan ing periode sing diwiwiti kriteria iki.", + "recentchanges-noresult": "Ora ana owahan ing kalamangsa sing mathuk karo pranatan iki.", "recentchanges-feed-description": "Urutna owah-owahan anyar ing wiki ing ''feed'' iki.", "recentchanges-label-newpage": "Besutan iki nggawé kaca anyar", "recentchanges-label-minor": "Iki besutan cilik", @@ -1343,7 +1343,7 @@ "recentchangeslinked-title": "Owah-owahan sing magepokan \"$1\"", "recentchangeslinked-summary": "Iki pratélaning owah-owahan sing mentas digawé tumrap ing kaca-kaca sing nggayut sawijining kaca (utawa kaca-kaca anggotaning sawijining kategori).\nKaca ing [[Special:Watchlist|pawawangané panjenegan]] dikandeli.", "recentchangeslinked-page": "Jeneng kaca:", - "recentchangeslinked-to": "Nuduhaké owah-owahan menyang kaca sing disambung menyang kaca-kaca iki", + "recentchangeslinked-to": "Nuduhaké owah-owahan kaca-kaca sing nggayut kaca iki", "recentchanges-page-added-to-category": "[[:$1]] ditambahaké ing kategori", "recentchanges-page-added-to-category-bundled": "[[:$1]] ditambahaké ing kategori, [[Special:WhatLinksHere/$1|kaca iki kalebu ing njeroné kaca liyané]]", "recentchanges-page-removed-from-category": "[[:$1]] dibusak saka kategori", @@ -1899,7 +1899,7 @@ "mywatchlist": "Pawawangan", "watchlistfor2": "Kanggo $1 $2", "nowatchlist": "Ora ana apa-apa ing pawawanganing sampéyan.", - "watchlistanontext": "Mangga $1 kanggo mirsani utawa nyunting daftar pangawasan panjenengan.", + "watchlistanontext": "Sumangga mlebu log saperlu ndeleng utawa mbesut barang ing pawawangané panjenengan.", "watchnologin": "Durung mlebu log", "addwatch": "Tambah nèng daptar pangawasan", "addedwatchtext": "Kaca \"[[:$1]]\" wis ditambahaké menyang [[Special:Watchlist|daftar pangawasan]].\nOwah-owahan sing dumadi ing tembé ing kaca iku lan kaca dhiskusi sing kagandhèng, bakal dipacak ing kéné.", @@ -2397,7 +2397,7 @@ "import-upload": "Ngunggahaké data XML", "import-token-mismatch": "Kélangan data sèsi. Mangga dijajal manèh.", "import-invalid-interwiki": "Ora bisa ngimport saka wiki sing kapilih.", - "import-error-edit": "Kaca \"$1\" ora diimpor amarga Sampéyan ora dililakaké nyunting kuwi.", + "import-error-edit": "Kaca \"$1\" ora kaimpor amarga panjenengan ora kawogan mbesut iku.", "import-error-create": "Kaca \"$1\" ora diimpor amarga Sampéyan ora dililakaké nggawé kuwi.", "import-error-interwiki": "Kaca \"$1\" ora diimpor amarga jenengé dicadhangaké kango pranala njaba (interwiki).", "import-error-special": "Kaca \"$1\" ora diimpor amarga darbèké mandala aran mirunggan sing ora nglilakaké anané kaca.", @@ -2451,7 +2451,7 @@ "tooltip-t-whatlinkshere": "Pratélané kabèh kaca wiki sing nggayut mréné", "tooltip-t-recentchangeslinked": "Owah-owahan anyar saka kaca-kaca sing nggayut kaca iki", "tooltip-feed-rss": "''RSS feed'' kanggo kaca iki", - "tooltip-feed-atom": "''Atom feed'' kanggo kaca iki", + "tooltip-feed-atom": "Pakan atom tumrap kaca iki", "tooltip-t-contributions": "Pratélaning pisumbanging {{GENDER:$1|panganggo iki}}", "tooltip-t-emailuser": "Kirimi layang-èl nyang {{GENDER:$1|panganggo iki}}", "tooltip-t-info": "Katerangan liyané ngenani kaca iki", @@ -2653,7 +2653,7 @@ "exif-referenceblackwhite": "Wiji réferènsi pasangan ireng putih", "exif-datetime": "Tanggal lan wektu owahé barkas", "exif-imagedescription": "Sesirah gambar", - "exif-make": "Produsèn kamera", + "exif-make": "Prodhusèn kodhak", "exif-model": "Modhèl kaméra", "exif-software": "Piranti alus sing dianggo", "exif-artist": "Prodhusèn", @@ -2994,7 +2994,7 @@ "scarytranscludetoolong": "[URL-é kedawan]", "deletedwhileediting": "Pélik: Kaca iki wis dibusak kawit pisanan panjenengan mbesut!", "confirmrecreate": "Panganggo [[User:$1|$1]] ([[User talk:$1|Wicara]]) wis mbusak kaca iki nalika panjenengan miwiti panyuntingan mawa alesan:\n: ''$2''\nMangga didhedhes (dikonfirmasi) menawa panjenengan kersa nggawé ulang kaca iki.", - "confirmrecreate-noreason": "Panganggo [[User:$1|$1]] ([[User talk:$1|wicara]]) mbusak kaca iki sakbaré Sampéyan lekas nyunting. Mangga pesthèkaké yèn Sampéyan pancen pingin tenan nggawé manèh kaca iki.", + "confirmrecreate-noreason": "Panganggo [[User:$1|$1]] ([[User talk:$1|rembug]]) {{GENDER:$1|mbusak}} kaca iki sawisé panjenengan wiwit mbesut. Sumangga konfirmasi yèn panjenengan temen arep nggawé manèh kaca iki.", "recreate": "Gawé ulang", "confirm-purge-title": "Buwang kaca iki", "confirm_purge_button": "OK", @@ -3108,7 +3108,7 @@ "redirect": "Lih-lihan miturut barkas, panganggo, kaca, owahan, utawa cathetan", "redirect-summary": "Kaca mirunggan iki ngener ing sawijining barkas (jeneng gambar diwenehi), kaca (ID revisi utama ID kaca diwenehi), utawa kaca panganggo (ID panganggo diwenehi). Cara nganggo: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], or [[{{#Special:Redirect}}/user/101]].", "redirect-submit": "Menyang", - "redirect-lookup": "Golek:", + "redirect-lookup": "Luru:", "redirect-value": "Aji:", "redirect-user": "ID panganggo", "redirect-page": "ID kaca", @@ -3295,7 +3295,7 @@ "logentry-patrol-patrol": "$1 {{GENDER:$2|nengeri}} révisi $4 saka kaca $3 sing diawasi", "logentry-patrol-patrol-auto": "$1 otomatis {{GENDER:$2|nandhani}} benahan $4 saka kaca $3 kaawasake", "logentry-newusers-newusers": "Akun panganggo $1 {{GENDER:$2|digawé}}", - "logentry-newusers-create": "Akun panganggo $1 {{GENDER:$2|digawé}}", + "logentry-newusers-create": "Akun panganggo $1 wis {{GENDER:$2|kagawé}}", "logentry-newusers-create2": "Akun panganggo $3 {{GENDER:$2|digawé}} déning $1", "logentry-newusers-byemail": "Akun panganggo $3 {{GENDER:$2|digawé}} déning $1 lan tembung wadi dikirim lumantar layang-èl", "logentry-newusers-autocreate": "Akun panganggo $1 otomatis {{GENDER:$2|digawé}}", diff --git a/languages/i18n/pt.json b/languages/i18n/pt.json index a4e13c659d..c6021f0d0e 100644 --- a/languages/i18n/pt.json +++ b/languages/i18n/pt.json @@ -545,7 +545,7 @@ "emailconfirmlink": "Confirme o seu endereço de correio eletrónico", "invalidemailaddress": "O endereço de correio eletrónico não pode ser aceite porque parece ter um formato inválido.\nIntroduza um endereço formatado corretamente ou deixe o campo vazio.", "cannotchangeemail": "Os endereços de correio eletrónico das contas não podem ser alterados nesta wiki.", - "emaildisabled": "Este site não consegue enviar mensagens de correio eletrónico.", + "emaildisabled": "Este sítio não consegue enviar mensagens de correio eletrónico.", "accountcreated": "Conta criada", "accountcreatedtext": "A conta de utilizador para [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) foi criada.", "createaccount-title": "Criação de conta na wiki {{SITENAME}}", @@ -730,8 +730,8 @@ "previewnote": "Lembre-se de que esta é apenas uma antevisão do resultado.\nAs modificações ainda não foram gravadas!", "continue-editing": "Ir para a área de edição", "previewconflict": "Esta antevisão do resultado apresenta o texto da caixa de edição acima tal como este aparecerá se escolher gravá-lo.", - "session_fail_preview": "Desculpe! Não foi possível processar a edição devido à perda dos dados da sua sessão.\n\nA sua sessão poderá ter sido encerrada. Verifique se ainda está autenticado e tente novamente, por favor. \nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite cookies deste site.", - "session_fail_preview_html": "Desculpe! Não foi possível processar a edição devido à perda de dados da sua sessão.\n\nComo a wiki {{SITENAME}} possibilita o uso de HTML puro, a antevisão está oculta por precaução contra ataques com JavaScript.\n\nSe esta é uma tentativa legítima de edição tente novamente, por favor. \nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite cookies deste site.", + "session_fail_preview": "Desculpe! Não foi possível processar a edição devido à perda dos dados da sua sessão.\n\nA sua sessão poderá ter sido encerrada. Verifique se ainda está autenticado e tente novamente, por favor. \nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite cookies deste sítio.", + "session_fail_preview_html": "Desculpe! Não foi possível processar a edição devido à perda de dados da sua sessão.\n\nComo a wiki {{SITENAME}} possibilita o uso de HTML puro, a antevisão está oculta por precaução contra ataques com JavaScript.\n\nSe esta é uma tentativa legítima de edição tente novamente, por favor. \nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite cookies deste sítio.", "token_suffix_mismatch": "A edição foi rejeitada porque o seu navegador alterou os sinais de pontuação no editor.\nA edição foi rejeitada para evitar perdas no texto da página.\nIsto acontece ocasionalmente quando se usa um serviço de proxy anonimizador mal configurado.", "edit_form_incomplete": "Algumas partes do formulário de edição não chegaram ao servidor; verifique que a sua edição continua intacta e tente novamente, por favor.", "editing": "A editar $1", @@ -1015,7 +1015,7 @@ "showingresultsinrange": "Apresenta-se abaixo {{PLURAL:$1|1 resultado|até $1 resultados}} no intervalo #$2 a #$3.", "search-showingresults": "{{PLURAL:$4|Resultado $1 de $3|Resultados $1 - $2 de $3}}", "search-nonefound": "A pesquisa não produziu resultados.", - "search-nonefound-thiswiki": "Não existem resultados que correspondam à consulta neste site.", + "search-nonefound-thiswiki": "Não existem resultados que correspondam à consulta neste sítio.", "powersearch-legend": "Pesquisa avançada", "powersearch-ns": "Pesquisar nos domínios:", "powersearch-togglelabel": "Marcar:", @@ -1094,7 +1094,7 @@ "prefs-custom-css": "CSS personalizado", "prefs-custom-js": "JS personalizado", "prefs-common-css-js": "CSS/JS partilhado por todos os temas:", - "prefs-reset-intro": "Pode usar esta página para repor as configurações padrão das preferências.\nAs suas preferências serão modificadas para os valores predefinidos do site.\nEsta operação não pode ser desfeita.", + "prefs-reset-intro": "Pode usar esta página para repor as configurações padrão das preferências.\nAs suas preferências serão modificadas para os valores predefinidos do sítio.\nEsta operação não pode ser desfeita.", "prefs-emailconfirm-label": "Confirmação do correio eletrónico:", "youremail": "Correio eletrónico:", "username": "Nome de {{GENDER:$1|utilizador|utilizadora|utilizador(a)}}:", @@ -1773,9 +1773,9 @@ "http-curl-error": "Ocorreu um erro ao aceder ao URL: $1", "http-bad-status": "Ocorreu um problema durante o pedido HTTP: $1 $2", "upload-curl-error6": "Não foi possível aceder ao URL", - "upload-curl-error6-text": "Não foi possível aceder ao URL.\nVerifique se o endereço está correto e o site disponível, por favor.", + "upload-curl-error6-text": "Não foi possível aceder ao URL.\nVerifique se o endereço está correto e o sítio disponível, por favor.", "upload-curl-error28": "Tempo limite para o envio do ficheiro excedido", - "upload-curl-error28-text": "O site demorou demasiado tempo a responder. Verifique que o site está disponível, aguarde alguns momentos e tente novamente, por favor. Talvez queira voltar a tentar numa altura menos congestionada.", + "upload-curl-error28-text": "O sítio demorou demasiado tempo a responder. Verifique que o sítio está disponível, aguarde alguns momentos e tente novamente, por favor. Talvez queira voltar a tentar numa altura menos congestionada.", "license": "Licença:", "license-header": "Licenciamento", "nolicense": "Nenhuma selecionada", @@ -2006,7 +2006,7 @@ "apihelp-no-such-module": "Módulo \"$1\" não encontrado.", "apisandbox": "Testes da API", "apisandbox-jsonly": "Para usar a área de testes da API é necessário o JavaScript.", - "apisandbox-api-disabled": "A API está desativada neste site.", + "apisandbox-api-disabled": "A API está desativada neste sítio.", "apisandbox-intro": "Use esta página para fazer experiências com a API operacional do MediaWiki.\nConsulte a [[mw:API:Main page|documentação da API]] para informações sobre o seu uso. Exemplo: [https://www.mediawiki.org/wiki/API#A_simple_example obter o conteúdo da Página Principal]. Selecione uma operação para ver mais exemplos.\n\nNote que, embora esta seja uma área de testes, as operações que executar nesta página podem modificar a wiki.", "apisandbox-fullscreen": "Expandir painel", "apisandbox-fullscreen-tooltip": "Expandir o painel da página de testes para preencher a janela do navegador.", @@ -2055,9 +2055,9 @@ "booksources-invalid-isbn": "O número ISBN fornecido não parece ser válido; verifique a existência de erros ao copiar da fonte original.", "magiclink-tracking-rfc": "Páginas que usam hiperligações mágicas RFC", "magiclink-tracking-rfc-desc": "Esta página usa hiperligações mágicas RFC. Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para saber como migrar.", - "magiclink-tracking-pmid": "Páginas que usam links mágicos PMID", + "magiclink-tracking-pmid": "Páginas que usam hiperligações mágicas PMID", "magiclink-tracking-pmid-desc": "Esta página usa hiperligações mágicas PMID. Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para saber como migrar.", - "magiclink-tracking-isbn": "Páginas que usam links mágicos ISBN", + "magiclink-tracking-isbn": "Páginas que usam hiperligações mágicas ISBN", "magiclink-tracking-isbn-desc": "Esta página usa hiperligações mágicas ISBN. Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para saber como migrar.", "specialloguserlabel": "Executante:", "speciallogtitlelabel": "Alvo (título ou página ou {{ns:user}}:nome de utilizador):", @@ -2724,7 +2724,7 @@ "import-nonewrevisions": "Não foi importada nenhuma revisão (já estavam todas presentes ou foram ignoradas devido a erros).", "xml-error-string": "$1 na linha $2, coluna $3 (byte $4): $5", "import-upload": "Enviar dados em XML", - "import-token-mismatch": "Perda de dados da sessão.\n\nA sua sessão pode ter sido encerrada. '''Verifique se ainda está autenticado e tente novamente, por favor'''. \nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite cookies deste site.", + "import-token-mismatch": "Perda de dados da sessão.\n\nA sua sessão pode ter sido encerrada. '''Verifique se ainda está autenticado e tente novamente, por favor'''. \nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite cookies deste sítio.", "import-invalid-interwiki": "Não é possível importar da wiki especificada.", "import-error-edit": "A página \"$1\" não foi importada porque não tem permissão para editá-la.", "import-error-create": "A página \"$1\" não foi importada porque não tem permissão para criá-la.", @@ -2831,7 +2831,7 @@ "creditspage": "Créditos da página", "nocredits": "Não há informação disponível sobre os créditos desta página.", "spamprotectiontitle": "Filtro de proteção contra spam", - "spamprotectiontext": "O texto que pretendia gravar foi bloqueado pelo filtro de spam.\nEste bloqueio foi provavelmente causado por uma hiperligação para um ''site'' externo que está na lista negra.", + "spamprotectiontext": "O texto que pretendia gravar foi bloqueado pelo filtro de spam.\nEste bloqueio foi provavelmente causado por uma hiperligação para um sítio externo que está na lista negra.", "spamprotectionmatch": "O seguinte texto ativou o filtro de spam: $1", "spambot_username": "MediaWiki limpeza de spam", "spam_reverting": "A reverter para a última revisão que não contém ligação para $1", @@ -3345,8 +3345,8 @@ "invalidateemail": "Cancelar confirmação do correio eletrónico", "notificationemail_subject_changed": "O endereço de correio eletrónico registado na wiki {{SITENAME}} foi alterado", "notificationemail_subject_removed": "O endereço de correio eletrónico registado na wiki {{SITENAME}} foi removido", - "notificationemail_body_changed": "Alguém, provavelmente você, a partir do endereço IP $1, alterou o endereço de correio eletrónico da conta \"$2\" para \"$3\" na wiki {{SITENAME}}.\n\nCaso não o tenha alterado, contacte imediatamente um administrador do site.", - "notificationemail_body_removed": "Alguém, provavelmente você, a partir do endereço IP $1, eliminou o endereço de correio eletrónico da conta \"$2\" na wiki {{SITENAME}}.\n\nCaso não o tenha eliminado, contacte imediatamente um administrador do site.", + "notificationemail_body_changed": "Alguém, provavelmente você, a partir do endereço IP $1, alterou o endereço de correio eletrónico da conta \"$2\" para \"$3\" na wiki {{SITENAME}}.\n\nCaso não o tenha alterado, contacte imediatamente um administrador do sítio.", + "notificationemail_body_removed": "Alguém, provavelmente você, a partir do endereço IP $1, eliminou o endereço de correio eletrónico da conta \"$2\" na wiki {{SITENAME}}.\n\nCaso não o tenha eliminado, contacte imediatamente um administrador do sítio.", "scarytranscludedisabled": "[Transclusão interwikis foi impossibilitada]", "scarytranscludefailed": "[Não foi possível obter a predefinição a partir de $1]", "scarytranscludefailed-httpstatus": "[Não foi possível obter a predefinição a partir de $1: HTTP $2]", @@ -3631,7 +3631,7 @@ "permanentlink": "Hiperligação permanente", "permanentlink-revid": "Identificador de revisão", "permanentlink-submit": "Ir para a revisão", - "dberr-problems": "Desculpe! Este site está com dificuldades técnicas.", + "dberr-problems": "Desculpe! Este sítio está com dificuldades técnicas.", "dberr-again": "Experimente esperar alguns minutos e atualizar.", "dberr-info": "(Não foi possível aceder ao servidor da base de dados: $1)", "dberr-info-hidden": "(Não foi possível aceder ao servidor da base de dados)", @@ -3809,7 +3809,7 @@ "expand_templates_generate_xml": "Mostrar a árvore de análise sintáctica do XML", "expand_templates_generate_rawhtml": "Mostrar o HTML puro", "expand_templates_preview": "Antevisão do resultado", - "expand_templates_preview_fail_html": "Porque a wiki {{SITENAME}} permite código HTML puro e ocorreu uma perda de dados da sessão, a antevisão ficará ocultada como precaução contra ataques por JavaScript.\n\nSe esta é uma tentativa legítima de visionamento, por favor tente novamente.\nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite que este site crie ''cookies''.", + "expand_templates_preview_fail_html": "Porque a wiki {{SITENAME}} permite código HTML puro e ocorreu uma perda de dados da sessão, a antevisão ficará ocultada como precaução contra ataques por JavaScript.\n\nSe esta é uma tentativa legítima de visionamento, por favor tente novamente.\nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite que este sítio crie ''cookies''.", "expand_templates_preview_fail_html_anon": "Porque a wiki {{SITENAME}} permite código HTML puro e não iniciou uma sessão, a antevisão ficará ocultada como precaução contra ataques por JavaScript.\n\nSe esta é uma tentativa legítima de visionamento, por favor [[Special:UserLogin|inicie uma sessão]] e tente novamente.", "expand_templates_input_missing": "Necessita de fornecer pelo menos algum texto wiki de entrada.", "pagelanguage": "Alterar a língua da página", @@ -4037,7 +4037,7 @@ "rawhtml-notallowed": "As etiquetas <html> não podem ser utilizadas fora de páginas normais.", "gotointerwiki": "A sair da wiki {{SITENAME}}", "gotointerwiki-invalid": "O título especificado é inválido.", - "gotointerwiki-external": "Está prestes a sair da wiki {{SITENAME}} para visitar [[$2]], que é um site externo.\n\n'''[$1 Continuar para $1]'''", + "gotointerwiki-external": "Está prestes a sair da wiki {{SITENAME}} para visitar [[$2]], que é um sítio externo.\n\n'''[$1 Continuar para $1]'''", "undelete-cantedit": "Não pode restaurar esta página porque não tem privilégios para a editar.", "undelete-cantcreate": "Não pode restaurar esta página porque não existe nenhuma página com este nome e não tem privilégios para criar esta página.", "pagedata-title": "Dados de página", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index e29bcad8bc..a4f1d64592 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -940,6 +940,7 @@ "postedit-confirmation-created": "{{gender}}\nShown after a user creates a new page. Parameters:\n* $1 - the current user, for GENDER support", "postedit-confirmation-restored": "{{gender}}\nShown after a user restores a page to a previous revision. Parameters:\n* $1 - the current user, for GENDER support", "postedit-confirmation-saved": "{{gender}}\nShown after a user saves a page. Parameters:\n* $1 - the current user, for GENDER support", + "postedit-confirmation-published": "{{gender}}\nShown after a user publishes a page. Parameters:\n* $1 - the current user, for GENDER support", "edit-already-exists": "Used as error message.\n\nSee also:\n* {{msg-mw|edit-hook-aborted}}\n* {{msg-mw|edit-gone-missing}}\n* {{msg-mw|edit-conflict}}\n* {{msg-mw|edit-no-change}}", "addsection-preload": "{{notranslate}}", "addsection-editintro": "{{notranslate}}", diff --git a/languages/i18n/sd.json b/languages/i18n/sd.json index 31abcc07f7..7bd0919c22 100644 --- a/languages/i18n/sd.json +++ b/languages/i18n/sd.json @@ -691,6 +691,7 @@ "search-showingresults": "{{PLURAL:$4|نتيجو $1 of $3|نتيجا $1 - $2 of $3}}", "search-nonefound": "توھان جي ڳولا جي نتيجي ۾ ڪجھہ بہ نہ لڌو.", "powersearch-legend": "اعليٰ ڳولا", + "powersearch-ns": "نالن لاءِ ڇڏين وڇوٽين ۾ ڳولھيو (سرچ اِن نيم اسپيسز)", "powersearch-togglelabel": "چڪاسيو:", "powersearch-toggleall": "سڀ", "powersearch-togglenone": "ڪو بہ نہ", @@ -1201,7 +1202,7 @@ "nrevisions": "$1 {{PLURAL:$1|مسودو|مسودا}}", "nimagelinks": "$1 {{PLURAL:$1|صفحي|صفحن}} ۾ استعمال ٿيل", "ntransclusions": "$1 {{PLURAL:$1|صفحي|صفحن}} ۾ استعمال ٿيل", - "specialpage-empty": "ھن رپورٽ لاءِ ڪي-بہ نتيجا ناھن.", + "specialpage-empty": "ھن رپورٽ لاءِ ڪي بہ نتيجا ناھن.", "lonelypages": "يتيم صفحا", "uncategorizedpages": "اڻ زمريل صفحا", "uncategorizedcategories": "اڻزمرايل زمرا", @@ -1416,7 +1417,7 @@ "restriction-level-sysop": "مڪمل طور تحفظيل", "restriction-level-autoconfirmed": "نيم تحفظيل", "viewdeletedpage": "ڊاٺل صفحا ڏسو", - "undelete-nodiff": "ڪوبہ پويون مسودو نہ لڌو", + "undelete-nodiff": "ڪوبہ اڳيون مسودو نہ لڌو", "undeletebtn": "بحاليو", "undeleteviewlink": "ڏسو", "undeletecomment": "سبب:", @@ -1838,6 +1839,7 @@ "version-libraries-description": "تشريح", "version-libraries-authors": "ليکڪ", "redirect-submit": "ھلو", + "redirect-lookup": "ڏسو:", "redirect-value": "قدر:", "redirect-user": "واپرائيندڙ آءِڊي", "redirect-page": "صفحي جي آءِڊي", diff --git a/languages/i18n/sl.json b/languages/i18n/sl.json index 05a1229a97..6d07338a1e 100644 --- a/languages/i18n/sl.json +++ b/languages/i18n/sl.json @@ -1641,7 +1641,7 @@ "lockmanager-fail-closelock": "Ne morem zapreti zaklenitvene datoteke »$1«.", "lockmanager-fail-deletelock": "Ne morem izbrisati zaklenitvene datoteke »$1«.", "lockmanager-fail-acquirelock": "Ne morem pridobiti zaklenitvene datoteke »$1«.", - "lockmanager-fail-openlock": "Ne morem odpreti zaklenitvene datoteke »$1«.", + "lockmanager-fail-openlock": "Ne morem odpreti zaklenitvene datoteke »$1«. Prepričajte se, da je mapa za nalaganje nastavljena pravilno in da ima vaš spletni strežnik pravice za pisanje v tej mapi. Oglejte si https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory za več informacij.", "lockmanager-fail-releaselock": "Ne morem sprostiti zaklepa »$1«.", "lockmanager-fail-db-bucket": "Ne morem kontaktirati zadostnega števila zaklenitvenih zbirk podatkov v vedru $1.", "lockmanager-fail-db-release": "Ne morem sprostiti zaklepov zbirke podatkov $1.", diff --git a/resources/Resources.php b/resources/Resources.php index 5a16641589..2142f1f408 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1508,6 +1508,7 @@ return [ 'postedit-confirmation-created', 'postedit-confirmation-restored', 'postedit-confirmation-saved', + 'postedit-confirmation-published', ], ], 'mediawiki.action.view.redirect' => [ diff --git a/resources/src/jquery/jquery.textSelection.js b/resources/src/jquery/jquery.textSelection.js index 3774cd25e7..394b42f0d9 100644 --- a/resources/src/jquery/jquery.textSelection.js +++ b/resources/src/jquery/jquery.textSelection.js @@ -318,7 +318,6 @@ // Return [start, end] instead of just start startAndEnd: false }, options ); - // FIXME: We may not need character position-based functions if we insert markers in the right places break; case 'setSelection': options = $.extend( { @@ -331,7 +330,6 @@ if ( options.end === undefined ) { options.end = options.start; } - // FIXME: We may not need character position-based functions if we insert markers in the right places break; case 'scrollToCaretPosition': options = $.extend( { diff --git a/resources/src/mediawiki.action/mediawiki.action.view.postEdit.js b/resources/src/mediawiki.action/mediawiki.action.view.postEdit.js index e0ab45a109..5e859ac8a0 100644 --- a/resources/src/mediawiki.action/mediawiki.action.view.postEdit.js +++ b/resources/src/mediawiki.action/mediawiki.action.view.postEdit.js @@ -38,7 +38,12 @@ data = data || {}; if ( data.message === undefined ) { - data.message = $.parseHTML( mw.message( 'postedit-confirmation-saved', data.user || mw.user ).escaped() ); + data.message = $.parseHTML( mw.message( + mw.config.get( 'wgEditSubmitButtonLabelPublish' ) ? + 'postedit-confirmation-published' : + 'postedit-confirmation-saved', + data.user || mw.user + ).escaped() ); } $content = $( '
' ).addClass( 'postedit-icon postedit-icon-checkmark postedit-content' ); diff --git a/resources/src/mediawiki/mediawiki.feedback.js b/resources/src/mediawiki/mediawiki.feedback.js index bfd5c06045..ca4d239606 100644 --- a/resources/src/mediawiki/mediawiki.feedback.js +++ b/resources/src/mediawiki/mediawiki.feedback.js @@ -57,6 +57,7 @@ this.feedbackPageTitle = config.title || new mw.Title( 'Feedback' ); this.messagePosterPromise = mw.messagePoster.factory.create( this.feedbackPageTitle, config.apiUrl ); + this.foreignApi = config.apiUrl ? new mw.ForeignApi( config.apiUrl ) : null; // Links this.bugsTaskSubmissionLink = config.bugsLink || '//phabricator.wikimedia.org/maniphest/task/edit/form/1/'; @@ -85,12 +86,14 @@ * Respond to dialog submit event. If the information was * submitted successfully, open a MessageDialog to thank the user. * - * @param {string} [status] A status of the end of operation + * @param {string} status A status of the end of operation * of the main feedback dialog. Empty if the dialog was * dismissed with no action or the user followed the button * to the external task reporting site. + * @param {string} feedbackPageName + * @param {string} feedbackPageUrl */ - mw.Feedback.prototype.onDialogSubmit = function ( status ) { + mw.Feedback.prototype.onDialogSubmit = function ( status, feedbackPageName, feedbackPageUrl ) { var dialogConfig; if ( status !== 'submitted' ) { @@ -101,10 +104,10 @@ title: mw.msg( 'feedback-thanks-title' ), message: $( '' ).msg( 'feedback-thanks', - this.feedbackPageTitle.getNameText(), + feedbackPageName, $( '' ).attr( { target: '_blank', - href: this.feedbackPageTitle.getUrl() + href: feedbackPageUrl } ) ), actions: [ @@ -150,6 +153,7 @@ this.constructor.static.dialog, { title: mw.msg( this.dialogTitleMessageKey ), + foreignApi: this.foreignApi, settings: { messagePosterPromise: this.messagePosterPromise, title: this.feedbackPageTitle, @@ -305,6 +309,24 @@ */ mw.Feedback.Dialog.prototype.getSetupProcess = function ( data ) { return mw.Feedback.Dialog.parent.prototype.getSetupProcess.call( this, data ) + .next( function () { + // Get the URL of the target page, we want to use that in links in the intro + // and in the success dialog + var dialog = this; + if ( data.foreignApi ) { + return data.foreignApi.get( { + action: 'query', + prop: 'info', + inprop: 'url', + formatversion: 2, + titles: data.settings.title.getPrefixedText() + } ).then( function ( data ) { + dialog.feedbackPageUrl = OO.getProp( data, 'query', 'pages', 0, 'canonicalurl' ); + } ); + } else { + this.feedbackPageUrl = data.settings.title.getUrl(); + } + }, this ) .next( function () { var plainMsg, parsedMsg, settings = data.settings; @@ -319,7 +341,6 @@ this.setBugReportLink( settings.bugsTaskSubmissionLink ); this.feedbackPageTitle = settings.title; this.feedbackPageName = settings.title.getNameText(); - this.feedbackPageUrl = settings.title.getUrl(); // Useragent checkbox if ( settings.useragentCheckbox.show ) { diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php index 7f42254102..f9e2cc1733 100644 --- a/tests/phpunit/includes/LinkerTest.php +++ b/tests/phpunit/includes/LinkerTest.php @@ -5,7 +5,6 @@ use MediaWiki\MediaWikiServices; /** * @group Database */ - class LinkerTest extends MediaWikiLangTestCase { /** diff --git a/tests/phpunit/includes/Storage/RevisionStoreDbTest.php b/tests/phpunit/includes/Storage/RevisionStoreDbTest.php index d1b9157c3c..8185670206 100644 --- a/tests/phpunit/includes/Storage/RevisionStoreDbTest.php +++ b/tests/phpunit/includes/Storage/RevisionStoreDbTest.php @@ -22,7 +22,6 @@ use TestUserRegistry; use Title; use WANObjectCache; use Wikimedia\Rdbms\Database; -use Wikimedia\Rdbms\DatabaseDomain; use Wikimedia\Rdbms\DatabaseSqlite; use Wikimedia\Rdbms\FakeResultWrapper; use Wikimedia\Rdbms\LoadBalancer; @@ -41,12 +40,7 @@ class RevisionStoreDbTest extends MediaWikiTestCase { private function getLoadBalancerMock( array $server ) { $lb = $this->getMockBuilder( LoadBalancer::class ) ->setMethods( [ 'reallyOpenConnection' ] ) - ->setConstructorArgs( [ [ - 'servers' => [ $server ], - 'localDomain' => new DatabaseDomain( - $server['dbname'], null, $server['tablePrefix'] - ), - ] ] ) + ->setConstructorArgs( [ [ 'servers' => [ $server ] ] ] ) ->getMock(); $lb->method( 'reallyOpenConnection' )->willReturnCallback( diff --git a/tests/phpunit/includes/WikiReferenceTest.php b/tests/phpunit/includes/WikiReferenceTest.php index 227dd87da5..dc2e9ae412 100644 --- a/tests/phpunit/includes/WikiReferenceTest.php +++ b/tests/phpunit/includes/WikiReferenceTest.php @@ -3,7 +3,6 @@ /** * @covers WikiReference */ - class WikiReferenceTest extends PHPUnit_Framework_TestCase { use MediaWikiCoversValidator; diff --git a/tests/phpunit/includes/db/DatabaseTestHelper.php b/tests/phpunit/includes/db/DatabaseTestHelper.php index d19d998146..fa9898d1cd 100644 --- a/tests/phpunit/includes/db/DatabaseTestHelper.php +++ b/tests/phpunit/includes/db/DatabaseTestHelper.php @@ -174,7 +174,7 @@ class DatabaseTestHelper extends Database { return false; } - function affectedRows() { + function fetchAffectedRowCount() { return -1; } diff --git a/tests/phpunit/includes/installer/OracleInstallerTest.php b/tests/phpunit/includes/installer/OracleInstallerTest.php index bd1412ebc1..2811a9cf41 100644 --- a/tests/phpunit/includes/installer/OracleInstallerTest.php +++ b/tests/phpunit/includes/installer/OracleInstallerTest.php @@ -6,7 +6,6 @@ * @group Database * @group Installer */ - class OracleInstallerTest extends MediaWikiTestCase { /** diff --git a/tests/phpunit/includes/libs/ArrayUtilsTest.php b/tests/phpunit/includes/libs/ArrayUtilsTest.php index 76b4ee17be..88312657d4 100644 --- a/tests/phpunit/includes/libs/ArrayUtilsTest.php +++ b/tests/phpunit/includes/libs/ArrayUtilsTest.php @@ -4,7 +4,6 @@ * * @group Database */ - class ArrayUtilsTest extends PHPUnit_Framework_TestCase { use MediaWikiCoversValidator; diff --git a/tests/phpunit/includes/libs/IPTest.php b/tests/phpunit/includes/libs/IPTest.php index 8a120eaab0..a36b259300 100644 --- a/tests/phpunit/includes/libs/IPTest.php +++ b/tests/phpunit/includes/libs/IPTest.php @@ -8,7 +8,6 @@ * @todo Test methods in this call should be split into a method and a * dataprovider. */ - class IPTest extends PHPUnit_Framework_TestCase { use MediaWikiCoversValidator; diff --git a/tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php b/tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php index a23a2a0096..caf1281e65 100644 --- a/tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php +++ b/tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php @@ -53,6 +53,9 @@ class FakeDatabaseMysqlBase extends DatabaseMysqlBase { protected function doQuery( $sql ) { } + protected function fetchAffectedRowCount() { + } + // From DatabaseMysqli protected function mysqlConnect( $realServer ) { } diff --git a/tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php b/tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php index 23f7865058..d8ebeff170 100644 --- a/tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php +++ b/tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php @@ -560,7 +560,7 @@ class DatabaseSQLTest extends PHPUnit_Framework_TestCase { 'rows' => [ 'field' => 'text', 'field2' => 'text2' ], ], "DELETE FROM replace_table " . - "WHERE ( field='text' ); " . + "WHERE (field = 'text'); " . "INSERT INTO replace_table " . "(field,field2) " . "VALUES ('text','text2')" @@ -576,7 +576,7 @@ class DatabaseSQLTest extends PHPUnit_Framework_TestCase { ], ], "DELETE FROM module_deps " . - "WHERE ( md_module='module' AND md_skin='skin' ); " . + "WHERE (md_module = 'module' AND md_skin = 'skin'); " . "INSERT INTO module_deps " . "(md_module,md_skin,md_deps) " . "VALUES ('module','skin','deps')" @@ -598,12 +598,12 @@ class DatabaseSQLTest extends PHPUnit_Framework_TestCase { ], ], "DELETE FROM module_deps " . - "WHERE ( md_module='module' AND md_skin='skin' ); " . + "WHERE (md_module = 'module' AND md_skin = 'skin'); " . "INSERT INTO module_deps " . "(md_module,md_skin,md_deps) " . "VALUES ('module','skin','deps'); " . "DELETE FROM module_deps " . - "WHERE ( md_module='module2' AND md_skin='skin2' ); " . + "WHERE (md_module = 'module2' AND md_skin = 'skin2'); " . "INSERT INTO module_deps " . "(md_module,md_skin,md_deps) " . "VALUES ('module2','skin2','deps2')" @@ -625,12 +625,12 @@ class DatabaseSQLTest extends PHPUnit_Framework_TestCase { ], ], "DELETE FROM module_deps " . - "WHERE ( md_module='module' ) OR ( md_skin='skin' ); " . + "WHERE (md_module = 'module') OR (md_skin = 'skin'); " . "INSERT INTO module_deps " . "(md_module,md_skin,md_deps) " . "VALUES ('module','skin','deps'); " . "DELETE FROM module_deps " . - "WHERE ( md_module='module2' ) OR ( md_skin='skin2' ); " . + "WHERE (md_module = 'module2') OR (md_skin = 'skin2'); " . "INSERT INTO module_deps " . "(md_module,md_skin,md_deps) " . "VALUES ('module2','skin2','deps2')" diff --git a/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php b/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php index 4a0a7e71df..e131506729 100644 --- a/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php +++ b/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php @@ -322,7 +322,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase { */ private function getMockDB( $methods = [] ) { static $abstractMethods = [ - 'affectedRows', + 'fetchAffectedRowCount', 'closeConnection', 'dataSeek', 'doQuery', diff --git a/tests/phpunit/includes/session/SessionBackendTest.php b/tests/phpunit/includes/session/SessionBackendTest.php index 88f58cf06b..e460960c3e 100644 --- a/tests/phpunit/includes/session/SessionBackendTest.php +++ b/tests/phpunit/includes/session/SessionBackendTest.php @@ -2,6 +2,7 @@ namespace MediaWiki\Session; +use Config; use MediaWikiTestCase; use User; use Wikimedia\TestingAccessWrapper; @@ -14,9 +15,16 @@ use Wikimedia\TestingAccessWrapper; class SessionBackendTest extends MediaWikiTestCase { const SESSIONID = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; + /** @var SessionManager */ protected $manager; + + /** @var Config */ protected $config; + + /** @var SessionProvider */ protected $provider; + + /** @var TestBagOStuff */ protected $store; protected $onSessionMetadataCalled = false; @@ -25,6 +33,7 @@ class SessionBackendTest extends MediaWikiTestCase { * Returns a non-persistent backend that thinks it has at least one session active * @param User|null $user * @param string $id + * @return SessionBackend */ protected function getBackend( User $user = null, $id = null ) { if ( !$this->config ) { @@ -149,7 +158,7 @@ class SessionBackendTest extends MediaWikiTestCase { $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() ); $expire = time() + 100; - $this->store->setSessionMeta( self::SESSIONID, [ 'expires' => $expire ], 2 ); + $this->store->setSessionMeta( self::SESSIONID, [ 'expires' => $expire ] ); $info = new SessionInfo( SessionInfo::MIN_PRIORITY, [ 'provider' => $this->provider, diff --git a/tests/phpunit/includes/session/SessionManagerTest.php b/tests/phpunit/includes/session/SessionManagerTest.php index 6c989f3cda..e042f7655a 100644 --- a/tests/phpunit/includes/session/SessionManagerTest.php +++ b/tests/phpunit/includes/session/SessionManagerTest.php @@ -14,7 +14,14 @@ use Wikimedia\TestingAccessWrapper; */ class SessionManagerTest extends MediaWikiTestCase { - protected $config, $logger, $store; + /** @var \HashConfig */ + private $config; + + /** @var \TestLogger */ + private $logger; + + /** @var TestBagOStuff */ + private $store; protected function getManager() { \ObjectCache::$instances['testSessionStore'] = new TestBagOStuff(); diff --git a/tests/phpunit/includes/session/TestBagOStuff.php b/tests/phpunit/includes/session/TestBagOStuff.php index bac2088d9a..f9e30f06ab 100644 --- a/tests/phpunit/includes/session/TestBagOStuff.php +++ b/tests/phpunit/includes/session/TestBagOStuff.php @@ -14,53 +14,44 @@ class TestBagOStuff extends \CachedBagOStuff { /** * @param string $id Session ID * @param array $data Session data - * @param int $expiry - * @param User $user User for metadata */ - public function setSessionData( $id, array $data, $expiry = 0, User $user = null ) { - $this->setSession( $id, [ 'data' => $data ], $expiry, $user ); + public function setSessionData( $id, array $data ) { + $this->setSession( $id, [ 'data' => $data ] ); } /** * @param string $id Session ID * @param array $metadata Session metadata - * @param int $expiry */ - public function setSessionMeta( $id, array $metadata, $expiry = 0 ) { - $this->setSession( $id, [ 'metadata' => $metadata ], $expiry ); + public function setSessionMeta( $id, array $metadata ) { + $this->setSession( $id, [ 'metadata' => $metadata ] ); } /** * @param string $id Session ID * @param array $blob Session metadata and data - * @param int $expiry - * @param User $user User for metadata */ - public function setSession( $id, array $blob, $expiry = 0, User $user = null ) { + public function setSession( $id, array $blob ) { $blob += [ 'data' => [], 'metadata' => [], ]; $blob['metadata'] += [ - 'userId' => $user ? $user->getId() : 0, - 'userName' => $user ? $user->getName() : null, - 'userToken' => $user ? $user->getToken( true ) : null, + 'userId' => 0, + 'userName' => null, + 'userToken' => null, 'provider' => 'DummySessionProvider', ]; - $this->setRawSession( $id, $blob, $expiry, $user ); + $this->setRawSession( $id, $blob ); } /** * @param string $id Session ID * @param array|mixed $blob Session metadata and data - * @param int $expiry */ - public function setRawSession( $id, $blob, $expiry = 0 ) { - if ( $expiry <= 0 ) { - $expiry = \RequestContext::getMain()->getConfig()->get( 'ObjectCacheSessionExpiry' ); - } - + public function setRawSession( $id, $blob ) { + $expiry = \RequestContext::getMain()->getConfig()->get( 'ObjectCacheSessionExpiry' ); $this->set( $this->makeKey( 'MWSession', $id ), $blob, $expiry ); } diff --git a/tests/phpunit/includes/skins/SkinTemplateTest.php b/tests/phpunit/includes/skins/SkinTemplateTest.php index 5b3fbfac89..06b0667738 100644 --- a/tests/phpunit/includes/skins/SkinTemplateTest.php +++ b/tests/phpunit/includes/skins/SkinTemplateTest.php @@ -7,7 +7,6 @@ * * @author Bene* < benestar.wikimedia@gmail.com > */ - class SkinTemplateTest extends MediaWikiTestCase { /** * @dataProvider makeListItemProvider diff --git a/tests/phpunit/includes/specials/ImageListPagerTest.php b/tests/phpunit/includes/specials/ImageListPagerTest.php index 22bdefdff3..10c6d04c9e 100644 --- a/tests/phpunit/includes/specials/ImageListPagerTest.php +++ b/tests/phpunit/includes/specials/ImageListPagerTest.php @@ -8,7 +8,6 @@ * * @group Database */ - class ImageListPagerTest extends MediaWikiTestCase { /** * @expectedException MWException