$prefs = Preferences::getPreferences( $user, $this->getContext() );
$prefsKinds = $user->getOptionKinds( $this->getContext(), $changes );
+ $htmlForm = null;
foreach ( $changes as $key => $value ) {
switch ( $prefsKinds[$key] ) {
case 'registered':
// Regular option.
+ if ( $htmlForm === null ) {
+ // We need a dummy HTMLForm for the validate callback...
+ $htmlForm = new HTMLForm( array(), $this );
+ }
$field = HTMLForm::loadInputFromParameters( $key, $prefs[$key] );
+ $field->mParent = $htmlForm;
$validation = $field->validate( $value, $user->getOptions() );
break;
case 'registered-multiselect':
"apihelp-options-example-reset": "Restablecer todas las preferencias",
"apihelp-paraminfo-description": "Obtener información acerca de los módulos de la API.",
"apihelp-paraminfo-param-helpformat": "Formato de las cadenas de ayuda.",
+ "apihelp-parse-paramvalue-prop-modules": "Da los módulos ResourceLoader utilizados en la página.",
"apihelp-patrol-example-rcid": "Patrullar un cambio reciente",
"apihelp-patrol-example-revid": "Patrullar una revisión",
"apihelp-protect-param-reason": "Motivo de la (des)protección.",
"apihelp-parse-param-pageid": "解析此页的内容。覆盖<var>$1page</var>。",
"apihelp-parse-param-redirects": "如果<var>$1page</var>或<var>$1pageid</var>被设置为一个重定向,则解析它。",
"apihelp-parse-param-oldid": "解析该修订版本的内容。覆盖<var>$1page</var>和<var>$1pageid</var>。",
+ "apihelp-parse-paramvalue-prop-categorieshtml": "提供HTML版本分类。",
"apihelp-parse-paramvalue-prop-modules": "提供在页面中使用的ResourceLoader模块。",
"apihelp-parse-param-pst": "在解析输入前,对输入做一次保存前变换处理。仅当使用文本时有效。",
"apihelp-parse-param-effectivelanglinks": "包含由扩展提供的语言链接(用于与<kbd>$1prop=langlinks</kbd>一起使用)。",
'body' => $params['content']
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 412 ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
'body' => $handle // resource
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 412 ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
) + $this->sanitizeHdrs( $params ), // extra headers merged into object
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 201 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
);
}
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $request['method'] === 'PUT' && $rcode === 201 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
'headers' => array()
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 204 ) {
// good
$status->fatal( 'backend-fail-delete', $params['src'] );
}
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
'headers' => $metaHdrs + $customHdrs
) );
- $be = $this;
+ $that = $this;
$method = __METHOD__;
- $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
+ $handler = function ( array $request, Status $status ) use ( $that, $method, $params ) {
list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
if ( $rcode === 202 ) {
// good
} elseif ( $rcode === 404 ) {
$status->fatal( 'backend-fail-describe', $params['src'] );
} else {
- $be->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
+ $that->onError( $status, $method, $params, $rerr, $rcode, $rdesc );
}
};
);
};
- $repo = $this;
+ $that = $this;
$applyMatchingFiles = function ( ResultWrapper $res, &$searchSet, &$finalFiles )
- use ( $repo, $fileMatchesSearch, $flags )
+ use ( $that, $fileMatchesSearch, $flags )
{
global $wgContLang;
- $info = $repo->getInfo();
+ $info = $that->getInfo();
foreach ( $res as $row ) {
- $file = $repo->newFileFromRow( $row );
+ $file = $that->newFileFromRow( $row );
// There must have been a search for this DB key, but this has to handle the
// cases were title capitalization is different on the client and repo wikis.
$dbKeysLook = array( str_replace( ' ', '_', $file->getName() ) );
// Hack: the lock()/unlock() pair is nested in a transaction so the locking is not
// tied to BEGIN/COMMIT. To avoid slow purges in the transaction, move them outside.
- $file = $this;
+ $that = $this;
$this->getRepo()->getMasterDB()->onTransactionIdle(
- function () use ( $file, $archiveNames ) {
+ function () use ( $that, $archiveNames ) {
global $wgUseSquid;
- $file->purgeEverything();
+ $that->purgeEverything();
foreach ( $archiveNames as $archiveName ) {
- $file->purgeOldThumbnails( $archiveName );
+ $that->purgeOldThumbnails( $archiveName );
}
if ( $wgUseSquid ) {
// Purge the squid
$purgeUrls = array();
foreach ( $archiveNames as $archiveName ) {
- $purgeUrls[] = $file->getArchiveUrl( $archiveName );
+ $purgeUrls[] = $that->getArchiveUrl( $archiveName );
}
SquidUpdate::purge( $purgeUrls );
}
/** Idiom for set()/getWithSetCallback() TTL */
const TTL_NONE = 0;
+ /** Idiom for getWithSetCallback() callbacks to avoid calling set() */
+ const TTL_UNCACHEABLE = -1;
/** Cache format version number */
const VERSION = 1;
/**
* Method to fetch/regenerate cache keys
*
- * On cache miss, the key will be set to the callback result.
+ * On cache miss, the key will be set to the callback result,
+ * unless the callback returns false. The arguments supplied are:
+ * (current value or false, &$ttl)
* The callback function returns the new value given the current
- * value (false if not present). If false is returned, then nothing
- * will be saved to cache.
+ * value (false if not present). Preemptive re-caching and $checkKeys
+ * can result in a non-false current value. The TTL of the new value
+ * can be set dynamically by altering $ttl in the callback (by reference).
*
* Usually, callbacks ignore the current value, but it can be used
* to maintain "most recent X" values that come from time or sequence
* @code
* $key = wfMemcKey( 'cat-recent-actions', $catId );
* // Function that derives the new key value given the old value
- * $callback = function( $cValue ) { ... };
+ * $callback = function( $cValue, &$ttl ) { ... };
* // Get the key value from cache or from source on cache miss;
* // try to only let one cluster thread manage doing cache updates
* $opts = array( 'lockTSE' => 5, 'lowTTL' => 10 );
*
* @param string $key Cache key
* @param callable $callback Value generation function
- * @param integer $ttl Seconds to live when the key is updated [0=forever]
+ * @param integer $ttl Seconds to live for key updates. Special values are:
+ * - WANObjectCache::TTL_NONE : cache forever
+ * - WANObjectCache::TTL_UNCACHEABLE : do not cache at all
* @param array $checkKeys List of "check" keys
* @param array $opts Options map:
* - lowTTL : consider pre-emptive updates when the current TTL (sec)
}
// Generate the new value from the callback...
- $value = call_user_func( $callback, $cValue );
+ $value = call_user_func_array( $callback, array( $cValue, &$ttl ) );
// When delete() is called, writes are write-holed by the tombstone,
// so use a special stash key to pass the new value around threads.
- if ( $value !== false && ( $isHot || $isTombstone ) ) {
+ if ( $value !== false && ( $isHot || $isTombstone ) && $ttl >= 0 ) {
$this->cache->set( self::STASH_KEY_PREFIX . $key, $value, $tempTTL );
}
$this->cache->unlock( $key );
}
- if ( $value !== false ) {
+ if ( $value !== false && $ttl >= 0 ) {
// Update the cache; this will fail if the key is tombstoned
$this->set( $key, $value, $ttl );
}
protected function extractHooks( array $info ) {
if ( isset( $info['Hooks'] ) ) {
- foreach ( $info['Hooks'] as $name => $callable ) {
- $this->globals['wgHooks'][$name][] = $callable;
+ foreach ( $info['Hooks'] as $name => $value ) {
+ foreach ( (array)$value as $callback ) {
+ $this->globals['wgHooks'][$name][] = $callback;
+ }
}
$this->processed[] = 'Hooks';
}
public function extractInfo( $path, array $info );
/**
- * @return array With 'globals', 'defines', 'callbacks', 'credits' keys.
+ * @return array With following keys:
+ * 'globals' - variables to be set to $GLOBALS
+ * 'defines' - constants to define
+ * 'callbacks' - functions to be executed by the registry
+ * 'credits' - metadata to be stored by registry
+ * 'attributes' - registration info which isn't a global variable
*/
public function getExtractedInfo();
}
$limit,
$descending
);
- $pager = $this;
/*
* This hook will allow extensions to add in additional queries, so they can get their data
) );
Hooks::run(
'ContribsPager::reallyDoQuery',
- array( &$data, $pager, $offset, $limit, $descending )
+ array( &$data, $this, $offset, $limit, $descending )
);
$result = array();
* @return ResultWrapper
*/
function reallyDoQuery( $offset, $limit, $descending ) {
- $pager = $this;
-
$data = array( parent::reallyDoQuery( $offset, $limit, $descending ) );
// This hook will allow extensions to add in additional queries, nearly
// identical to ContribsPager::reallyDoQuery.
Hooks::run(
'DeletedContribsPager::reallyDoQuery',
- array( &$data, $pager, $offset, $limit, $descending )
+ array( &$data, $this, $offset, $limit, $descending )
);
$result = array();
"querypage-disabled": "Ista pachina especial ye desactivata por motivos de rendimiento.",
"booksources": "Fuents de libros",
"booksources-search-legend": "Mirar fuents de libros",
+ "booksources-search": "Mirar",
"booksources-text": "Contino ye una lista de vinclos ta atros puestos an que venden libros nuevos y usatos, talment bi haiga más información sobre os libros que ye mirando.",
"booksources-invalid-isbn": "O numero d'ISBN dato pareix que no ye conforme; comprebe si no bi ha garra error en copiar d'a fuent orichinal.",
"specialloguserlabel": "Fedor:",
"title-invalid-characters": "Запытаная назва старонкі ўтрымлівае няслушныя сымбалі: «$1».",
"title-invalid-relative": "Назва мае адносны шлях. Адносныя назвы старонак (./, ../) няслушныя, бо яны часта робяцца недаступнымі, калі апрацоўваюцца браўзэрам карыстальніка.",
"title-invalid-magic-tilde": "Запытаная назва старонкі ўтрымлівае недазволенае спалучэньне тыльдаў (<nowiki>~~~</nowiki>).",
+ "title-invalid-too-long": "Запытаная назва старонкі занадта доўгая. Яна ня мусіць быць даўжэй за $1 байтаў у кадаваньні UTF-8.",
"perfcached": "Наступныя зьвесткі кэшаваныя і могуць быць састарэлымі. У кэшы {{PLURAL:$1|даступны|даступныя}} ня больш за $1 {{PLURAL:$1|вынік|вынікі|вынікаў}}.",
"perfcachedts": "Наступныя зьвесткі кэшаваныя і апошні раз былі абноўленыя $1. У кэшы {{PLURAL:$4|даступны|даступныя}} ня больш за $4 {{PLURAL:$4|вынік|вынікі|вынікаў}}.",
"querypage-no-updates": "Абнаўленьні гэтай старонкі цяпер адключаныя. Зьвесткі ня будуць абнаўляцца.",
"missingcommentheader": "'''Дагадаийтар.''' Ахьа хӀокху къамелан дӀахьедар/корта билгал бина бац. Кнопка «{{int:savearticle}}» юху тӀетаӀича хийцамах лаьцна хӀума доцуш Ӏалашбира бу.",
"summary-preview": "Цуьнах лаьцна хирду:",
"subject-preview": "Коьрта могӀа хира бу:",
+ "previewerrortext": "Хьан хийцамашка хьалха хьажа гӀертачу хенахь гӀалат даьлла.",
"blockedtitle": "Декъашхочун блоктоьхана",
"blockedtext": "'''Хьан декъашхочун дӀаяздар я IP-адрес блоктоьхна ду.'''\n\nБлоктоьхна куьйгалхочо $1.\nБилгалдина бахьна: «''$2''».\n\n* Блоктохар доладелла: $8\n* Блоктохар чекхдолу: $6\n* Блоктохаран Ӏалашо: $7\n\nХьа йиш ю $1 декъашхочуьнга дехардан я кхечу муьлха [[{{MediaWiki:Grouppage-sysop}}|куьйгалхочуьнга]].\nТергам бе, хьа таро яц «декъашхочунга кехат» олу функци лелаян, хьан [[Special:Preferences|гӀирс нисбар чохь]] нийса электронан поштан адрес яздина дацахь, я кехаташ кхехӀитарна а блоктоьхна елахь.\nХьан IP-адрес — $3, блоктохаран идентификатор — $5.\nДехар до, хьайн хаам чохь билгалде и.",
"blockednoreason": "бахьана билгалдина дац",
"no-null-revision": "No se pudo crear una nueva revisión nula para la página «$1»",
"badtitle": "Título incorrecto",
"badtitletext": "El título de la página solicitada está vacío, no es válido, o es un enlace interidioma o interwiki incorrecto.\nPuede que contenga uno o más caracteres que no se pueden usar en los títulos.",
+ "title-invalid-interwiki": "El título contiene un enlace interwiki",
+ "title-invalid-characters": "El título de la página solicitada contiene caracteres no válidos: \"$1\".",
+ "title-invalid-leading-colon": "El título de la página solicitada contiene un caracater (:) no válido en el comienzo.",
"perfcached": "Los siguientes datos provienen de la caché y pueden no estar actualizados. La caché puede contener {{PLURAL:$1|un resultado|$1 resultados}} como máximo.",
"perfcachedts": "Los siguientes datos provienen de la caché, y fueron actualizados por última vez a fecha de: $1. La caché contiene {{PLURAL:$4|un resultado|$4 resultados}} como máximo.",
"querypage-no-updates": "Actualmente las actualizaciones de esta página están desactivadas. Estos datos no serán actualizados a corto plazo.",
"movepagetalktext": "La page de discussion associée, si présente, sera automatiquement renommée '''sauf si :'''\n* vous déplacez la page vers un autre espace de noms, ou\n* une page de discussion non vide existe déjà sous le nouveau nom, ou\n* vous décochez la case ci-dessous.\n\nDans ces cas-là, vous devrez renommer ou fusionner cette page de discussion manuellement si vous le désirez.",
"movearticle": "Renommer la page :",
"moveuserpage-warning": "'''Attention :''' Vous êtes sur le point de renommer une page d’utilisateur. Veuillez noter que seule la page sera renommée et que l’utilisateur '''ne''' sera '''pas''' renommé.",
- "movecategorypage-warning": "<strong>Avertissement :</strong> Vous êtes sur le point de renommer une page de catégorie. Veuillez noter que seule la page sera renommée et que toutes les pages dans l'ancienne catégorie ne seront <em>pas</em> transférées dans la nouvelle.",
+ "movecategorypage-warning": "<strong>Avertissement :</strong> Vous êtes sur le point de renommer une page de catégorie. Veuillez noter que seule la catégorie sera renommée et <em>qu’aucune</em> des pages de l’ancienne catégorie ne sera transférée dans la nouvelle.",
"movenologintext": "Pour pouvoir renommer une page, vous devez être [[Special:UserLogin|identifié{{GENDER:||e}}]] avec un compte utilisateur enregistré et d'ancienneté suffisante.",
"movenotallowed": "Vous n'avez pas la permission de renommer les pages.",
"movenotallowedfile": "Vous n'avez pas la permission de renommer les fichiers.",
"right-sendemail": "다른 사용자에게 이메일 보내기",
"right-passwordreset": "비밀번호 재설정 이메일을 보기",
"right-managechangetags": "데이터베이스에서 [[Special:Tags|태그]]를 만들거나 지우기",
+ "right-applychangetags": "자신이 편집할 때 [[Special:Tags|태그]]를 적용하기",
+ "right-changetags": "문서의 특정 판과 특정 기록 항목에 임의의 [[Special:Tags|태그]]를 추가하거나 제거하기",
"newuserlogpage": "사용자 만들기 기록",
"newuserlogpagetext": "사용자가 만들어진 기록입니다.",
"rightslog": "사용자 권한 기록",
"action-editmyprivateinfo": "자신의 개인정보 편집",
"action-editcontentmodel": "문서의 콘텐츠 모델을 편집",
"action-managechangetags": "데이터베이스에서 태그를 만들거나 지울",
+ "action-applychangetags": "당신이 편집할 때 태그를 적용하기",
+ "action-changetags": "문서의 특정 판과 특정 기록 항목에 임의의 태그를 추가하거나 제거하기",
"nchanges": "$1개 {{PLURAL:$1|바뀜}}",
"enhancedrc-since-last-visit": "{{PLURAL:$1|마지막 방문 이후}} $1개",
"enhancedrc-history": "역사",
"createacct-error": "Error in ratione creanda",
"createaccounterror": "Rationem creare non potuit: $1",
"nocookiesnew": "Ratio usoris creata est, sed conventum non apertum est. {{SITENAME}} ''Cookies'' utitur in usorum conventa aperiendo. Cookies tua debiles sunt. Eis potestatem fac, tum conventum aperi cum nomine usoris tesseraque tua nova.",
- "nocookieslogin": "{{SITENAME}} ''Cookies'' utitur in usorum conventa aperiendo. Cookies tua debiles sunt. Eis potestatem fac, tum conare denuo.",
+ "nocookieslogin": "{{SITENAME}} ''Cookies'' in conventis collatorum aperiendis adhibentur. ''Cookies'' tua debilitata sunt. Eis potestatem fac, tum conare denuo.",
"noname": "Nomen usoris ratum non designavisti.",
"loginsuccesstitle": "Conventum prospere apertum est",
"loginsuccess": "'''Apud {{grammar:accusative|{{SITENAME}}}} agnosceris nomine \"$1\".'''",
"no-null-revision": "Nie można utworzyć zerowej wersji strony \"$1\"",
"badtitle": "Niepoprawny tytuł",
"badtitletext": "Podano niepoprawny tytuł strony. Prawdopodobnie jest pusty lub zawiera znaki, których użycie jest zabronione.",
+ "title-invalid-empty": "Żądany tytuł strony jest pusty lub zawiera tylko nazwę przestrzeni nazw.",
+ "title-invalid-utf8": "Żądany tytuł strony zawiera błędny ciąg znaków UTF-8.",
"title-invalid-interwiki": "Tytuł zawiera link interwiki",
+ "title-invalid-talk-namespace": "Żądany tytuł strony dotyczy strony dyskusji, która nie istnieje.",
+ "title-invalid-characters": "Żądany tytuł strony zawiera błędne znaki: \"$1\".",
+ "title-invalid-magic-tilde": "Żądany tytuł strony zawiera błędną, magiczną sekwencję tyld (<nowiki>~~~</nowiki>)",
"perfcached": "Poniższe dane są kopią z pamięci podręcznej i mogą być nieaktualne. W pamięci podręcznej {{PLURAL:$1|znajduje|znajdują|znajduje}} się maksymalnie {{PLURAL:$1|jeden wynik|$1 wyniki|$1 wyników}}.",
"perfcachedts": "Poniższe dane są kopią z pamięci podręcznej. Ostatnia aktualizacja odbyła się $1. W pamięci podręcznej {{PLURAL:$4|znajduje|znajdują|znajduje}} się maksymalnie {{PLURAL:$4|jeden wynik|$4 wyniki|$4 wyników}}.",
"querypage-no-updates": "Uaktualnienia dla tej strony są obecnie wyłączone. Znajdujące się tutaj dane nie zostaną odświeżone.",
"feb": "Fev.",
"mar": "Mar.",
"apr": "Abr.",
- "may": "Maio",
+ "may": "Mai.",
"jun": "Jun.",
"jul": "Jul.",
"aug": "Ago.",
"currentevents": "Notícias",
"currentevents-url": "Project:Notícias",
"disclaimers": "Exoneração de responsabilidade",
- "disclaimerpage": "Project:Aviso_geral",
+ "disclaimerpage": "Project:Aviso geral",
"edithelp": "Ajuda de edição",
"helppage-top-gethelp": "Ajuda",
"mainpage": "Página principal",
"portal": "Portal comunitário",
"portal-url": "Project:Portal comunitário",
"privacy": "Política de privacidade",
- "privacypage": "Project:Política_de_privacidade",
+ "privacypage": "Project:Política de privacidade",
"badaccess": "Erro de permissão",
"badaccess-group0": "Não está autorizado a executar a operação solicitada.",
"badaccess-groups": "A operação solicitada está limitada a utilizadores {{PLURAL:$2|do grupo|de um dos seguintes grupos}}: $1.",
"feedback-termsofuse": "Label with an agreement about the terms of use.",
"feedback-thanks": "Thanks message, appears if feedback was successful. Parameters:\n* $1 - \"Feedback\"\n* $2 - Feedback page URL",
"feedback-thanks-title": "The title of the thank you dialog at the end of the submission process.\n{{Identical|Thank you}}",
- "feedback-useragent": "A label denoting the user agent in the feedback that is posted to the feedback page.",
+ "feedback-useragent": "A label denoting the user agent in the feedback that is posted to the feedback page.\n{{Identical|User agent}}",
"searchsuggest-search": "Greyed out default text in the simple search box in the Vector skin. (It disappears and lets the user enter the requested search terms when the search box receives focus.)\n\n{{Identical|Search}}",
"searchsuggest-containing": "Label used in the special item of the search suggestions list which gives the user an option to perform a full text search for the term.",
"api-error-badaccess-groups": "API error message that can be used for client side localisation of API errors.",
"log-name-pagelang": "Журнал изменения языка",
"log-description-pagelang": "Это журнал изменений в языках страницы.",
"logentry-pagelang-pagelang": "$1 изменил{{GENDER:$2||а}} язык страницы для $3 с $4 на $5.",
- "default-skin-not-found": "Упс! Тема оформления по умолчанию для вашей вики <code>$wgDefaultSkin</code>, <code>$1</code> недоступна.\n\nВаша установка, похоже, содержит {{PLURAL:$4|следующую тему|следующие темы}} оформления. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить {{PLURAL:$4|её|их и выбрать тему по умолчанию}}.\n\n$2\n\n; Если вы только что установили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* Загрузив [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений. Вы можете скопировать папку <code>skins/</code> из него.\n:* Загрузив архивы отдельных тем оформления с [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Клонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code dir=\"ltr\">skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию, если вы MediaWiki-разработчик. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.\n; Если вы только что обновили MediaWiki:\n: MediaWiki версии 1.24 и новее больше не включает автоматически установленные темы (см. [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]).\nВы можете вставить {{PLURAL:$5|следующую строку|следующие строки}} в <code>LocalSettings.php</code>, чтобы включить {{PLURAL:$5|установленную в текущее время тему|все установленные в текущее время темы}} оформления: \n\n<pre dir=\"ltr\">$3</pre>\n\n\n; Если вы только что изменили <code>LocalSettings.php</code>:\n: Перепроверьте названия тем на наличие опечаток.",
- "default-skin-not-found-no-skins": "Упс! Тема оформления по умолчанию для вашей вики <code>$wgDefaultSkin</code>, <code>$1</code> недоступна.\n\nУ вас нет установленных тем оформления.\n\n; Если вы только что установили или обновили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. MediaWiki версии 1.24 и новее не содержат темы оформления в основном репозитории. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* Загрузив [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений. Вы можете скопировать папку <code>skins/</code> из него.\n:* Загрузив архивы отдельных тем оформления с [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* Клонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code dir=\"ltr\">skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию, если вы MediaWiki-разработчик. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.",
+ "default-skin-not-found": "Упс! Тема оформления по умолчанию для вашей вики <code>$wgDefaultSkin</code>, <code>$1</code> недоступна.\n\nВаша установка, похоже, содержит {{PLURAL:$4|следующую тему|следующие темы}} оформления. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] с информацией о том, как включить {{PLURAL:$4|её|их и выбрать тему по умолчанию}}.\n\n$2\n\n; Если вы только что установили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* скачав [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений; вы можете скопировать из него папку <code>skins/</code>;\n:* скачав архивы отдельных тем оформления с [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org];\n:* клонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code dir=\"ltr\">skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию Git, если вы разработчик MediaWiki. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] с информацией о том, как включить темы оформления и выбрать тему по умолчанию.\n; Если вы только что обновили MediaWiki:\n: MediaWiki версии 1.24 и новее больше не включает автоматически установленные темы (см. [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]).\nВы можете вставить {{PLURAL:$5|следующую строку|следующие строки}} в <code>LocalSettings.php</code>, чтобы включить {{PLURAL:$5|установленную в текущее время тему|все установленные в текущее время темы}} оформления: \n\n<pre dir=\"ltr\">$3</pre>\n\n; Если вы только что изменили <code>LocalSettings.php</code>:\n: Перепроверьте названия тем на наличие опечаток.",
+ "default-skin-not-found-no-skins": "Упс! Тема оформления по умолчанию для вашей вики <code>$wgDefaultSkin</code>, <code>$1</code> недоступна.\n\nУ вас нет установленных тем оформления.\n\n; Если вы только что установили или обновили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. MediaWiki версии 1.24 и новее не содержат темы оформления в основном репозитории. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* crfxfd [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений; вы можете скопировать папку <code>skins/</code> из него;\n:* скачав архивы отдельных тем оформления с [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org];\n:* rлонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code dir=\"ltr\">skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию Git, если вы разработчик MediaWiki. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] с информацией о том, как включить темы оформления и выбрать тему по умолчанию.",
"default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (включено)",
"default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''отключено''')",
"mediastatistics": "Медиа-статистика",
}
function provideFindLowerBound() {
- $self = $this;
- $indexValueCallback = function ( $size ) use ( $self ) {
- return function ( $val ) use ( $self, $size ) {
- $self->assertTrue( $val >= 0 );
- $self->assertTrue( $val < $size );
+ $that = $this;
+ $indexValueCallback = function ( $size ) use ( $that ) {
+ return function ( $val ) use ( $that, $size ) {
+ $that->assertTrue( $val >= 0 );
+ $that->assertTrue( $val < $size );
return $val;
};
};
$cKey2 = wfRandomString();
$wasSet = 0;
- $func = function() use ( &$wasSet, $value ) { ++$wasSet; return $value; };
+ $func = function( $old, &$ttl ) use ( &$wasSet, $value ) {
+ ++$wasSet;
+ $ttl = 20; // override with another value
+ return $value;
+ };
$wasSet = 0;
$v = $cache->getWithSetCallback( $key, $func, 30, array(), array( 'lockTSE' => 5 ) );
$this->assertEquals( $v, $value );
$this->assertEquals( 1, $wasSet, "Value regenerated" );
+ $curTTL = null;
+ $v = $cache->get( $key, $curTTL );
+ $this->assertLessThanOrEqual( 20, $curTTL, 'Current TTL between 19-20 (overriden)' );
+ $this->assertGreaterThanOrEqual( 19, $curTTL, 'Current TTL between 19-20 (overriden)' );
+
$wasSet = 0;
$v = $cache->getWithSetCallback( $key, $func, 30, array(), array( 'lockTSE' => 5 ) );
$this->assertEquals( $v, $value );
}
public static function provideRegisterHooks() {
+ // Format:
+ // Current $wgHooks
+ // Content in extension.json
+ // Expected value of $wgHooks
return array(
// No hooks
array(
'FooBaz' => array( 'FooBazCallback' ),
),
),
+ // Callbacks for FooBaz wrapped in an array
+ array(
+ array(),
+ array( 'Hooks' => array( 'FooBaz' => array( 'Callback1' ) ) ) + self::$default,
+ array(
+ 'FooBaz' => array( 'Callback1' ),
+ ),
+ ),
+ // Multiple callbacks for FooBaz hook
+ array(
+ array(),
+ array( 'Hooks' => array( 'FooBaz' => array( 'Callback1', 'Callback2' ) ) ) + self::$default,
+ array(
+ 'FooBaz' => array( 'Callback1', 'Callback2' ),
+ ),
+ ),
);
}
->getMock();
// php 5.3 compatibility!
- $self = $this;
+ $that = $this;
$dbSiteStore->expects( $this->any() )
->method( 'getSite' )
- ->will( $this->returnValue( $self->getTestSite() ) );
+ ->will( $this->returnValue( $that->getTestSite() ) );
$dbSiteStore->expects( $this->any() )
->method( 'getSites' )
- ->will( $this->returnCallback( function() use( $self ) {
+ ->will( $this->returnCallback( function() use ( $that ) {
$siteList = new SiteList();
- $siteList->setSite( $self->getTestSite() );
+ $siteList->setSite( $that->getTestSite() );
return $siteList;
} ) );
private function newSiteImporter( array $expectedSites, $errorCount ) {
$store = $this->getMock( 'SiteStore' );
- $self = $this;
+ $that = $this;
$store->expects( $this->once() )
->method( 'saveSites' )
- ->will( $this->returnCallback( function ( $sites ) use ( $expectedSites, $self ) {
- $self->assertSitesEqual( $expectedSites, $sites );
+ ->will( $this->returnCallback( function ( $sites ) use ( $expectedSites, $that ) {
+ $that->assertSitesEqual( $expectedSites, $sites );
} ) );
$store->expects( $this->any() )