mirror of
https://github.com/YunoHost-Apps/mediawiki_ynh.git
synced 2024-09-03 19:46:05 +02:00
[fix] PHP5 CLI dependency + sources in the git repo
This commit is contained in:
parent
feb297c93b
commit
b138f92d88
2785 changed files with 1443335 additions and 11 deletions
|
@ -17,6 +17,9 @@ db_pwd=$(dd if=/dev/urandom bs=1 count=200 2> /dev/null | tr -c -d '[A-Za-z0-9]'
|
|||
# Use 'mediawiki' as database name and user
|
||||
db_user=mediawiki
|
||||
|
||||
# Instal php5-cli dependency
|
||||
sudo apt-get install php5-cli -y
|
||||
|
||||
# Initialize database and store mysql password for upgrade
|
||||
sudo yunohost app initdb $db_user -p $db_pwd -s $(readlink -e ../conf/SQL/mysql.initial.sql)
|
||||
sudo yunohost app setting mediawiki mysqlpwd -v $db_pwd
|
||||
|
@ -24,19 +27,11 @@ sudo yunohost app setting mediawiki mysqlpwd -v $db_pwd
|
|||
# Copy files to the right place
|
||||
final_path=/var/www/mediawiki
|
||||
sudo mkdir -p $final_path
|
||||
sudo wget http://releases.wikimedia.org/mediawiki/1.22/mediawiki-1.22.6.tar.gz
|
||||
sudo tar xvzf mediawiki-*.tar.gz
|
||||
sudo mv mediawiki-*/* $final_path
|
||||
sudo rm -R mediawiki-*
|
||||
sudo cp ../sources/mediawiki/* $final_path
|
||||
sudo cp ../conf/LocalSettings.php $final_path/
|
||||
|
||||
# LDAP Extension
|
||||
sudo wget https://codeload.github.com/wikimedia/mediawiki-extensions-LdapAuthentication/legacy.tar.gz/REL1_22
|
||||
sudo tar -xzf REL1_22
|
||||
sudo mkdir $final_path/extensions/LdapAuthentication
|
||||
sudo mv wikimedia-mediawiki-extensions-LdapAuthentication*/* $final_path/extensions/LdapAuthentication/
|
||||
sudo rm -R wikimedia-mediawiki-extensions-LdapAuthentication*
|
||||
sudo rm REL1_22
|
||||
sudo cp -r ../sources/LdapAuthentication $final_path/extensions/
|
||||
|
||||
# Change variables in Mediawiki configuration
|
||||
sudo sed -i "s/ynh_wiki_name/$wiki_name/g" $final_path/LocalSettings.php
|
||||
|
@ -60,4 +55,4 @@ sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/mediawiki.conf
|
|||
|
||||
# Reload Nginx and regenerate SSOwat conf
|
||||
sudo service nginx reload
|
||||
sudo yunohost app ssowatconf
|
||||
sudo yunohost app ssowatconf
|
||||
|
|
4
sources/LdapAuthentication/.gitignore
vendored
Normal file
4
sources/LdapAuthentication/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.svn
|
||||
*~
|
||||
*.kate-swp
|
||||
.*.swp
|
5
sources/LdapAuthentication/.gitreview
Normal file
5
sources/LdapAuthentication/.gitreview
Normal file
|
@ -0,0 +1,5 @@
|
|||
[gerrit]
|
||||
host=gerrit.wikimedia.org
|
||||
port=29418
|
||||
project=mediawiki/extensions/LdapAuthentication.git
|
||||
defaultbranch=master
|
363
sources/LdapAuthentication/LdapAuthentication.i18n.php
Normal file
363
sources/LdapAuthentication/LdapAuthentication.i18n.php
Normal file
|
@ -0,0 +1,363 @@
|
|||
<?php
|
||||
/**
|
||||
* Internationalisation file for extension LdapAuthentication.
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
|
||||
/** English
|
||||
* @author Ryan Lane
|
||||
*/
|
||||
$messages['en'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP authentication plugin with support for multiple LDAP authentication methods',
|
||||
);
|
||||
|
||||
/** Message documentation (Message documentation)
|
||||
* @author Fryed-peach
|
||||
* @author Shirayuki
|
||||
*/
|
||||
$messages['qqq'] = array(
|
||||
'ldapauthentication-desc' => '{{desc|name=LDAP Authentication|url=http://www.mediawiki.org/wiki/Extension:LDAP_Authentication}}',
|
||||
);
|
||||
|
||||
/** Afrikaans (Afrikaans)
|
||||
* @author Naudefj
|
||||
*/
|
||||
$messages['af'] = array(
|
||||
'ldapauthentication-desc' => 'Uitbreiding vir LDAP-outentisiteit wat die meeste LDAP-outentisiteitsmetodes ondersteun',
|
||||
);
|
||||
|
||||
/** Gheg Albanian (Gegë)
|
||||
* @author Mdupont
|
||||
*/
|
||||
$messages['aln'] = array(
|
||||
'ldapauthentication-desc' => 'plugin LDAP vertetimi me mbështetje për metoda të shumta tek LDAP',
|
||||
);
|
||||
|
||||
/** Arabic (العربية)
|
||||
* @author Meno25
|
||||
*/
|
||||
$messages['ar'] = array(
|
||||
'ldapauthentication-desc' => 'إضافة تحقيق LDAP بدعم لوسائل تحقيق LDAP متعددة',
|
||||
);
|
||||
|
||||
/** Asturian (asturianu)
|
||||
* @author Xuacu
|
||||
*/
|
||||
$messages['ast'] = array(
|
||||
'ldapauthentication-desc' => "Complemento p'autenticación LDAP con sofitu pa dellos métodos d'autenticación LDAP",
|
||||
);
|
||||
|
||||
/** Belarusian (Taraškievica orthography) (беларуская (тарашкевіца))
|
||||
* @author EugeneZelenko
|
||||
*/
|
||||
$messages['be-tarask'] = array(
|
||||
'ldapauthentication-desc' => 'Дапаўненьне LDAP-аўтэнтыфікацыі з падтрымкай некалькіх мэтадаў аўтэнтыфікацыі LDAP',
|
||||
);
|
||||
|
||||
/** Breton (brezhoneg)
|
||||
* @author Fulup
|
||||
*/
|
||||
$messages['br'] = array(
|
||||
'ldapauthentication-desc' => 'Adveziant gwiriekaat LDAP ennañ meur a hentenn wiriekaat LDAP',
|
||||
);
|
||||
|
||||
/** Bosnian (bosanski)
|
||||
* @author CERminator
|
||||
*/
|
||||
$messages['bs'] = array(
|
||||
'ldapauthentication-desc' => 'Proširenje LDAP autentifikacije sa podrškom za mnoge metode LDAP autentifikacije',
|
||||
);
|
||||
|
||||
/** Catalan (català)
|
||||
* @author Paucabot
|
||||
*/
|
||||
$messages['ca'] = array(
|
||||
'ldapauthentication-desc' => "Connector d'autentificació LDAP amb suport per a diversos mètodes d'autenticació LDAP",
|
||||
);
|
||||
|
||||
/** Czech (česky)
|
||||
* @author Mormegil
|
||||
*/
|
||||
$messages['cs'] = array(
|
||||
'ldapauthentication-desc' => 'Autentizační modul pro LDAP podporující několik autentizačních metod LDAP',
|
||||
);
|
||||
|
||||
/** German (Deutsch)
|
||||
* @author Imre
|
||||
* @author Kghbln
|
||||
*/
|
||||
$messages['de'] = array(
|
||||
'ldapauthentication-desc' => 'Ermöglicht die LDAP-Authentifizierung mit Hilfe mehrerer Authentifizierungsmethoden',
|
||||
);
|
||||
|
||||
/** Lower Sorbian (dolnoserbski)
|
||||
* @author Michawiki
|
||||
*/
|
||||
$messages['dsb'] = array(
|
||||
'ldapauthentication-desc' => 'Tykac awtentifikacije LDAP z pódpěru za někotare metody LDAP-awtentifikacije',
|
||||
);
|
||||
|
||||
/** Esperanto (Esperanto)
|
||||
* @author Blahma
|
||||
*/
|
||||
$messages['eo'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP-aŭtentiga kromprogramo kun subteno de pluraj LDAP-aŭtentigaj metodoj',
|
||||
);
|
||||
|
||||
/** Spanish (español)
|
||||
* @author Translationista
|
||||
*/
|
||||
$messages['es'] = array(
|
||||
'ldapauthentication-desc' => 'Complemento de autentificación LDAP con apoyo de múltiples métodos de autentificación LDAP',
|
||||
);
|
||||
|
||||
/** Finnish (suomi)
|
||||
* @author Centerlink
|
||||
*/
|
||||
$messages['fi'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP-todentamisliitännäinen useiden LDAP-todennustapojen tuella',
|
||||
);
|
||||
|
||||
/** French (français)
|
||||
* @author IAlex
|
||||
* @author Urhixidur
|
||||
*/
|
||||
$messages['fr'] = array(
|
||||
'ldapauthentication-desc' => 'Extension d’authentification LDAP prenant en charge de multiples méthodes d’authentification LDAP',
|
||||
);
|
||||
|
||||
/** Galician (galego)
|
||||
* @author Toliño
|
||||
*/
|
||||
$messages['gl'] = array(
|
||||
'ldapauthentication-desc' => 'Complemento de autenticación LDAP con soporte para varios métodos de autenticación LDAP',
|
||||
);
|
||||
|
||||
/** Swiss German (Alemannisch)
|
||||
* @author Als-Holder
|
||||
*/
|
||||
$messages['gsw'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP-Authentifizierigs-Plugin mit Unterstitzig fir multipli LDAP-Authentifizierigs-Merthode',
|
||||
);
|
||||
|
||||
/** Hebrew (עברית)
|
||||
* @author YaronSh
|
||||
*/
|
||||
$messages['he'] = array(
|
||||
'ldapauthentication-desc' => 'תוסף אימות LDAP עם תמיכה במספר שיטות LDAP לאימות',
|
||||
);
|
||||
|
||||
/** Upper Sorbian (hornjoserbsce)
|
||||
* @author Michawiki
|
||||
*/
|
||||
$messages['hsb'] = array(
|
||||
'ldapauthentication-desc' => 'Tykač awtentifikacije LDAP z podpěru za wjacore metody LDAP-awtentifikacije',
|
||||
);
|
||||
|
||||
/** Hungarian (magyar)
|
||||
* @author Glanthor Reviol
|
||||
*/
|
||||
$messages['hu'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP hitelesítési bővítmény többféle LDAP azonosítási módszer támogatásával',
|
||||
);
|
||||
|
||||
/** Interlingua (interlingua)
|
||||
* @author McDutchie
|
||||
*/
|
||||
$messages['ia'] = array(
|
||||
'ldapauthentication-desc' => 'Plugin pro authentication LDAP con supporto pro multiple methodos de authentication LDAP',
|
||||
);
|
||||
|
||||
/** Indonesian (Bahasa Indonesia)
|
||||
* @author IvanLanin
|
||||
*/
|
||||
$messages['id'] = array(
|
||||
'ldapauthentication-desc' => 'Pengaya otentikasi LDAP dengan dukungan untuk berbagai metode otentikasi LDAP',
|
||||
);
|
||||
|
||||
/** Italian (italiano)
|
||||
* @author HalphaZ
|
||||
*/
|
||||
$messages['it'] = array(
|
||||
'ldapauthentication-desc' => 'Plugin di autenticazione LDAP con supporto a diversi metodi di autenticazione LDAP',
|
||||
);
|
||||
|
||||
/** Japanese (日本語)
|
||||
* @author Aotake
|
||||
* @author Shirayuki
|
||||
*/
|
||||
$messages['ja'] = array(
|
||||
'ldapauthentication-desc' => '複数の LDAP 認証方式対応の LDAP 認証プラグイン',
|
||||
);
|
||||
|
||||
/** Korean (한국어)
|
||||
* @author 아라
|
||||
*/
|
||||
$messages['ko'] = array(
|
||||
'ldapauthentication-desc' => '여러 LDAP 인증 방법에 대해 지원하는 LDAP 인증 플러그인',
|
||||
);
|
||||
|
||||
/** Colognian (Ripoarisch)
|
||||
* @author Purodha
|
||||
*/
|
||||
$messages['ksh'] = array(
|
||||
'ldapauthentication-desc' => 'Dat Zohsatzprojramm för et Enlogge övver <i lang="en">LDAP</i> löht ungerscheidlijje Mettoohde zoh, för et Prööfe, wä wä es.',
|
||||
);
|
||||
|
||||
/** Luxembourgish (Lëtzebuergesch)
|
||||
* @author Robby
|
||||
*/
|
||||
$messages['lb'] = array(
|
||||
'ldapauthentication-desc' => 'Authentifikatiouns-Plugin fir LDAP mat Ënnerstëtzung fir multipel LDAP Authentifikatiouns-Methoden',
|
||||
);
|
||||
|
||||
/** Macedonian (македонски)
|
||||
* @author Bjankuloski06
|
||||
*/
|
||||
$messages['mk'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP приклучок за потврдување со поддршка за повеќе методи на LDAP потврдување',
|
||||
);
|
||||
|
||||
/** Malay (Bahasa Melayu)
|
||||
* @author Anakmalaysia
|
||||
*/
|
||||
$messages['ms'] = array(
|
||||
'ldapauthentication-desc' => 'Pemalam pengesahan LDAP dengan sokongan untuk berbilang kaedah pengesahan LDAP',
|
||||
);
|
||||
|
||||
/** Norwegian Bokmål (norsk bokmål)
|
||||
* @author Nghtwlkr
|
||||
*/
|
||||
$messages['nb'] = array(
|
||||
'ldapauthentication-desc' => 'Programutvidelse for LDAP-autentisering med støtte for flere LDAP-autentiseringsmetoder',
|
||||
);
|
||||
|
||||
/** Dutch (Nederlands)
|
||||
* @author Siebrand
|
||||
*/
|
||||
$messages['nl'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP-authenticatieplug-in met ondersteuning voor meerdere LDAP-authenticatiemethoden',
|
||||
);
|
||||
|
||||
/** Occitan (occitan)
|
||||
* @author Cedric31
|
||||
*/
|
||||
$messages['oc'] = array(
|
||||
'ldapauthentication-desc' => "Plugin d'autentificacion LDAP amb supòrt de metòdes d'autentificacion LDAP multiples",
|
||||
);
|
||||
|
||||
/** Polish (polski)
|
||||
* @author Sp5uhe
|
||||
*/
|
||||
$messages['pl'] = array(
|
||||
'ldapauthentication-desc' => 'Wtyczka autoryzacji użytkowników z użyciem LDAP ze wsparciem dla wielu metod autoryzacji',
|
||||
);
|
||||
|
||||
/** Piedmontese (Piemontèis)
|
||||
* @author Borichèt
|
||||
* @author Dragonòt
|
||||
*/
|
||||
$messages['pms'] = array(
|
||||
'ldapauthentication-desc' => "Plugin për l'autenticassion LDAP con apògg për vàire manere d'autenticassion LDAP",
|
||||
);
|
||||
|
||||
/** Portuguese (português)
|
||||
* @author Hamilton Abreu
|
||||
*/
|
||||
$messages['pt'] = array(
|
||||
'ldapauthentication-desc' => "''Plugin'' de autenticação LDAP, com suporte para vários métodos de autenticação",
|
||||
);
|
||||
|
||||
/** Brazilian Portuguese (português do Brasil)
|
||||
* @author Giro720
|
||||
*/
|
||||
$messages['pt-br'] = array(
|
||||
'ldapauthentication-desc' => "''Plugin'' de autenticação LDAP, com suporte para vários métodos de autenticação",
|
||||
);
|
||||
|
||||
/** tarandíne (tarandíne)
|
||||
* @author Joetaras
|
||||
*/
|
||||
$messages['roa-tara'] = array(
|
||||
'ldapauthentication-desc' => "plugin de autendicazione LDAP cu 'u supporte pe autendicaziune multeple de metode LDAP",
|
||||
);
|
||||
|
||||
/** Russian (русский)
|
||||
* @author Александр Сигачёв
|
||||
*/
|
||||
$messages['ru'] = array(
|
||||
'ldapauthentication-desc' => 'Плагин LDAP-аутентификации с поддержкой нескольких методов проверки подлинности LDAP',
|
||||
);
|
||||
|
||||
/** Slovak (slovenčina)
|
||||
* @author Helix84
|
||||
*/
|
||||
$messages['sk'] = array(
|
||||
'ldapauthentication-desc' => 'Zásuvný modul na autentifikáciu prostredníctvom LDAP s podporou viacerých metód LDAP',
|
||||
);
|
||||
|
||||
/** Serbian (Cyrillic script) (српски (ћирилица))
|
||||
* @author Михајло Анђелковић
|
||||
*/
|
||||
$messages['sr-ec'] = array(
|
||||
'ldapauthentication-desc' => 'Плагин за LDAP ауторизацију, са подршком за више метода LDAP ауторизације',
|
||||
);
|
||||
|
||||
/** Serbian (Latin script) (srpski (latinica))
|
||||
*/
|
||||
$messages['sr-el'] = array(
|
||||
'ldapauthentication-desc' => 'Plagin za LDAP autorizaciju, sa podrškom za više metoda LDAP autorizacije',
|
||||
);
|
||||
|
||||
/** Swedish (svenska)
|
||||
* @author Boivie
|
||||
*/
|
||||
$messages['sv'] = array(
|
||||
'ldapauthentication-desc' => 'LDAP-autentiseringsplugin med stöd för flera LDAP-autentiseringsmetoder',
|
||||
);
|
||||
|
||||
/** Tagalog (Tagalog)
|
||||
* @author AnakngAraw
|
||||
*/
|
||||
$messages['tl'] = array(
|
||||
'ldapauthentication-desc' => 'Pampasak na pangpagpapatotoo ng LDAP na may suporta para sa maramihang mga pamamaraan ng pagpapatotoo ng LDAP',
|
||||
);
|
||||
|
||||
/** Turkish (Türkçe)
|
||||
* @author Vito Genovese
|
||||
*/
|
||||
$messages['tr'] = array(
|
||||
'ldapauthentication-desc' => 'Birden çok LDAP kimlik doğrulama yöntemini destekleyen LDAP kimlik doğrulama eklentisi',
|
||||
);
|
||||
|
||||
/** Ukrainian (українська)
|
||||
* @author Ytsukeng Fyvaprol
|
||||
*/
|
||||
$messages['uk'] = array(
|
||||
'ldapauthentication-desc' => 'Плагін LDAP-аутентифікації з підтримкою декількох методів перевірки автентичності LDAP',
|
||||
);
|
||||
|
||||
/** Vietnamese (Tiếng Việt)
|
||||
* @author Minh Nguyen
|
||||
*/
|
||||
$messages['vi'] = array(
|
||||
'ldapauthentication-desc' => 'Phần bổ trợ xác thực LDAP hỗ trợ nhiều phương pháp xác thực LDAP',
|
||||
);
|
||||
|
||||
/** Simplified Chinese (中文(简体))
|
||||
* @author Yanmiao liu
|
||||
*/
|
||||
$messages['zh-hans'] = array(
|
||||
'ldapauthentication-desc' => '具有多种LDAP认证方法支持的LDAP认证插件',
|
||||
);
|
||||
|
||||
/** Traditional Chinese (中文(繁體))
|
||||
* @author Anakmalaysia
|
||||
*/
|
||||
$messages['zh-hant'] = array(
|
||||
'ldapauthentication-desc' => '具有多種LDAP認證方法支持的LDAP認證外掛程式',
|
||||
);
|
2104
sources/LdapAuthentication/LdapAuthentication.php
Normal file
2104
sources/LdapAuthentication/LdapAuthentication.php
Normal file
File diff suppressed because it is too large
Load diff
124
sources/LdapAuthentication/LdapAutoAuthentication.php
Normal file
124
sources/LdapAuthentication/LdapAutoAuthentication.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
class LdapAutoAuthentication {
|
||||
|
||||
/**
|
||||
* Does the web server authentication piece of the LDAP plugin.
|
||||
*
|
||||
* @param $user User
|
||||
* @param $result bool
|
||||
* @return bool
|
||||
*/
|
||||
public static function Authenticate( $user, &$result = null ) {
|
||||
/**
|
||||
* @var $wgAuth LdapAuthenticationPlugin
|
||||
*/
|
||||
global $wgAuth;
|
||||
|
||||
$wgAuth->printDebug( "Entering AutoAuthentication.", NONSENSITIVE );
|
||||
|
||||
if ( $user->isLoggedIn() ) {
|
||||
$wgAuth->printDebug( "User is already logged in.", NONSENSITIVE );
|
||||
return true;
|
||||
}
|
||||
|
||||
$wgAuth->printDebug( "User isn't logged in, calling setup.", NONSENSITIVE );
|
||||
|
||||
// Let regular authentication plugins configure themselves for auto
|
||||
// authentication chaining
|
||||
$wgAuth->autoAuthSetup();
|
||||
|
||||
$autoauthname = $wgAuth->getConf( 'AutoAuthUsername' );
|
||||
$wgAuth->printDebug( "Calling authenticate with username ($autoauthname).", NONSENSITIVE );
|
||||
|
||||
// The user hasn't already been authenticated, let's check them
|
||||
$authenticated = $wgAuth->authenticate( $autoauthname, '' );
|
||||
if ( !$authenticated ) {
|
||||
// If the user doesn't exist in LDAP, there isn't much reason to
|
||||
// go any further.
|
||||
$wgAuth->printDebug( "User wasn't found in LDAP, exiting.", NONSENSITIVE );
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need the username that MediaWiki will always use, not necessarily the one we
|
||||
// get from LDAP.
|
||||
$mungedUsername = $wgAuth->getCanonicalName( $autoauthname );
|
||||
|
||||
$wgAuth->printDebug( "User exists in LDAP; finding the user by name ($mungedUsername) in MediaWiki.", NONSENSITIVE );
|
||||
$localId = User::idFromName( $mungedUsername );
|
||||
$wgAuth->printDebug( "Got id ($localId).", NONSENSITIVE );
|
||||
|
||||
// Is the user already in the database?
|
||||
if ( !$localId ) {
|
||||
$userAdded = self::attemptAddUser( $user, $mungedUsername );
|
||||
if ( !$userAdded ) {
|
||||
$result = false;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$wgAuth->printDebug( "User exists in local database, logging in.", NONSENSITIVE );
|
||||
$user->setID( $localId );
|
||||
$user->loadFromId();
|
||||
$user->setCookies();
|
||||
$wgAuth->updateUser( $user );
|
||||
wfSetupSession();
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user User
|
||||
* @param $mungedUsername String
|
||||
* @return bool
|
||||
*/
|
||||
public static function attemptAddUser( $user, $mungedUsername ) {
|
||||
/**
|
||||
* @var $wgAuth LdapAuthenticationPlugin
|
||||
*/
|
||||
global $wgAuth;
|
||||
|
||||
if ( !$wgAuth->autoCreate() ) {
|
||||
$wgAuth->printDebug( "Cannot automatically create accounts.", NONSENSITIVE );
|
||||
return false;
|
||||
}
|
||||
|
||||
$wgAuth->printDebug( "User does not exist in local database; creating.", NONSENSITIVE );
|
||||
// Checks passed, create the user
|
||||
$user->loadDefaults( $mungedUsername );
|
||||
$status = $user->addToDatabase();
|
||||
if ( $status !== null && !$status->isOK() ) {
|
||||
$wgAuth->printDebug( "Creation failed: " . $status->getWikiText(), NONSENSITIVE );
|
||||
return false;
|
||||
}
|
||||
$wgAuth->initUser( $user, true );
|
||||
$user->setCookies();
|
||||
wfSetupSession();
|
||||
# Update user count
|
||||
$ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
|
||||
$ssUpdate->doUpdate();
|
||||
# Notify hooks (e.g. Newuserlog)
|
||||
wfRunHooks( 'AuthPluginAutoCreate', array( $user ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* No logout link in MW
|
||||
* @param $personal_urls array
|
||||
* @param $title Title
|
||||
* @return bool
|
||||
*/
|
||||
public static function NoLogout( &$personal_urls, $title ) {
|
||||
/**
|
||||
* @var $wgAuth LdapAuthenticationPlugin
|
||||
*/
|
||||
global $wgAuth;
|
||||
|
||||
$wgAuth->printDebug( "Entering NoLogout.", NONSENSITIVE );
|
||||
unset( $personal_urls['logout'] );
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
1
sources/LdapAuthentication/README
Normal file
1
sources/LdapAuthentication/README
Normal file
|
@ -0,0 +1 @@
|
|||
This authentication plugin allows MediaWiki to use an LDAP store as its user database for authentication, and some authorization. Full functionality and configuration information can be found at: http://www.mediawiki.org/wiki/Extension:LDAP_Authentication
|
13
sources/LdapAuthentication/schema/ldap-mysql.sql
Normal file
13
sources/LdapAuthentication/schema/ldap-mysql.sql
Normal file
|
@ -0,0 +1,13 @@
|
|||
CREATE TABLE /*_*/ldap_domains (
|
||||
-- IF for domain
|
||||
domain_id int not null primary key auto_increment,
|
||||
|
||||
-- domain itself
|
||||
domain varchar(255) binary not null,
|
||||
|
||||
-- User to which this domain belongs
|
||||
user_id int not null
|
||||
|
||||
) /*$wgDBTableOptions*/;
|
||||
|
||||
CREATE INDEX /*i*/user_id on /*_*/ldap_domains (user_id);
|
13
sources/LdapAuthentication/schema/ldap-postgres.sql
Normal file
13
sources/LdapAuthentication/schema/ldap-postgres.sql
Normal file
|
@ -0,0 +1,13 @@
|
|||
CREATE TABLE ldap_domains (
|
||||
-- IF for domain
|
||||
domain_id serial PRIMARY KEY,
|
||||
|
||||
-- domain itself
|
||||
domain varchar(255) not null,
|
||||
|
||||
-- User to which this domain belongs
|
||||
user_id integer not null
|
||||
|
||||
) /*$wgDBTableOptions*/;
|
||||
|
||||
CREATE INDEX user_id on ldap_domains (user_id);
|
380
sources/mediawiki/COPYING
Normal file
380
sources/mediawiki/COPYING
Normal file
|
@ -0,0 +1,380 @@
|
|||
== License and copyright information ==
|
||||
|
||||
=== License ===
|
||||
|
||||
MediaWiki is licensed under the terms of the GNU General Public License,
|
||||
version 2 or later. Derivative works and later versions of the code must be
|
||||
free software licensed under the same or a compatible license. This includes
|
||||
"extensions" that use MediaWiki functions or variables; see
|
||||
http://www.gnu.org/licenses/gpl-faq.html#GPLAndPlugins for details.
|
||||
|
||||
For the full text of version 2 of the license, see
|
||||
https://www.gnu.org/licenses/gpl-2.0.html or '''GNU General Public License'''
|
||||
below.
|
||||
|
||||
=== Copyright owners ===
|
||||
|
||||
MediaWiki contributors, including those listed in the CREDITS file, hold the
|
||||
copyright to this work.
|
||||
|
||||
=== Additional license information ===
|
||||
|
||||
Some components of MediaWiki imported from other projects may be under other
|
||||
Free and Open Source, or Free Culture, licenses. Specific details of their
|
||||
licensing information can be found in those components.
|
||||
|
||||
Sections of code written exclusively by Lee Crocker or Erik Moeller are also
|
||||
released into the public domain, which does not impair the obligations of users
|
||||
under the GPL for use of the whole code or other sections thereof.
|
||||
|
||||
MediaWiki uses the following Creative Commons icons to illustrate links to the
|
||||
CC licenses:
|
||||
|
||||
* skins/common/images/cc-by-nc-sa.png
|
||||
* skins/common/images/cc-by-sa.png
|
||||
|
||||
These icons are trademarked, and used subject to the CC trademark license,
|
||||
available at http://creativecommons.org/policies#trademark
|
||||
|
||||
== GNU GENERAL PUBLIC LICENSE ==
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
=== Preamble ===
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
== TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ==
|
||||
|
||||
'''0.''' This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
'''1.''' You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
'''2.''' You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
'''a)''' You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
'''b)''' You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
'''c)''' If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
'''3.''' You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
'''a)''' Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
'''b)''' Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
'''c)''' Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
'''4.''' You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
'''5.''' You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
'''6.''' Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
'''7.''' If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
'''8.''' If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
'''9.''' The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
'''10.''' If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
=== NO WARRANTY ===
|
||||
|
||||
'''11.''' BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
'''12.''' IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
'''END OF TERMS AND CONDITIONS'''
|
||||
|
||||
== How to Apply These Terms to Your New Programs ==
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
242
sources/mediawiki/CREDITS
Normal file
242
sources/mediawiki/CREDITS
Normal file
|
@ -0,0 +1,242 @@
|
|||
MediaWiki 1.22 is a collaborative project released under the
|
||||
GNU General Public License v2. We would like to recognize the
|
||||
following names for their contribution to the product.
|
||||
|
||||
<!-- Please notice that the following can be found parsed under Special:Version/Credits -->
|
||||
== Developers ==
|
||||
* Aaron Schulz
|
||||
* Alex Z.
|
||||
* Alexander Monk
|
||||
* Alexandre Emsenhuber
|
||||
* Andrew Garrett
|
||||
* Arthur Richards
|
||||
* Aryeh Gregor
|
||||
* Antoine Musso
|
||||
* Brian Wolff
|
||||
* Bertrand Grondin
|
||||
* Brad Jorsch
|
||||
* Brion Vibber
|
||||
* Bryan Tong Minh
|
||||
* Chad Horohoe
|
||||
* Charles Melbye
|
||||
* church of emacs
|
||||
* Daniel Friesen
|
||||
* Daniel Kinzler
|
||||
* Daniel Renfro
|
||||
* Danny B.
|
||||
* David McCabe
|
||||
* Derk-Jan Hartman
|
||||
* Domas Mituzas
|
||||
* Emufarmers
|
||||
* Fran Rogers
|
||||
* Greg Sabino Mullane
|
||||
* Guy Van den Broeck
|
||||
* Happy-melon
|
||||
* Hojjat
|
||||
* Ian Baker
|
||||
* Ilmari Karonen
|
||||
* Jack D. Pond
|
||||
* Jack Phoenix
|
||||
* Jan Paul Posma
|
||||
* Jason Richey
|
||||
* Jeroen De Dauw
|
||||
* John Du Hart
|
||||
* Jon Harald Søby
|
||||
* Juliano F. Ravasi
|
||||
* Ryan Kaldari
|
||||
* Leo Koppelkamm
|
||||
* Leon Weber
|
||||
* Leslie Hoare
|
||||
* Marco Schuster
|
||||
* Marius Hoch
|
||||
* Matěj Grabovský
|
||||
* Matt Johnston
|
||||
* Max Semenik
|
||||
* Meno25
|
||||
* MinuteElectron
|
||||
* Mohamed Magdy
|
||||
* Nathaniel Herman
|
||||
* Neil Kandalgaonkar
|
||||
* Nicolas Dumazet
|
||||
* Niklas Laxström
|
||||
* Ori Livneh
|
||||
* Patrick Reilly
|
||||
* Philip Tzou
|
||||
* Platonides
|
||||
* Purodha Blissenbach
|
||||
* Raimond Spekking
|
||||
* Remember the dot
|
||||
* Roan Kattouw
|
||||
* Robert Stojnić
|
||||
* Robin Pepermans
|
||||
* Rotem Liss
|
||||
* Ryan Lane
|
||||
* Ryan Schmidt
|
||||
* Sam Reed
|
||||
* Shinjiman
|
||||
* Siebrand Mazeland
|
||||
* SQL
|
||||
* Soxred93
|
||||
* Szymon Świerkosz
|
||||
* Thomas Bleher
|
||||
* Tim Starling
|
||||
* Timo Tijhof
|
||||
* Thomas Gries
|
||||
* Trevor Parscal
|
||||
* Victor Vasiliev
|
||||
* Yesid Carrillo
|
||||
* Yuri Astrakhan
|
||||
|
||||
== Patch Contributors ==
|
||||
* Aaron Pramana
|
||||
* Aaron Ball
|
||||
* Agbad
|
||||
* Ahmad Sherif
|
||||
* Alejandro Mery
|
||||
* Amalthea
|
||||
* Amir E. Aharoni
|
||||
* Andrew Dunbar
|
||||
* Antonio Ospite
|
||||
* Asier Lostalé
|
||||
* Azliq7
|
||||
* Bagariavivek
|
||||
* Bartosz Dziewoński
|
||||
* Beau
|
||||
* Benny Situ
|
||||
* Bergi
|
||||
* Borislav Manolov
|
||||
* Brad Jorsch
|
||||
* Brent G
|
||||
* Brianna Laugher
|
||||
* Carlin
|
||||
* Carsten Nielsen
|
||||
* Chris Steipp
|
||||
* Christian Neubauer
|
||||
* Christian Aistleitner
|
||||
* Conrad Irwin
|
||||
* cryptocoryne
|
||||
* Dan Barrett
|
||||
* Dan Collins
|
||||
* Dan Nessett
|
||||
* Daniel Arnold
|
||||
* Daniel Werner
|
||||
* David Baumgarten
|
||||
* Denny Vrandecic
|
||||
* Dévai Tamás
|
||||
* Ebrahim Byagowi
|
||||
* Edward Z. Yang
|
||||
* Elvis Stansvik
|
||||
* Erwin Dokter
|
||||
* Federico Leva
|
||||
* FunPika
|
||||
* fomafix
|
||||
* Gabriel Wicke
|
||||
* Gero Scholz
|
||||
* Gilles van den Hoven
|
||||
* Grunny
|
||||
* Harry Burt
|
||||
* Ireas
|
||||
* Jacob Block
|
||||
* Jan Gerber
|
||||
* Jan Luca Naumann
|
||||
* Jaska Zedlik
|
||||
* Jeremy Baron
|
||||
* Jidanni
|
||||
* Jimmy Xu
|
||||
* Jonathan Wiltshire
|
||||
* John N
|
||||
* JuneHyeon Bae
|
||||
* Jure Kajzer
|
||||
* Karun Dambiec
|
||||
* Katie Filbert
|
||||
* Kevin Israel
|
||||
* Kim Hyun-Joon
|
||||
* Lee Worden
|
||||
* Lejonel
|
||||
* liangent
|
||||
* Louperivois
|
||||
* Lucas Garczewski
|
||||
* Luigi Corsaro
|
||||
* Lupo
|
||||
* Madman
|
||||
* Manuel Menal
|
||||
* Marcin Cieślak
|
||||
* Marcus Buck
|
||||
* Marc-André Pelletier
|
||||
* Mark Hershberger
|
||||
* Mark Holmquist
|
||||
* Marooned
|
||||
* Mathias Ertl
|
||||
* Matthias Mullie
|
||||
* Matthew Britton
|
||||
* mati
|
||||
* Max
|
||||
* Max Sikström
|
||||
* merl
|
||||
* Michael Dale
|
||||
* Michael De La Rue
|
||||
* Michael M.
|
||||
* Michael Newton
|
||||
* Michael Walsh
|
||||
* Mike Horvath
|
||||
* Mormegil
|
||||
* moejoe0000
|
||||
* MrBlueSky
|
||||
* MrPete
|
||||
* MZMcBride
|
||||
* mybugs.mail
|
||||
* Nakon
|
||||
* Nathan Larson
|
||||
* nephele
|
||||
* Nik
|
||||
* Nx.devnull
|
||||
* Nikola Kovacs
|
||||
* Nikolaos S. Karastathis
|
||||
* Nischay Nahata
|
||||
* Olaf Lenz
|
||||
* Olivier Finlay Beaton
|
||||
* Patricio Molina
|
||||
* Paul Copperman
|
||||
* Paul Oranje
|
||||
* Peter Gehres
|
||||
* Petr Onderka
|
||||
* PieRRoMaN
|
||||
* quietust
|
||||
* René Kijewski
|
||||
* rgcjonas
|
||||
* Rob Moen
|
||||
* Robert Treat
|
||||
* RockMFR
|
||||
* Russell Blau
|
||||
* Rusty Burchfield
|
||||
* S Page
|
||||
* Salvatore Ingala
|
||||
* Santhosh Thottingal
|
||||
* Scott Colcord
|
||||
* se4598
|
||||
* Sébastien Santoro
|
||||
* Simon Walker
|
||||
* Solitarius
|
||||
* Søren Løvborg
|
||||
* Srikanth Lakshmanan
|
||||
* Stefano Codari
|
||||
* Str4nd
|
||||
* Subramanya Sastry
|
||||
* svip
|
||||
* The Evil IP address
|
||||
* Tim Landscheidt
|
||||
* Tisane
|
||||
* Tyler Anthony Romeo
|
||||
* Umherirrender
|
||||
* Van de Bugger
|
||||
* Ville Stadista
|
||||
* Vitaliy Filippov
|
||||
* Waldir Pimenta
|
||||
* William Demchick
|
||||
* Yusuke Matsubara
|
||||
* Yuvaraj Pandian T
|
||||
* Zachary Hauri
|
||||
|
||||
== Translators ==
|
||||
|
||||
* [https://translatewiki.net/wiki/Translating:MediaWiki/Credits Translators on translatewiki.net and others]
|
2
sources/mediawiki/FAQ
Normal file
2
sources/mediawiki/FAQ
Normal file
|
@ -0,0 +1,2 @@
|
|||
The MediaWiki FAQ can be found at:
|
||||
http://www.mediawiki.org/wiki/Manual:FAQ
|
10914
sources/mediawiki/HISTORY
Normal file
10914
sources/mediawiki/HISTORY
Normal file
File diff suppressed because it is too large
Load diff
89
sources/mediawiki/INSTALL
Normal file
89
sources/mediawiki/INSTALL
Normal file
|
@ -0,0 +1,89 @@
|
|||
---
|
||||
Installing MediaWiki
|
||||
---
|
||||
|
||||
Starting with MediaWiki 1.2.0, it's possible to install and configure the wiki
|
||||
"in-place", as long as you have the necessary prerequisites available.
|
||||
|
||||
Required software:
|
||||
* Web server with PHP 5.3.2 or higher.
|
||||
* A SQL server, the following types are supported
|
||||
** MySQL 5.0.2 or higher
|
||||
** PostgreSQL 8.3 or higher
|
||||
** SQLite 3.3.7 or higher
|
||||
** Oracle 9.0.1 or higher
|
||||
|
||||
MediaWiki is developed and tested mainly on Unix/Linux platforms, but should
|
||||
work on Windows as well.
|
||||
|
||||
If your PHP is configured as a CGI plug-in rather than an Apache module you may
|
||||
experience problems, as this configuration is not well tested. safe_mode is also
|
||||
not tested and unlikely to work.
|
||||
|
||||
Support for rendering mathematical formulas requires installing the Math extension,
|
||||
see http://www.mediawiki.org/wiki/Extension:Math
|
||||
|
||||
Don't forget to check the RELEASE-NOTES file...
|
||||
|
||||
|
||||
Additional documentation is available online, which may include more detailed
|
||||
notes on particular operating systems and workarounds for difficult hosting
|
||||
environments:
|
||||
|
||||
http://www.mediawiki.org/wiki/Manual:Installation_guide
|
||||
|
||||
|
||||
******************* WARNING *******************
|
||||
|
||||
REMEMBER: ALWAYS BACK UP YOUR DATABASE BEFORE
|
||||
ATTEMPTING TO INSTALL OR UPGRADE!!!
|
||||
|
||||
******************* WARNING *******************
|
||||
|
||||
----
|
||||
In-place web install
|
||||
----
|
||||
|
||||
Decompress the MediaWiki installation archive either on your server, or on your
|
||||
local machine and upload the directory tree. Rename it from "mediawiki-1.x.x" to
|
||||
something nice, like "wiki", since it will be appearing in your URL,
|
||||
ie. /wiki/index.php/Article.
|
||||
|
||||
+--------------------------------------------------------------------------+
|
||||
| Note: If you plan to use a fancy URL-rewriting scheme to prettify your |
|
||||
| URLs, such as http://www.example.com/wiki/Article, you should put the |
|
||||
| files in a *different* directory from the virtual path where page names |
|
||||
| will appear. It is common in this case to use w as the folder name and |
|
||||
| /wiki/ as the virtual article path where your articles pretend to be. |
|
||||
| |
|
||||
| See: http://www.mediawiki.org/wiki/Manual:Short_URL |
|
||||
+--------------------------------------------------------------------------+
|
||||
|
||||
Hop into your browser and surf into the wiki directory. It'll direct you into
|
||||
the config script. Fill out the form... remember you're probably not on an
|
||||
encrypted connection.
|
||||
Gaaah! :)
|
||||
|
||||
If all goes well, you should soon be told that it's set up your wiki database
|
||||
and generated a configuration file. There is now a copy of "LocalSettings.php"
|
||||
available to download from the installer. Download this now, there is not a
|
||||
way (yet) to get it after you exit the installer. Place it in the main wiki
|
||||
directory, and the wiki should now be working.
|
||||
|
||||
Once the wiki is set up, you should remove the mw-config directory (though it will
|
||||
refuse to config again if the wiki is set up).
|
||||
|
||||
----
|
||||
|
||||
Don't forget that this is free software under development! Chances are good
|
||||
there's a crucial step that hasn't made it into the documentation. You should
|
||||
probably sign up for the MediaWiki developers' mailing list; you can ask for
|
||||
help (please provide enough information to work with, and preferably be aware of
|
||||
what you're doing!) and keep track of major changes to the software, including
|
||||
performance improvements and security patches.
|
||||
|
||||
http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce (low traffic)
|
||||
|
||||
http://lists.wikimedia.org/mailman/listinfo/mediawiki-l (site admin support)
|
||||
|
||||
http://lists.wikimedia.org/mailman/listinfo/wikitech-l (development)
|
33
sources/mediawiki/README
Normal file
33
sources/mediawiki/README
Normal file
|
@ -0,0 +1,33 @@
|
|||
== MediaWiki ==
|
||||
|
||||
MediaWiki is a popular and free, open-source wiki software package written in
|
||||
PHP. It serves as the platform for Wikipedia and the other projects of the Wikimedia
|
||||
Foundation, which deliver content in over 280 languages to more than half a billion
|
||||
people each month. MediaWiki's reliability and robust feature set have earned it a
|
||||
large and vibrant community of third-party users and developers.
|
||||
|
||||
MediaWiki is:
|
||||
|
||||
* feature-rich and extensible, both on-wiki and with over 2,000 extensions;
|
||||
* scalable and suitable for both small and large sites;
|
||||
* available in your language; and
|
||||
* simple to install, working on most hardware/software combinations.
|
||||
|
||||
For system requirements, installation, and upgrade details, see the files
|
||||
RELEASE-NOTES, INSTALL, and UPGRADE.
|
||||
|
||||
* Ready to get started?
|
||||
** https://www.mediawiki.org/wiki/Download
|
||||
* Looking for the technical manual?
|
||||
** https://www.mediawiki.org/wiki/Manual:Contents
|
||||
* Seeking help from a person?
|
||||
** https://www.mediawiki.org/wiki/Communication
|
||||
* Looking to file a bug report or a feature request?
|
||||
** https://bugs.mediawiki.org/
|
||||
* Interested in helping out?
|
||||
** https://www.mediawiki.org/wiki/How_to_contribute
|
||||
|
||||
MediaWiki is the result of global collaboration and cooperation. The CREDITS
|
||||
file lists technical contributors to the project. The COPYING file explains
|
||||
MediaWiki's copyright and license (GNU General Public License, version 2 or
|
||||
later). Many thanks to the Wikimedia community for testing and suggestions.
|
1
sources/mediawiki/README.mediawiki
Symbolic link
1
sources/mediawiki/README.mediawiki
Symbolic link
|
@ -0,0 +1 @@
|
|||
README
|
721
sources/mediawiki/RELEASE-NOTES-1.22
Normal file
721
sources/mediawiki/RELEASE-NOTES-1.22
Normal file
|
@ -0,0 +1,721 @@
|
|||
= MediaWiki release notes =
|
||||
|
||||
Security reminder: MediaWiki does not require PHP's register_globals. If you
|
||||
have it on, turn it '''off''' if you can.
|
||||
|
||||
== MediaWiki 1.22.6 ==
|
||||
|
||||
This is a security release of the MediaWiki 1.22 branch.
|
||||
|
||||
=== Changes since 1.22.5 ===
|
||||
|
||||
* (bug 63251) SECURITY: Escape sortKey in pageInfo.
|
||||
|
||||
== MediaWiki 1.22.5 ==
|
||||
|
||||
This is a security and maintenance release of the MediaWiki 1.22 branch.
|
||||
|
||||
=== Changes since 1.22.4 ===
|
||||
|
||||
* (bug 62497) SECURITY: Add CSRF token on Special:ChangePassword.
|
||||
* (bug 62467) Set a title for the context during import on the cli.
|
||||
* Fix custom local MediaWiki:Helppage values.
|
||||
* mediawiki.js: Fix documentation breakage.
|
||||
* (bug 58153) Make MySQLi work with non standard port.
|
||||
* (bug 53887) Reintroduced a link to help pages in the default sidebar, that
|
||||
any sysop can customize by editing [[MediaWiki:Sidebar]] locally. The link
|
||||
now points to a mediawiki.org page which is guaranteed to exist. Nothing needs
|
||||
to be done on your end, but remember to adjust [[MediaWiki:Sidebar]] for the
|
||||
needs of your wikis. Everyone can help with the shared documentation by
|
||||
translating: https://www.mediawiki.org/wiki/Special:Translate/agg-Help_pages .
|
||||
* (bug 53888) Corrected a regression in 1.22 which introduced red links on the
|
||||
login page. If you previously installed 1.22.x and have created a local page
|
||||
to make the red link blue, write its title as in [[MediaWiki:helplogin-url]]
|
||||
if you didn't already. Otherwise, you don't need to do anything, but you can
|
||||
translate the help page at https://www.mediawiki.org/wiki/Help:Logging_in .
|
||||
|
||||
== MediaWiki 1.22.4 ==
|
||||
|
||||
This is a maintenance release of the MediaWiki 1.22 branch.
|
||||
|
||||
=== Changes since 1.22.3 ===
|
||||
|
||||
* Use the correct branch of the extensions' git repositories.
|
||||
|
||||
== MediaWiki 1.22.3 ==
|
||||
|
||||
This is a security and bugfix release of the MediaWiki 1.22 branch.
|
||||
|
||||
=== Changes since 1.22.2 ===
|
||||
|
||||
* (bug 60771) SECURITY: Disallow uploading SVG files using non-whitelisted
|
||||
namespaces. Also disallow iframe elements. User will get an error
|
||||
including the namespace name if they use a non- whitelisted namespace.
|
||||
* (bug 61346) SECURITY: Make token comparison use constant time. It seems like
|
||||
our token comparison would be vulnerable to timing attacks. This will take
|
||||
constant time.
|
||||
* (bug 61362) SECURITY: API: Don't find links in the middle of api.php links.
|
||||
* (bug 53710) Add sequence support for upsert in DatabaseOracle in the same way
|
||||
as in selectInsert
|
||||
* (bug 60231, 58719) Various fixes to job running code in Wiki.php: Make it
|
||||
async on Windows. Fixed possible "invalid filename" errors on Windows.
|
||||
Redirect output to dev/null to avoid hanging PHP.
|
||||
* (bug 60083) Correct sequence name for fresh Postgres installation. Spotted
|
||||
by gebhkla
|
||||
* (bug 60531) Avoid variable naming conflicts in
|
||||
DatabasePostgres::selectSQLText. Spotted by gebhkla
|
||||
* (bug 60094) Fix rebuildall.php fatal error with PostgreSQL. The fix for
|
||||
47055 introduced a fatal error when running rebuildall.php. This is a
|
||||
workaround suggested by gebhkla on Bugzilla. It just checks to make sure
|
||||
$options is actually an array before calling array_search on it.
|
||||
* (bug 43817c12) Add error handling if descriptionmsg isn't defined for
|
||||
extension.
|
||||
* (bug 60543) Special:PrefixIndex omits stripprefix=1 for "Next page" link.
|
||||
|
||||
== MediaWiki 1.22.2 ==
|
||||
|
||||
This is a security and bugfix release of the MediaWiki 1.22 branch.
|
||||
|
||||
=== Changes since 1.22.1 ===
|
||||
|
||||
* (bug 60339) SECURITY: Sanitize shell arguments to DjVu files, and other media
|
||||
formats.
|
||||
* (bug 58253) Check for very old PCRE versions in installer and updater.
|
||||
* (bug 60054) Make WikiPage::$mPreparedEdit public.
|
||||
|
||||
== MediaWiki 1.22.1 ==
|
||||
|
||||
This is a security and maintenance release of the MediaWiki 1.22 branch.
|
||||
|
||||
=== Changes since 1.22.0 ===
|
||||
|
||||
* (bug 57550) SECURITY: Disallow stylesheets in SVG Uploads
|
||||
* (bug 58088) SECURITY: Don't normalize U+FF3C to \ in CSS Checks
|
||||
* (bug 58472) SECURITY: Disallow -o-link in styles
|
||||
* (bug 58553) SECURITY: Return error on invalid XML for SVG Uploads
|
||||
* (bug 58699) SECURITY: Fix RevDel log entry information leaks
|
||||
* (bug 58178) Restore compatibility with curl < 7.16.2.
|
||||
* (bug 56931) Updated the plural rules to CLDR 24. They are in new format
|
||||
which is detailed in UTS 35 Rev 33. The PHP parser and evaluator as well as
|
||||
the JavaScript evaluator were updated to support the new format. Plural rules
|
||||
for some languages have changed, most notably Russian. Affected software
|
||||
messages have been updated and marked for review at translatewiki.net.
|
||||
This change is backported from the development branch of MediaWiki 1.23.
|
||||
* (bug 58434) The broken installer for database backend Oracle was fixed.
|
||||
* (bug 58167) The web installer no longer throws an exception when PHP is
|
||||
compiled without support for MySQL yet with support for another DBMS.
|
||||
* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages
|
||||
to appear blank or with missing text.
|
||||
* (bug 47055) Changed FOR UPDATE handling in Postgresql
|
||||
* (bug 57026) Avoid extra parsing in prepareContentForEdit()
|
||||
|
||||
== MediaWiki 1.22.0 ==
|
||||
|
||||
MediaWiki 1.22.0 is the stable branch and is recommended for use in production.
|
||||
MediaWiki 1.22.0 is a large release that contains many new features and bug fixes.
|
||||
|
||||
* Breaking Changes in 1.22.0
|
||||
* New features in 1.22.0
|
||||
* Configuration changes in 1.22.0
|
||||
* Bug fixes in 1.22.0
|
||||
* API changes in 1.22.0
|
||||
* Languages updated in 1.22.0
|
||||
* Other changes in 1.22.0
|
||||
|
||||
=== Breaking Changes in 1.22.0 ===
|
||||
* BREAKING CHANGE: (bug 41729) Display editsection links next to headings. Also
|
||||
change their class name from .editsection to .mw-editsection and place them at
|
||||
the end of the heading element instead of the beginning. Client-side code and
|
||||
screen-scrapers will have to be adjusted to handle both cases (old HTML will
|
||||
still be visible on cached page renders until they are purged); extensions
|
||||
using the DoEditSectionLink or EditSectionLink hooks might need adjustments as
|
||||
well.
|
||||
* (bug 55818) BREAKING CHANGE: Removed undocumented 'Debug' hook in wfDebug.
|
||||
This resolves an infinite loop when using $wgDebugFunctionEntry = true.
|
||||
* BREAKING CHANGE: action=parse no longer returns all langlinks for the page
|
||||
with prop=langlinks by default. The new effectivelanglinks parameter will
|
||||
request that the LanguageLinks hook be called to determine the effective
|
||||
language links.
|
||||
* BREAKING CHANGE: list=allpages, list=langbacklinks, and prop=langlinks do not
|
||||
apply the new LanguageLinks hook, and thus only consider language links
|
||||
stored in the database.
|
||||
* BREAKING CHANGE: Implementation of MediaWiki's JS and JSON value encoding
|
||||
has changed:
|
||||
** MediaWiki no longer supports PHP installations in which the native JSON
|
||||
extension is missing or disabled.
|
||||
** XmlJsCode objects can no longer be nested inside objects or arrays.
|
||||
(For Xml::encodeJsCall(), this individually applies to each argument.)
|
||||
** The sets of characters escaped by default, along with the precise escape
|
||||
sequences used, have changed (except for the Xml::escapeJsString()
|
||||
function, which is now deprecated).
|
||||
* BREAKING CHANGE: The Services_JSON class has been removed. If necessary,
|
||||
be sure to upgrade affected extensions at the same time (e.g. Collection).
|
||||
* BREAKING CHANGE: Legacy skins Simple, MySkin, Chick, Standard and Nostalgia
|
||||
were all removed. (Nostalgia was moved to an extension.) The SkinLegacy and
|
||||
LegacyTemplate classes that supported them were removed as well and are now a
|
||||
part of the Nostalgia extension.
|
||||
* BREAKING CHANGE: The "ExternalAuth" authentication subsystem was removed, along
|
||||
with its associated globals of $wgExternalAuthType, $wgExternalAuthConf,
|
||||
$wgAutocreatePolicy and $wgAllowPrefChange. Affected users are encouraged to
|
||||
use AuthPlugin for external authentication/authorization needs.
|
||||
* BREAKING CHANGE: mw.util.tooltipAccessKeyRegexp: The match group for the
|
||||
accesskey character is now $6 instead of $5.
|
||||
* BREAKING CHANGE: meta keywords are no longer supported. A <meta name="keywords"
|
||||
will no longer be output and OutputPage::addKeyword no longer exists.
|
||||
* BREAKING CHANGE: The EditSectionLink hook was removed after being
|
||||
deprecated since MediaWiki 1.14. Use DoEditSectionLink instead.
|
||||
* (bug 50310) BREAKING CHANGE: wikibits: Drop support for mwCustomEditButtons.
|
||||
It defaults to an empty array and emits mw.log.warn when accessed.
|
||||
* BREAKING CHANGE: Special:Disambiguations has been removed from MediaWiki core.
|
||||
Functions related to disambiguation pages are now handled by the Disambiguator
|
||||
extension (https://www.mediawiki.org/wiki/Extension:Disambiguator) (bug
|
||||
35981).
|
||||
* BREAKING CHANGE: The 'mediawiki.legacy.wikiprintable' module has been removed.
|
||||
The skins/common/wikiprintable.css file no longer exists. Return value of
|
||||
Skin#commonPrintStylesheet is ignored. Please use the 'mediawiki.legacy.commonPrint'
|
||||
module instead or base your skin on SkinTemplate.
|
||||
* BREAKING CHANGE: The module 'mediawiki.legacy.IEFixes' has been removed as it was
|
||||
unused. The file skins/common/IEFixes.js remains but is only used by wikibits.
|
||||
The file never contained any re-usable components. To use it in a skin, load
|
||||
'mediawiki.legacy.wikibits' (which IEFixes depends on) and that will import
|
||||
IEFixes automatically if user agent conditions are met.
|
||||
|
||||
=== New features in 1.22.0 ===
|
||||
* You can now install extensions using Composer.
|
||||
See https://www.mediawiki.org/wiki/Composer
|
||||
* (bug 44525) mediawiki.jqueryMsg can now parse (whitelisted) HTML elements and attributes.
|
||||
* (bug 33454) Language::sprintfDate now has a timezone parameter, and supports
|
||||
the "eIOPTZ" formatting characters.
|
||||
* EditWarning: A warning is shown when an editor leaves the edit form without
|
||||
saving (enabled by default, users can opt-out via the 'useeditwarning'
|
||||
preference). This feature was moved from the Vector extension, and is now part
|
||||
of core for all skins. Take care when upgrading that you don't use an older
|
||||
version of the Vector extension as this feature may conflict.
|
||||
* New 'mediawiki.ui' CSS module providing mw-ui-* styles for buttons and a
|
||||
compact vertical form layout.
|
||||
* HTMLForm supports a new display format 'vform' which applies this compact vertical
|
||||
layout and button styling. Special:PasswordReset uses this format.
|
||||
* New versions of login (Special:UserLogin) and create account
|
||||
(Special:UserLogin/signup) forms using the "vform" compact vertical form layout.
|
||||
These forms use new messages that assume a "Help logging in" link, see
|
||||
https://www.mediawiki.org/wiki/Manual:Page_customizations;
|
||||
https://www.mediawiki.org/wiki/Account_creation_user_experience/Strings lists the
|
||||
message key changes.
|
||||
* (bug 23343) Implemented ability to apply IP blocks to the contents of X-Forwarded-For headers
|
||||
by adding a new configuration variable $wgApplyIpBlocksToXff (disabled by default).
|
||||
* The new hook 'APIGetPossibleErrors' to modify the list of possible errors was
|
||||
added.
|
||||
* (bug 25592) LogEventsList::showLogExtract() will now ignore various
|
||||
Pager-related WebRequest parameters by default, as this is overwhelmingly
|
||||
likely to be what was intended by users of the method. If any caller wishes
|
||||
to use these parameters, the new param 'useRequestParams' may be set to true.
|
||||
* mw.util.addPortletLink: Tooltip is no longer required to be plain (without
|
||||
an accesskey in it already). As such it now rountrips. Creating a link with a
|
||||
message as tooltip, grabbing the title attribute and using it to create
|
||||
another portlet will work as expected.
|
||||
* (bug 6747) {{ROOTPAGENAME}} introduced, contains the name of the topmost
|
||||
page without namespace.
|
||||
* (bug 45535) introduced the new 'LanguageLinks' hook for manipulating the
|
||||
language links associated with a page before display.
|
||||
* Chosen (http://harvesthq.github.io/chosen/) was added as module 'jquery.chosen'
|
||||
* HTMLForm will turn multiselect checkboxes into a Chosen interface when setting cssclass 'mw-chosen'
|
||||
* rebuildLocalisationCache learned --lang option. Let you rebuild l10n caches
|
||||
of the specified languages instead of all of them.
|
||||
* New GetNewMessagesAlert hook allowing extensions to disable or modify the new
|
||||
messages alert
|
||||
* New wgUserNewMsgRevisionId JS global for logged in users. This will be null
|
||||
if the user has no new talk page messages. Otherwise it will be set to the
|
||||
revision ID of the oldest new talk page message. This will allow gadgets and
|
||||
extensions to create their own new message alerts on the client side.
|
||||
* mediawiki.log: Added log.warn wrapper (uses console.warn and console.trace).
|
||||
* mediawiki.log: Implemented log.deprecate. This method defines a property and
|
||||
uses ES5 getter/setter to emit a warning when they are used.
|
||||
* $wgCascadingRestrictionLevels was added, allowing one to specify restriction levels
|
||||
which can be cascading (previously 'sysop' was hard-coded as the only one).
|
||||
* XHTML5 support has been improved. If you set $wgMimeType = 'application/xhtml+xml'
|
||||
MediaWiki will try outputting markup acording to XHTML5 rules.
|
||||
* Altered hook 'ProtectionForm::save', adding the reason page protection is
|
||||
changed as third parameter.
|
||||
* New hook 'TitleSquidURLs' for manipulating the list of URLs to be purged from
|
||||
HTTP caches when a page is changed.
|
||||
* Changed the patrolling system to always show the link for patrolling in case the
|
||||
current revision is patrollable. This also removed the usage of the rcid URI parameters.
|
||||
* Oracle DB backend now supports Database Resident Connection Pooling (DRCP).
|
||||
Can be enabled by setting $wgDBOracleDRCP=true.
|
||||
Requires Oracle DB 11gR1 or above, enabled DRCP inside the DB itself and a
|
||||
propper connect string.
|
||||
More about DRCP can be found at:
|
||||
http://www.oracle-base.com/articles/11g/database-resident-connection-pool-11gr1.php
|
||||
* Add a new parameter $patrolFooterShown to hook ArticleViewFooter so the hook
|
||||
handlers can take further action based on the status of the patrol footer
|
||||
* A new hook TitleQuickPermissions was added to allow overriding of quick
|
||||
permissions in the Title class.
|
||||
* LinkCache singleton can now be altered or cleared, letting one to specify
|
||||
another instance that does not rely on a database backend.
|
||||
* MediaWiki's PHPUnit tests can now use PHPUnit installed using composer --dev.
|
||||
* (bug 43689) The lists of templates used on the page and hidden categories it
|
||||
is a member of, shown below the edit form, are now collapsible (and collapsed
|
||||
by default).
|
||||
* Parser profiling data, formerly only available in the "NewPP limit report"
|
||||
HTML comment, is now also displayed at the bottom of page previews.
|
||||
* Added ParserLimitReportPrepare and ParserLimitReportFormat hooks, deprecated
|
||||
ParserLimitReport hook.
|
||||
* New user rights have been added to increase granularity in rights management
|
||||
for extensions such as OAuth:
|
||||
** editmyusercss controls whether a user may edit their own CSS subpages.
|
||||
** editmyuserjs controls whether a user may edit their own JS subpages.
|
||||
** viewmywatchlist controls whether a user may view their watchlist.
|
||||
** editmywatchlist controls whether a user may edit their watchlist.
|
||||
** viewmyprivateinfo controls whether a user may access their private
|
||||
information (e.g. registered email address, real name).
|
||||
** editmyprivateinfo controls whether a user may change their private
|
||||
information.
|
||||
** editmyoptions controls whether a user may change their preferences.
|
||||
* Add new hook AbortTalkPageEmailNotification, this will be used to determine
|
||||
whether to send the regular talk page email notification
|
||||
* Action classes registered in $wgActions are now also supported in the form of
|
||||
a callback (which returns an instance of Action) instead of providing the name
|
||||
of a subclass of Action.
|
||||
* (bug 46513) Vector: Add the collapsibleTabs script from the Vector extension.
|
||||
* Added $wgRecentChangesFlags for defining new flags for RecentChanges and
|
||||
watchlists.
|
||||
* (bug 40518) mw.toolbar: Implemented mw.toolbar.addButtons for adding multiple
|
||||
button objects in one call.
|
||||
* Rights used for the default protection levels ('sysop' and 'autoconfirmed')
|
||||
are now used just for that purpose, instead of overloading other rights. This
|
||||
allows easy granting of the ability to edit sysop-protected pages without
|
||||
also granting the ability to protect and unprotect.
|
||||
* (bug 48256) Make brackets in section edit links accessible to CSS.
|
||||
They are now wrapped in <span class="mw-editsection-bracket" />.
|
||||
* (bug 8480) Allow handler specific parameters in galleries (like page number)
|
||||
* jquery.client: Add detection for Opera 15 and Internet Explorer 11.
|
||||
* Change tags (used by the AbuseFilter extension) are now shown on diff pages.
|
||||
* Change tag lists (shown on recent changes, watchlist, user contributions,
|
||||
history pages, diff pages) now include a link to Special:Tags to distinguish
|
||||
them from edit summaries.
|
||||
* Added a new method and hook, User::isEveryoneAllowed() and
|
||||
UserIsEveryoneAllowed, for use in situations where a "does everyone have this
|
||||
right?" check is used to avoid more expensive checks.
|
||||
* (bug 14431) Display "(No difference)" instead of an empty diff (when comparing
|
||||
revisions in the history or when previewing changes while editing).
|
||||
* New hook 'IsUploadAllowedFromUrl' is added which can be used to intercept uploads by
|
||||
URL, useful for blacklisting specific URLs
|
||||
* (bug 21912) Watchlist token implementation has been refactored and
|
||||
Special:ResetTokens was added to allow users to reset their tokens
|
||||
instead of presenting them in Preferences.
|
||||
* Special:PrefixIndex now lets you strip the searched prefix from the displayed
|
||||
titles. Given a list of articles named Bug1, Bug2, you can now transclude the
|
||||
list of bug numbers using: {{Special:PrefixIndex/Bug|stripprefix=1}}.
|
||||
The special page form received a new checkbox matching that option.
|
||||
* (bug 23580) Implement javascript callback interface "mw.hook".
|
||||
* (bug 30713) New mw.hook "wikipage.content".
|
||||
* (bug 40430) jquery.placeholder gets a new parameter to set the attribute value
|
||||
to be used.
|
||||
* $wgHTCPMulticastRouting renamed $wgHTCPRouting since it accepts unicast.
|
||||
* $wgHTCPRouting rules can now be passed an array of hosts/ports to send purge
|
||||
too. Can be used whenever several multicast group could be interested by a
|
||||
specific purge.
|
||||
* (bug 25931) Add Special:RandomInCategory.
|
||||
* mediawiki.util: addPortletLink now supports passing a jQuery object as nextnode.
|
||||
* <wbr> can now be used inside WikiText.
|
||||
* WebResponse::setcookie is much more featureful. Callers using PHP's
|
||||
setcookie() or setrawcookie() should begin using this instead.
|
||||
* New hook WebResponseSetCookie, called from WebResponse::setcookie().
|
||||
* New hook ResetSessionID, called when the session id is reset.
|
||||
* Add a mode parameter to <gallery> tag with potential options of "traditional",
|
||||
"nolines", "packed", "packed-overlay", or "packed-hover".
|
||||
* (bug 47399) A success message is now displayed after changing the password.
|
||||
* Make thumb.php give HTTP redirects for file redirects
|
||||
* (bug 30607) Special:ListFiles can now show old versions of files. Additionally
|
||||
Special:AllMyUploads was introduced so the user can get a list of all things
|
||||
they have ever uploaded, even if it was subsequently overriden.
|
||||
* Introduced Special:MyFiles and Special:AllMyFiles as an alias for Special:MyUploads
|
||||
and Special:AllMyUploads respectively.
|
||||
* IPv6 addresses in X-Forwarded-For headers are now normalised before checking
|
||||
against allowed proxy lists.
|
||||
* Add deferrable update support for callback/closure.
|
||||
* Add TitleMove hook before page renames.
|
||||
* Revision deletion backend code is moved out of SpecialRevisiondelete
|
||||
* Added {{REVISIONSIZE}} variable to get the current size of a revision.
|
||||
* Add support for the LESS stylesheet language to ResourceLoader. LESS is a
|
||||
stylesheet language that compiles into CSS. ResourceLoader file modules may
|
||||
include LESS style files; ResourceLoader will compile these files into CSS
|
||||
before sending them to the client.
|
||||
** The $wgResourceLoaderLESSVars configuration variable is an associative array
|
||||
mapping variable names to string CSS values. These variables are considered
|
||||
declared for all LESS files. Additional variables may be registered by
|
||||
adding keys to the array.
|
||||
** $wgResourceLoaderLESSFunctions is an associative array of custom LESS
|
||||
function names to PHP callables. See <http://leafo.net/lessphp/docs/#custom_functions>
|
||||
for more details regarding custom functions.
|
||||
** $wgResourceLoaderLESSImportPaths is an array of file system paths. Files
|
||||
referenced in LESS '@import' statements are looked up here first.
|
||||
* ResourceLoader supports hashes as module cache invalidation trigger (instead
|
||||
of or in addition to timestamps).
|
||||
* Added $wgExtensionEntryPointListFiles for use in mergeMessageFileList.php.
|
||||
* Added a hook, APIQuerySiteInfoStatisticsInfo, to allow extensions to modify
|
||||
the output of the API query meta=siteinfo&siprop=statistics
|
||||
* Primary keys have been added to both the archive table and the externallinks
|
||||
tables.
|
||||
* Added $wgEnableParserLimitReporting to control whether the NewPP limit report is
|
||||
output in a HTML comment.
|
||||
* The 'UnwatchArticle' and 'WatchArticle' hooks now support a Status object
|
||||
instead of just a boolean return value to abort the hook.
|
||||
* Added a hook, SpecialWatchlistGetNonRevisionTypes, to allow extensions
|
||||
with custom recentchanges entries to hook into the Watchlist without
|
||||
clobbering each other.
|
||||
* A hidden, empty input field was added to the edit form, and any edit that fills
|
||||
it in will be rejected. This prevents against the simplest form of spambots.
|
||||
Previously in the "SimpleAntiSpam" extension by Ryan Schmidt.
|
||||
* populateRevisionLength.php maintenance script updated to also populate
|
||||
archive.ar_len field.
|
||||
* (bug 43571) DatabaseMySQLBase learned to list views, optionally filtered by a
|
||||
prefix. Also fixed PHPUnit test suite when using a MySQL backend containing
|
||||
views.
|
||||
|
||||
=== Configuration changes in 1.22.0 ===
|
||||
* $wgRedirectScript was removed. It was unused.
|
||||
* Removed $wgLocalMessageCacheSerialized, it is now always true.
|
||||
* $wgVectorUseIconWatch is now enabled by default.
|
||||
* $wgCascadingRestrictionLevels was added.
|
||||
* ftps, ssh, sftp, xmpp, sip, sips, tel, sms, bitcoin, magnet, urn, and geo
|
||||
have been whitelisted inside of $wgUrlProtocols.
|
||||
* $wgDocType and $wgDTD have been removed and are no longer used for the DOCTYPE.
|
||||
* $wgHtml5 is no longer used by core. Setting it to false will no longer disable HTML5.
|
||||
It is still set to true for extension compatibility but doing so in extensions is deprecated.
|
||||
* $wgXhtmlDefaultNamespace is no longer used by core. Setting it will no longer change the
|
||||
xmlns used by MediaWiki. Reliance on this variable by extensions is deprecated.
|
||||
* $wgHandheldStyle was removed.
|
||||
* $wgHandheldForIPhone was removed.
|
||||
* $wgJsMimeType is no longer used by core. Most usage has been removed since
|
||||
HTML output is now exclusively HTML5.
|
||||
* $wgDBOracleDRCP added. True enables persistent connection with DRCP on Oracle.
|
||||
* $wgLogAutopatrol added to allow disabling logging of autopatrol edits in the logging table.
|
||||
default for $wgLogAutopatrol is true.
|
||||
* The 'edit' right no longer allows for editing a user's own CSS and JS.
|
||||
* New rights 'editmyusercss', 'editmyuserjs', 'viewmywatchlist',
|
||||
'editmywatchlist', 'viewmyprivateinfo', 'editmyprivateinfo', and
|
||||
'editmyoptions' restrict actions that were formerly allowed by default. They
|
||||
have been added to the default for $wgGroupPermissions['*'].
|
||||
* The 'editprotected' right no longer allows bypassing of all page protection
|
||||
restrictions. Any group using it for this purpose will now need to have all
|
||||
the individual rights listed in $wgRestrictionTypes for the same effect.
|
||||
* The 'protect' and 'autoconfirmed' rights are no longer used for the default
|
||||
page protection levels. The rights 'editprotected' and 'editsemiprotected'
|
||||
are now used for this purpose instead.
|
||||
* (bug 40866) wgOldChangeTagsIndex removed.
|
||||
* $wgNoFollowDomainExceptions now only matches entire domains. For example,
|
||||
an entry for 'bar.com' will still match 'foo.bar.com' but not 'foobar.com'.
|
||||
* $wgCopyUploadTimeout and $wgCopyUploadAsyncTimeout added to change the timeout times for
|
||||
fetching the file during upload by url.
|
||||
* New key added to $wgGalleryOptions - $wgGalleryOptions['mode'] to set
|
||||
default gallery mode.
|
||||
* New hook 'GalleryGetModes' to allow extensions to make new gallery modes.
|
||||
* The checkbox for staying in HTTPS displayed on the login form when $wgSecureLogin is
|
||||
enabled has been removed. Instead, whether the user stays in HTTPS will be determined
|
||||
based on the user's preferences, and whether they came from HTTPS or not.
|
||||
* $wgRC2UDPAddress, $wgRC2UDPInterwikiPrefix, $wgRC2UDPOmitBots, $wgRC2UDPPort,
|
||||
and $wgRC2UDPPrefix configuration options have been deprecated in favor of a
|
||||
$wgRCFeeds configuration array. $wgRCFeeds makes both the format and
|
||||
destination of recent change notifications customizable, and allows for
|
||||
multiple destinations to be specified.
|
||||
* (bug 53862) portal-url, currentevents-url and helppage have been removed from the
|
||||
default Sidebar.
|
||||
* The 'vector-simplesearch' preference is now enabled by default. Previously
|
||||
it was only enabled if the Vector extension was installed.
|
||||
* The precise format of metric datagrams produced by the UDP profiler and stats counter
|
||||
may now be specified as $wgUDPProfilerFormatString and $wgStatsFormatString,
|
||||
respectively.
|
||||
* (bug 54597) $wgBlockOpenProxies, $wgProxyPorts, $wgProxyScriptPath, and
|
||||
$wgProxyMemcExpiry have been removed, along with the open proxy scanner
|
||||
script they were added for.
|
||||
* Default value of $wgMaxShellMemory has been tripled (it's now 300 MB).
|
||||
|
||||
=== Bug fixes in 1.22.0 ===
|
||||
* (bug 47271) $wgContentHandlerUseDB should be set to false during the upgrade
|
||||
* Disable Special:PasswordReset when $wgEnableEmail is false. Previously one
|
||||
could still navigate to the page by entering the URL directly.
|
||||
* (bug 47138) Fixed a fatal error when a blocked user tries to automatically
|
||||
create an account on login due external authentication in some circumstances.
|
||||
* (bug 23393) HTML <hN> headings containing line breaks are now handled
|
||||
correctly.
|
||||
* (bug 45803) Whitespace within == Headline == syntax and within <hN> headings
|
||||
is now non-significant and not preserved in the HTML output.
|
||||
* (bug 47218) Special:BlockList now handles correctly user names with spaces
|
||||
when passed as subpage.
|
||||
* Pager's properly validate which fields are allowed to be sorted on.
|
||||
* mw.util.tooltipAccessKeyRegexp: The regex now matches "option-" as well.
|
||||
Support for Mac "option" was added in 1.16, but the regex was never updated.
|
||||
* (bug 46768) Usernames of blocking users now display correctly, even if numeric.
|
||||
* (bug 39590) Self-transclusions now show the most up to date result always
|
||||
after save instead of being a revision behind.
|
||||
* A bias in wfRandomString() toward digits 1-7 has been corrected. Generated
|
||||
strings will now start with digits 0 and 8-f as often as they should.
|
||||
* (bug 45371) Removed Parser_LinkHooks and CoreLinkFunctions classes.
|
||||
* (bug 41545) Allow <kbd>, <samp>, and <var> to be nested like allowed in html.
|
||||
* PLURAL magic word no longer causes a PHP notice when no matching form exists.
|
||||
* (bug 36641) Patrol page links no longer show on non-existent revisions.
|
||||
* (bug 35810) Pages not linked from Special:RecentChanges or Special:NewPages
|
||||
are patrollable now.
|
||||
* (bug 30213) JavaScript for search suggestions is now disabled when the API
|
||||
is disabled, and AJAX patrolling and watching are now disabled when use of
|
||||
the write API is not allowed.
|
||||
* (bug 48294) API: Fix chunk upload async mode.
|
||||
* (bug 46749) Broken files tracking category removed from pages if an image
|
||||
with that name is uploaded.
|
||||
* (bug 14176) System messages that are empty were previously incorrectly treated
|
||||
as non-existent, causing a fallback to the default. This stopped users from
|
||||
overriding system messages to make them blank.
|
||||
* (bug 48319) action=parse no longer returns an error if passed none of 'oldid',
|
||||
'pageid', 'page', 'title', and 'text' (e.g. if only passed 'summary'). A
|
||||
warning will instead be issued if 'title' is non-default, unless no props are
|
||||
requested.
|
||||
* Special:Recentchangeslinked will now include upload log entries
|
||||
* (bug 41281) Fixed ugly output if file size could not be extracted for multi-page media.
|
||||
* (bug 50315) list=logevents API module will now output log entries by anonymous users.
|
||||
* (bug 38911) Handle headers with rowspan in jquery.tablesorter
|
||||
* (bug 658) Converted the table of contents on wiki pages from <table> to <div>
|
||||
and adjusted skin CSS accordingly. The CSS was carefully crafted to be
|
||||
backwards-compatible in all reasonable cases (uses of the __TOC__ magic word,
|
||||
the #toc CSS id and the .toc CSS class). However, particularly bad abuse of
|
||||
the id or the class can possibly break.
|
||||
* CSSJanus now supports rgb, hsl, rgba, and hsla color syntaxes.
|
||||
* Special:Listfiles can no longer be sorted by image name when filtering
|
||||
by user in miser mode.
|
||||
* (bug 49074) CSSJanus: Handle values of border-radius correctly.
|
||||
* Handle relative inclusions ({{../name}}) in main namespace with subpages
|
||||
enabled correctly (previously MediaWiki tried to include Template:Parent/name
|
||||
instead of just Parent/name).
|
||||
* Added $wgAPIUselessQueryPages to allow extensions to flag their query pages
|
||||
for non-inclusion in ApiQueryQueryPages.
|
||||
* (bug 50870) mediawiki.notification: Notification area should remain visible
|
||||
when scrolled down.
|
||||
* (bug 13438) Special:MIMESearch no longer an expensive special page.
|
||||
* (bug 48342) Fixed a fatal error when $wgValidateAllHtml is set to true and
|
||||
the function apache_request_headers() function is not available.
|
||||
* (bug 33399) LivePreview: Re-run wikipage content handlers
|
||||
(jquery.makeCollapsible, jquery.tablesorter) after preview content is loaded.
|
||||
* (bug 51891) Fixed PHP notice on Special:PagesWithProp when no properties
|
||||
are defined.
|
||||
* (bug 52006) Corrected documentation of $wgTranscludeCacheExpiry.
|
||||
* (bug 52077) The APIEditBeforeSave hook is giving the content of the whole
|
||||
revision as second argument now, rather than just the current section.
|
||||
* (bug 49694) $wgSpamRegex is now also applied on the new section headline text
|
||||
adding a new topic on a page
|
||||
* (bug 41756) Improve treatment of multiple comments on a blank line.
|
||||
* (bug 51064) Purge upstream caches when deleting file assets.
|
||||
* (bug 39012) File types with a mime that we do not know the extension for
|
||||
can no longer be uploaded as an extension that we do know the mime type
|
||||
for.
|
||||
* (bug 51742) Add data-sort-value for better sorting of hitcounts Special:Tags
|
||||
* (bug 26811) On DB error pages, server hostnames are now hidden when both
|
||||
$wgShowHostnames and $wgShowSQLErrors are false.
|
||||
* (bug 6200) line breaks in <blockquote> are handled like they are in <div>
|
||||
* (bug 14931) Default character set now set to 'utf8' when a new MySQL
|
||||
database is created.
|
||||
* (bug 47191) Fixed "Column 'si_title' cannot be part of FULLTEXT index"
|
||||
MySQL error when installing using the binary character set option.
|
||||
* (bug 45288) Support mysqli PHP extension
|
||||
* (bug 56707) Correct tooltip of "Next n results" on query special pages.
|
||||
* (bug 56770) mw.util.addPortletLink: Check length before access array index.
|
||||
|
||||
=== API changes in 1.22.0 ===
|
||||
* (bug 25553) The JSON output formatter now leaves forward slashes unescaped
|
||||
to improve human readability of URLs and similar strings. Also, a "utf8"
|
||||
option is now provided to use UTF-8 encoding instead of hex escape codes
|
||||
for most non-ASCII characters.
|
||||
* (bug 46626) xmldoublequote parameter was removed. Because of a bug, the
|
||||
parameter has had no effect since MediaWiki 1.16, and so its removal is
|
||||
unlikely to impact existing clients.
|
||||
* (bug 47216) action=query&meta=siteinfo&siprop=skins will now indicate which
|
||||
skin is the default and which are unusable (e.g. listed in $wgSkipSkins).
|
||||
* (bug 25325) Added support for wlshow filtering (bots/anon/minor/patrolled)
|
||||
to action=feedwatchlist.
|
||||
* WDDX formatted output will actually be formatted (and normal output will no
|
||||
longer be), and will no longer choke on booleans.
|
||||
* action=opensearch no longer silently ignores the format parameter.
|
||||
* action=opensearch now supports format=jsonfm.
|
||||
* list=usercontribs&ucprop=ids will now include the parent revision id.
|
||||
* (bug 47219) Allow specifying change type of Wikipedia feed items
|
||||
* prop=imageinfo now allows setting iiurlheight without setting iiurlwidth
|
||||
* prop=info now adds the content model and page language of the title.
|
||||
* New upload log entries will now contain information on the relevant
|
||||
image (sha1 and timestamp).
|
||||
* (bug 49239) action=parse now can parse in preview and section preview modes.
|
||||
* (bug 49259) action=patrol now accepts revision ids.
|
||||
* (bug 48129) list=blocks&bkip= now correctly handles IPv6 CIDR ranges and
|
||||
honors $wgBlockCIDRLimit. Note any clients passing invalid values to bkip
|
||||
will now receive an error, rather than the previous behavior listing all
|
||||
user blocks.
|
||||
* (bug 48201) action=parse&text=foo now assumes wikitext if no title is given,
|
||||
rather than using the content model of the page "API".
|
||||
* action=watch no longer silently ignores hook abort.
|
||||
* (bug 50785) action=purge with forcelinkupdate=1 no longer queues refreshLinks
|
||||
jobs in the job queue for link table updates of pages that use the given page
|
||||
as a template. Instead, forcerecursivelinkupdate=1 is introduced and should
|
||||
be used if that behaviour is desirable.
|
||||
* The 'debugLog' property (enabled by $wgDebugToolbar) no longer sets the log
|
||||
entry values through ApiResult::content but directly. This changes the JSON
|
||||
output from an array of objects with content in '*' to an array of strings
|
||||
with the content.
|
||||
* (bug 51342) prop=imageinfo iicontinue now contains the dbkey, not the text
|
||||
version of the title.
|
||||
* (bug 52538) action=edit will now use empty text instead of the contents
|
||||
of section 0 when passed prependtext or appendtext with section=new.
|
||||
* Support for the 'gettoken' parameter to action=block and action=unblock,
|
||||
deprecated since 1.20, has been removed.
|
||||
* (bug 49090) Token-getting functions will fail when using jsonp callbacks.
|
||||
* (bug 52699) action=upload returns normalized file name on warning
|
||||
"exists-normalized" instead of filename to be uploaded to.
|
||||
* (bug 53884) action=edit will now return an error when the specified section
|
||||
does not exist in the page.
|
||||
* Added meta=filerepoinfo API module for getting information about foreign
|
||||
file repositories, and related ForeignAPIRepo methods getInfo and getApiUrl.
|
||||
* The new query module list=allfileusages to enumerate file usages was added.
|
||||
|
||||
=== Languages updated in 1.22.0 ===
|
||||
|
||||
MediaWiki supports over 350 languages. Many localisations are updated
|
||||
regularly. Below only new and removed languages are listed, as well as
|
||||
changes to languages because of Bugzilla reports.
|
||||
|
||||
* (bug 47099) Plural rules were updated to those from CLDR 24 for Manx (gv).
|
||||
* (bug 54514) Explicit plural forms now work for Russian.
|
||||
* (bug 46422) Explicit plural forms for languages that use a custom
|
||||
implementation for Language::convertPlural now work correctly.
|
||||
* Batak Toba (bbc-latn) added.
|
||||
* (bug 46751) Made Buryat (Russia) (буряад) (bxr) fallback to Russian.
|
||||
|
||||
=== Other changes in 1.22.0 ===
|
||||
* redirect.php was removed. It was unused.
|
||||
* ClickTracking integration was dropped from the mediaWiki.user.bucket
|
||||
JavaScript function. The 'tracked' option is now ignored.
|
||||
* Event namespace used by jquery.makeCollapsible has been changed from
|
||||
'mw-collapse' to 'mw-collapsible' for consistency with the module name.
|
||||
* The Quickbar feature of the legacy skin model and the last remnants of it
|
||||
throughout the code base have been removed.
|
||||
* Externaledit/externaldiff preference was removed. Very few users used this
|
||||
feature, and improper configuration can actually prevent a user from editing
|
||||
* Calling Linker methods using a skin will now output deprecation warnings.
|
||||
* (bug 46680) "Return to" links are no longer tagged with rel="next".
|
||||
* HipHop compiler (hphpc) support was removed. HipHop VM support (hhvm) was
|
||||
added.
|
||||
* A new Special:Redirect page was added, providing lookup by revision ID,
|
||||
user ID, or file name. The old Special:Filepath page was reimplemented
|
||||
to redirect through Special:Redirect.
|
||||
* Monobook: Removed the old conditional stylesheets for Opera 6, 7 and 9.
|
||||
* Support for XHTML 1.0 has been removed. MediaWiki now only outputs (X)HTML5.
|
||||
* wikibits: User-agent related globals have been deprecated. The following
|
||||
properties now default to false and emit mw.log.warn: is_gecko, is_chrome_mac,
|
||||
is_chrome, webkit_version, is_safari_win, is_safari, webkit_match, is_ff2,
|
||||
ff2_bugs, is_ff2_win, is_ff2_x11, opera95_bugs, opera7_bugs, opera6_bugs,
|
||||
is_opera_95, is_opera_preseven, is_opera, and ie6_bugs.
|
||||
* (bug 48276) MediaWiki will now flash a confirmation message upon successfully
|
||||
editing a page.
|
||||
* (bug 40785) mediawiki.legacy.ajax has been marked as deprecated. The following
|
||||
properties now emit mw.log.warn when accessed: sajax_debug, sajax_init_object,
|
||||
sajax_do_call and wfSupportsAjax.
|
||||
* Methods Title::userCanEditCssSubpage and Title::userCanEditJsSubpage,
|
||||
deprecated since 1.19, have been removed.
|
||||
* (bug 50134) Hook functions are no longer required to return a value. When a
|
||||
hook function does not return a value (or when it returns an explicit null),
|
||||
processing continues. To abort the hook, a hook function must return an
|
||||
explicit, boolean false or a string error message. Other falsey values are
|
||||
tantamount to a 'return true' in earlier versions of MediaWiki.
|
||||
* (bug 48256) The 'editsection-brackets' optional message was removed.
|
||||
Section edit links' brackets can now be customized using CSS by
|
||||
styling span.mw-editsection-bracket.
|
||||
* The usePatrol function in ChangesList has been marked as deprecated.
|
||||
* (bug 50785) A "null edit", that is, a save action in which no changes to the
|
||||
page text are made and no revision recorded, will no longer send refreshLinks
|
||||
jobs to the job table to update pages which use the edited page as a template.
|
||||
* The LivePreviewPrepare and LivePreviewDone events triggered on "jQuery( mw )"
|
||||
have been deprecated in favour of using mw.hook.
|
||||
* The 'showjumplinks' user preference has been removed, jump links are now
|
||||
always included.
|
||||
* Methods RecentChange::notifyRC2UDP, RecentChange::sendToUDP, and
|
||||
RecentChange::cleanupForIRC have been deprecated, as it is now the
|
||||
responsibility of classes implementing the RCFeedFormatter and RCFeedEngine
|
||||
interfaces to implement the formatting and delivery for recent change
|
||||
notifications.
|
||||
* SpecialPrefixindex methods namespacePrefixForm() and showPrefixChunk() have
|
||||
been made protected. They were accepting form variance arguments, this is now
|
||||
using properties in the SpecialPrefixindex class.
|
||||
* (bug 49629) The hook ExtractThumbParamaters has been deprecated in favour
|
||||
of media handler overriding MediaHandler::parseParamString.
|
||||
* (bug 46512) The collapsibleNav feature from the Vector extension has been moved
|
||||
to the Vector skin in core.
|
||||
* SpecialRecentChanges::addRecentChangesJS() function has been renamed
|
||||
to addModules() and made protected.
|
||||
* Methods WatchAction::doWatch and WatchAction::doUnwatch now return a Status
|
||||
object instead of a boolean.
|
||||
* Information boxes (CSS classes errorbox, warningbox, successbox) have been
|
||||
made more subtle.
|
||||
* Code specific to the Math extension was marked as deprecated.
|
||||
* mediawiki.util: mw.util.wikiGetlink has been renamed to getUrl. (The old name
|
||||
still works, but is deprecated.)
|
||||
|
||||
== Compatibility ==
|
||||
|
||||
MediaWiki 1.22.0 requires PHP 5.3.2 or later.
|
||||
|
||||
MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but
|
||||
support for them is somewhat less mature. There is experimental support for
|
||||
Oracle.
|
||||
|
||||
The supported versions are:
|
||||
|
||||
* MySQL 5.0.2 or later
|
||||
* PostgreSQL 8.3 or later
|
||||
* SQLite 3.3.7 or later
|
||||
* Oracle 9.0.1 or later
|
||||
|
||||
== Upgrading ==
|
||||
|
||||
1.22.0 has several database changes since 1.21, and will not work without schema
|
||||
updates. Note that due to changes to some very large tables like the revision
|
||||
table, the schema update may take quite long (minutes on a medium sized site,
|
||||
many hours on a large site).
|
||||
|
||||
If upgrading from before 1.11, and you are using a wiki as a commons
|
||||
repository, make sure that it is updated as well. Otherwise, errors may arise
|
||||
due to database schema changes.
|
||||
|
||||
If upgrading from before 1.7, you may want to run refreshLinks.php to ensure
|
||||
new database fields are filled with data.
|
||||
|
||||
If you are upgrading from MediaWiki 1.4.x or earlier, you should upgrade to
|
||||
1.5 first. The upgrade script maintenance/upgrade1_5.php has been removed
|
||||
with MediaWiki 1.21.
|
||||
|
||||
Don't forget to always back up your database before upgrading!
|
||||
|
||||
See the file UPGRADE for more detailed upgrade instructions.
|
||||
|
||||
For notes on 1.21.x and older releases, see HISTORY.
|
||||
|
||||
== Online documentation ==
|
||||
|
||||
Documentation for both end-users and site administrators is available on
|
||||
MediaWiki.org, and is covered under the GNU Free Documentation License (except
|
||||
for pages that explicitly state that their contents are in the public domain):
|
||||
|
||||
https://www.mediawiki.org/wiki/Documentation
|
||||
|
||||
== Mailing list ==
|
||||
|
||||
A mailing list is available for MediaWiki user support and discussion:
|
||||
|
||||
https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
|
||||
|
||||
A low-traffic announcements-only list is also available:
|
||||
|
||||
https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
|
||||
|
||||
It's highly recommended that you sign up for one of these lists if you're
|
||||
going to run a public MediaWiki, so you can be notified of security fixes.
|
||||
|
||||
== IRC help ==
|
||||
|
||||
There's usually someone online in #mediawiki on irc.freenode.net.
|
||||
|
17
sources/mediawiki/StartProfiler.sample
Normal file
17
sources/mediawiki/StartProfiler.sample
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* To use a profiler, copy this file to StartProfiler.php,
|
||||
* and add something like this:
|
||||
*
|
||||
* $wgProfiler['class'] = 'Profiler';
|
||||
*
|
||||
* Or for a sampling profiler:
|
||||
* if ( !mt_rand( 0, 100 ) ) {
|
||||
* $wgProfiler['class'] = 'Profiler';
|
||||
* } else {
|
||||
* $wgProfiler['class'] = 'ProfilerStub';
|
||||
* }
|
||||
*
|
||||
* Configuration of the profiler output can be done in LocalSettings.php
|
||||
*/
|
298
sources/mediawiki/UPGRADE
Normal file
298
sources/mediawiki/UPGRADE
Normal file
|
@ -0,0 +1,298 @@
|
|||
|
||||
This file provides an overview of the MediaWiki upgrade process. For help with
|
||||
specific problems, check
|
||||
|
||||
* the documentation at http://www.mediawiki.org
|
||||
* the mediawiki-l mailing list archive at
|
||||
http://lists.wikimedia.org/pipermail/mediawiki-l/
|
||||
* the bug tracker at https://bugzilla.wikimedia.org
|
||||
|
||||
for information and workarounds to common issues.
|
||||
|
||||
== Overview ==
|
||||
|
||||
Comprehensive documentation on upgrading to the latest version of the software
|
||||
is available at http://www.mediawiki.org/wiki/Manual:Upgrading.
|
||||
|
||||
=== Consult the release notes ===
|
||||
|
||||
Before doing anything, stop and consult the release notes supplied with the new
|
||||
version of the software. These detail bug fixes, new features and functionality,
|
||||
and any particular points that may need to be noted during the upgrade
|
||||
procedure.
|
||||
|
||||
=== Backup first ===
|
||||
|
||||
It is imperative that, prior to attempting an upgrade of the database schema,
|
||||
you take a complete backup of your wiki database and files and verify it. While
|
||||
the upgrade scripts are somewhat robust, there is no guarantee that things will
|
||||
not fail, leaving the database in an inconsistent state.
|
||||
|
||||
http://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki provides an overview of
|
||||
the backup process. You should also refer to the documentation for your
|
||||
database management system for information on backing up a database, and to
|
||||
your operating system documentation for information on making copies of files.
|
||||
|
||||
=== Perform the file upgrade ===
|
||||
|
||||
Download the files for the new version of the software. These are available
|
||||
as a compressed "tar" archive from the Wikimedia Download Service
|
||||
(http://download.wikimedia.org/mediawiki).
|
||||
|
||||
You can also obtain the new files directly from our Git source code
|
||||
repository.
|
||||
|
||||
Replace the existing MediaWiki files with the new. You should preserve the
|
||||
LocalSettings.php file and the "extensions" and "images" directories.
|
||||
|
||||
Depending upon your configuration, you may also need to preserve additional
|
||||
directories, including a custom upload directory ($wgUploadDirectory),
|
||||
deleted file archives, and any custom skins.
|
||||
|
||||
=== Perform the database upgrade ===
|
||||
|
||||
As of 1.21, it is possible to separate schema changes (i.e. adding,
|
||||
dropping, or changing tables, fields, or indices) from all other
|
||||
database changes (e.g. populating fields). If you need this
|
||||
capability, see "From the command line" below.
|
||||
|
||||
==== From the web ====
|
||||
|
||||
If you browse to the web-based installation script (usually at
|
||||
/mw-config/index.php) from your wiki installation you can follow the script and
|
||||
upgrade your database in place.
|
||||
|
||||
==== From the command line ====
|
||||
|
||||
From the command line, browse to the "maintenance" directory and run the
|
||||
update.php script to check and update the schema. This will insert missing
|
||||
tables, update existing tables, and move data around as needed. In most cases,
|
||||
this is successful and nothing further needs to be done.
|
||||
|
||||
If you need to separate out the schema changes so they can be run
|
||||
by someone with more privileges, then you can use the --schema option
|
||||
to produce a text file with the necessary commands. You can use
|
||||
--schema, --noschema, $wgAllowSchemaUpdates as well as proper database
|
||||
permissions to enforce this separation.
|
||||
|
||||
=== Check configuration settings ===
|
||||
|
||||
The names of configuration variables, and their default values and purposes,
|
||||
can change between release branches, e.g. $wgDisableUploads in 1.4 is replaced
|
||||
with $wgEnableUploads in later versions. When upgrading, consult the release
|
||||
notes to check for configuration changes which would alter the expected
|
||||
behavior of MediaWiki.
|
||||
|
||||
=== Check installed extensions ===
|
||||
|
||||
Extensions usually need to be upgraded at the same time as the MediaWiki core.
|
||||
|
||||
In MediaWiki 1.14 some extensions were migrated into the core. Please see the
|
||||
HISTORY section "Migrated extensions" and disable these extensions in your
|
||||
LocalSettings.php
|
||||
|
||||
=== Test ===
|
||||
|
||||
It makes sense to test your wiki immediately following any kind of maintenance
|
||||
procedure, and especially after upgrading; check that page views and edits work
|
||||
normally and that special pages continue to function, etc. and correct errors
|
||||
and quirks which reveal themselves.
|
||||
|
||||
You should also test any extensions, and upgrade these if necessary.
|
||||
|
||||
== Upgrading from 1.16 or earlier ==
|
||||
|
||||
If you have a Chinese or Japanese wiki ($wgLanguageCode is set to one
|
||||
of "zh", "ja", or "yue") and you are using MySQL fulltext search, you
|
||||
will probably want to update the search index.
|
||||
|
||||
In the "maintenance" directory, run the updateDoubleWidthSearch.php
|
||||
script. This will update the searchindex table for those pages that
|
||||
contain double-byte latin characters.
|
||||
|
||||
== Upgrading from 1.8 or earlier ==
|
||||
|
||||
MediaWiki 1.9 and later no longer keep default localized message text
|
||||
in the database; 'MediaWiki:'-namespace pages that do not exist in the
|
||||
database are simply transparently filled-in on demand.
|
||||
|
||||
The upgrade process will delete any 'MediaWiki:' pages which are left
|
||||
in the default state (last edited by 'MediaWiki default'). This may
|
||||
take a few moments, similar to the old initial setup.
|
||||
|
||||
Note that the large number of deletions may cause older edits to expire
|
||||
from the list on Special:Recentchanges, although the deletions themselves
|
||||
will be hidden by default. (Click "show bot edits" to list them.)
|
||||
|
||||
See RELEASE-NOTES for more details about new and changed options.
|
||||
|
||||
== Upgrading from 1.7 or earlier ==
|
||||
|
||||
$wgDefaultUserOptions now contains all the defaults, not only overrides.
|
||||
If you're setting this as a complete array(), you may need to change it
|
||||
to set only specific items as recommended in DefaultSettings.php.
|
||||
|
||||
== Upgrading from 1.6 or earlier ==
|
||||
|
||||
$wgLocalTZoffset was in hours, it is now using minutes.
|
||||
|
||||
== Upgrading from 1.5 or earlier ==
|
||||
|
||||
Major changes have been made to the schema from 1.4.x. The updater
|
||||
has not been fully tested for all conditions, and might well break.
|
||||
|
||||
On a large site, the schema update might take a long time. It might
|
||||
explode, or leave your database half-done or otherwise badly hurting.
|
||||
|
||||
Among other changes, note that Latin-1 encoding (ISO-8859-1) is
|
||||
no longer supported. Latin-1 wikis will need to be upgraded to
|
||||
UTF-8; an experimental command-line upgrade helper script,
|
||||
'upgrade1_5.php', can do this -- run it prior to 'update.php' or
|
||||
the web upgrader.
|
||||
|
||||
NOTE that upgrade1_5.php does not work properly with recent version
|
||||
of MediaWiki. If upgrading a 1.4.x wiki, you should upgrade to 1.5
|
||||
first. upgrade1_5.php has been removed from MediaWiki 1.21.
|
||||
|
||||
If you absolutely cannot make the UTF-8 upgrade work, you can try
|
||||
doing it by hand: dump your old database, convert the dump file
|
||||
using iconv as described here:
|
||||
http://portal.suse.com/sdb/en/2004/05/jbartsh_utf-8.html
|
||||
and then reimport it. You can also convert filenames using convmv,
|
||||
but note that the old directory hashes will no longer be valid,
|
||||
so you will also have to move them to new destinations.
|
||||
|
||||
Message changes:
|
||||
* A number of additional UI messages have been changed from HTML to
|
||||
wikitext, and will need to be manually fixed if customized.
|
||||
|
||||
=== Configuration changes from 1.4.x: ===
|
||||
|
||||
$wgDisableUploads has been replaced with $wgEnableUploads.
|
||||
|
||||
$wgWhitelistAccount has been replaced by the 'createaccount' permission
|
||||
key in $wgGroupPermissions. To emulate the old effect of setting:
|
||||
$wgWhitelistAccount['user'] = 0;
|
||||
set:
|
||||
$wgGroupPermissions['*']['createaccount'] = false;
|
||||
|
||||
$wgWhitelistEdit has been replaced by the 'edit' permission key.
|
||||
To emulate the old effect of setting:
|
||||
$wgWhitelistEdit = true;
|
||||
set:
|
||||
$wgGroupPermissions['*']['edit'] = false;
|
||||
|
||||
If $wgWhitelistRead is set, you must also disable the 'read' permission
|
||||
for it to take affect on anonymous users:
|
||||
$wgWhitelistRead = array( "Main Page", "Special:Userlogin" );
|
||||
$wgGroupPermissions['*']['read'] = false;
|
||||
|
||||
Note that you can disable/enable several other permissions by modifying
|
||||
this configuration array in your LocalSettings.php; see DefaultSettings.php
|
||||
for the complete default permission set.
|
||||
|
||||
If using Memcached, you must enabled it differently now:
|
||||
$wgUseMemCached = true;
|
||||
should be replaced with:
|
||||
$wgMainCacheType = CACHE_MEMCACHED;
|
||||
|
||||
== Upgrading from 1.4.2 or earlier ==
|
||||
|
||||
1.4.3 has added new fields to the sitestats table. These fields are
|
||||
optional and help to speed Special:Statistics on large sites. If you
|
||||
choose not to run the database upgrades, everything will continue to
|
||||
work in 1.4.3.
|
||||
|
||||
You can apply the update by running maintenance/update.php, or
|
||||
manually run the SQL commands from this file:
|
||||
maintenance/archives/patch-ss_total_articles.sql
|
||||
|
||||
|
||||
== Upgrading from 1.4rc1 or earlier betas ==
|
||||
|
||||
The logging table has been altered from 1.4beta4 to 1.4beta5
|
||||
and again in 1.4.0 final. Copy in the new files and use the web
|
||||
installer to upgrade, or the command-line maintenance/update.php.
|
||||
|
||||
If you cannot use the automated installers/updaters, you may
|
||||
update the table by manually running the SQL commands in these
|
||||
files:
|
||||
maintenance/archives/patch-log_params.sql
|
||||
maintenance/archives/patch-logging-title.sql
|
||||
|
||||
|
||||
== Upgrading from 1.3 or earlier ==
|
||||
|
||||
This should generally go smoothly.
|
||||
|
||||
If you keep your LocalSettings.php, you may need to change the style paths
|
||||
to match the newly rearranged skin modules. Change these lines:
|
||||
$wgStylePath = "$wgScriptPath/stylesheets";
|
||||
$wgStyleDirectory = "$IP/stylesheets";
|
||||
$wgLogo = "$wgStylePath/images/wiki.png";
|
||||
|
||||
to this:
|
||||
$wgStylePath = "$wgScriptPath/skins";
|
||||
$wgStyleDirectory = "$IP/skins";
|
||||
$wgLogo = "$wgStylePath/common/images/wiki.png";
|
||||
|
||||
As well as new messages, the processing of some messages has changed.
|
||||
If you have customized them, please compare the new format using
|
||||
Special:Allmessages or the relevant LanguageXX.php files:
|
||||
|
||||
* copyrightwarning
|
||||
* dberrortext
|
||||
* editingcomment (was named commentedit)
|
||||
* editingsection (was named sectionedit)
|
||||
* numauthors
|
||||
* numedits
|
||||
* numtalkauthors
|
||||
* numtalkedits
|
||||
* numwatchers
|
||||
* protectedarticle
|
||||
* searchresulttext
|
||||
* showhideminor
|
||||
* unprotectedarticle
|
||||
|
||||
Note that the 1.3 beta releases included a potential vulnerability if PHP
|
||||
is configured with register_globals on and the includes directory is
|
||||
served to the web. For general safety, turn register_globals *off* if you
|
||||
don't _really_ need it for another package.
|
||||
|
||||
If your hosting provider turns it on and you can't turn it off yourself,
|
||||
send them a kind note explaining that it can expose their servers and their
|
||||
customers to attacks.
|
||||
|
||||
|
||||
== Upgrading from 1.2 or earlier ==
|
||||
|
||||
If you've been using the MediaWiki: namespace for custom page templates,
|
||||
note that things are a little different. The Template: namespace has been
|
||||
added which is more powerful -- templates can include parameters for
|
||||
instance.
|
||||
|
||||
If you were using custom MediaWiki: entries for text inclusions, they
|
||||
will *not* automatically be moved to Template: entries at upgrade time.
|
||||
Be sure to go through and check that everything is working properly;
|
||||
you can move them manually or you can try using moveCustomMessages.php
|
||||
in maintenance/archives to do it automatically, but this might break things.
|
||||
|
||||
Also, be sure to pick the correct character encoding -- some languages were
|
||||
only available in Latin-1 on 1.2.x and are now available for Unicode as well.
|
||||
If you want to upgrade an existing wiki from Latin-1 to Unicode you'll have
|
||||
to dump the database to SQL, run it through iconv or another conversion tool,
|
||||
and restore it. Sorry.
|
||||
|
||||
|
||||
== Upgrading from 1.1 or earlier ==
|
||||
|
||||
This is less thoroughly tested, but should work.
|
||||
|
||||
You need to specify the *admin* database username and password to the
|
||||
installer in order for it to successfully upgrade the database structure.
|
||||
You may wish to manually change the GRANTs later.
|
||||
|
||||
If you have a very old database (earlier than organized MediaWiki releases
|
||||
in late August 2003) you may need to manually run some of the update SQL
|
||||
scripts in maintenance/archives before the installer is able to pick up
|
||||
with remaining updates.
|
105
sources/mediawiki/api.php
Normal file
105
sources/mediawiki/api.php
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is the entry point for all API queries.
|
||||
*
|
||||
* It begins by checking whether the API is enabled on this wiki; if not,
|
||||
* it informs the user that s/he should set $wgEnableAPI to true and exits.
|
||||
* Otherwise, it constructs a new ApiMain using the parameter passed to it
|
||||
* as an argument in the URL ('?action=') and with write-enabled set to the
|
||||
* value of $wgEnableWriteAPI as specified in LocalSettings.php.
|
||||
* It then invokes "execute()" on the ApiMain object instance, which
|
||||
* produces output in the format specified in the URL.
|
||||
*
|
||||
* Copyright © 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
*/
|
||||
|
||||
// So extensions (and other code) can check whether they're running in API mode
|
||||
define( 'MW_API', true );
|
||||
|
||||
// Bail if PHP is too low
|
||||
if ( !function_exists( 'version_compare' ) || version_compare( phpversion(), '5.3.2' ) < 0 ) {
|
||||
// We need to use dirname( __FILE__ ) here cause __DIR__ is PHP5.3+
|
||||
require dirname( __FILE__ ) . '/includes/PHPVersionError.php';
|
||||
wfPHPVersionError( 'api.php' );
|
||||
}
|
||||
|
||||
// Initialise common code.
|
||||
require __DIR__ . '/includes/WebStart.php';
|
||||
|
||||
wfProfileIn( 'api.php' );
|
||||
$starttime = microtime( true );
|
||||
|
||||
// URL safety checks
|
||||
if ( !$wgRequest->checkUrlExtension() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify that the API has not been disabled
|
||||
if ( !$wgEnableAPI ) {
|
||||
header( $_SERVER['SERVER_PROTOCOL'] . ' 500 MediaWiki configuration Error', true, 500 );
|
||||
echo 'MediaWiki API is not enabled for this site. Add the following line to your LocalSettings.php'
|
||||
. '<pre><b>$wgEnableAPI=true;</b></pre>';
|
||||
die( 1 );
|
||||
}
|
||||
|
||||
// Set a dummy $wgTitle, because $wgTitle == null breaks various things
|
||||
// In a perfect world this wouldn't be necessary
|
||||
$wgTitle = Title::makeTitle( NS_MAIN, 'API' );
|
||||
|
||||
/* Construct an ApiMain with the arguments passed via the URL. What we get back
|
||||
* is some form of an ApiMain, possibly even one that produces an error message,
|
||||
* but we don't care here, as that is handled by the ctor.
|
||||
*/
|
||||
$processor = new ApiMain( RequestContext::getMain(), $wgEnableWriteAPI );
|
||||
|
||||
// Process data & print results
|
||||
$processor->execute();
|
||||
|
||||
// Execute any deferred updates
|
||||
DeferredUpdates::doUpdates();
|
||||
|
||||
// Log what the user did, for book-keeping purposes.
|
||||
$endtime = microtime( true );
|
||||
wfProfileOut( 'api.php' );
|
||||
wfLogProfilingData();
|
||||
|
||||
// Log the request
|
||||
if ( $wgAPIRequestLog ) {
|
||||
$items = array(
|
||||
wfTimestamp( TS_MW ),
|
||||
$endtime - $starttime,
|
||||
$wgRequest->getIP(),
|
||||
$_SERVER['HTTP_USER_AGENT']
|
||||
);
|
||||
$items[] = $wgRequest->wasPosted() ? 'POST' : 'GET';
|
||||
$module = $processor->getModule();
|
||||
if ( $module->mustBePosted() ) {
|
||||
$items[] = "action=" . $wgRequest->getVal( 'action' );
|
||||
} else {
|
||||
$items[] = wfArrayToCgi( $wgRequest->getValues() );
|
||||
}
|
||||
wfErrorLog( implode( ',', $items ) . "\n", $wgAPIRequestLog );
|
||||
wfDebug( "Logged API request to $wgAPIRequestLog\n" );
|
||||
}
|
||||
|
||||
// Shut down the database. foo()->bar() syntax is not supported in PHP4: we won't ever actually
|
||||
// get here to worry about whether this should be = or =&, but the file has to parse properly.
|
||||
$lb = wfGetLBFactory();
|
||||
$lb->shutdown();
|
24
sources/mediawiki/api.php5
Normal file
24
sources/mediawiki/api.php5
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
/**
|
||||
* Version of api.php to used in web server requiring .php5 extension
|
||||
* to execute scripts with PHP5 engine.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
*/
|
||||
|
||||
require 'api.php';
|
1
sources/mediawiki/cache/.htaccess
vendored
Executable file
1
sources/mediawiki/cache/.htaccess
vendored
Executable file
|
@ -0,0 +1 @@
|
|||
Deny from all
|
11
sources/mediawiki/composer-example.json
Normal file
11
sources/mediawiki/composer-example.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-fileinfo": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-wikidiff2": "*",
|
||||
"ext-apc": "*"
|
||||
}
|
||||
}
|
16
sources/mediawiki/docs/README
Normal file
16
sources/mediawiki/docs/README
Normal file
|
@ -0,0 +1,16 @@
|
|||
[July 22nd 2008]
|
||||
|
||||
The 'docs' directory contain various text files that should help you understand
|
||||
the most important parts of the code of MediaWiki. More in-depth documentation
|
||||
can be found at http://www.mediawiki.org/wiki/Manual:Code.
|
||||
|
||||
API documentation is automatically generated and updated daily at:
|
||||
http://svn.wikimedia.org/doc/
|
||||
|
||||
You can get a fresh version using 'make doc' or mwdocgen.php in the
|
||||
../maintenance/ directory.
|
||||
|
||||
|
||||
For end user / administrators, most of the documentation is located online at:
|
||||
http://www.mediawiki.org/wiki/Help:Contents
|
||||
http://www.mediawiki.org/wiki/Manual:Contents
|
2
sources/mediawiki/docs/code-coverage/README
Normal file
2
sources/mediawiki/docs/code-coverage/README
Normal file
|
@ -0,0 +1,2 @@
|
|||
This directory is for the auto-generated phpunit code coverage.
|
||||
Run 'make coverage' in the tests/phpunit subdirectory to build.
|
184
sources/mediawiki/docs/contenthandler.txt
Normal file
184
sources/mediawiki/docs/contenthandler.txt
Normal file
|
@ -0,0 +1,184 @@
|
|||
The ContentHandler facility adds support for arbitrary content types on wiki pages, instead of relying on wikitext
|
||||
for everything. It was introduced in MediaWiki 1.21.
|
||||
|
||||
Each kind of content ("content model") supported by MediaWiki is identified by unique name. The content model determines
|
||||
how a page's content is rendered, compared, stored, edited, and so on.
|
||||
|
||||
Built-in content types are:
|
||||
|
||||
* wikitext - wikitext, as usual
|
||||
* javascript - user provided javascript code
|
||||
* css - user provided css code
|
||||
* text - plain text
|
||||
|
||||
In PHP, use the corresponding CONTENT_MODEL_XXX constant.
|
||||
|
||||
A page's content model is available using the Title::getContentModel() method. A page's default model is determined by
|
||||
ContentHandler::getDefaultModelFor($title) as follows:
|
||||
|
||||
* The global setting $wgNamespaceContentModels specifies a content model for the given namespace.
|
||||
* The hook ContentHandlerDefaultModelFor may be used to override the page's default model.
|
||||
* Pages in NS_MEDIAWIKI and NS_USER default to the CSS or JavaScript model if they end in .js or .css, respectively.
|
||||
Pages in NS_MEDIAWIKI default to the wikitext model otherwise.
|
||||
* The hook TitleIsCssOrJsPage may be used to force a page to use the CSS or JavaScript model.
|
||||
This is a compatibility feature. The ContentHandlerDefaultModelFor hook should be used instead if possible.
|
||||
* The hook TitleIsWikitextPage may be used to force a page to use the wikitext model.
|
||||
This is a compatibility feature. The ContentHandlerDefaultModelFor hook should be used instead if possible.
|
||||
* Otherwise, the wikitext model is used.
|
||||
|
||||
Note that is currently no mechanism to convert a page from one content model to another, and there is no guarantee that
|
||||
revisions of a page will all have the same content model. Use Revision::getContentModel() to find it.
|
||||
|
||||
|
||||
== Architecture ==
|
||||
|
||||
Two class hierarchies are used to provide the functionality associated with the different content models:
|
||||
|
||||
* Content interface (and AbstractContent base class) define functionality that acts on the concrete content of a page, and
|
||||
* ContentHandler base class provides functionality specific to a content model, but not acting on concrete content.
|
||||
|
||||
The most important function of ContentHandler is to act as a factory for the appropriate implementation of Content. These
|
||||
Content objects are to be used by MediaWiki everywhere, instead of passing page content around as text. All manipulation
|
||||
and analysis of page content must be done via the appropriate methods of the Content object.
|
||||
|
||||
For each content model, a subclass of ContentHandler has to be registered with $wgContentHandlers. The ContentHandler
|
||||
object for a given content model can be obtained using ContentHandler::getForModelID( $id ). Also Title, WikiPage and
|
||||
Revision now have getContentHandler() methods for convenience.
|
||||
|
||||
ContentHandler objects are singletons that provide functionality specific to the content type, but not directly acting
|
||||
on the content of some page. ContentHandler::makeEmptyContent() and ContentHandler::unserializeContent() can be used to
|
||||
create a Content object of the appropriate type. However, it is recommended to instead use WikiPage::getContent() resp.
|
||||
Revision::getContent() to get a page's content as a Content object. These two methods should be the ONLY way in which
|
||||
page content is accessed.
|
||||
|
||||
Another important function of ContentHandler objects is to define custom action handlers for a content model, see
|
||||
ContentHandler::getActionOverrides(). This is similar to what WikiPage::getActionOverrides() was already doing.
|
||||
|
||||
|
||||
== Serialization ==
|
||||
|
||||
With the ContentHandler facility, page content no longer has to be text based. Objects implementing the Content interface
|
||||
are used to represent and handle the content internally. For storage and data exchange, each content model supports
|
||||
at least one serialization format via ContentHandler::serializeContent( $content ). The list of supported formats for
|
||||
a given content model can be accessed using ContentHandler::getSupportedFormats().
|
||||
|
||||
Content serialization formats are identified using MIME type like strings. The following formats are built in:
|
||||
|
||||
* text/x-wiki - wikitext
|
||||
* text/javascript - for js pages
|
||||
* text/css - for css pages
|
||||
* text/plain - for future use, e.g. with plain text messages.
|
||||
* text/html - for future use, e.g. with plain html messages.
|
||||
* application/vnd.php.serialized - for future use with the api and for extensions
|
||||
* application/json - for future use with the api, and for use by extensions
|
||||
* application/xml - for future use with the api, and for use by extensions
|
||||
|
||||
In PHP, use the corresponding CONTENT_FORMAT_XXX constant.
|
||||
|
||||
Note that when using the API to access page content, especially action=edit, action=parse and action=query&prop=revisions,
|
||||
the model and format of the content should always be handled explicitly. Without that information, interpretation of
|
||||
the provided content is not reliable. The same applies to XML dumps generated via maintenance/dumpBackup.php or
|
||||
Special:Export.
|
||||
|
||||
Also note that the API will provide encapsulated, serialized content - so if the API was called with format=json, and
|
||||
contentformat is also json (or rather, application/json), the page content is represented as a string containing an
|
||||
escaped json structure. Extensions that use JSON to serialize some types of page content may provide specialized API
|
||||
modules that allow access to that content in a more natural form.
|
||||
|
||||
|
||||
== Compatibility ==
|
||||
|
||||
The ContentHandler facility is introduced in a way that should allow all existing code to keep functioning at least
|
||||
for pages that contain wikitext or other text based content. However, a number of functions and hooks have been
|
||||
deprecated in favor of new versions that are aware of the page's content model, and will now generate warnings when
|
||||
used.
|
||||
|
||||
Most importantly, the following functions have been deprecated:
|
||||
|
||||
* Revisions::getText() and Revisions::getRawText() is deprecated in favor Revisions::getContent()
|
||||
* WikiPage::getText() is deprecated in favor WikiPage::getContent()
|
||||
|
||||
Also, the old Article::getContent() (which returns text) is superceded by Article::getContentObject(). However, both
|
||||
methods should be avoided since they do not provide clean access to the page's actual content. For instance, they may
|
||||
return a system message for non-existing pages. Use WikiPage::getContent() instead.
|
||||
|
||||
Code that relies on a textual representation of the page content should eventually be rewritten. However,
|
||||
ContentHandler::getContentText() provides a stop-gap that can be used to get text for a page. Its behavior is controlled
|
||||
by $wgContentHandlerTextFallback; per default it will return the text for text based content, and null for any other
|
||||
content.
|
||||
|
||||
For rendering page content, Content::getParserOutput() should be used instead of accessing the parser directly.
|
||||
ContentHandler::makeParserOptions() can be used to construct appropriate options.
|
||||
|
||||
|
||||
Besides some functions, some hooks have also been replaced by new versions (see hooks.txt for details).
|
||||
These hooks will now trigger a warning when used:
|
||||
|
||||
* ArticleAfterFetchContent was replaced by ArticleAfterFetchContentObject
|
||||
* ArticleInsertComplete was replaced by PageContentInsertComplete
|
||||
* ArticleSave was replaced by PageContentSave
|
||||
* ArticleSaveComplete was replaced by PageContentSaveComplete
|
||||
* ArticleViewCustom was replaced by ArticleContentViewCustom (also consider a custom implementation of the view action)
|
||||
* EditFilterMerged was replaced by EditFilterMergedContent
|
||||
* EditPageGetDiffText was replaced by EditPageGetDiffContent
|
||||
* EditPageGetPreviewText was replaced by EditPageGetPreviewContent
|
||||
* ShowRawCssJs was deprecated in favor of custom rendering implemented in the respective ContentHandler object.
|
||||
|
||||
|
||||
== Database Storage ==
|
||||
|
||||
Page content is stored in the database using the same mechanism as before. Non-text content is serialized first. The
|
||||
appropriate serialization and deserialization is handled by the Revision class.
|
||||
|
||||
Each revision's content model and serialization format is stored in the revision table (resp. in the archive table, if
|
||||
the revision was deleted). The page's (current) content model (that is, the content model of the latest revision) is also
|
||||
stored in the page table.
|
||||
|
||||
Note however that the content model and format is only stored if it differs from the page's default, as determined by
|
||||
ContentHandler::getDefaultModelFor( $title ). The default values are represented as NULL in the database, to preserve
|
||||
space.
|
||||
|
||||
Storage of content model and format can be disabled altogether by setting $wgContentHandlerUseDB = false. In that case,
|
||||
the page's default model (and the model's default format) will be used everywhere. Attempts to store a revision of a page
|
||||
using a model or format different from the default will result in an error.
|
||||
|
||||
|
||||
== Globals ==
|
||||
|
||||
There are some new globals that can be used to control the behavior of the ContentHandler facility:
|
||||
|
||||
* $wgContentHandlers associates content model IDs with the names of the appropriate ContentHandler subclasses.
|
||||
|
||||
* $wgNamespaceContentModels maps namespace IDs to a content model that should be the default for that namespace.
|
||||
|
||||
* $wgContentHandlerUseDB determines whether each revision's content model should be stored in the database.
|
||||
Defaults is true.
|
||||
|
||||
* $wgContentHandlerTextFallback determines how the compatibility method ContentHandler::getContentText() will behave for
|
||||
non-text content:
|
||||
'ignore' causes null to be returned for non-text content (default).
|
||||
'serialize' causes the serialized form of any non-text content to be returned (scary).
|
||||
'fail' causes an exception to be thrown for non-text content (strict).
|
||||
|
||||
|
||||
== Caveats ==
|
||||
|
||||
There are some changes in behavior that might be surprising to users:
|
||||
|
||||
* Javascript and CSS pages are no longer parsed as wikitext (though pre-save transform is still applied). Most
|
||||
importantly, this means that links, including categorization links, contained in the code will not work.
|
||||
|
||||
* With $wgContentHandlerUseDB = false, pages can not be moved in a way that would change the
|
||||
default model. E.g. [[MediaWiki:foo.js]] can not be moved to [[MediaWiki:foo bar]], but can still be moved to
|
||||
[[User:John/foo.js]]. Also, in this mode, changing the default content model for a page (e.g. by changing
|
||||
$wgNamespaceContentModels) may cause it to become inaccessible.
|
||||
|
||||
* action=edit will fail for pages with non-text content, unless the respective ContentHandler implementation has
|
||||
provided a specialized handler for the edit action. This is true for the API as well.
|
||||
|
||||
* action=raw will fail for all non-text content. This seems better than serving content in other formats to an
|
||||
unsuspecting recipient. This will also cause client-side diffs to fail.
|
||||
|
||||
* File pages provide their own action overrides that do not combine gracefully with any custom handlers defined by a
|
||||
ContentHandler. If for example a File page used a content model with a custom revert action, this would be overridden by
|
||||
WikiFilePage's handler for the revert action.
|
198
sources/mediawiki/docs/database.txt
Normal file
198
sources/mediawiki/docs/database.txt
Normal file
|
@ -0,0 +1,198 @@
|
|||
Some information about database access in MediaWiki.
|
||||
By Tim Starling, January 2006.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Database layout
|
||||
------------------------------------------------------------------------
|
||||
|
||||
For information about the MediaWiki database layout, such as a
|
||||
description of the tables and their contents, please see:
|
||||
http://www.mediawiki.org/wiki/Manual:Database_layout
|
||||
https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/core.git;a=blob_plain;f=maintenance/tables.sql;hb=HEAD
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
API
|
||||
------------------------------------------------------------------------
|
||||
|
||||
To make a read query, something like this usually suffices:
|
||||
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
$res = $dbr->select( /* ...see docs... */ );
|
||||
foreach ( $res as $row ) {
|
||||
...
|
||||
}
|
||||
|
||||
For a write query, use something like:
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->insert( /* ...see docs... */ );
|
||||
|
||||
We use the convention $dbr for read and $dbw for write to help you keep
|
||||
track of whether the database object is a slave (read-only) or a master
|
||||
(read/write). If you write to a slave, the world will explode. Or to be
|
||||
precise, a subsequent write query which succeeded on the master may fail
|
||||
when replicated to the slave due to a unique key collision. Replication
|
||||
on the slave will stop and it may take hours to repair the database and
|
||||
get it back online. Setting read_only in my.cnf on the slave will avoid
|
||||
this scenario, but given the dire consequences, we prefer to have as
|
||||
many checks as possible.
|
||||
|
||||
We provide a query() function for raw SQL, but the wrapper functions
|
||||
like select() and insert() are usually more convenient. They take care
|
||||
of things like table prefixes and escaping for you. If you really need
|
||||
to make your own SQL, please read the documentation for tableName() and
|
||||
addQuotes(). You will need both of them.
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Basic query optimisation
|
||||
------------------------------------------------------------------------
|
||||
|
||||
MediaWiki developers who need to write DB queries should have some
|
||||
understanding of databases and the performance issues associated with
|
||||
them. Patches containing unacceptably slow features will not be
|
||||
accepted. Unindexed queries are generally not welcome in MediaWiki,
|
||||
except in special pages derived from QueryPage. It's a common pitfall
|
||||
for new developers to submit code containing SQL queries which examine
|
||||
huge numbers of rows. Remember that COUNT(*) is O(N), counting rows in a
|
||||
table is like counting beans in a bucket.
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Replication
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The largest installation of MediaWiki, Wikimedia, uses a large set of
|
||||
slave MySQL servers replicating writes made to a master MySQL server. It
|
||||
is important to understand the issues associated with this setup if you
|
||||
want to write code destined for Wikipedia.
|
||||
|
||||
It's often the case that the best algorithm to use for a given task
|
||||
depends on whether or not replication is in use. Due to our unabashed
|
||||
Wikipedia-centrism, we often just use the replication-friendly version,
|
||||
but if you like, you can use wfGetLB()->getServerCount() > 1 to
|
||||
check to see if replication is in use.
|
||||
|
||||
=== Lag ===
|
||||
|
||||
Lag primarily occurs when large write queries are sent to the master.
|
||||
Writes on the master are executed in parallel, but they are executed in
|
||||
serial when they are replicated to the slaves. The master writes the
|
||||
query to the binlog when the transaction is committed. The slaves poll
|
||||
the binlog and start executing the query as soon as it appears. They can
|
||||
service reads while they are performing a write query, but will not read
|
||||
anything more from the binlog and thus will perform no more writes. This
|
||||
means that if the write query runs for a long time, the slaves will lag
|
||||
behind the master for the time it takes for the write query to complete.
|
||||
|
||||
Lag can be exacerbated by high read load. MediaWiki's load balancer will
|
||||
stop sending reads to a slave when it is lagged by more than 30 seconds.
|
||||
If the load ratios are set incorrectly, or if there is too much load
|
||||
generally, this may lead to a slave permanently hovering around 30
|
||||
seconds lag.
|
||||
|
||||
If all slaves are lagged by more than 30 seconds, MediaWiki will stop
|
||||
writing to the database. All edits and other write operations will be
|
||||
refused, with an error returned to the user. This gives the slaves a
|
||||
chance to catch up. Before we had this mechanism, the slaves would
|
||||
regularly lag by several minutes, making review of recent edits
|
||||
difficult.
|
||||
|
||||
In addition to this, MediaWiki attempts to ensure that the user sees
|
||||
events occurring on the wiki in chronological order. A few seconds of lag
|
||||
can be tolerated, as long as the user sees a consistent picture from
|
||||
subsequent requests. This is done by saving the master binlog position
|
||||
in the session, and then at the start of each request, waiting for the
|
||||
slave to catch up to that position before doing any reads from it. If
|
||||
this wait times out, reads are allowed anyway, but the request is
|
||||
considered to be in "lagged slave mode". Lagged slave mode can be
|
||||
checked by calling wfGetLB()->getLaggedSlaveMode(). The only
|
||||
practical consequence at present is a warning displayed in the page
|
||||
footer.
|
||||
|
||||
=== Lag avoidance ===
|
||||
|
||||
To avoid excessive lag, queries which write large numbers of rows should
|
||||
be split up, generally to write one row at a time. Multi-row INSERT ...
|
||||
SELECT queries are the worst offenders should be avoided altogether.
|
||||
Instead do the select first and then the insert.
|
||||
|
||||
=== Working with lag ===
|
||||
|
||||
Despite our best efforts, it's not practical to guarantee a low-lag
|
||||
environment. Lag will usually be less than one second, but may
|
||||
occasionally be up to 30 seconds. For scalability, it's very important
|
||||
to keep load on the master low, so simply sending all your queries to
|
||||
the master is not the answer. So when you have a genuine need for
|
||||
up-to-date data, the following approach is advised:
|
||||
|
||||
1) Do a quick query to the master for a sequence number or timestamp 2)
|
||||
Run the full query on the slave and check if it matches the data you got
|
||||
from the master 3) If it doesn't, run the full query on the master
|
||||
|
||||
To avoid swamping the master every time the slaves lag, use of this
|
||||
approach should be kept to a minimum. In most cases you should just read
|
||||
from the slave and let the user deal with the delay.
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Lock contention
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Due to the high write rate on Wikipedia (and some other wikis),
|
||||
MediaWiki developers need to be very careful to structure their writes
|
||||
to avoid long-lasting locks. By default, MediaWiki opens a transaction
|
||||
at the first query, and commits it before the output is sent. Locks will
|
||||
be held from the time when the query is done until the commit. So you
|
||||
can reduce lock time by doing as much processing as possible before you
|
||||
do your write queries.
|
||||
|
||||
Often this approach is not good enough, and it becomes necessary to
|
||||
enclose small groups of queries in their own transaction. Use the
|
||||
following syntax:
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->begin( __METHOD__ );
|
||||
/* Do queries */
|
||||
$dbw->commit( __METHOD__ );
|
||||
|
||||
Use of locking reads (e.g. the FOR UPDATE clause) is not advised. They
|
||||
are poorly implemented in InnoDB and will cause regular deadlock errors.
|
||||
It's also surprisingly easy to cripple the wiki with lock contention. If
|
||||
you must use them, define a new flag for $wgAntiLockFlags which allows
|
||||
them to be turned off, because we'll almost certainly need to do so on
|
||||
the Wikimedia cluster.
|
||||
|
||||
Instead of locking reads, combine your existence checks into your write
|
||||
queries, by using an appropriate condition in the WHERE clause of an
|
||||
UPDATE, or by using unique indexes in combination with INSERT IGNORE.
|
||||
Then use the affected row count to see if the query succeeded.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Supported DBMSs
|
||||
------------------------------------------------------------------------
|
||||
|
||||
MediaWiki is written primarily for use with MySQL. Queries are optimized
|
||||
for it and its schema is considered the canonical version. However,
|
||||
MediaWiki does support the following other DBMSs to varying degrees.
|
||||
|
||||
* PostgreSQL
|
||||
* SQLite
|
||||
* Oracle
|
||||
* MSSQL
|
||||
|
||||
More information can be found about each of these databases (known issues,
|
||||
level of support, extra configuration) in the "databases" subdirectory in
|
||||
this folder.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Use of GROUP BY
|
||||
------------------------------------------------------------------------
|
||||
|
||||
MySQL supports GROUP BY without checking anything in the SELECT clause.
|
||||
Other DBMSs (especially Postgres) are stricter and require that all the
|
||||
non-aggregate items in the SELECT clause appear in the GROUP BY. For
|
||||
this reason, it is highly discouraged to use SELECT * with GROUP BY
|
||||
queries.
|
||||
|
112
sources/mediawiki/docs/databases/postgres.txt
Normal file
112
sources/mediawiki/docs/databases/postgres.txt
Normal file
|
@ -0,0 +1,112 @@
|
|||
This document describes the state of Postgres support in MediaWiki.
|
||||
|
||||
|
||||
== Overview ==
|
||||
|
||||
Support for PostgreSQL has been available since version 1.7
|
||||
of MediaWiki, and is fairly well maintained. The main code
|
||||
is very well integrated, while extensions are very hit and miss.
|
||||
Still, it is probably the most supported database after MySQL.
|
||||
Much of the work in making MediaWiki database-agnostic came
|
||||
about through the work of creating Postgres support.
|
||||
|
||||
|
||||
== Required versions ==
|
||||
|
||||
The current minimum version of PostgreSQL for MediaWiki is 8.1.
|
||||
It is expected that this will be raised to 8.3 at some point,
|
||||
as 8.1 and 8.2 are nearing end of life.
|
||||
|
||||
|
||||
|
||||
== Database schema ==
|
||||
|
||||
Postgres has its own schema file at maintenance/postgres/tables.sql.
|
||||
|
||||
The goal is to keep this file as close as possible to the canonical
|
||||
schema at maintenance/tables.sql, but without copying over
|
||||
all the usage comments. General notes on the conversion:
|
||||
|
||||
* The use of a true TIMESTAMP rather than the text string that
|
||||
MySQL uses is highly encouraged. There are still places in the
|
||||
code (especially extensions) which make assumptions about the
|
||||
textual nature of timestamp fields, but these can almost always
|
||||
be programmed around.
|
||||
|
||||
* Although Postgres has a true BOOLEAN type, boolean columns
|
||||
are always mapped to SMALLINT, as the code does not always treat
|
||||
the column as a boolean (which is limited to accepting true,
|
||||
false, 0, 1, t, or f)
|
||||
|
||||
* The default data type for all VARCHAR, CHAR, and VARBINARY
|
||||
columns should simply be TEXT. The only exception is
|
||||
when VARBINARY is used to store true binary data, such as
|
||||
the math_inputhash column, in which case BYTEA should be used.
|
||||
|
||||
* All integer variants should generally be mapped to INTEGER.
|
||||
There is small-to-no advantage in using SMALLINT versus
|
||||
INTEGER in Postgres, and the possibility of running out of
|
||||
room outweighs such concerns. The columns that are BIGINT
|
||||
in other schemas should be INTEGER as well, as none of them
|
||||
so far are even remotely likely to reach the 32 billion
|
||||
limit of an INTEGER.
|
||||
|
||||
* Blobs (blob, tinyblog, mediumblob) should be mapped to TEXT
|
||||
whenever possible, and to BYTEA if they are known to contain
|
||||
binary data.
|
||||
|
||||
* All length modifiers on data types should be removed. If
|
||||
they are on an INTEGER, it's probably an error, and if on
|
||||
any text-based field, simply using TEXT is preferred.
|
||||
|
||||
* Sequences should be explicitly named rather than using
|
||||
SERIAL, as the code can depend on having a specific name.
|
||||
|
||||
* Foreign keys should be used when possible. This makes things
|
||||
both easier and harder in the code, but most of the major
|
||||
problems have now been overcome. Always add an explicit ON DELETE
|
||||
clause, and consider carefully what choice to use (all things
|
||||
considered, prefer CASCADE).
|
||||
|
||||
* The use of CIDR should be done very carefully, because the code
|
||||
will sometimes want to store things such as an empty string or
|
||||
other non-IP value in the column. When in doubt, use TEXT.
|
||||
|
||||
* Indexes should be created using the original MySQL tables.sql
|
||||
as a guide, but keeping in mind the ability of Postgres to use
|
||||
partial indexes, functional indexes, and bitmaps. The index names
|
||||
should be logical but are not too important, as they are never
|
||||
referenced directly by the code (unlike sequence names). Most of
|
||||
the indexes in the file as of this writing are there due to production
|
||||
testing of expensive queries on a busy wiki.
|
||||
|
||||
|
||||
== Keeping in sync with tables.sql ==
|
||||
|
||||
The script maintenance/postgres/compare_schemas.pl should be
|
||||
periodically run. It will parse both "tables.sql" files and
|
||||
produce any differences found. Such differences should be fixed
|
||||
or exceptions specifically carved out by editing the script
|
||||
itself. This script has also been very useful in finding problems
|
||||
in maintenance/tables.sql itself, as it is very strict in the
|
||||
format it expects things to be in. :)
|
||||
|
||||
|
||||
== MySQL differences ==
|
||||
|
||||
The major differences between MySQL and Postgres are represented as
|
||||
methods in the Database class. For example, implicitGroupby() is
|
||||
true for MySQL and false for Postgres. This means that in those
|
||||
places where the code does not add all the non-aggregate items
|
||||
from the SELECT clause to the GROUP BY, we can add them in, but in
|
||||
a conditional manner with the above method, as simply adding them
|
||||
all in to the main query may cause performance problems with
|
||||
MySQL.
|
||||
|
||||
|
||||
== Getting help ==
|
||||
|
||||
In addition to the normal venues (MediaWiki mailing lists
|
||||
and IRC channels), the #postgresql channel on irc.freenode.net
|
||||
is a friendly and expert resource if you should encounter a
|
||||
problem with your Postgres-enabled MediaWiki.
|
12
sources/mediawiki/docs/databases/sqlite.txt
Normal file
12
sources/mediawiki/docs/databases/sqlite.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
SQLite shares the MySQL schema file at maintenance/tables.sql, with a set of
|
||||
compatibility regexes to convert MySQL syntax to SQLite syntax:
|
||||
|
||||
* BINARY() and VARBINARY() fields are converted to BLOB
|
||||
* the UNSIGNED modifier is removed
|
||||
* "INT" fields are converted to "INTEGER"
|
||||
* ENUM is converted to BLOB
|
||||
* the BINARY collation modifier is removed
|
||||
* AUTO_INCREMENT is converted to AUTOINCREMENT
|
||||
* Any table options are removed
|
||||
* Truncated indexes are upgraded to full-width indexes
|
||||
* FULLTEXT indexes are converted to ordinary indexes
|
36
sources/mediawiki/docs/deferred.txt
Normal file
36
sources/mediawiki/docs/deferred.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
deferred.txt
|
||||
|
||||
A few of the database updates required by various functions here can be
|
||||
deferred until after the result page is displayed to the user. For example,
|
||||
updating the view counts, updating the linked-to tables after a save, etc. PHP
|
||||
does not yet have any way to tell the server to actually return and disconnect
|
||||
while still running these updates (as a Java servelet could), but it might have
|
||||
such a feature in the future.
|
||||
|
||||
We handle these by creating a deferred-update object and putting those objects
|
||||
on a global list, then executing the whole list after the page is displayed. We
|
||||
don't do anything smart like collating updates to the same table or such
|
||||
because the list is almost always going to have just one item on it, if that,
|
||||
so it's not worth the trouble.
|
||||
|
||||
Since 1.6 there is a 'job queue' in the jobs table, which is used to update
|
||||
link tables of transcluding pages after edits; this may be extended in the
|
||||
future to more general background tasks.
|
||||
|
||||
Job queue items are fetched out of the queue and run either at a random rate
|
||||
during regular page views (by default) or by a batch process which can be run
|
||||
via maintenance/runJobs.php.
|
||||
|
||||
Currently there are a few different types of jobs:
|
||||
|
||||
refreshLinks
|
||||
Used to refresh the database tables that store the links between pages.
|
||||
When a page is changed, all pages using that page are also cleared by
|
||||
inserting a new job for all those pages. Each job refreshes only one page.
|
||||
|
||||
htmlCacheUpdate
|
||||
Clear caches when a template is changed to ensure that changes can be seen.
|
||||
Each job clears $wgUpdateRowsPerJob pages (500 by default).
|
||||
|
||||
enotifNotify
|
||||
Used when $wgEnotifUseJobQ is true to send mail using the job queue.
|
106
sources/mediawiki/docs/design.txt
Normal file
106
sources/mediawiki/docs/design.txt
Normal file
|
@ -0,0 +1,106 @@
|
|||
design.txt
|
||||
|
||||
This is a brief overview of the new design.
|
||||
|
||||
More thorough and up-to-date information is available on the documentation
|
||||
wiki at http://www.mediawiki.org/
|
||||
|
||||
Primary classes:
|
||||
|
||||
User
|
||||
Encapsulates the state of the user viewing/using the site. Can be queried
|
||||
for things like the user's settings, name, etc. Handles the details of
|
||||
getting and saving to the "user" table of the database, and dealing with
|
||||
sessions and cookies.
|
||||
|
||||
OutputPage
|
||||
Encapsulates the entire HTML page that will be sent in response to any
|
||||
server request. It is used by calling its functions to add text, headers,
|
||||
etc., in any order, and then calling output() to send it all. It could be
|
||||
easily changed to send incrementally if that becomes useful, but I prefer
|
||||
the flexibility. This should also do the output encoding. The system
|
||||
allocates a global one in $wgOut.
|
||||
|
||||
Title
|
||||
Represents the title of an article, and does all the work of translating
|
||||
among various forms such as plain text, URL, database key, etc. For
|
||||
convenience, and for historical reasons, it also represents a few features
|
||||
of articles that don't involve their text, such as access rights.
|
||||
See also title.txt.
|
||||
|
||||
Article
|
||||
Encapsulates access to the "page" table of the database. The object
|
||||
represents a an article, and maintains state such as text (in Wikitext
|
||||
format), flags, etc.
|
||||
|
||||
Revision
|
||||
Encapsulates individual page revision data and access to the
|
||||
revision/text/blobs storage system. Higher-level code should never touch
|
||||
text storage directly; this class mediates it.
|
||||
|
||||
Skin
|
||||
Encapsulates a "look and feel" for the wiki. All of the functions that
|
||||
render HTML, and make choices about how to render it, are here, and are
|
||||
called from various other places when needed (most notably,
|
||||
OutputPage::addWikiText()). The StandardSkin object is a complete
|
||||
implementation, and is meant to be subclassed with other skins that may
|
||||
override some of its functions. The User object contains a reference to a
|
||||
skin (according to that user's preference), and so rather than having a
|
||||
global skin object we just rely on the global User and get the skin with
|
||||
$wgUser->getSkin().
|
||||
See also skin.txt.
|
||||
|
||||
Language
|
||||
Represents the language used for incidental text, and also has some
|
||||
character encoding functions and other locale stuff. The current user
|
||||
interface language is instantiated as $wgLang, and the local content
|
||||
language as $wgContLang; be sure to use the *correct* language object
|
||||
depending upon the circumstances.
|
||||
See also language.txt.
|
||||
|
||||
Parser
|
||||
Class used to transform wikitext to html.
|
||||
|
||||
LinkCache
|
||||
Keeps information on existence of articles. See linkcache.txt.
|
||||
|
||||
Naming/coding conventions:
|
||||
|
||||
These are meant to be descriptive, not dictatorial; I won't presume to tell
|
||||
you how to program, I'm just describing the methods I chose to use for myself.
|
||||
If you do choose to follow these guidelines, it will probably be easier for
|
||||
you to collaborate with others on the project, but if you want to contribute
|
||||
without bothering, by all means do so (and don't be surprised if I reformat
|
||||
your code).
|
||||
|
||||
- I have the code indented with tabs to save file size and so that users can
|
||||
set their tab stops to any depth they like. I use 4-space tab stops, which
|
||||
work well. I also use K&R brace matching style. I know that's a religious
|
||||
issue for some, so if you want to use a style that puts opening braces on
|
||||
the next line, that's OK too, but please don't use a style where closing
|
||||
braces don't align with either the opening brace on its own line or the
|
||||
statement that opened the block--that's confusing as hell.
|
||||
|
||||
- Certain functions and class members are marked with /* private */, rather
|
||||
than being marked as such. This is a hold-over from PHP 4, which didn't
|
||||
support proper visibilities. You should not access things marked in this
|
||||
manner outside the class/inheritance line as this code is subjected to be
|
||||
updated in a manner that enforces this at some time in the near future, and
|
||||
things will break. New code should use the standard method of setting
|
||||
visibilities as normal.
|
||||
|
||||
- Globals are particularly evil in PHP; it sets a lot of them automatically
|
||||
from cookies, query strings, and such, leading to namespace conflicts; when
|
||||
a variable name is used in a function, it is silently declared as a new
|
||||
local masking the global, so you'll get weird error because you forgot the
|
||||
global declaration; lack of static class member variables means you have to
|
||||
use globals for them, etc. Evil, evil.
|
||||
|
||||
I think I've managed to pare down the number of globals we use to a scant
|
||||
few dozen or so, and I've prefixed them all with "wg" so you can spot errors
|
||||
better (odds are, if you see a "wg" variable being used in a function that
|
||||
doesn't declare it global, that's probably an error).
|
||||
|
||||
Other conventions: Top-level functions are wfFuncname(), names of session
|
||||
variables are wsName, cookies wcName, and form field values wpName ("p" for
|
||||
"POST").
|
208
sources/mediawiki/docs/distributors.txt
Normal file
208
sources/mediawiki/docs/distributors.txt
Normal file
|
@ -0,0 +1,208 @@
|
|||
This document is intended to provide useful advice for parties seeking to
|
||||
redistribute MediaWiki to end users. It's targeted particularly at maintainers
|
||||
for Linux distributions, since it's been observed that distribution packages of
|
||||
MediaWiki often break. We've consistently had to recommend that users seeking
|
||||
support use official tarballs instead of their distribution's packages, and
|
||||
this often solves whatever problem the user is having. It would be nice if
|
||||
this could change.
|
||||
|
||||
== Background: why web applications are different ==
|
||||
|
||||
MediaWiki is intended to be usable on any web host that provides support for
|
||||
PHP and a database. Many users of low-end shared hosting have very limited
|
||||
access to their machine: often only FTP access to some subdirectory of the web
|
||||
root. Support for these users entails several restrictions, such as:
|
||||
|
||||
1) We cannot require installation of any files outside the web root. Few of
|
||||
our users have access to directories like /usr or /etc.
|
||||
2) We cannot require the ability to run any utility on the command line.
|
||||
Many shared hosts have exec() and similar PHP functions disabled.
|
||||
3) We cannot assume that the software has write access anywhere useful. The
|
||||
user account that MediaWiki (including its installer) runs under is often
|
||||
different from the account the user used to upload the files, and we might be
|
||||
restricted by PHP settings such as safe mode or open_basedir.
|
||||
4) We cannot assume that the software even has read access anywhere useful.
|
||||
Many shared hosts run all users' web applications under the same user, so
|
||||
they can't rely on Unix permissions, and must forbid reads to even standard
|
||||
directories like /tmp lest users read each others' files.
|
||||
5) We cannot assume that the user has the ability to install or run any
|
||||
programs not written as web-accessible PHP scripts.
|
||||
|
||||
Since anything that works on cheap shared hosting will work if you have shell
|
||||
or root access too, MediaWiki's design is based around catering to the lowest
|
||||
common denominator. Although we support higher-end setups as well (like
|
||||
Wikipedia!), the way many things work by default is tailored toward shared
|
||||
hosting. These defaults are unconventional from the point of view of normal
|
||||
(non-web) applications -- they might conflict with distributors' policies, and
|
||||
they certainly aren't ideal for someone who's installing MediaWiki as root.
|
||||
|
||||
== Directory structure ==
|
||||
|
||||
Because of constraint (1) above, MediaWiki does not conform to normal
|
||||
Unix filesystem layout. Hopefully we'll offer direct support for standard
|
||||
layouts in the future, but for now *any change to the location of files is
|
||||
unsupported*. Moving things and leaving symlinks will *probably* not break
|
||||
anything, but it is *strongly* advised not to try any more intrusive changes to
|
||||
get MediaWiki to conform more closely to your filesystem hierarchy. Any such
|
||||
attempt will almost certainly result in unnecessary bugs.
|
||||
|
||||
The standard recommended location to install MediaWiki, relative to the web
|
||||
root, is /w (so, e.g., /var/www/w). Rewrite rules can then be used to enable
|
||||
"pretty URLs" like /wiki/Article instead of /w/index.php?title=Article. (This
|
||||
is the convention Wikipedia uses.) In theory, it should be possible to enable
|
||||
the appropriate rewrite rules by default, if you can reconfigure the web
|
||||
server, but you'd need to alter LocalSettings.php too. See
|
||||
<http://www.mediawiki.org/wiki/Manual:Short_URL> for details on short URLs.
|
||||
|
||||
If you really must mess around with the directory structure, note that the
|
||||
following files *must* all be web-accessible for MediaWiki to function
|
||||
correctly:
|
||||
|
||||
* api.php, img_auth.php, index.php, load.php, opensearch_desc.php, thumb.php,
|
||||
profileinfo.php, redirect.php, trackback.php. These are the entry points for
|
||||
normal usage. This list may be incomplete and is subject to change.
|
||||
* mw-config/index.php: Used for web-based installation (sets up the database,
|
||||
prompts for the name of the wiki, etc.).
|
||||
* images/: Used for uploaded files. This could be somewhere else if
|
||||
$wgUploadDirectory and $wgUploadPath are changed appropriately.
|
||||
* skins/*/: Subdirectories of skins/ contain CSS and JavaScript files that
|
||||
must be accessible to web browsers. The PHP files and Skin.sample in skins/
|
||||
don't need to be accessible. This could be somewhere else if
|
||||
$wgStyleDirectory and $wgStylePath are changed appropriately.
|
||||
* extensions/: Many extensions include CSS and JavaScript files in their
|
||||
extensions directory, and will break if they aren't web-accessible. Some
|
||||
extensions might theoretically provide additional entry points as well, at
|
||||
least in principle.
|
||||
|
||||
But all files should keep their position relative to the web-visible
|
||||
installation directory no matter what. If you must move includes/ somewhere in
|
||||
/usr/share, provide a symlink from /var/www/w. If you don't, you *will* break
|
||||
something. You have been warned.
|
||||
|
||||
== Configuration ==
|
||||
|
||||
MediaWiki is configured using LocalSettings.php. This is a PHP file that's
|
||||
generated when the user visits mw-config/index.php to install the software, and
|
||||
which the user can edit by hand thereafter. It's just a plain old PHP file,
|
||||
and can contain any PHP statements. It usually sets global variables that are
|
||||
used for configuration, and includes files used by any extensions.
|
||||
|
||||
Distributors can easily add extra statements to the autogenerated
|
||||
LocalSettings.php by changing mw-config/overrides.php (see that file for details
|
||||
and examples).
|
||||
|
||||
There's a new maintenance/install.php script which could be used for performing
|
||||
an install through the command line.
|
||||
|
||||
Some configuration options that distributors might be in a position to set
|
||||
intelligently:
|
||||
|
||||
* $wgEmergencyContact: An e-mail address that can be used to contact the wiki
|
||||
administrator. By default, "wikiadmin@ServerName".
|
||||
* $wgPasswordSender: The e-mail address to use when sending password e-mails.
|
||||
By default, "MediaWiki Mail <apache@ServerName>".
|
||||
(with ServerName guessed from the http request)
|
||||
* $wgSMTP: Can be configured to use SMTP for mail sending instead of PHP
|
||||
mail().
|
||||
|
||||
== Updates ==
|
||||
|
||||
The correct way for updating a wiki is to update the files and then run from
|
||||
command line the maintenance/update.php script (with appropriate parameters if
|
||||
files were moved). It will perform all the needed steps to update the database
|
||||
schema and contents to the version from whatever old one it has.
|
||||
Any package manager which replaces the files but doesn't update the db is leaving
|
||||
an inconsistent wiki that may produce blank pages (php errors) when new features
|
||||
using the changed schema would be used.
|
||||
|
||||
Since MediaWiki 1.17 it is possible to upgrade using the installer by providing
|
||||
an arbitrary secret value stored as $wgUpgradeKey in LocalSettings (older versions
|
||||
needed to rename LocalSettings.php in order to upgrade using the installer).
|
||||
|
||||
== Documentation ==
|
||||
|
||||
MediaWiki's official documentation is split between two places: the source
|
||||
code, and <http://www.mediawiki.org/>. The source code documentation is written
|
||||
exclusively by developers, and so is likely to be reliable (at worst,
|
||||
outdated). However, it can be pretty sparse. mediawiki.org documentation is
|
||||
often much more thorough, but it's maintained by a wiki that's open to
|
||||
anonymous edits, so its quality is sometimes sketchy -- don't assume that
|
||||
anything there is officially endorsed!
|
||||
|
||||
== Upstream ==
|
||||
|
||||
MediaWiki is a project hosted and led by the Wikimedia Foundation, the
|
||||
not-for-profit charity that operates Wikipedia. Wikimedia employs the lead
|
||||
developer and several other paid developers, but commit access is given out
|
||||
liberally and there are multiple very active volunteer developers as well. A
|
||||
list of developers can be found at <http://www.mediawiki.org/wiki/Developers>.
|
||||
|
||||
MediaWiki's bug tracker is at <https://bugzilla.wikimedia.org>. However, most
|
||||
developers follow the bug tracker little or not at all. The best place to
|
||||
post if you want to get developers' attention is the wikitech-l mailing list
|
||||
<https://lists.wikimedia.org/mailman/listinfo/wikitech-l>. Posts to wikitech-l
|
||||
will inevitably be read by multiple experienced MediaWiki developers. There's
|
||||
also an active IRC chat at <irc://irc.freenode.net/mediawiki>, where there are
|
||||
usually several developers at reasonably busy times of day.
|
||||
|
||||
Unfortunately, we don't have a very good system for patch review. Patches
|
||||
should be submitted on Bugzilla (as unified diffs produced with "svn diff"
|
||||
against the latest trunk revision), but many patches languish without review
|
||||
until they bitrot into uselessness. You might want to get a developer to
|
||||
commit to reviewing your patch before you put too much effort into it.
|
||||
Reasonably straightforward patches shouldn't be too hard to get accepted if
|
||||
there's an interested developer, however -- posting to Bugzilla and then
|
||||
dropping a note on wikitech-l if nobody responds is a good tactic.
|
||||
|
||||
All redistributors of MediaWiki should be subscribed to mediawiki-announce
|
||||
<https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce>. It's
|
||||
extremely low-traffic, with an average of less than one post per month. All
|
||||
new releases are announced here, including critical security updates.
|
||||
|
||||
== Useful software to install ==
|
||||
|
||||
There are several other pieces of software that MediaWiki can make good use of.
|
||||
Distributors might choose to install these automatically with MediaWiki and
|
||||
perhaps configure it to use them (see Configuration section of this document):
|
||||
|
||||
* APC (Alternative PHP Cache), XCache, or similar: Will greatly speed up the
|
||||
execution of MediaWiki, and all other PHP applications, at some cost in
|
||||
memory usage. Will be used automatically for the most part.
|
||||
* clamav: Can be used for virus scanning of uploaded files. Enable with
|
||||
"$wgAntivirus = 'clamav';".
|
||||
* DjVuLibre: Allows processing of DjVu files. To enable this, set
|
||||
"$wgDjvuDump = 'djvudump'; $wgDjvuRenderer = 'ddjvu'; $wgDjvuTxt = 'djvutxt';".
|
||||
* HTML Tidy: Fixes errors in HTML at runtime. Can be enabled with
|
||||
"$wgUseTidy = true;".
|
||||
* ImageMagick: For resizing images. "$wgUseImageMagick = true;" will enable
|
||||
it. PHP's GD can also be used, but ImageMagick is preferable.
|
||||
* Squid: Can provide a drastic speedup and a major cut in resource
|
||||
consumption, but enabling it may interfere with other applications. It might
|
||||
be suitable for a separate mediawiki-squid package. For setup details, see:
|
||||
<http://www.mediawiki.org/wiki/Manual:Squid_caching>
|
||||
* rsvg or other SVG rasterizer: ImageMagick can be used for SVG support, but
|
||||
is not ideal. Wikipedia (as of the time of this writing) uses rsvg. To
|
||||
enable, set "$wgSVGConverter = 'rsvg';" (or other as appropriate).
|
||||
* texvc: Included with MediaWiki. Instructions for compiling and
|
||||
installing it are in the math/ directory.
|
||||
|
||||
MediaWiki uses some standard GNU utilities as well, such as diff and diff3. If
|
||||
these are present in /usr/bin or some other reasonable location, they will be
|
||||
configured automatically on install.
|
||||
|
||||
MediaWiki also has a "job queue" that handles background processing. Because
|
||||
shared hosts often don't provide access to cron, the job queue is run on every
|
||||
page view by default. This means the background tasks aren't really done in
|
||||
the background. Busy wikis can set $wgJobRunRate to 0 and run
|
||||
maintenance/runJobs.php periodically out of cron. Distributors probably
|
||||
shouldn't set this up as a default, however, since the extra cron job is
|
||||
unnecessary overhead for a little-used wiki.
|
||||
|
||||
== Web server configuration ==
|
||||
|
||||
MediaWiki includes several .htaccess files to restrict access to some
|
||||
directories. If the web server is not configured to support these files, and
|
||||
the relevant directories haven't been moved someplace inaccessible anyway (e.g.
|
||||
symlinked in /usr/share with the web server configured to not follow symlinks),
|
||||
then it might be useful to deny web access to those directories in the web
|
||||
server's configuration.
|
19
sources/mediawiki/docs/doxygen_first_page.php
Normal file
19
sources/mediawiki/docs/doxygen_first_page.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
die("Not a valid entry point\n");
|
||||
/**
|
||||
* This file does not hold any code. It is only there so we can generate
|
||||
* the doxygen documentation main page.
|
||||
*
|
||||
* @file
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage Introduction
|
||||
*
|
||||
* Welcome on MediaWiki autogenerated documentation system.
|
||||
*
|
||||
* If you are looking to use, install or configure your wiki, you probably
|
||||
* want to look at the main site: https://www.mediawiki.org/
|
||||
*
|
||||
* @note this page is generated from docs/doxygen_first_page.php
|
||||
*/
|
76
sources/mediawiki/docs/export-0.1.xsd
Normal file
76
sources/mediawiki/docs/export-0.1.xsd
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.1.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.1/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.1/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.1/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType"/>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required"/>
|
||||
<attribute ref="xml:lang" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string"/>
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Zero or more sets of revision data -->
|
||||
<element name="revision" type="mw:RevisionType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="minor" minOccurs="0" />
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
<element name="text" type="string"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0"/>
|
||||
<element name="id" type="positiveInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
100
sources/mediawiki/docs/export-0.2.xsd
Normal file
100
sources/mediawiki/docs/export-0.2.xsd
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
Version 0.2 adds optional basic file upload info support,
|
||||
which is used by our OAI export/import submodule.
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.2.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.2/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.2/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.2/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType"/>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required"/>
|
||||
<attribute ref="xml:lang" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string"/>
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Zero or more sets of revision or upload data -->
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<element name="revision" type="mw:RevisionType" />
|
||||
<element name="upload" type="mw:UploadType" />
|
||||
</choice>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="minor" minOccurs="0" />
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
<element name="text" type="string"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0"/>
|
||||
<element name="id" type="positiveInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="UploadType">
|
||||
<sequence>
|
||||
<!-- Revision-style data... -->
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Filename. (Using underscores, not spaces. No 'Image:' namespace marker.) -->
|
||||
<element name="filename" type="string"/>
|
||||
|
||||
<!-- URI at which this resource can be obtained -->
|
||||
<element name="src" type="anyURI"/>
|
||||
|
||||
<element name="size" type="positiveInteger" />
|
||||
|
||||
<!-- TODO: add other metadata fields -->
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
154
sources/mediawiki/docs/export-0.3.xsd
Normal file
154
sources/mediawiki/docs/export-0.3.xsd
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
Version 0.2 adds optional basic file upload info support,
|
||||
which is used by our OAI export/import submodule.
|
||||
|
||||
Version 0.3 adds some site configuration information such
|
||||
as a list of defined namespaces.
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.3.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.3/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.3/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.3/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType"/>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="siteinfo" type="mw:SiteInfoType"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required"/>
|
||||
<attribute ref="xml:lang" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="SiteInfoType">
|
||||
<sequence>
|
||||
<element name="sitename" type="string" minOccurs="0" />
|
||||
<element name="base" type="anyURI" minOccurs="0" />
|
||||
<element name="generator" type="string" minOccurs="0" />
|
||||
<element name="case" type="mw:CaseType" minOccurs="0" />
|
||||
<element name="namespaces" type="mw:NamespacesType" minOccurs="0" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="CaseType">
|
||||
<restriction base="NMTOKEN">
|
||||
<!-- Cannot have two titles differing only by case of first letter. -->
|
||||
<!-- Default behavior through 1.5, $wgCapitalLinks = true -->
|
||||
<enumeration value="first-letter" />
|
||||
|
||||
<!-- Complete title is case-sensitive -->
|
||||
<!-- Behavior when $wgCapitalLinks = false -->
|
||||
<enumeration value="case-sensitive" />
|
||||
|
||||
<!-- Cannot have two titles differing only by case. -->
|
||||
<!-- Not yet implemented as of MediaWiki 1.5 -->
|
||||
<enumeration value="case-insensitive" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<complexType name="NamespacesType">
|
||||
<sequence>
|
||||
<element name="namespace" type="mw:NamespaceType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="NamespaceType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="key" type="integer" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string"/>
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Zero or more sets of revision or upload data -->
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<element name="revision" type="mw:RevisionType" />
|
||||
<element name="upload" type="mw:UploadType" />
|
||||
</choice>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="minor" minOccurs="0" />
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="TextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0"/>
|
||||
<element name="id" type="positiveInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0"/>
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="UploadType">
|
||||
<sequence>
|
||||
<!-- Revision-style data... -->
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Filename. (Using underscores, not spaces. No 'Image:' namespace marker.) -->
|
||||
<element name="filename" type="string"/>
|
||||
|
||||
<!-- URI at which this resource can be obtained -->
|
||||
<element name="src" type="anyURI"/>
|
||||
|
||||
<element name="size" type="positiveInteger" />
|
||||
|
||||
<!-- TODO: add other metadata fields -->
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
216
sources/mediawiki/docs/export-0.4.xsd
Normal file
216
sources/mediawiki/docs/export-0.4.xsd
Normal file
|
@ -0,0 +1,216 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
Version 0.2 adds optional basic file upload info support,
|
||||
which is used by our OAI export/import submodule.
|
||||
|
||||
Version 0.3 adds some site configuration information such
|
||||
as a list of defined namespaces.
|
||||
|
||||
Version 0.4 adds per-revision delete flags, log exports,
|
||||
discussion threading data, a per-page redirect flag, and
|
||||
per-namespace capitalization.
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.4.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.4/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.4/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.4/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType"/>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="siteinfo" type="mw:SiteInfoType"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required"/>
|
||||
<attribute ref="xml:lang" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="SiteInfoType">
|
||||
<sequence>
|
||||
<element name="sitename" type="string" minOccurs="0" />
|
||||
<element name="base" type="anyURI" minOccurs="0" />
|
||||
<element name="generator" type="string" minOccurs="0" />
|
||||
<element name="case" type="mw:CaseType" minOccurs="0" />
|
||||
<element name="namespaces" type="mw:NamespacesType" minOccurs="0" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="CaseType">
|
||||
<restriction base="NMTOKEN">
|
||||
<!-- Cannot have two titles differing only by case of first letter. -->
|
||||
<!-- Default behavior through 1.5, $wgCapitalLinks = true -->
|
||||
<enumeration value="first-letter" />
|
||||
|
||||
<!-- Complete title is case-sensitive -->
|
||||
<!-- Behavior when $wgCapitalLinks = false -->
|
||||
<enumeration value="case-sensitive" />
|
||||
|
||||
<!-- Cannot have non-case senstitive titles eg [[FOO]] == [[Foo]] -->
|
||||
<!-- Not yet implemented as of MediaWiki 1.18 -->
|
||||
<enumeration value="case-insensitive" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="DeletedFlagType">
|
||||
<restriction base="NMTOKEN">
|
||||
<enumeration value="deleted"/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<complexType name="NamespacesType">
|
||||
<sequence>
|
||||
<element name="namespace" type="mw:NamespaceType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="NamespaceType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="key" type="integer" />
|
||||
<attribute name="case" type="mw:CaseType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string"/>
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
|
||||
<!-- flag if the current revision is a redirect -->
|
||||
<element name="redirect" minOccurs="0"/>
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Zero or more sets of revision or upload data -->
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<element name="revision" type="mw:RevisionType" />
|
||||
<element name="upload" type="mw:UploadType" />
|
||||
<element name="logitem" type="mw:LogItemType" />
|
||||
</choice>
|
||||
|
||||
<!-- Zero or One sets of discussion threading data -->
|
||||
<element name="discussionthreadinginfo" minOccurs="0" maxOccurs="1" type="mw:DiscussionThreadingInfo" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="minor" minOccurs="0" />
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0"/>
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogItemType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0"/>
|
||||
<element name="type" type="string" />
|
||||
<element name="action" type="string" />
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="CommentType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
|
||||
<complexType name="TextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
<!-- This isn't a good idea; we should be using "ID" instead of "NMTOKEN" -->
|
||||
<!-- However, "NMTOKEN" is strictest definition that is both compatible with existing -->
|
||||
<!-- usage ([0-9]+) and with the "ID" type. -->
|
||||
<attribute name="id" type="NMTOKEN"/>
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0"/>
|
||||
<element name="id" type="positiveInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0"/>
|
||||
</sequence>
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="UploadType">
|
||||
<sequence>
|
||||
<!-- Revision-style data... -->
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Filename. (Using underscores, not spaces. No 'Image:' namespace marker.) -->
|
||||
<element name="filename" type="string"/>
|
||||
|
||||
<!-- URI at which this resource can be obtained -->
|
||||
<element name="src" type="anyURI"/>
|
||||
|
||||
<element name="size" type="positiveInteger" />
|
||||
|
||||
<!-- TODO: add other metadata fields -->
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- Discussion threading data for LiquidThreads -->
|
||||
<complexType name="DiscussionThreadingInfo">
|
||||
<sequence>
|
||||
<element name="ThreadSubject" type="string" />
|
||||
<element name="ThreadParent" type="positiveInteger" />
|
||||
<element name="ThreadAncestor" type="positiveInteger" />
|
||||
<element name="ThreadPage" type="string" />
|
||||
<element name="ThreadID" type="positiveInteger" />
|
||||
<element name="ThreadAuthor" type="string" />
|
||||
<element name="ThreadEditStatus" type="string" />
|
||||
<element name="ThreadType" type="string" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
219
sources/mediawiki/docs/export-0.5.xsd
Normal file
219
sources/mediawiki/docs/export-0.5.xsd
Normal file
|
@ -0,0 +1,219 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
Version 0.2 adds optional basic file upload info support,
|
||||
which is used by our OAI export/import submodule.
|
||||
|
||||
Version 0.3 adds some site configuration information such
|
||||
as a list of defined namespaces.
|
||||
|
||||
Version 0.4 adds per-revision delete flags, log exports,
|
||||
discussion threading data, a per-page redirect flag, and
|
||||
per-namespace capitalization.
|
||||
|
||||
Version 0.5 adds byte count per revision.
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.5.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.5/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.5/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.5/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType"/>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="siteinfo" type="mw:SiteInfoType"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required"/>
|
||||
<attribute ref="xml:lang" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="SiteInfoType">
|
||||
<sequence>
|
||||
<element name="sitename" type="string" minOccurs="0" />
|
||||
<element name="base" type="anyURI" minOccurs="0" />
|
||||
<element name="generator" type="string" minOccurs="0" />
|
||||
<element name="case" type="mw:CaseType" minOccurs="0" />
|
||||
<element name="namespaces" type="mw:NamespacesType" minOccurs="0" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="CaseType">
|
||||
<restriction base="NMTOKEN">
|
||||
<!-- Cannot have two titles differing only by case of first letter. -->
|
||||
<!-- Default behavior through 1.5, $wgCapitalLinks = true -->
|
||||
<enumeration value="first-letter" />
|
||||
|
||||
<!-- Complete title is case-sensitive -->
|
||||
<!-- Behavior when $wgCapitalLinks = false -->
|
||||
<enumeration value="case-sensitive" />
|
||||
|
||||
<!-- Cannot have non-case senstitive titles eg [[FOO]] == [[Foo]] -->
|
||||
<!-- Not yet implemented as of MediaWiki 1.18 -->
|
||||
<enumeration value="case-insensitive" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="DeletedFlagType">
|
||||
<restriction base="NMTOKEN">
|
||||
<enumeration value="deleted"/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<complexType name="NamespacesType">
|
||||
<sequence>
|
||||
<element name="namespace" type="mw:NamespaceType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="NamespaceType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="key" type="integer" />
|
||||
<attribute name="case" type="mw:CaseType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string"/>
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
|
||||
<!-- flag if the current revision is a redirect -->
|
||||
<element name="redirect" minOccurs="0"/>
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Zero or more sets of revision or upload data -->
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<element name="revision" type="mw:RevisionType" />
|
||||
<element name="upload" type="mw:UploadType" />
|
||||
<element name="logitem" type="mw:LogItemType" />
|
||||
</choice>
|
||||
|
||||
<!-- Zero or One sets of discussion threading data -->
|
||||
<element name="discussionthreadinginfo" minOccurs="0" maxOccurs="1" type="mw:DiscussionThreadingInfo" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="minor" minOccurs="0" />
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0"/>
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogItemType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0"/>
|
||||
<element name="type" type="string" />
|
||||
<element name="action" type="string" />
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="CommentType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
|
||||
<complexType name="TextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
<!-- This isn't a good idea; we should be using "ID" instead of "NMTOKEN" -->
|
||||
<!-- However, "NMTOKEN" is strictest definition that is both compatible with existing -->
|
||||
<!-- usage ([0-9]+) and with the "ID" type. -->
|
||||
<attribute name="id" type="NMTOKEN"/>
|
||||
<attribute name="bytes" use="optional" type="nonNegativeInteger"/>
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0"/>
|
||||
<element name="id" type="positiveInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0"/>
|
||||
</sequence>
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="UploadType">
|
||||
<sequence>
|
||||
<!-- Revision-style data... -->
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Filename. (Using underscores, not spaces. No 'Image:' namespace marker.) -->
|
||||
<element name="filename" type="string"/>
|
||||
|
||||
<!-- URI at which this resource can be obtained -->
|
||||
<element name="src" type="anyURI"/>
|
||||
|
||||
<element name="size" type="positiveInteger" />
|
||||
|
||||
<!-- TODO: add other metadata fields -->
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- Discussion threading data for LiquidThreads -->
|
||||
<complexType name="DiscussionThreadingInfo">
|
||||
<sequence>
|
||||
<element name="ThreadSubject" type="string" />
|
||||
<element name="ThreadParent" type="positiveInteger" />
|
||||
<element name="ThreadAncestor" type="positiveInteger" />
|
||||
<element name="ThreadPage" type="string" />
|
||||
<element name="ThreadID" type="positiveInteger" />
|
||||
<element name="ThreadAuthor" type="string" />
|
||||
<element name="ThreadEditStatus" type="string" />
|
||||
<element name="ThreadType" type="string" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
226
sources/mediawiki/docs/export-0.6.xsd
Normal file
226
sources/mediawiki/docs/export-0.6.xsd
Normal file
|
@ -0,0 +1,226 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
Version 0.2 adds optional basic file upload info support,
|
||||
which is used by our OAI export/import submodule.
|
||||
|
||||
Version 0.3 adds some site configuration information such
|
||||
as a list of defined namespaces.
|
||||
|
||||
Version 0.4 adds per-revision delete flags, log exports,
|
||||
discussion threading data, a per-page redirect flag, and
|
||||
per-namespace capitalization.
|
||||
|
||||
Version 0.5 adds byte count per revision.
|
||||
|
||||
Version 0.6 adds a separate namespace tag, and resolves the
|
||||
redirect target and adds a separate sha1 tag for each revision.
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.6.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.6/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.6/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.6/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType"/>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="siteinfo" type="mw:SiteInfoType"
|
||||
minOccurs="0" maxOccurs="1"/>
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required"/>
|
||||
<attribute ref="xml:lang" use="required"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="SiteInfoType">
|
||||
<sequence>
|
||||
<element name="sitename" type="string" minOccurs="0" />
|
||||
<element name="base" type="anyURI" minOccurs="0" />
|
||||
<element name="generator" type="string" minOccurs="0" />
|
||||
<element name="case" type="mw:CaseType" minOccurs="0" />
|
||||
<element name="namespaces" type="mw:NamespacesType" minOccurs="0" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="CaseType">
|
||||
<restriction base="NMTOKEN">
|
||||
<!-- Cannot have two titles differing only by case of first letter. -->
|
||||
<!-- Default behavior through 1.5, $wgCapitalLinks = true -->
|
||||
<enumeration value="first-letter" />
|
||||
|
||||
<!-- Complete title is case-sensitive -->
|
||||
<!-- Behavior when $wgCapitalLinks = false -->
|
||||
<enumeration value="case-sensitive" />
|
||||
|
||||
<!-- Cannot have non-case senstitive titles eg [[FOO]] == [[Foo]] -->
|
||||
<!-- Not yet implemented as of MediaWiki 1.18 -->
|
||||
<enumeration value="case-insensitive" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="DeletedFlagType">
|
||||
<restriction base="NMTOKEN">
|
||||
<enumeration value="deleted"/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<complexType name="NamespacesType">
|
||||
<sequence>
|
||||
<element name="namespace" type="mw:NamespaceType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="NamespaceType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="key" type="integer" />
|
||||
<attribute name="case" type="mw:CaseType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string"/>
|
||||
|
||||
<!-- Namespace in canonical form -->
|
||||
<element name="ns" type="positiveInteger"/>
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
|
||||
<!-- flag if the current revision is a redirect -->
|
||||
<element name="redirect" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Zero or more sets of revision or upload data -->
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<element name="revision" type="mw:RevisionType" />
|
||||
<element name="upload" type="mw:UploadType" />
|
||||
<element name="logitem" type="mw:LogItemType" />
|
||||
</choice>
|
||||
|
||||
<!-- Zero or One sets of discussion threading data -->
|
||||
<element name="discussionthreadinginfo" minOccurs="0" maxOccurs="1" type="mw:DiscussionThreadingInfo" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="minor" minOccurs="0" />
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0"/>
|
||||
<element name="sha1" type="string" />
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogItemType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" minOccurs="0"/>
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0"/>
|
||||
<element name="type" type="string" />
|
||||
<element name="action" type="string" />
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="CommentType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
|
||||
<complexType name="TextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
<!-- This isn't a good idea; we should be using "ID" instead of "NMTOKEN" -->
|
||||
<!-- However, "NMTOKEN" is strictest definition that is both compatible with existing -->
|
||||
<!-- usage ([0-9]+) and with the "ID" type. -->
|
||||
<attribute name="id" type="NMTOKEN"/>
|
||||
<attribute name="bytes" use="optional" type="nonNegativeInteger"/>
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0"/>
|
||||
<element name="id" type="positiveInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0"/>
|
||||
</sequence>
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType"/>
|
||||
</complexType>
|
||||
|
||||
<complexType name="UploadType">
|
||||
<sequence>
|
||||
<!-- Revision-style data... -->
|
||||
<element name="timestamp" type="dateTime"/>
|
||||
<element name="contributor" type="mw:ContributorType"/>
|
||||
<element name="comment" type="string" minOccurs="0"/>
|
||||
|
||||
<!-- Filename. (Using underscores, not spaces. No 'Image:' namespace marker.) -->
|
||||
<element name="filename" type="string"/>
|
||||
|
||||
<!-- URI at which this resource can be obtained -->
|
||||
<element name="src" type="anyURI"/>
|
||||
|
||||
<element name="size" type="positiveInteger" />
|
||||
|
||||
<!-- TODO: add other metadata fields -->
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- Discussion threading data for LiquidThreads -->
|
||||
<complexType name="DiscussionThreadingInfo">
|
||||
<sequence>
|
||||
<element name="ThreadSubject" type="string" />
|
||||
<element name="ThreadParent" type="positiveInteger" />
|
||||
<element name="ThreadAncestor" type="positiveInteger" />
|
||||
<element name="ThreadPage" type="string" />
|
||||
<element name="ThreadID" type="positiveInteger" />
|
||||
<element name="ThreadAuthor" type="string" />
|
||||
<element name="ThreadEditStatus" type="string" />
|
||||
<element name="ThreadType" type="string" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
272
sources/mediawiki/docs/export-0.7.xsd
Normal file
272
sources/mediawiki/docs/export-0.7.xsd
Normal file
|
@ -0,0 +1,272 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
Version 0.2 adds optional basic file upload info support,
|
||||
which is used by our OAI export/import submodule.
|
||||
|
||||
Version 0.3 adds some site configuration information such
|
||||
as a list of defined namespaces.
|
||||
|
||||
Version 0.4 adds per-revision delete flags, log exports,
|
||||
discussion threading data, a per-page redirect flag, and
|
||||
per-namespace capitalization.
|
||||
|
||||
Version 0.5 adds byte count per revision.
|
||||
|
||||
Version 0.6 adds a separate namespace tag, and resolves the
|
||||
redirect target and adds a separate sha1 tag for each revision.
|
||||
|
||||
Version 0.7 adds a unique identity constraint for both page and
|
||||
revision identifiers. See also bug 4220.
|
||||
Fix type for <ns> from "positiveInteger" to "nonNegativeInteger" to allow 0
|
||||
Moves <logitem> to its right location.
|
||||
Add parentid to revision.
|
||||
Fix type for <id> within <contributor> to "nonNegativeInteger"
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.7.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.7/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.7/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.7/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd" />
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType">
|
||||
<!-- Page ID contraint, see bug 4220 -->
|
||||
<unique name="PageIDConstraint">
|
||||
<selector xpath="mw:page" />
|
||||
<field xpath="mw:id" />
|
||||
</unique>
|
||||
<!-- Revision ID contraint, see bug 4220 -->
|
||||
<unique name="RevIDConstraint">
|
||||
<selector xpath="mw:page/mw:revision" />
|
||||
<field xpath="mw:id" />
|
||||
</unique>
|
||||
</element>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="siteinfo" type="mw:SiteInfoType"
|
||||
minOccurs="0" maxOccurs="1" />
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
<element name="logitem" type="mw:LogItemType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required" />
|
||||
<attribute ref="xml:lang" use="required" />
|
||||
</complexType>
|
||||
|
||||
<complexType name="SiteInfoType">
|
||||
<sequence>
|
||||
<element name="sitename" type="string" minOccurs="0" />
|
||||
<element name="base" type="anyURI" minOccurs="0" />
|
||||
<element name="generator" type="string" minOccurs="0" />
|
||||
<element name="case" type="mw:CaseType" minOccurs="0" />
|
||||
<element name="namespaces" type="mw:NamespacesType" minOccurs="0" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="CaseType">
|
||||
<restriction base="NMTOKEN">
|
||||
<!-- Cannot have two titles differing only by case of first letter. -->
|
||||
<!-- Default behavior through 1.5, $wgCapitalLinks = true -->
|
||||
<enumeration value="first-letter" />
|
||||
|
||||
<!-- Complete title is case-sensitive -->
|
||||
<!-- Behavior when $wgCapitalLinks = false -->
|
||||
<enumeration value="case-sensitive" />
|
||||
|
||||
<!-- Cannot have non-case senstitive titles eg [[FOO]] == [[Foo]] -->
|
||||
<!-- Not yet implemented as of MediaWiki 1.18 -->
|
||||
<enumeration value="case-insensitive" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="DeletedFlagType">
|
||||
<restriction base="NMTOKEN">
|
||||
<enumeration value="deleted" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<complexType name="NamespacesType">
|
||||
<sequence>
|
||||
<element name="namespace" type="mw:NamespaceType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="NamespaceType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="key" type="integer" />
|
||||
<attribute name="case" type="mw:CaseType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RedirectType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="title" type="string" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string" />
|
||||
|
||||
<!-- Namespace in canonical form -->
|
||||
<element name="ns" type="nonNegativeInteger" />
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" />
|
||||
|
||||
<!-- flag if the current revision is a redirect -->
|
||||
<element name="redirect" type="mw:RedirectType" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0" />
|
||||
|
||||
<!-- Zero or more sets of revision or upload data -->
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<element name="revision" type="mw:RevisionType" />
|
||||
<element name="upload" type="mw:UploadType" />
|
||||
</choice>
|
||||
|
||||
<!-- Zero or One sets of discussion threading data -->
|
||||
<element name="discussionthreadinginfo" minOccurs="0" maxOccurs="1" type="mw:DiscussionThreadingInfo" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" />
|
||||
<element name="parentid" type="positiveInteger" minOccurs="0" />
|
||||
<element name="timestamp" type="dateTime" />
|
||||
<element name="contributor" type="mw:ContributorType" />
|
||||
<element name="minor" minOccurs="0" maxOccurs="1" />
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0" maxOccurs="1" />
|
||||
<element name="sha1" type="string" />
|
||||
<element name="text" type="mw:TextType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogItemType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" />
|
||||
<element name="timestamp" type="dateTime" />
|
||||
<element name="contributor" type="mw:ContributorType" />
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0" />
|
||||
<element name="type" type="string" />
|
||||
<element name="action" type="string" />
|
||||
<element name="text" type="mw:LogTextType" minOccurs="0" maxOccurs="1" />
|
||||
<element name="logtitle" type="string" minOccurs="0" maxOccurs="1" />
|
||||
<element name="params" type="mw:LogParamsType" minOccurs="0" maxOccurs="1" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="CommentType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="TextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
<!-- This isn't a good idea; we should be using "ID" instead of "NMTOKEN" -->
|
||||
<!-- However, "NMTOKEN" is strictest definition that is both compatible with existing -->
|
||||
<!-- usage ([0-9]+) and with the "ID" type. -->
|
||||
<attribute name="id" type="NMTOKEN" />
|
||||
<attribute name="bytes" use="optional" type="nonNegativeInteger" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogTextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogParamsType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0" />
|
||||
<element name="id" type="nonNegativeInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0" />
|
||||
</sequence>
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
</complexType>
|
||||
|
||||
<complexType name="UploadType">
|
||||
<sequence>
|
||||
<!-- Revision-style data... -->
|
||||
<element name="timestamp" type="dateTime" />
|
||||
<element name="contributor" type="mw:ContributorType" />
|
||||
<element name="comment" type="string" minOccurs="0" />
|
||||
|
||||
<!-- Filename. (Using underscores, not spaces. No 'File:' namespace marker.) -->
|
||||
<element name="filename" type="string" />
|
||||
|
||||
<!-- URI at which this resource can be obtained -->
|
||||
<element name="src" type="anyURI" />
|
||||
|
||||
<element name="size" type="positiveInteger" />
|
||||
|
||||
<!-- TODO: add other metadata fields -->
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- Discussion threading data for LiquidThreads -->
|
||||
<complexType name="DiscussionThreadingInfo">
|
||||
<sequence>
|
||||
<element name="ThreadSubject" type="string" />
|
||||
<element name="ThreadParent" type="positiveInteger" />
|
||||
<element name="ThreadAncestor" type="positiveInteger" />
|
||||
<element name="ThreadPage" type="string" />
|
||||
<element name="ThreadID" type="positiveInteger" />
|
||||
<element name="ThreadAuthor" type="string" />
|
||||
<element name="ThreadEditStatus" type="string" />
|
||||
<element name="ThreadType" type="string" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
289
sources/mediawiki/docs/export-0.8.xsd
Normal file
289
sources/mediawiki/docs/export-0.8.xsd
Normal file
|
@ -0,0 +1,289 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
This is an XML Schema description of the format
|
||||
output by MediaWiki's Special:Export system.
|
||||
|
||||
Version 0.2 adds optional basic file upload info support,
|
||||
which is used by our OAI export/import submodule.
|
||||
|
||||
Version 0.3 adds some site configuration information such
|
||||
as a list of defined namespaces.
|
||||
|
||||
Version 0.4 adds per-revision delete flags, log exports,
|
||||
discussion threading data, a per-page redirect flag, and
|
||||
per-namespace capitalization.
|
||||
|
||||
Version 0.5 adds byte count per revision.
|
||||
|
||||
Version 0.6 adds a separate namespace tag, and resolves the
|
||||
redirect target and adds a separate sha1 tag for each revision.
|
||||
|
||||
Version 0.7 adds a unique identity constraint for both page and
|
||||
revision identifiers. See also bug 4220.
|
||||
Fix type for <ns> from "positiveInteger" to "nonNegativeInteger" to allow 0
|
||||
Moves <logitem> to its right location.
|
||||
Add parentid to revision.
|
||||
Fix type for <id> within <contributor> to "nonNegativeInteger"
|
||||
|
||||
Version 0.8 adds support for a <model> and a <format> tag for
|
||||
each revision. See contenthandler.txt.
|
||||
|
||||
The canonical URL to the schema document is:
|
||||
http://www.mediawiki.org/xml/export-0.8.xsd
|
||||
|
||||
Use the namespace:
|
||||
http://www.mediawiki.org/xml/export-0.8/
|
||||
-->
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:mw="http://www.mediawiki.org/xml/export-0.8/"
|
||||
targetNamespace="http://www.mediawiki.org/xml/export-0.8/"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<annotation>
|
||||
<documentation xml:lang="en">
|
||||
MediaWiki's page export format
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<!-- Need this to reference xml:lang -->
|
||||
<import namespace="http://www.w3.org/XML/1998/namespace"
|
||||
schemaLocation="http://www.w3.org/2001/xml.xsd" />
|
||||
|
||||
<!-- Our root element -->
|
||||
<element name="mediawiki" type="mw:MediaWikiType">
|
||||
<!-- Page ID contraint, see bug 4220 -->
|
||||
<unique name="PageIDConstraint">
|
||||
<selector xpath="mw:page" />
|
||||
<field xpath="mw:id" />
|
||||
</unique>
|
||||
<!-- Revision ID contraint, see bug 4220 -->
|
||||
<unique name="RevIDConstraint">
|
||||
<selector xpath="mw:page/mw:revision" />
|
||||
<field xpath="mw:id" />
|
||||
</unique>
|
||||
</element>
|
||||
|
||||
<complexType name="MediaWikiType">
|
||||
<sequence>
|
||||
<element name="siteinfo" type="mw:SiteInfoType"
|
||||
minOccurs="0" maxOccurs="1" />
|
||||
<element name="page" type="mw:PageType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
<element name="logitem" type="mw:LogItemType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
<attribute name="version" type="string" use="required" />
|
||||
<attribute ref="xml:lang" use="required" />
|
||||
</complexType>
|
||||
|
||||
<complexType name="SiteInfoType">
|
||||
<sequence>
|
||||
<element name="sitename" type="string" minOccurs="0" />
|
||||
<element name="base" type="anyURI" minOccurs="0" />
|
||||
<element name="generator" type="string" minOccurs="0" />
|
||||
<element name="case" type="mw:CaseType" minOccurs="0" />
|
||||
<element name="namespaces" type="mw:NamespacesType" minOccurs="0" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="CaseType">
|
||||
<restriction base="NMTOKEN">
|
||||
<!-- Cannot have two titles differing only by case of first letter. -->
|
||||
<!-- Default behavior through 1.5, $wgCapitalLinks = true -->
|
||||
<enumeration value="first-letter" />
|
||||
|
||||
<!-- Complete title is case-sensitive -->
|
||||
<!-- Behavior when $wgCapitalLinks = false -->
|
||||
<enumeration value="case-sensitive" />
|
||||
|
||||
<!-- Cannot have non-case senstitive titles eg [[FOO]] == [[Foo]] -->
|
||||
<!-- Not yet implemented as of MediaWiki 1.18 -->
|
||||
<enumeration value="case-insensitive" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="DeletedFlagType">
|
||||
<restriction base="NMTOKEN">
|
||||
<enumeration value="deleted" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<complexType name="NamespacesType">
|
||||
<sequence>
|
||||
<element name="namespace" type="mw:NamespaceType"
|
||||
minOccurs="0" maxOccurs="unbounded" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="NamespaceType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="key" type="integer" />
|
||||
<attribute name="case" type="mw:CaseType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RedirectType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute name="title" type="string" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<simpleType name="ContentModelType">
|
||||
<restriction base="string">
|
||||
<pattern value="[a-zA-Z][-+./a-zA-Z0-9]*" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="ContentFormatType">
|
||||
<restriction base="string">
|
||||
<pattern value="[a-zA-Z][-+.a-zA-Z0-9]*/[a-zA-Z][-+.a-zA-Z0-9]*" />
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<complexType name="PageType">
|
||||
<sequence>
|
||||
<!-- Title in text form. (Using spaces, not underscores; with namespace ) -->
|
||||
<element name="title" type="string" />
|
||||
|
||||
<!-- Namespace in canonical form -->
|
||||
<element name="ns" type="nonNegativeInteger" />
|
||||
|
||||
<!-- optional page ID number -->
|
||||
<element name="id" type="positiveInteger" />
|
||||
|
||||
<!-- flag if the current revision is a redirect -->
|
||||
<element name="redirect" type="mw:RedirectType" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
<!-- comma-separated list of string tokens, if present -->
|
||||
<element name="restrictions" type="string" minOccurs="0" />
|
||||
|
||||
<!-- Zero or more sets of revision or upload data -->
|
||||
<choice minOccurs="0" maxOccurs="unbounded">
|
||||
<element name="revision" type="mw:RevisionType" />
|
||||
<element name="upload" type="mw:UploadType" />
|
||||
</choice>
|
||||
|
||||
<!-- Zero or One sets of discussion threading data -->
|
||||
<element name="discussionthreadinginfo" minOccurs="0" maxOccurs="1" type="mw:DiscussionThreadingInfo" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="RevisionType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" />
|
||||
<element name="parentid" type="positiveInteger" minOccurs="0" />
|
||||
<element name="timestamp" type="dateTime" />
|
||||
<element name="contributor" type="mw:ContributorType" />
|
||||
<element name="minor" minOccurs="0" maxOccurs="1" />
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0" maxOccurs="1" />
|
||||
<element name="text" type="mw:TextType" />
|
||||
<element name="sha1" type="string" />
|
||||
<element name="model" type="mw:ContentModelType" />
|
||||
<element name="format" type="mw:ContentFormatType" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogItemType">
|
||||
<sequence>
|
||||
<element name="id" type="positiveInteger" />
|
||||
<element name="timestamp" type="dateTime" />
|
||||
<element name="contributor" type="mw:ContributorType" />
|
||||
<element name="comment" type="mw:CommentType" minOccurs="0" />
|
||||
<element name="type" type="string" />
|
||||
<element name="action" type="string" />
|
||||
<element name="text" type="mw:LogTextType" minOccurs="0" maxOccurs="1" />
|
||||
<element name="logtitle" type="string" minOccurs="0" maxOccurs="1" />
|
||||
<element name="params" type="mw:LogParamsType" minOccurs="0" maxOccurs="1" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<complexType name="CommentType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="TextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
<!-- This isn't a good idea; we should be using "ID" instead of "NMTOKEN" -->
|
||||
<!-- However, "NMTOKEN" is strictest definition that is both compatible with existing -->
|
||||
<!-- usage ([0-9]+) and with the "ID" type. -->
|
||||
<attribute name="id" type="NMTOKEN" />
|
||||
<attribute name="bytes" use="optional" type="nonNegativeInteger" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogTextType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="LogParamsType">
|
||||
<simpleContent>
|
||||
<extension base="string">
|
||||
<attribute ref="xml:space" use="optional" default="preserve" />
|
||||
</extension>
|
||||
</simpleContent>
|
||||
</complexType>
|
||||
|
||||
<complexType name="ContributorType">
|
||||
<sequence>
|
||||
<element name="username" type="string" minOccurs="0" />
|
||||
<element name="id" type="nonNegativeInteger" minOccurs="0" />
|
||||
|
||||
<element name="ip" type="string" minOccurs="0" />
|
||||
</sequence>
|
||||
<!-- This allows deleted=deleted on non-empty elements, but XSD is not omnipotent -->
|
||||
<attribute name="deleted" use="optional" type="mw:DeletedFlagType" />
|
||||
</complexType>
|
||||
|
||||
<complexType name="UploadType">
|
||||
<sequence>
|
||||
<!-- Revision-style data... -->
|
||||
<element name="timestamp" type="dateTime" />
|
||||
<element name="contributor" type="mw:ContributorType" />
|
||||
<element name="comment" type="string" minOccurs="0" />
|
||||
|
||||
<!-- Filename. (Using underscores, not spaces. No 'File:' namespace marker.) -->
|
||||
<element name="filename" type="string" />
|
||||
|
||||
<!-- URI at which this resource can be obtained -->
|
||||
<element name="src" type="anyURI" />
|
||||
|
||||
<element name="size" type="positiveInteger" />
|
||||
|
||||
<!-- TODO: add other metadata fields -->
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
<!-- Discussion threading data for LiquidThreads -->
|
||||
<complexType name="DiscussionThreadingInfo">
|
||||
<sequence>
|
||||
<element name="ThreadSubject" type="string" />
|
||||
<element name="ThreadParent" type="positiveInteger" />
|
||||
<element name="ThreadAncestor" type="positiveInteger" />
|
||||
<element name="ThreadPage" type="string" />
|
||||
<element name="ThreadID" type="positiveInteger" />
|
||||
<element name="ThreadAuthor" type="string" />
|
||||
<element name="ThreadEditStatus" type="string" />
|
||||
<element name="ThreadType" type="string" />
|
||||
</sequence>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
157
sources/mediawiki/docs/export-demo.xml
Normal file
157
sources/mediawiki/docs/export-demo.xml
Normal file
|
@ -0,0 +1,157 @@
|
|||
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.8/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.8/ http://www.mediawiki.org/xml/export-0.8.xsd" version="0.8" xml:lang="en">
|
||||
|
||||
<!-- Optional global configuration info -->
|
||||
<siteinfo>
|
||||
<!-- Site name, as set in $wgSitename -->
|
||||
<sitename>DemoWiki</sitename>
|
||||
|
||||
<!-- Forgot where you got this set? -->
|
||||
<base>http://example.com/wiki/Main_Page</base>
|
||||
|
||||
<!-- Source software version -->
|
||||
<generator>MediaWiki 1.20</generator>
|
||||
|
||||
<!-- Title case sensitivity options of the wiki this data came from -->
|
||||
<!-- May be 'first-letter', 'case-sensitive', or 'case-insensitive' -->
|
||||
<case>first-letter</case>
|
||||
|
||||
<!-- Defined namespace keys on the source wiki. -->
|
||||
<namespaces>
|
||||
<namespace key="-2" case="first-letter">Media</namespace>
|
||||
<namespace key="-1" case="first-letter">Special</namespace>
|
||||
<namespace key="0" case="first-letter" />
|
||||
<namespace key="1" case="first-letter">Talk</namespace>
|
||||
<namespace key="2" case="first-letter">User</namespace>
|
||||
<namespace key="3" case="first-letter">User talk</namespace>
|
||||
<namespace key="4" case="first-letter">DemoWiki</namespace>
|
||||
<namespace key="5" case="first-letter">DemoWIki talk</namespace>
|
||||
<namespace key="6" case="first-letter">File</namespace>
|
||||
<namespace key="7" case="first-letter">File talk</namespace>
|
||||
<namespace key="8" case="first-letter">MediaWiki</namespace>
|
||||
<namespace key="9" case="first-letter">MediaWiki talk</namespace>
|
||||
<namespace key="10" case="first-letter">Template</namespace>
|
||||
<namespace key="11" case="first-letter">Template talk</namespace>
|
||||
<namespace key="12" case="first-letter">Help</namespace>
|
||||
<namespace key="13" case="first-letter">Help talk</namespace>
|
||||
<namespace key="14" case="first-letter">Category</namespace>
|
||||
<namespace key="15" case="first-letter">Category talk</namespace>
|
||||
</namespaces>
|
||||
</siteinfo>
|
||||
|
||||
<!-- The rest of the data will be a series of page records -->
|
||||
<page>
|
||||
<!-- Titles are listed here in text form, with namespace prefix -->
|
||||
<!-- if any, and spaces rather than the underscores used in URLs. -->
|
||||
<title>Page title</title>
|
||||
|
||||
<!-- Namespace in canonical form -->
|
||||
<ns>0</ns>
|
||||
|
||||
<!-- The page's immutable page_id number in the source database. -->
|
||||
<!-- Page ID numbers are kept across page moves, but may change -->
|
||||
<!-- if a page is deleted and recreated. -->
|
||||
<id>1</id>
|
||||
|
||||
<!-- Tag wether this article is a redirect and its target -->
|
||||
<!-- This corresponds to the page_is_redirect in the page table -->
|
||||
<redirect title="Target" />
|
||||
|
||||
<!-- If restricted, the ACL is listed here raw. -->
|
||||
<restrictions>edit=sysop:move=sysop</restrictions>
|
||||
|
||||
<!-- With a series of revision records... -->
|
||||
|
||||
<!-- Remember this is XML; if you must use a regex-based extractor -->
|
||||
<!-- in place of a standard XML parser, be very careful. -->
|
||||
<!-- * Don't forget to decode character entities! -->
|
||||
<!-- * If using a 'loose' XML parser, ensure that whitespace is -->
|
||||
<!-- preserved in the <text> elements. -->
|
||||
<revision>
|
||||
<!-- Unique revision ID number (rev_id) in the source database. -->
|
||||
<!-- This number uniquely identifies the revision on that wiki. -->
|
||||
<id>100</id>
|
||||
<!-- revision id of the parent revision -->
|
||||
<parentid>99</parentid>
|
||||
<timestamp>2001-01-15T13:15:00Z</timestamp>
|
||||
<contributor>
|
||||
<username>Foobar</username>
|
||||
<id>42</id>
|
||||
</contributor>
|
||||
<minor />
|
||||
<comment>I have just one thing to say!</comment>
|
||||
<text xml:space="preserve" bytes="25">A bunch of [[text]] here.</text>
|
||||
<sha1>5x0ux8iwjrbmfzgv6pkketxgkcnpr7h</sha1>
|
||||
<model>wikitext</model>
|
||||
<format>text/x-wiki</format>
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<id>99</id>
|
||||
<timestamp>2001-01-15T13:10:27Z</timestamp>
|
||||
<contributor>
|
||||
<ip>10.0.0.2</ip>
|
||||
</contributor>
|
||||
<comment>new!</comment>
|
||||
<text xml:space="preserve" bytes="24">An earlier [[revision]].</text>
|
||||
<sha1>etaxt3shcge6igz1biwy3d4um2pnle4</sha1>
|
||||
<model>wikitext</model>
|
||||
<format>text/x-wiki</format>
|
||||
</revision>
|
||||
</page>
|
||||
|
||||
<page>
|
||||
<title>Talk:Page title</title>
|
||||
<ns>1</ns>
|
||||
<id>2</id>
|
||||
<revision>
|
||||
<id>101</id>
|
||||
<timestamp>2001-01-15T14:03:00Z</timestamp>
|
||||
<contributor><ip>10.0.0.2</ip></contributor>
|
||||
<comment>hey</comment>
|
||||
<text xml:space="preserve" bytes="47">WHYD YOU LOCK PAGE??!!! i was editing that jerk</text>
|
||||
<sha1>ml80vmyjlixdstnywwihx003exfzq9j</sha1>
|
||||
<model>wikitext</model>
|
||||
<format>text/x-wiki</format>
|
||||
</revision>
|
||||
</page>
|
||||
|
||||
<page>
|
||||
<title>File:Some image.jpg</title>
|
||||
<ns>6</ns>
|
||||
<id>3</id>
|
||||
<revision>
|
||||
<id>102</id>
|
||||
<timestamp>2001-01-15T20:34:12Z</timestamp>
|
||||
<contributor><username>Foobar</username><id>42</id></contributor>
|
||||
<comment>My awesomeest image!</comment>
|
||||
<text xml:space="preserve" bytes="52">This is an awesome little imgae. I lurves it. {{PD}}</text>
|
||||
<sha1>mehom37npwkpzhaiwu3wyr0egalumki</sha1>
|
||||
<model>wikitext</model>
|
||||
<format>text/x-wiki</format>
|
||||
</revision>
|
||||
<upload>
|
||||
<timestamp>2001-01-15T20:34:12Z</timestamp>
|
||||
<contributor><username>Foobar</username><id>42</id></contributor>
|
||||
<comment>My awesomeest image!</comment>
|
||||
<filename>Some_image.jpg</filename>
|
||||
<src>http://upload.wikimedia.org/commons/2/22/Some_image.jpg</src>
|
||||
<size>12345</size>
|
||||
</upload>
|
||||
</page>
|
||||
|
||||
<!-- or a series of logitem records, but normaly page and logitem never exist both in one file -->
|
||||
<logitem>
|
||||
<id>15</id>
|
||||
<timestamp>2008-10-23T03:20:32Z</timestamp>
|
||||
<contributor>
|
||||
<username>Wikimedian</username>
|
||||
<id>12345</id>
|
||||
</contributor>
|
||||
<comment>content was: 'I think this was a silly edit'</comment>
|
||||
<type>delete</type>
|
||||
<action>delete</action>
|
||||
<logtitle>Silly page name</logtitle>
|
||||
<params xml:space="preserve" />
|
||||
</logitem>
|
||||
|
||||
</mediawiki>
|
67
sources/mediawiki/docs/globals.txt
Normal file
67
sources/mediawiki/docs/globals.txt
Normal file
|
@ -0,0 +1,67 @@
|
|||
globals.txt
|
||||
|
||||
Globals are evil. The original MediaWiki code relied on globals for processing
|
||||
context far too often. MediaWiki development since then has been a story of
|
||||
slowly moving context out of global variables and into objects. Storing
|
||||
processing context in object member variables allows those objects to be reused
|
||||
in a much more flexible way. Consider the elegance of:
|
||||
|
||||
# Generate the article HTML as if viewed by a web request
|
||||
$article = new Article( Title::newFromText( $t ) );
|
||||
$article->view();
|
||||
|
||||
versus
|
||||
|
||||
# Save current globals
|
||||
$oldTitle = $wgTitle;
|
||||
$oldArticle = $wgArticle;
|
||||
|
||||
# Generate the HTML
|
||||
$wgTitle = Title::newFromText( $t );
|
||||
$wgArticle = new Article;
|
||||
$wgArticle->view();
|
||||
|
||||
# Restore globals
|
||||
$wgTitle = $oldTitle
|
||||
$wgArticle = $oldArticle
|
||||
|
||||
Some of the current MediaWiki developers have an idle fantasy that some day,
|
||||
globals will be eliminated from MediaWiki entirely, replaced by an application
|
||||
object which would be passed to constructors. Whether that would be an
|
||||
efficient, convenient solution remains to be seen, but certainly PHP 5 makes
|
||||
such object-oriented programming models easier than they were in previous
|
||||
versions.
|
||||
|
||||
For the time being though, MediaWiki programmers will have to work in an
|
||||
environment with some global context. At the time of writing, 418 globals were
|
||||
initialised on startup by MediaWiki. 304 of these were configuration settings,
|
||||
which are documented in DefaultSettings.php. There is no comprehensive
|
||||
documentation for the remaining 114 globals, however some of the most important
|
||||
ones are listed below. They are typically initialised either in index.php or in
|
||||
Setup.php.
|
||||
|
||||
For a description of the classes, see design.txt.
|
||||
|
||||
$wgTitle
|
||||
Title object created from the request URL.
|
||||
|
||||
$wgOut
|
||||
OutputPage object for HTTP response.
|
||||
|
||||
$wgUser
|
||||
User object for the user associated with the current request.
|
||||
|
||||
$wgLang
|
||||
Language object selected by user preferences.
|
||||
|
||||
$wgContLang
|
||||
Language object associated with the wiki being viewed.
|
||||
|
||||
$wgParser
|
||||
Parser object. Parser extensions register their hooks here.
|
||||
|
||||
$wgRequest
|
||||
WebRequest object, to get request data
|
||||
|
||||
$wgMemc, $messageMemc, $parserMemc
|
||||
Object caches
|
2829
sources/mediawiki/docs/hooks.txt
Normal file
2829
sources/mediawiki/docs/hooks.txt
Normal file
File diff suppressed because it is too large
Load diff
4
sources/mediawiki/docs/html/README
Normal file
4
sources/mediawiki/docs/html/README
Normal file
|
@ -0,0 +1,4 @@
|
|||
This directory is for the auto-generated doxygen documentation.
|
||||
Run 'php mwdocgen.php' in the maintenance subdirectory to build the docs.
|
||||
|
||||
Get Doxygen from http://www.doxygen.org/
|
5
sources/mediawiki/docs/language.txt
Normal file
5
sources/mediawiki/docs/language.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
language.txt
|
||||
|
||||
The Language object handles all readable text produced by the software.
|
||||
|
||||
See http://www.mediawiki.org/wiki/Localisation#General_use_.28for_developers.29
|
24
sources/mediawiki/docs/linkcache.txt
Normal file
24
sources/mediawiki/docs/linkcache.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
linkcache.txt
|
||||
|
||||
The LinkCache class maintains a list of article titles and the information about
|
||||
whether or not the article exists in the database. This is used to mark up links
|
||||
when displaying a page. If the same link appears more than once on any page,
|
||||
then it only has to be looked up once. In most cases, link lookups are done in
|
||||
batches with the LinkBatch class, or the equivalent in Parser::replaceLinkHolders(),
|
||||
so the link cache is mostly useful for short snippets of parsed text (such as
|
||||
the site notice), and for links in the navigation areas of the skin.
|
||||
|
||||
The link cache was formerly used to track links used in a document for the
|
||||
purposes of updating the link tables. This application is now deprecated.
|
||||
|
||||
To create a batch, you can use the following code:
|
||||
|
||||
$pages = array( 'Main Page', 'Project:Help', /* ... */ );
|
||||
$titles = array();
|
||||
|
||||
foreach( $pages as $page ){
|
||||
$titles[] = Title::newFromText( $page );
|
||||
}
|
||||
|
||||
$batch = new LinkBatch( $titles );
|
||||
$batch->execute();
|
95
sources/mediawiki/docs/magicword.txt
Normal file
95
sources/mediawiki/docs/magicword.txt
Normal file
|
@ -0,0 +1,95 @@
|
|||
magicword.txt
|
||||
|
||||
Magic Words are some phrases used in the wikitext. They are used for two things:
|
||||
* Variables (like {{PAGENAME}}, {{SERVER}}, ...): part of wikitext, that looks
|
||||
like templates but that don't accept any parameter.
|
||||
* Parser functions (like {{fullurl:...}}, {{#special:...}}): behaves like
|
||||
functions and accepts parameters.
|
||||
|
||||
The localized arrays keys are the internal name, and the values are an array,
|
||||
whose include their case-sensitivity and their alias forms. The first form
|
||||
defined is used by the program, for example, when moving a page and its old name
|
||||
should include #REDIRECT.
|
||||
|
||||
They can be added in several arrays:
|
||||
* By adding a file to $wgExtensionMessagesFiles and defining there $magicWords.
|
||||
This array is associative with the language code in the first dimension key
|
||||
and then a "normal" array of magic words.
|
||||
* Localized arrays (languages/messages/LanguageXX.php) include their different
|
||||
names to be used by the users.
|
||||
|
||||
To add a new variable, you should use the "MagicWordwgVariableIDs" hook to add
|
||||
the internal name to the $magicWords array. You'll need to define the value of
|
||||
the variable with the "ParserGetVariableValueSwitch" hook.
|
||||
|
||||
For example to add a new variable:
|
||||
|
||||
Create a file called ExtensionName.i18n.magic.php with the following contents:
|
||||
----
|
||||
<?php
|
||||
|
||||
$magicWords = array();
|
||||
|
||||
$magicWords['en'] = array(
|
||||
// Case sensitive.
|
||||
'mag_custom' => array( 1, 'CUSTOM' ),
|
||||
);
|
||||
|
||||
$magicWords['es'] = array(
|
||||
'mag_custom' => array( 1, 'ADUANERO' ),
|
||||
);
|
||||
----
|
||||
|
||||
$wgExtensionMessagesFiles['ExtensionNameMagic'] = __DIR__ . '/ExtensionName.i18n.magic.php';
|
||||
$wgHooks['MagicWordwgVariableIDs'][] = 'wfAddCustomMagicWordID';
|
||||
$wgHooks['ParserGetVariableValueSwitch'][] = 'wfGetCustomMagicWordValue';
|
||||
|
||||
function wfAddCustomMagicWordID( &$magicWords ) {
|
||||
$magicWords[] = 'mag_custom';
|
||||
return true;
|
||||
}
|
||||
|
||||
function wfGetCustomMagicWordValue( &$parser, &$varCache, &$index, &$ret ){
|
||||
if( $index == 'mag_custom' ){
|
||||
$ret = $varCache['mag_custom'] = "Custom value";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
And to add a new parser function:
|
||||
|
||||
Create a file called ExtensionName.i18n.magic.php with the following contents:
|
||||
----
|
||||
<?php
|
||||
|
||||
$magicWords = array();
|
||||
|
||||
$magicWords['en'] = array(
|
||||
// Case insensitive.
|
||||
'mag_custom' => array( 0, 'custom' ),
|
||||
);
|
||||
|
||||
$magicWords['es'] = array(
|
||||
'mag_custom' => array( 0, 'aduanero' ),
|
||||
);
|
||||
----
|
||||
|
||||
$wgExtensionMessagesFiles['ExtensionNameMagic'] = __DIR__ . '/ExtensionName.i18n.magic.php';
|
||||
$wgHooks['ParserFirstCallInit'][] = 'wfRegisterCustomMagicWord';
|
||||
|
||||
function wfRegisterCustomMagicWord( &$parser ){
|
||||
$parser->setFunctionHook( 'mag_custom', 'wfGetCustomMagicWordValue' );
|
||||
return true;
|
||||
}
|
||||
|
||||
function wfGetCustomMagicWordValue( &$parser, $var1, $var2 ){
|
||||
return "custom: var1 is $var1, var2 is $var2";
|
||||
}
|
||||
|
||||
Note: the 'ParserFirstCallInit' hook is only aviable since 1.12. To work with
|
||||
an older version, you'll need to use an extension function.
|
||||
|
||||
Online documentation (contains more informations):
|
||||
Magic words: http://www.mediawiki.org/wiki/Manual:Magic_words
|
||||
Variables: http://www.mediawiki.org/wiki/Manual:Variable
|
||||
Parser functions: http://www.mediawiki.org/wiki/Manual:Parser_functions
|
57
sources/mediawiki/docs/maintenance.txt
Normal file
57
sources/mediawiki/docs/maintenance.txt
Normal file
|
@ -0,0 +1,57 @@
|
|||
Prior to version 1.16, maintenance scripts were a hodgepodge of code that
|
||||
had no cohesion or formal method of action. Beginning in 1.16, maintenance
|
||||
scripts have been cleaned up to use a unified class.
|
||||
|
||||
1. Directory structure
|
||||
2. How to run a script
|
||||
3. How to write your own
|
||||
|
||||
1. DIRECTORY STRUCTURE
|
||||
The /maintenance directory of a MediaWiki installation contains several
|
||||
subdirectories, all of which have unique purposes.
|
||||
|
||||
2. HOW TO RUN A SCRIPT
|
||||
Ridiculously simple, just call 'php someScript.php' that's in the top-
|
||||
level /maintenance directory.
|
||||
|
||||
Example:
|
||||
php clearCacheStats.php
|
||||
|
||||
The following parameters are available to all maintenance scripts
|
||||
--help : Print a help message
|
||||
--quiet : Quiet non-error output
|
||||
--dbuser : The database user to use for the script (if needed)
|
||||
--dbpass : Same as above (if needed)
|
||||
--conf : Location of LocalSettings.php, if not default
|
||||
--wiki : For specifying the wiki ID
|
||||
--batch-size : If the script supports batch operations, do this many per batch
|
||||
|
||||
3. HOW TO WRITE YOUR OWN
|
||||
Make a file in the maintenance directory called myScript.php or something.
|
||||
In it, write the following:
|
||||
|
||||
==BEGIN==
|
||||
|
||||
<?php
|
||||
|
||||
require_once 'Maintenance.php';
|
||||
|
||||
class DemoMaint extends Maintenance {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
}
|
||||
}
|
||||
|
||||
$maintClass = "DemoMaint";
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
|
||||
==END==
|
||||
|
||||
That's it. In the execute() method, you have access to all of the normal
|
||||
MediaWiki functions, so you can get a DB connection, use the cache, etc.
|
||||
For full docs on the Maintenance class, see the auto-generated docs at
|
||||
http://svn.wikimedia.org/doc/classMaintenance.html
|
251
sources/mediawiki/docs/memcached.txt
Normal file
251
sources/mediawiki/docs/memcached.txt
Normal file
|
@ -0,0 +1,251 @@
|
|||
MediaWiki has optional support for memcached, a "high-performance,
|
||||
distributed memory object caching system". For general information
|
||||
on it, see: http://www.danga.com/memcached/
|
||||
|
||||
Memcached is likely more trouble than a small site will need, but
|
||||
for a larger site with heavy load, like Wikipedia, it should help
|
||||
lighten the load on the database servers by caching data and objects
|
||||
in memory.
|
||||
|
||||
== Installation ==
|
||||
|
||||
Packages are available for Fedora, Debian, Ubuntu and probably other
|
||||
Linux distributions. If you there's no package available for your
|
||||
distribution, you can compile it from source.
|
||||
|
||||
== Compilation ==
|
||||
|
||||
* PHP must be compiled with --enable-sockets
|
||||
|
||||
* libevent: http://www.monkey.org/~provos/libevent/
|
||||
(as of 2003-08-11, 0.7a is current)
|
||||
|
||||
* optionally, epoll-rt patch for Linux kernel:
|
||||
http://www.xmailserver.org/linux-patches/nio-improve.html
|
||||
|
||||
* memcached: http://www.danga.com/memcached/download.bml
|
||||
(as of this writing, 1.1.9 is current)
|
||||
|
||||
Memcached and libevent are under BSD-style licenses.
|
||||
|
||||
The server should run on Linux and other Unix-like systems... you
|
||||
can run multiple servers on one machine or on multiple machines on
|
||||
a network; storage can be distributed across multiple servers, and
|
||||
multiple web servers can use the same cache cluster.
|
||||
|
||||
********************* W A R N I N G ! ! ! ! ! ***********************
|
||||
Memcached has no security or authentication. Please ensure that your
|
||||
server is appropriately firewalled, and that the port(s) used for
|
||||
memcached servers are not publicly accessible. Otherwise, anyone on
|
||||
the internet can put data into and read data from your cache.
|
||||
|
||||
An attacker familiar with MediaWiki internals could use this to steal
|
||||
passwords and email addresses, or to make themselves a sysop and
|
||||
install malicious javascript on the site. There may be other types
|
||||
of vulnerability, no audit has been done -- so be safe and keep it
|
||||
behind a firewall.
|
||||
********************* W A R N I N G ! ! ! ! ! ***********************
|
||||
|
||||
== Setup ==
|
||||
|
||||
If you installed memcached using a distro, the daemon should be started
|
||||
automatically using /etc/init.d/memcached.
|
||||
|
||||
To start the daemon manually, use something like:
|
||||
|
||||
memcached -d -l 127.0.0.1 -p 11211 -m 64
|
||||
|
||||
(to run in daemon mode, accessible only via loopback interface,
|
||||
on port 11211, using up to 64MB of memory)
|
||||
|
||||
In your LocalSettings.php file, set:
|
||||
|
||||
$wgMainCacheType = CACHE_MEMCACHED;
|
||||
$wgMemCachedServers = array( "127.0.0.1:11211" );
|
||||
|
||||
The wiki should then use memcached to cache various data. To use
|
||||
multiple servers (physically separate boxes or multiple caches
|
||||
on one machine on a large-memory x86 box), just add more items
|
||||
to the array. To increase the weight of a server (say, because
|
||||
it has twice the memory of the others and you want to spread
|
||||
usage evenly), make its entry a subarray:
|
||||
|
||||
$wgMemCachedServers = array(
|
||||
"127.0.0.1:11211", # one gig on this box
|
||||
array("192.168.0.1:11211", 2 ) # two gigs on the other box
|
||||
);
|
||||
|
||||
== PHP client for memcached ==
|
||||
|
||||
MediaWiki uses a fork of Ryan T. Dean's pure-PHP memcached client.
|
||||
The newer PECL module is supported.
|
||||
|
||||
MediaWiki uses three object for object caching:
|
||||
* $wgMemc, controlled by $wgMainCacheType
|
||||
* $parserMemc, controlled by $wgParserCacheType
|
||||
* $messageMemc, controlled by $wgMessageCacheType
|
||||
If you set CACHE_NONE to one of the three control variable, (default
|
||||
value for $wgMainCacheType), MediaWiki still create a MemCacheClient,
|
||||
but requests to it are no-ops and we always fall through to the
|
||||
database. If the cache daemon can't be contacted, it should also
|
||||
disable itself fairly smoothly.
|
||||
|
||||
By default, $wgMemc is used but when it is $parserMemc or $messageMemc
|
||||
this is mentionned below.
|
||||
|
||||
== Keys used ==
|
||||
|
||||
(incomplete, out of date)
|
||||
|
||||
Date Formatter:
|
||||
key: $wgDBname:dateformatter
|
||||
ex: wikidb:dateformatter
|
||||
stores: a single instance of the DateFormatter class
|
||||
cleared by: nothing
|
||||
expiry: one hour
|
||||
|
||||
Difference Engine:
|
||||
key: $wgDBname:diff:version:{MW_DIFF_VERSION}:oldid:$old:newid:$new
|
||||
ex: wikidb:diff:version:1.11a:oldid:1:newid:2
|
||||
stores: body of a difference
|
||||
cleared by: nothing
|
||||
expiry: one week
|
||||
|
||||
Interwiki:
|
||||
key: $wgDBname:interwiki:$prefix
|
||||
ex: wikidb:interwiki:w
|
||||
stores: object from the interwiki table of the database
|
||||
expiry: $wgInterwikiExpiry
|
||||
cleared by: nothing
|
||||
|
||||
Lag time of the databases:
|
||||
key: $wgDBname:lag_times
|
||||
ex: wikidb:lag_times
|
||||
stores: array mapping the database id to its lag time
|
||||
expriy: 5 secondes
|
||||
cleared by: nothing
|
||||
|
||||
Localisation:
|
||||
key: $wgDBname:localisation:$lang
|
||||
ex: wikidb:localisation:de
|
||||
stores: array of localisation settings
|
||||
set in: Language::loadLocalisation()
|
||||
expiry: none
|
||||
cleared by: Language::loadLocalisation()
|
||||
|
||||
Message Cache:
|
||||
stored in: $messageMemc
|
||||
key: $wgDBname:messages, $wgDBname:messages-hash, $wgDBname:messages-status
|
||||
ex: wikidb:messages, wikidb:messages-hash, wikidb:messages-status
|
||||
stores: an array where the keys are DB keys and the values are messages
|
||||
set in: wfMessage(), Article::editUpdates() and Title::moveTo()
|
||||
expriy: $wgMsgCacheExpiry
|
||||
cleared by: nothing
|
||||
|
||||
Newtalk:
|
||||
key: $wgDBname:newtalk:ip:$ip
|
||||
ex: wikidb:newtalk:ip:123.45.67.89
|
||||
stores: integer, 0 or 1
|
||||
set in: User::loadFromDatabase()
|
||||
cleared by: User::saveSettings() # ?
|
||||
expiry: 30 minutes
|
||||
|
||||
Parser Cache:
|
||||
stored in: $parserMemc
|
||||
controlled by: $wgEnableParserCache
|
||||
key: $wgDBname:pcache:idhash:$pageid-$renderkey!$hash
|
||||
$pageid: id of the page
|
||||
$renderkey: 1 if action=render, 0 otherwise
|
||||
$hash: hash of user options applied to the page, see ParserOptions::optionsHash()
|
||||
ex: wikidb:pcache:idhash:1-0!1!0!!en!2
|
||||
stores: ParserOutput object
|
||||
modified by: WikiPage::doEditUpdates() or PoolWorkArticleView::doWork()
|
||||
expiry: $wgParserCacheExpireTime or less if it contains short lived functions
|
||||
|
||||
key: $wgDBname:pcache:idoptions:$pageid
|
||||
stores: CacheTime object with an additional list of used options for the hash,
|
||||
serves as ParserCache pointer.
|
||||
modified by: ParserCache::save()
|
||||
expiry: The same as the ParserCache entry it points to.
|
||||
|
||||
Ping limiter:
|
||||
controlled by: $wgRateLimits
|
||||
key: $wgDBname:limiter:action:$action:ip:$ip,
|
||||
$wgDBname:limiter:action:$action:user:$id,
|
||||
mediawiki:limiter:action:$action:ip:$ip and
|
||||
mediawiki:limiter:action:$action:subnet:$sub
|
||||
ex: wikidb:limiter:action:edit:ip:123.45.67.89,
|
||||
wikidb:limiter:action:edit:user:1012
|
||||
mediawiki:limiter:action:edit:ip:123.45.67.89 and
|
||||
mediawiki:limiter:action:$action:subnet:123.45.67
|
||||
stores: number of action made by user/ip/subnet
|
||||
cleared by: nothing
|
||||
expiry: expiry set for the action and group in $wgRateLimits
|
||||
|
||||
|
||||
Proxy Check: (deprecated)
|
||||
key: $wgDBname:proxy:ip:$ip
|
||||
ex: wikidb:proxy:ip:123.45.67.89
|
||||
stores: 1 if the ip is a proxy
|
||||
cleared by: nothing
|
||||
expiry: $wgProxyMemcExpiry
|
||||
|
||||
Revision text:
|
||||
key: $wgDBname:revisiontext:textid:$id
|
||||
ex: wikidb:revisiontext:textid:1012
|
||||
stores: text of a revision
|
||||
cleared by: nothing
|
||||
expriry: $wgRevisionCacheExpiry
|
||||
|
||||
Sessions:
|
||||
controlled by: $wgSessionsInObjectCache
|
||||
key: $wgBDname:session:$id
|
||||
ex: wikidb:session:38d7c5b8d3bfc51egf40c69bc40f8be3
|
||||
stores: $SESSION, useful when using a multi-sever wiki
|
||||
expriy: one hour
|
||||
cleared by: session_destroy()
|
||||
|
||||
Sidebar:
|
||||
stored in: $parserMemc
|
||||
controlled by: $wgEnableSidebarCache
|
||||
key: $wgDBname:sidebar
|
||||
ex: wikidb:sidebar
|
||||
stores: the html output of the sidebar
|
||||
expriy: $wgSidebarCacheExpiry
|
||||
cleared by: MessageCache::replace()
|
||||
|
||||
Special:Allpages:
|
||||
key: $wgDBname:allpages:ns:$ns
|
||||
ex: wikidb:allpages:ns:0
|
||||
stores: array of pages in a namespace
|
||||
expiry: one hour
|
||||
cleared by: nothing
|
||||
|
||||
Special:Recentchanges (feed):
|
||||
stored in: $messageMemc
|
||||
key: $wgDBname:rcfeed:$format:$limit:$hideminor:$target and
|
||||
rcfeed:$format:timestamp
|
||||
ex: wikidb:rcfeed:rss:50:: and rcfeed:rss:timestamp
|
||||
stores: xml output of feed
|
||||
expiry: one day
|
||||
clear by: maintenance/rebuildrecentchanges.php script, or
|
||||
calling Special:Recentchanges?action=purge&feed=rss,
|
||||
Special:Recentchanges?action=purge&feed=atom,
|
||||
but note need $wgGroupPermissions[...]['purge'] permission.
|
||||
|
||||
Statistics:
|
||||
controlled by: $wgStatsMethod
|
||||
key: $wgDBname:stats:$key
|
||||
ex: wikibd:stats:request_with_session
|
||||
stores: counter for statistics (see maintenance/showCacheStats.php script)
|
||||
expiry: none (?)
|
||||
cleared by: maintenance/clearCacheStats.php script
|
||||
|
||||
User:
|
||||
key: $wgDBname:user:id:$sId
|
||||
ex: wikidb:user:id:51
|
||||
stores: instance of class User
|
||||
set in: User::saveToCache()
|
||||
cleared by: User::saveSettings(), User::clearSharedCache()
|
||||
|
||||
... more to come ...
|
28
sources/mediawiki/docs/php-memcached/ChangeLog
Normal file
28
sources/mediawiki/docs/php-memcached/ChangeLog
Normal file
|
@ -0,0 +1,28 @@
|
|||
09 Oct 2003:
|
||||
1455 UTC:
|
||||
Released version 0.1.2
|
||||
Fixed bug in get_multi; when debugging was enabled but no keys were fetched,
|
||||
script execution would halt (uninitialized $val)
|
||||
|
||||
08 Oct 2003:
|
||||
1848 UTC:
|
||||
Released version 0.1.1
|
||||
|
||||
1825 UTC:
|
||||
Fixed bug in memcached::memcached; was attempting to initialize
|
||||
memcached::_dead_sock (function) instead of memcached::_dead_hosts
|
||||
(oops!)
|
||||
|
||||
1812 UTC:
|
||||
Fixed memcached::enable_compression;
|
||||
thanks to Justin Matlock <jmat@shutdown.net> for pointing it out
|
||||
|
||||
07 Oct 2003:
|
||||
1635 UTC:
|
||||
Fixed call to memcached::_dead_sock in memcached::delete
|
||||
Added documentation for class variable $_buckets
|
||||
|
||||
06 Oct 2003:
|
||||
2039 UTC:
|
||||
Initial release of memcached-client-php; version 0.1
|
||||
|
258
sources/mediawiki/docs/php-memcached/Documentation
Normal file
258
sources/mediawiki/docs/php-memcached/Documentation
Normal file
|
@ -0,0 +1,258 @@
|
|||
Ryan Gilfether <hotrodder@rocketmail.com>
|
||||
http://www.gilfether.com
|
||||
This module is Copyright (c) 2003 Ryan Gilfether.
|
||||
All rights reserved.
|
||||
|
||||
You may distribute under the terms of the GNU General Public License
|
||||
This is free software. IT COMES WITHOUT WARRANTY OF ANY KIND.
|
||||
|
||||
See the memcached website: http://www.danga.com/memcached/
|
||||
|
||||
|
||||
// Takes one parameter, a array of options. The most important key is
|
||||
// options["servers"], but that can also be set later with the set_servers()
|
||||
// method. The servers must be an array of hosts, each of which is
|
||||
// either a scalar of the form <10.0.0.10:11211> or an array of the
|
||||
// former and an integer weight value. (the default weight if
|
||||
// unspecified is 1.) It's recommended that weight values be kept as low
|
||||
// as possible, as this module currently allocates memory for bucket
|
||||
// distribution proportional to the total host weights.
|
||||
// $options["debug"] turns the debugging on if set to true
|
||||
MemCachedClient::MemCachedClient($options);
|
||||
|
||||
// sets up the list of servers and the ports to connect to
|
||||
// takes an array of servers in the same format as in the constructor
|
||||
MemCachedClient::set_servers($servers);
|
||||
|
||||
// Retrieves a key from the memcache. Returns the value (automatically
|
||||
// unserialized, if necessary) or FALSE if it fails.
|
||||
// The $key can optionally be an array, with the first element being the
|
||||
// hash value, if you want to avoid making this module calculate a hash
|
||||
// value. You may prefer, for example, to keep all of a given user's
|
||||
// objects on the same memcache server, so you could use the user's
|
||||
// unique id as the hash value.
|
||||
// Possible errors set are:
|
||||
// MC_ERR_GET
|
||||
MemCachedClient::get($key);
|
||||
|
||||
// just like get(), but takes an array of keys, returns FALSE on error
|
||||
// Possible errors set are:
|
||||
// MC_ERR_NOT_ACTIVE
|
||||
MemCachedClient::get_multi($keys)
|
||||
|
||||
// Unconditionally sets a key to a given value in the memcache. Returns true
|
||||
// if it was stored successfully.
|
||||
// The $key can optionally be an arrayref, with the first element being the
|
||||
// hash value, as described above.
|
||||
// returns TRUE on success else FALSE
|
||||
// Possible errors set are:
|
||||
// MC_ERR_NOT_ACTIVE
|
||||
// MC_ERR_GET_SOCK
|
||||
// MC_ERR_SOCKET_WRITE
|
||||
// MC_ERR_SOCKET_READ
|
||||
// MC_ERR_SET
|
||||
MemCachedClient::set($key, $value, $exptime);
|
||||
|
||||
// Like set(), but only stores in memcache if the key doesn't already exist.
|
||||
// returns TRUE on success else FALSE
|
||||
// Possible errors set are:
|
||||
// MC_ERR_NOT_ACTIVE
|
||||
// MC_ERR_GET_SOCK
|
||||
// MC_ERR_SOCKET_WRITE
|
||||
// MC_ERR_SOCKET_READ
|
||||
// MC_ERR_SET
|
||||
MemCachedClient::add($key, $value, $exptime);
|
||||
|
||||
// Like set(), but only stores in memcache if the key already exists.
|
||||
// returns TRUE on success else FALSE
|
||||
// Possible errors set are:
|
||||
// MC_ERR_NOT_ACTIVE
|
||||
// MC_ERR_GET_SOCK
|
||||
// MC_ERR_SOCKET_WRITE
|
||||
// MC_ERR_SOCKET_READ
|
||||
// MC_ERR_SET
|
||||
MemCachedClient::replace($key, $value, $exptime);
|
||||
|
||||
// removes the key from the MemCache
|
||||
// $time is the amount of time in seconds (or Unix time) until which
|
||||
// the client wishes the server to refuse "add" and "replace" commands
|
||||
// with this key. For this amount of item, the item is put into a
|
||||
// delete queue, which means that it won't possible to retrieve it by
|
||||
// the "get" command, but "add" and "replace" command with this key
|
||||
// will also fail (the "set" command will succeed, however). After the
|
||||
// time passes, the item is finally deleted from server memory.
|
||||
// The parameter $time is optional, and, if absent, defaults to 0
|
||||
// (which means that the item will be deleted immediately and further
|
||||
// storage commands with this key will succeed).
|
||||
// returns TRUE on success else returns FALSE
|
||||
// Possible errors set are:
|
||||
// MC_ERR_NOT_ACTIVE
|
||||
// MC_ERR_GET_SOCK
|
||||
// MC_ERR_SOCKET_WRITE
|
||||
// MC_ERR_SOCKET_READ
|
||||
// MC_ERR_DELETE
|
||||
MemCachedClient::delete($key, $time = 0);
|
||||
|
||||
// Sends a command to the server to atomically increment the value for
|
||||
// $key by $value, or by 1 if $value is undefined. Returns FALSE if $key
|
||||
// doesn't exist on server, otherwise it returns the new value after
|
||||
// incrementing. Value should be zero or greater. Overflow on server
|
||||
// is not checked. Be aware of values approaching 2**32. See decr.
|
||||
// Possible errors set are:
|
||||
// MC_ERR_NOT_ACTIVE
|
||||
// MC_ERR_GET_SOCK
|
||||
// MC_ERR_SOCKET_WRITE
|
||||
// MC_ERR_SOCKET_READ
|
||||
// returns new value on success, else returns FALSE
|
||||
// ONLY WORKS WITH NUMERIC VALUES
|
||||
MemCachedClient::incr($key[, $value]);
|
||||
|
||||
// Like incr, but decrements. Unlike incr, underflow is checked and new
|
||||
// values are capped at 0. If server value is 1, a decrement of 2
|
||||
// returns 0, not -1.
|
||||
// Possible errors set are:
|
||||
// MC_ERR_NOT_ACTIVE
|
||||
// MC_ERR_GET_SOCK
|
||||
// MC_ERR_SOCKET_WRITE
|
||||
// MC_ERR_SOCKET_READ
|
||||
// returns new value on success, else returns FALSE
|
||||
// ONLY WORKS WITH NUMERIC VALUES
|
||||
MemCachedClient::decr($key[, $value]);
|
||||
|
||||
// disconnects from all servers
|
||||
MemCachedClient::disconnect_all();
|
||||
|
||||
// if $do_debug is set to true, will print out
|
||||
// debugging info, else debug is turned off
|
||||
MemCachedClient::set_debug($do_debug);
|
||||
|
||||
// remove all cached hosts that are no longer good
|
||||
MemCachedClient::forget_dead_hosts();
|
||||
|
||||
// When a function returns FALSE, an error code is set.
|
||||
// This funtion will return the error code.
|
||||
// See error_string()
|
||||
// returns last error code set
|
||||
MemCachedClient::error()
|
||||
|
||||
// Returns a string describing the error set in error()
|
||||
// See error()
|
||||
// returns a string describing the error code given
|
||||
MemCachedClient::error_string()
|
||||
|
||||
// Resets the error number and error string
|
||||
MemCachedClient::error_clear()
|
||||
|
||||
Error codes are as follows:
|
||||
MC_ERR_NOT_ACTIVE // no active servers
|
||||
MC_ERR_SOCKET_WRITE // socket_write() failed
|
||||
MC_ERR_SOCKET_READ // socket_read() failed
|
||||
MC_ERR_SOCKET_CONNECT // failed to connect to host
|
||||
MC_ERR_DELETE // delete() did not recieve DELETED command
|
||||
MC_ERR_HOST_FORMAT // sock_to_host() invalid host format
|
||||
MC_ERR_HOST_DEAD // sock_to_host() host is dead
|
||||
MC_ERR_GET_SOCK // get_sock() failed to find a valid socket
|
||||
MC_ERR_SET // _set() failed to receive the STORED response
|
||||
MC_ERR_LOADITEM_HEADER // _load_items failed to receive valid data header
|
||||
MC_ERR_LOADITEM_END // _load_items failed to receive END response
|
||||
MC_ERR_LOADITEM_BYTES // _load_items bytes read larger than bytes available
|
||||
MC_ERR_GET // failed to get value associated with key
|
||||
|
||||
// Turns compression on or off; 0=off, 1=on
|
||||
MemCacheClient::set_compression($setting)
|
||||
|
||||
EXAMPLE:
|
||||
<?php
|
||||
require 'MemCachedClient.inc.php';
|
||||
|
||||
// set the servers, with the last one having an integer weight value of 3
|
||||
$options["servers"] = array("10.0.0.15:11000","10.0.0.16:11001",array("10.0.0.17:11002", 3));
|
||||
$options["debug"] = false;
|
||||
|
||||
$memc = new MemCachedClient($options);
|
||||
|
||||
|
||||
/***********************
|
||||
* STORE AN ARRAY
|
||||
***********************/
|
||||
$myarr = array("one","two", 3);
|
||||
$memc->set("key_one", $myarr);
|
||||
$val = $memc->get("key_one");
|
||||
print $val[0]."\n"; // prints 'one'
|
||||
print $val[1]."\n"; // prints 'two'
|
||||
print $val[2]."\n"; // prints 3
|
||||
|
||||
|
||||
print "\n";
|
||||
|
||||
|
||||
/***********************
|
||||
* STORE A CLASS
|
||||
***********************/
|
||||
class tester
|
||||
{
|
||||
var $one;
|
||||
var $two;
|
||||
var $three;
|
||||
}
|
||||
|
||||
$t = new tester;
|
||||
$t->one = "one";
|
||||
$t->two = "two";
|
||||
$t->three = 3;
|
||||
$memc->set("key_two", $t);
|
||||
$val = $memc->get("key_two");
|
||||
print $val->one."\n";
|
||||
print $val->two."\n";
|
||||
print $val->three."\n";
|
||||
|
||||
|
||||
print "\n";
|
||||
|
||||
|
||||
/***********************
|
||||
* STORE A STRING
|
||||
***********************/
|
||||
$memc->set("key_three", "my string");
|
||||
$val = $memc->get("key_three");
|
||||
print $val; // prints 'my string'
|
||||
|
||||
$memc->delete("key_one");
|
||||
$memc->delete("key_two");
|
||||
$memc->delete("key_three");
|
||||
|
||||
$memc->disconnect_all();
|
||||
|
||||
|
||||
|
||||
print "\n";
|
||||
|
||||
|
||||
/***********************
|
||||
* STORE A BINARY FILE
|
||||
***********************/
|
||||
|
||||
// first read the file and save it in memcache
|
||||
$fp = fopen( "./image.jpg", "rb" ) ;
|
||||
if ( !$fp )
|
||||
{
|
||||
print "Could not open ./file.dat!\n" ;
|
||||
exit ;
|
||||
}
|
||||
$data = fread( $fp, filesize( "./image.jpg" ) ) ;
|
||||
fclose( $fp ) ;
|
||||
print "Data length is " . strlen( $data ) . "\n" ;
|
||||
$memc->set( "key", $data ) ;
|
||||
|
||||
// now open a file for writing and write the data
|
||||
// retrieved from memcache
|
||||
$fp = fopen("./test.jpg","wb");
|
||||
$data = $memc->get( "key" ) ;
|
||||
print "Data length is " . strlen( $data ) . "\n" ;
|
||||
fwrite($fp,$data,strlen( $data ));
|
||||
fclose($fp);
|
||||
|
||||
|
||||
?>
|
||||
|
||||
|
1
sources/mediawiki/docs/php-memcached/README
Normal file
1
sources/mediawiki/docs/php-memcached/README
Normal file
|
@ -0,0 +1 @@
|
|||
HTML documentation is under http://phpca.cytherianage.net/memcached/doc/
|
9
sources/mediawiki/docs/schema.txt
Normal file
9
sources/mediawiki/docs/schema.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
The most up-to-date schema for the tables in the database
|
||||
will always be "tables.sql" in the maintenance directory,
|
||||
which is called from the installation script.
|
||||
|
||||
That file has been commented with details of the usage for
|
||||
each table and field.
|
||||
|
||||
Historical information and some other notes are available at
|
||||
http://www.mediawiki.org/wiki/Manual:Database_layout
|
55
sources/mediawiki/docs/scripts.txt
Normal file
55
sources/mediawiki/docs/scripts.txt
Normal file
|
@ -0,0 +1,55 @@
|
|||
scripts.txt
|
||||
|
||||
MediaWiki primary scripts are in the root directory of the software. Users
|
||||
should only use these scripts to access the wiki. There are also some .php that
|
||||
aren't primary scripts but helper files and won't work if they are accessed
|
||||
directly by the web.
|
||||
|
||||
Primary scripts:
|
||||
|
||||
index.php
|
||||
Main access point. It handles the most of requests.
|
||||
See http://www.mediawiki.org/wiki/Manual:Index.php
|
||||
|
||||
api.php
|
||||
Script to provide an API for bots to fetch content and informations about
|
||||
the site and also modify it. See http://www.mediawiki.org/wiki/API
|
||||
for more informations.
|
||||
|
||||
img_auth.php
|
||||
Script that only serve images to logged in users. To configure the wiki
|
||||
to use that script, see http://www.mediawiki.org/wiki/Manual:Image_Authorisation.
|
||||
|
||||
load.php
|
||||
Used by ResourceLoader to serve minified, concatenated and gzipped CSS and JS.
|
||||
|
||||
opensearch_desc.php
|
||||
Returns a OpenSearch description document (see http://www.opensearch.org/)
|
||||
that points to the search engines of the wiki.
|
||||
|
||||
profileinfo.php
|
||||
Allow users to see the profiling information that are stored in the
|
||||
database.
|
||||
|
||||
To save the profiling information in the database (required to use this
|
||||
script), you have to modify StartProfiler.php to use the Profiler class and
|
||||
not the stub profiler which is enabled by default.
|
||||
You will also need to set $wgProfileToDatabase to true in LocalSettings.php
|
||||
to force the profiler to save the informations in the database and apply the
|
||||
maintenance/archives/patch-profiling.sql patch to the database.
|
||||
|
||||
To enable the profileinfo.php itself, you'll need to set $wgDBadminuser
|
||||
and $wgDBadminpassword in your LocalSettings.php, as well as $wgEnableProfileInfo
|
||||
See also http://www.mediawiki.org/wiki/How_to_debug#Profiling.
|
||||
|
||||
thumb.php
|
||||
Script used to resize images if it is configured to be done when the web
|
||||
browser requests the image and not when generating the page. This script can
|
||||
be used as a 404 handler to generate image thumbs when they don't exist.
|
||||
|
||||
There is also a file with a .php5 extension for each script. They can be used if
|
||||
the web server needs a .php5 to run the file with the PHP 5 engine and runs .php
|
||||
scripts with PHP 4. To use these files, you have to modify $wgScriptExtension to
|
||||
'.php5' is LocalSettings.php but it is already done by the config script if you
|
||||
used mw-config/index.php5 for installation.
|
||||
|
92
sources/mediawiki/docs/skin.txt
Normal file
92
sources/mediawiki/docs/skin.txt
Normal file
|
@ -0,0 +1,92 @@
|
|||
skin.txt
|
||||
|
||||
MediaWiki includes four core skins:
|
||||
|
||||
* Vector: The default skin. Introduced in the 1.16 release (2010), it has been
|
||||
set as the default in MediaWiki since the 1.17 release (2011), replacing
|
||||
Monobook.
|
||||
|
||||
* Monobook: Named after the black-and-white photo of a book in the page
|
||||
background. Introduced in the 2004 release of 1.3, it had been been the
|
||||
default skin since then, before being replaced by Vector.
|
||||
|
||||
* Modern: An attractive blue/grey theme with sidebar and top bar. Derived from
|
||||
Monobook.
|
||||
|
||||
* Cologne Blue: A lightweight skin with minimal formatting. The oldest of the
|
||||
currently bundled skins, largely rewritten in 2012 while keeping its
|
||||
appearance.
|
||||
|
||||
|
||||
Several legacy skins were removed in the 1.22 release, as the burden of
|
||||
supporting them became too heavy to bear. Those were:
|
||||
|
||||
* Standard (a.k.a. Classic): The old default skin written by Lee Crocker during
|
||||
the phase 3 rewrite, in 2002.
|
||||
|
||||
* Nostalgia: A skin which looks like Wikipedia did in its first year (2001).
|
||||
This skin is now used for the old Wikipedia snapshot at
|
||||
http://nostalgia.wikipedia.org/
|
||||
|
||||
* Chick: A lightweight Monobook skin with no sidebar. The sidebar links were
|
||||
given at the bottom of the page instead.
|
||||
|
||||
* Simple: A lightweight skin with a simple white-background sidebar and no top
|
||||
bar.
|
||||
|
||||
* MySkin: Essentially Monobook without the CSS. The idea was that it could be
|
||||
customised using user-specific or site-wide CSS (see below).
|
||||
|
||||
|
||||
== Custom CSS/JS ==
|
||||
|
||||
It is possible to customise the site CSS and JavaScript without editing any
|
||||
server-side source files. This is done by editing some pages on the wiki:
|
||||
|
||||
* [[MediaWiki:Common.css]] -- for skin-independent CSS
|
||||
* [[MediaWiki:Common.js]] -- for skin-independent JavaScript
|
||||
* [[MediaWiki:Vector.css]], [[MediaWiki:Monobook.css]], etc. -- for
|
||||
skin-dependent CSS
|
||||
* [[MediaWiki:Vector.js]], [[MediaWiki:Monobook.js]], etc. -- for
|
||||
skin-dependent JavaScript
|
||||
|
||||
These can also be customised on a per-user basis, by editing
|
||||
[[User:<name>/vector.css]], [[User:<name>/vector.js]], etc.
|
||||
|
||||
This feature has led to a wide variety of "user styles" becoming available:
|
||||
|
||||
http://www.mediawiki.org/wiki/Manual:Gallery_of_user_styles
|
||||
|
||||
If you want a different look for your wiki, that gallery is a good place to start.
|
||||
|
||||
== Drop-in custom skins ==
|
||||
|
||||
If you put a file in MediaWiki's skins directory, ending in .php, the name of
|
||||
the file will automatically be added as a skin name, and the file will be
|
||||
expected to contain a class called Skin<name> with the skin class. You can then
|
||||
make that skin the default by adding to LocalSettings.php:
|
||||
|
||||
$wgDefaultSkin = '<name>';
|
||||
|
||||
You can also disable dropped-in or core skins using:
|
||||
|
||||
$wgSkipSkins[] = '<name>';
|
||||
|
||||
This technique is used by the more ambitious MediaWiki site operators, to
|
||||
create complex custom skins for their wikis. It should be preferred over
|
||||
editing the core Monobook skin directly.
|
||||
|
||||
See http://www.mediawiki.org/wiki/Manual:Skinning for more information.
|
||||
|
||||
== Extension skins ==
|
||||
|
||||
It is now possible (since MediaWiki 1.12) to write a skin as a standard
|
||||
MediaWiki extension, enabled via LocalSettings.php. This is done by adding
|
||||
it to $wgValidSkinNames, for example:
|
||||
|
||||
$wgValidSkinNames['mycoolskin'] = 'MyCoolSkin';
|
||||
|
||||
and then registering a class in $wgAutoloadClasses called SkinMycoolSkin, which
|
||||
derives from Skin. This technique is apparently not yet used (as of 2008)
|
||||
outside the DumpHTML extension.
|
||||
|
67
sources/mediawiki/docs/title.txt
Normal file
67
sources/mediawiki/docs/title.txt
Normal file
|
@ -0,0 +1,67 @@
|
|||
title.txt
|
||||
|
||||
The MediaWiki software's "Title" class represents article titles, which are used
|
||||
for many purposes: as the human-readable text title of the article, in the URL
|
||||
used to access the article, the wikitext link to the article, the key into the
|
||||
article database, and so on. The class in instantiated from one of these forms
|
||||
and can be queried for the others, and for other attributes of the title. This
|
||||
is intended to be an immutable "value" class, so there are no mutator functions.
|
||||
|
||||
To get a new instance, call Title::newFromText(). Once instantiated, the
|
||||
non-static accessor methods can be used, such as getText(), getDBkey(),
|
||||
getNamespace(), etc. Note that Title::newFromText() may return false if the text
|
||||
is illegal according to the rules below.
|
||||
|
||||
The prefix rules: a title consists of an optional interwiki prefix (such as "m:"
|
||||
for meta or "de:" for German), followed by an optional namespace, followed by
|
||||
the remainder of the title. Both interwiki prefixes and namespace prefixes have
|
||||
the same rules: they contain only letters, digits, space, and underscore, must
|
||||
start with a letter, are case insensitive, and spaces and underscores are
|
||||
interchangeable. Prefixes end with a ":". A prefix is only recognized if it is
|
||||
one of those specifically allowed by the software. For example, "de:name" is a
|
||||
link to the article "name" in the German Wikipedia, because "de" is recognized
|
||||
as one of the allowable interwikis. The title "talk:name" is a link to the
|
||||
article "name" in the "talk" namespace of the current wiki, because "talk" is a
|
||||
recognized namespace. Both may be present, and if so, the interwiki must
|
||||
come first, for example, "m:talk:name". If a title begins with a colon as its
|
||||
first character, no prefixes are scanned for, and the colon is just removed.
|
||||
Note that because of these rules, it is possible to have articles with colons in
|
||||
their names. "E. Coli 0157:H7" is a valid title, as is "2001: A Space Odyssey",
|
||||
because "E. Coli 0157" and "2001" are not valid interwikis or namespaces.
|
||||
|
||||
It is not possible to have an article whose bare name includes a namespace or
|
||||
interwiki prefix.
|
||||
|
||||
An initial colon in a title listed in wiki text may however suppress special
|
||||
handling for interlanguage links, image links, and category links. It is also
|
||||
used to indicate the main namespace in template inclusions.
|
||||
|
||||
Once prefixes have been stripped, the rest of the title processed this way:
|
||||
|
||||
* Spaces and underscores are treated as equivalent and each is converted to the
|
||||
other in the appropriate context (underscore in URL and database keys, spaces
|
||||
in plain text).
|
||||
* Multiple consecutive spaces are converted to a single space.
|
||||
* Leading or trailing space is removed.
|
||||
* If $wgCapitalLinks is enabled (the default), the first letter is capitalised,
|
||||
using the capitalisation function of the content language object.
|
||||
* The unicode characters LRM (U+200E) and RLM (U+200F) are silently stripped.
|
||||
* Invalid UTF-8 sequences or instances of the replacement character (U+FFFD) are
|
||||
considered illegal.
|
||||
* A percent sign followed by two hexadecimal characters is illegal
|
||||
* Anything that looks like an XML/HTML character reference is illegal
|
||||
* Any character not matched by the $wgLegalTitleChars regex is illegal
|
||||
* Zero-length titles (after whitespace stripping) are illegal
|
||||
|
||||
All titles except special pages must be less than 255 bytes when encoded with
|
||||
UTF-8, because that is the size of the database field. Special page titles may
|
||||
be up to 512 bytes.
|
||||
|
||||
Note that Unicode Normal Form C (NFC) is enforced by MediaWiki's user interface
|
||||
input functions, and so titles will typically be in this form.
|
||||
|
||||
getArticleID() needs some explanation: for "internal" articles, it should return
|
||||
the "page_id" field if the article exists, else it returns 0. For all external
|
||||
articles it returns 0. All of the IDs for all instances of Title created during
|
||||
a request are cached, so they can be looked up quickly while rendering wiki text
|
||||
with lots of internal links. See linkcache.txt.
|
100
sources/mediawiki/docs/uidesign/child-selector-emu.html
Normal file
100
sources/mediawiki/docs/uidesign/child-selector-emu.html
Normal file
|
@ -0,0 +1,100 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Child selector emulation for IE 6</title>
|
||||
<style>
|
||||
/** Common rules **/
|
||||
body { background-color: #CCC; }
|
||||
table { border:1px black solid; }
|
||||
caption {
|
||||
background-color: #98fb98;
|
||||
border:1px solid #40FF40;
|
||||
}
|
||||
|
||||
/** "old" rules" **/
|
||||
table.global th,
|
||||
table.global td
|
||||
{
|
||||
border: 1px red solid;
|
||||
background-color:white;
|
||||
padding:1em;
|
||||
}
|
||||
table.global th
|
||||
{
|
||||
background-color: #ffc0cb;
|
||||
}
|
||||
|
||||
/** second table. Try to emulate child selector */
|
||||
table.childemu th,
|
||||
table.childemu td {
|
||||
border: 1px red solid;
|
||||
background-color:white;
|
||||
padding:1em;
|
||||
}
|
||||
table.childemu th
|
||||
{
|
||||
background-color: #ffc0cb;
|
||||
}
|
||||
|
||||
/** Reset style applied in childemu classes */
|
||||
/** TODO: find the real default value!! */
|
||||
table.childemu tr * th,
|
||||
table.childemu tr * td {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** child selector emulation */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
The following table show how nested tables inherit colors from the wikitable class (here it was renamed "global").
|
||||
</p>
|
||||
<table class="global">
|
||||
<caption>Global table</caption>
|
||||
<tr>
|
||||
<th>TH: should have pink bg</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TD: white bg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="nested">
|
||||
<caption>Nested table</caption>
|
||||
<tr>
|
||||
<th>Nested TH: transparent</th>
|
||||
<td>Nested TD: transparent</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
With child selector we could limit the wikitable styling to the direct childs of the table. Unfortunately, Internet Explorer 6.0 does not support child selector. See <a href="https://bugzilla.wikimedia.org/show_bug.cgi?id=33752">our bug #33752</a>.
|
||||
</p>
|
||||
<table class="childemu">
|
||||
<caption>Global table</caption>
|
||||
<tr>
|
||||
<th>TH: should have pink bg</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TD: white bg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="nested">
|
||||
<caption>Nested table</caption>
|
||||
<tr>
|
||||
<th>Nested TH: transparent</th>
|
||||
<td>Nested TD: transparent</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p><strong>NOTE:</strong>The nested caption keep the green background. The nested table keep the black border. This is because those declarations are global so we did not reset them.</p>
|
35
sources/mediawiki/docs/uidesign/design.html
Normal file
35
sources/mediawiki/docs/uidesign/design.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../skins/common/shared.css">
|
||||
</head>
|
||||
<body style="font-size: small;">
|
||||
|
||||
<h2>Messages</h2>
|
||||
<p class="success">Success message</p>
|
||||
<p class="warning">Warning message</p>
|
||||
<p class="error">Error message</p>
|
||||
|
||||
<h2>Messages box</h2>
|
||||
<p class="visualClear successbox">Success message</p>
|
||||
<p class="visualClear warningbox">Warning message</p>
|
||||
<p class="visualClear errorbox">Error message</p>
|
||||
|
||||
<br class="visualClear"/>
|
||||
<h2>Various</h2>
|
||||
<span class="comment">span.comment</span>
|
||||
<a class="feedlink">a.feedlink</a>
|
||||
<table class="wikitable">
|
||||
<tr><th colspan="2">table.wikitable</th></tr>
|
||||
<tr><td>cell</td><td>cell</td></tr>
|
||||
<tr><td>cell</td><td>cell</td></tr>
|
||||
</table>
|
||||
|
||||
<table class="mw-datatable">
|
||||
<tr><th colspan="2">table.mw-datatable</th></tr>
|
||||
<tr><td>line with hover</td><td>line with hover</td></tr>
|
||||
<tr><td>line with hover</td><td>line with hover</td></tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../resources/mediawiki.action/mediawiki.action.history.diff.css">
|
||||
</head>
|
||||
<body style="background-color: #C0C0C0;">
|
||||
<p>
|
||||
This show various styles for our diff action, the background being hardcoded to gray (<code>#C0C0C0</code>) The reference style sheet is:</p>
|
||||
<p>
|
||||
<code><a href="../../resources/mediawiki.action/mediawiki.action.history.diff.css">resources/mediawiki.action/mediawiki.action.history.diff.css</a></code>.
|
||||
</p>
|
||||
<p>
|
||||
This file might help us fix our diff colors which have been a recurring issues among the community for a loooong time.</p>
|
||||
|
||||
<p>
|
||||
First, show the diff mostly like it would be chown on a wiki</p>
|
||||
<table class="diff">
|
||||
<tr>
|
||||
<td class="diff-marker">-</td>
|
||||
<td class="diff-deletedline"><div>
|
||||
Some content <span class="diffchange diffchange-inline">deleted / replaced</span>
|
||||
</div></td>
|
||||
<td class="diff-marker">+</td>
|
||||
<td class="diff-addedline"><div>
|
||||
Some content <span class="diffchange diffchange-inline">added / replacement</span>
|
||||
</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<p>
|
||||
Below are some basic lines being applied one or two classes. Mainly for debugging purposes</p>
|
||||
|
||||
<table class="diff">
|
||||
|
||||
<tr><th>Diff</th></tr>
|
||||
|
||||
<tr><td class="diff-addedline"><code>diff-addedline</code>: added line</td></tr>
|
||||
<tr><td class="diff-deletedline"><code>diff-deletedline</code>: deleted line</td></tr>
|
||||
<tr><td class="diff-context"><code>diff-context</code>: context</td></tr>
|
||||
|
||||
|
||||
<tr><th>Same as above with a <code><span></code> child element having the <code>diffchange</code> class</th></tr>
|
||||
|
||||
<tr><td class="diffchange">Diffchange</td></tr>
|
||||
<tr><td class="diff-addedline">
|
||||
<span class="diffchange">Added line + diffchange</span>
|
||||
</td></tr>
|
||||
<tr><td class="diff-deletedline">
|
||||
<span class="diffchange">Deleted line + diffchange</span>
|
||||
</td></tr>
|
||||
<tr><td class="diff-context">
|
||||
<span class="diffchange">Context + diffchange</span>
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
77
sources/mediawiki/docs/uidesign/monospace.html
Normal file
77
sources/mediawiki/docs/uidesign/monospace.html
Normal file
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<style>
|
||||
pre {
|
||||
border: 1px dashed #AAA;
|
||||
background-color: #E0E0E0;
|
||||
color: #000000;
|
||||
margin: 1em 10%;
|
||||
padding: 0.5em;
|
||||
}
|
||||
blockquote {
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
This page let you test the rendering font-family declaration for monospaced fonts. TODO: add some references here :-)
|
||||
</p>
|
||||
<p>
|
||||
Erwin Dokter had the following explanation on <a href="https://bugzilla.wikimedia.org/33496">Bugzilla #33496</a>:
|
||||
</p>
|
||||
<blockquote>
|
||||
By default, a (Windows) browser has it's default font-sizes set at 16px for
|
||||
serif and sans-serif, and 13px for monospace. Except in IE, where you cannot
|
||||
set any font-sizes... it uses 16px for all fonts.
|
||||
<br/>
|
||||
Vector has a base font-size of 0.8em, and most browsers *correctly* scale down
|
||||
all fonts, including the monospace font, accordingly. So monospace is shown at
|
||||
0.8 x 13px = 10px (which is perceived as 'too small'). But when you assign any
|
||||
font besides just "monospace", those browsers will no longer treat it as
|
||||
monospace and use 0.8 x 16px = 13px instead.
|
||||
</blockquote>
|
||||
<p>
|
||||
Below are various rendering:
|
||||
</p>
|
||||
|
||||
<pre style='
|
||||
font-family: monospace;'>
|
||||
font-family: monospace;
|
||||
</pre>
|
||||
|
||||
<pre style='
|
||||
font-family: "Courier New";'>
|
||||
font-family: "Courier New";
|
||||
</pre>
|
||||
|
||||
<pre style='
|
||||
font-family: Courier;'>
|
||||
font-family: Courier;
|
||||
</pre>
|
||||
|
||||
<pre style='
|
||||
font-family: monospace, monospace;'>
|
||||
font-family: monospace, monospace;
|
||||
</pre>
|
||||
|
||||
<pre style='
|
||||
font-family: monospace, "Courier New";'>
|
||||
font-family: monospace, "Courier New";
|
||||
</pre>
|
||||
|
||||
<pre style='
|
||||
font-family: monospace, Courier;'>
|
||||
font-family: monospace, Courier;
|
||||
</pre>
|
||||
|
||||
<pre style='
|
||||
font-family: monospace, Verdana;'>
|
||||
font-family: monospace, Verdana;
|
||||
</pre>
|
||||
|
||||
<pre style='
|
||||
font-family: monospace, DOESNOTEXISTREALLY;'>
|
||||
font-family: monospace, DOESNOTEXISTREALLY;
|
||||
</pre>
|
59
sources/mediawiki/docs/uidesign/table-layout.html
Normal file
59
sources/mediawiki/docs/uidesign/table-layout.html
Normal file
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
/** This is just for coloring: */
|
||||
table { border: 1px solid #CC0; }
|
||||
td { border: 1px solid #CCC; }
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
#first {
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
This play with table-layout:fixed; and applying the width to colgroup or col element. Firefox only recongize the width if it is applied on col element!</p>
|
||||
<p>
|
||||
On a perfect browser, both tables should look the same</p>
|
||||
|
||||
<dl>
|
||||
<dt>colgroup</dt>
|
||||
<dd>300 px width is applied to the first colgroup element</dd>
|
||||
</dl>
|
||||
<div style="width: 400px;">
|
||||
<table>
|
||||
<colgroup id="first" /></colgroup>
|
||||
<colgroup id="second"/></colgroup>
|
||||
<colgroup id="third" /></colgroup>
|
||||
<tr>
|
||||
<td>Very long?</td>
|
||||
<td>#</td>
|
||||
<td>$</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<dt>col</dt>
|
||||
<dd>Each colgroup has an additional col element. The first col element is applied the 300 px width</dd>
|
||||
</dl>
|
||||
|
||||
<div style="width: 400px;">
|
||||
<table>
|
||||
<colgroup><col id="first" /></colgroup>
|
||||
<colgroup><col id="second"/></colgroup>
|
||||
<colgroup><col id="third" /></colgroup>
|
||||
<tr>
|
||||
<td>Very long?</td>
|
||||
<td>#</td>
|
||||
<td>$</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
3878
sources/mediawiki/extensions/Cite/Cite.i18n.php
Normal file
3878
sources/mediawiki/extensions/Cite/Cite.i18n.php
Normal file
File diff suppressed because one or more lines are too long
119
sources/mediawiki/extensions/Cite/Cite.php
Normal file
119
sources/mediawiki/extensions/Cite/Cite.php
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
if ( ! defined( 'MEDIAWIKI' ) )
|
||||
die();
|
||||
/**#@+
|
||||
* A parser extension that adds two tags, <ref> and <references> for adding
|
||||
* citations to pages
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*
|
||||
* @link http://www.mediawiki.org/wiki/Extension:Cite/Cite.php Documentation
|
||||
*
|
||||
* @bug 4579
|
||||
*
|
||||
* @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
* @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
|
||||
*/
|
||||
|
||||
$wgHooks['ParserFirstCallInit'][] = 'wfCite';
|
||||
$wgHooks['BeforePageDisplay'][] = 'wfCiteBeforePageDisplay';
|
||||
|
||||
|
||||
$wgExtensionCredits['parserhook'][] = array(
|
||||
'path' => __FILE__,
|
||||
'name' => 'Cite',
|
||||
'author' => array( 'Ævar Arnfjörð Bjarmason', 'Marius Hoch' ),
|
||||
'descriptionmsg' => 'cite-desc',
|
||||
'url' => 'https://www.mediawiki.org/wiki/Extension:Cite/Cite.php'
|
||||
);
|
||||
$wgParserTestFiles[] = __DIR__ . "/citeParserTests.txt";
|
||||
$wgExtensionMessagesFiles['Cite'] = __DIR__ . "/Cite.i18n.php";
|
||||
$wgAutoloadClasses['Cite'] = __DIR__ . "/Cite_body.php";
|
||||
$wgSpecialPageGroups['Cite'] = 'pagetools';
|
||||
|
||||
define( 'CITE_DEFAULT_GROUP', '' );
|
||||
/**
|
||||
* The emergency shut-off switch. Override in local settings to disable
|
||||
* groups; or remove all references from this file to enable unconditionally
|
||||
*/
|
||||
$wgAllowCiteGroups = true;
|
||||
|
||||
/**
|
||||
* An emergency optimisation measure for caching cite <references /> output.
|
||||
*/
|
||||
$wgCiteCacheReferences = false;
|
||||
|
||||
/**
|
||||
* Enables experimental popups
|
||||
*/
|
||||
$wgCiteEnablePopups = false;
|
||||
|
||||
/**
|
||||
* Performs the hook registration.
|
||||
* Note that several extensions (and even core!) try to detect if Cite is
|
||||
* installed by looking for wfCite().
|
||||
*
|
||||
* @param $parser Parser
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function wfCite( $parser ) {
|
||||
return Cite::setHooks( $parser );
|
||||
}
|
||||
|
||||
// Resources
|
||||
$citeResourceTemplate = array(
|
||||
'localBasePath' => __DIR__ . '/modules',
|
||||
'remoteExtPath' => 'Cite/modules'
|
||||
);
|
||||
|
||||
$wgResourceModules['ext.cite'] = $citeResourceTemplate + array(
|
||||
'scripts' => 'ext.cite.js',
|
||||
'styles' => 'ext.cite.css',
|
||||
'messages' => array(
|
||||
'cite_references_link_accessibility_label',
|
||||
'cite_references_link_many_accessibility_label',
|
||||
),
|
||||
);
|
||||
|
||||
$wgResourceModules['ext.cite.popups'] = $citeResourceTemplate + array(
|
||||
'scripts' => 'ext.cite.popups.js',
|
||||
'position' => 'bottom',
|
||||
'dependencies' => array(
|
||||
'jquery.tooltip',
|
||||
),
|
||||
);
|
||||
|
||||
$wgResourceModules['jquery.tooltip'] = $citeResourceTemplate + array(
|
||||
'styles' => 'jquery.tooltip/jquery.tooltip.css',
|
||||
'scripts' => 'jquery.tooltip/jquery.tooltip.js',
|
||||
'position' => 'bottom',
|
||||
);
|
||||
|
||||
/* Add RTL fix for the cite <sup> elements */
|
||||
$wgResourceModules['ext.rtlcite'] = $citeResourceTemplate + array(
|
||||
'styles' => 'ext.rtlcite.css',
|
||||
'position' => 'top',
|
||||
);
|
||||
|
||||
/**
|
||||
* @param $out OutputPage
|
||||
* @param $sk Skin
|
||||
* @return bool
|
||||
*/
|
||||
function wfCiteBeforePageDisplay( $out, &$sk ) {
|
||||
global $wgCiteEnablePopups;
|
||||
|
||||
$out->addModules( 'ext.cite' );
|
||||
if ( $wgCiteEnablePopups ) {
|
||||
$out->addModules( 'ext.cite.popups' );
|
||||
}
|
||||
|
||||
/* RTL support quick-fix module */
|
||||
$out->addModuleStyles( 'ext.rtlcite' );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**#@-*/
|
1185
sources/mediawiki/extensions/Cite/Cite_body.php
Normal file
1185
sources/mediawiki/extensions/Cite/Cite_body.php
Normal file
File diff suppressed because it is too large
Load diff
420
sources/mediawiki/extensions/Cite/SpecialCite.alias.php
Normal file
420
sources/mediawiki/extensions/Cite/SpecialCite.alias.php
Normal file
|
@ -0,0 +1,420 @@
|
|||
<?php
|
||||
/**
|
||||
* Aliases for Special:Cite
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
// @codingStandardsIgnoreFile
|
||||
|
||||
$specialPageAliases = array();
|
||||
|
||||
/** English (English) */
|
||||
$specialPageAliases['en'] = array(
|
||||
'Cite' => array( 'Cite' ),
|
||||
);
|
||||
|
||||
/** Arabic (العربية) */
|
||||
$specialPageAliases['ar'] = array(
|
||||
'Cite' => array( 'استشهاد' ),
|
||||
);
|
||||
|
||||
/** Egyptian Spoken Arabic (مصرى) */
|
||||
$specialPageAliases['arz'] = array(
|
||||
'Cite' => array( 'استشهاد' ),
|
||||
);
|
||||
|
||||
/** Assamese (অসমীয়া) */
|
||||
$specialPageAliases['as'] = array(
|
||||
'Cite' => array( 'উদ্ধৃতি' ),
|
||||
);
|
||||
|
||||
/** Bikol Central (Bikol Central) */
|
||||
$specialPageAliases['bcl'] = array(
|
||||
'Cite' => array( 'Sambitón' ),
|
||||
);
|
||||
|
||||
/** Bulgarian (български) */
|
||||
$specialPageAliases['bg'] = array(
|
||||
'Cite' => array( 'Цитиране' ),
|
||||
);
|
||||
|
||||
/** Banjar (Bahasa Banjar) */
|
||||
$specialPageAliases['bjn'] = array(
|
||||
'Cite' => array( 'Juhut' ),
|
||||
);
|
||||
|
||||
/** Breton (brezhoneg) */
|
||||
$specialPageAliases['br'] = array(
|
||||
'Cite' => array( 'Menegiñ' ),
|
||||
);
|
||||
|
||||
/** Bosnian (bosanski) */
|
||||
$specialPageAliases['bs'] = array(
|
||||
'Cite' => array( 'Citiraj' ),
|
||||
);
|
||||
|
||||
/** буряад (буряад) */
|
||||
$specialPageAliases['bxr'] = array(
|
||||
'Cite' => array( 'Сайт' ),
|
||||
);
|
||||
|
||||
/** Catalan (català) */
|
||||
$specialPageAliases['ca'] = array(
|
||||
'Cite' => array( 'Citau', 'Citeu' ),
|
||||
);
|
||||
|
||||
/** Min Dong Chinese (Mìng-dĕ̤ng-ngṳ̄) */
|
||||
$specialPageAliases['cdo'] = array(
|
||||
'Cite' => array( '註' ),
|
||||
);
|
||||
|
||||
/** Chechen (нохчийн) */
|
||||
$specialPageAliases['ce'] = array(
|
||||
'Cite' => array( 'Дош' ),
|
||||
);
|
||||
|
||||
/** Czech (česky) */
|
||||
$specialPageAliases['cs'] = array(
|
||||
'Cite' => array( 'Citovat' ),
|
||||
);
|
||||
|
||||
/** Danish (dansk) */
|
||||
$specialPageAliases['da'] = array(
|
||||
'Cite' => array( 'Citer' ),
|
||||
);
|
||||
|
||||
/** German (Deutsch) */
|
||||
$specialPageAliases['de'] = array(
|
||||
'Cite' => array( 'Zitierhilfe', 'Zitieren' ),
|
||||
);
|
||||
|
||||
/** Zazaki (Zazaki) */
|
||||
$specialPageAliases['diq'] = array(
|
||||
'Cite' => array( 'Sita' ),
|
||||
);
|
||||
|
||||
/** Lower Sorbian (dolnoserbski) */
|
||||
$specialPageAliases['dsb'] = array(
|
||||
'Cite' => array( 'Citěrowańska_pomoc' ),
|
||||
);
|
||||
|
||||
/** Greek (Ελληνικά) */
|
||||
$specialPageAliases['el'] = array(
|
||||
'Cite' => array( 'Παραπομπή' ),
|
||||
);
|
||||
|
||||
/** Esperanto (Esperanto) */
|
||||
$specialPageAliases['eo'] = array(
|
||||
'Cite' => array( 'Citi' ),
|
||||
);
|
||||
|
||||
/** Spanish (español) */
|
||||
$specialPageAliases['es'] = array(
|
||||
'Cite' => array( 'Citar' ),
|
||||
);
|
||||
|
||||
/** Estonian (eesti) */
|
||||
$specialPageAliases['et'] = array(
|
||||
'Cite' => array( 'Tsiteerimine' ),
|
||||
);
|
||||
|
||||
/** Persian (فارسی) */
|
||||
$specialPageAliases['fa'] = array(
|
||||
'Cite' => array( 'یادکرد' ),
|
||||
);
|
||||
|
||||
/** Finnish (suomi) */
|
||||
$specialPageAliases['fi'] = array(
|
||||
'Cite' => array( 'Viittaus' ),
|
||||
);
|
||||
|
||||
/** French (français) */
|
||||
$specialPageAliases['fr'] = array(
|
||||
'Cite' => array( 'Citer' ),
|
||||
);
|
||||
|
||||
/** Franco-Provençal (arpetan) */
|
||||
$specialPageAliases['frp'] = array(
|
||||
'Cite' => array( 'Citar' ),
|
||||
);
|
||||
|
||||
/** Galician (galego) */
|
||||
$specialPageAliases['gl'] = array(
|
||||
'Cite' => array( 'Cita', 'Citar' ),
|
||||
);
|
||||
|
||||
/** Swiss German (Alemannisch) */
|
||||
$specialPageAliases['gsw'] = array(
|
||||
'Cite' => array( 'Zitierhilf' ),
|
||||
);
|
||||
|
||||
/** Hebrew (עברית) */
|
||||
$specialPageAliases['he'] = array(
|
||||
'Cite' => array( 'ציטוט' ),
|
||||
);
|
||||
|
||||
/** Croatian (hrvatski) */
|
||||
$specialPageAliases['hr'] = array(
|
||||
'Cite' => array( 'Citiraj' ),
|
||||
);
|
||||
|
||||
/** Upper Sorbian (hornjoserbsce) */
|
||||
$specialPageAliases['hsb'] = array(
|
||||
'Cite' => array( 'Citowanska_pomoc' ),
|
||||
);
|
||||
|
||||
/** 湘语 (湘语) */
|
||||
$specialPageAliases['hsn'] = array(
|
||||
'Cite' => array( '建脚注' ),
|
||||
);
|
||||
|
||||
/** Haitian (Kreyòl ayisyen) */
|
||||
$specialPageAliases['ht'] = array(
|
||||
'Cite' => array( 'Site' ),
|
||||
);
|
||||
|
||||
/** Hungarian (magyar) */
|
||||
$specialPageAliases['hu'] = array(
|
||||
'Cite' => array( 'Hivatkozás', 'Irodalomjegyzék' ),
|
||||
);
|
||||
|
||||
/** Interlingua (interlingua) */
|
||||
$specialPageAliases['ia'] = array(
|
||||
'Cite' => array( 'Citation' ),
|
||||
);
|
||||
|
||||
/** Indonesian (Bahasa Indonesia) */
|
||||
$specialPageAliases['id'] = array(
|
||||
'Cite' => array( 'Kutip' ),
|
||||
);
|
||||
|
||||
/** Igbo (Igbo) */
|
||||
$specialPageAliases['ig'] = array(
|
||||
'Cite' => array( 'Dépùtà' ),
|
||||
);
|
||||
|
||||
/** Ido (Ido) */
|
||||
$specialPageAliases['io'] = array(
|
||||
'Cite' => array( 'Citar' ),
|
||||
);
|
||||
|
||||
/** Italian (italiano) */
|
||||
$specialPageAliases['it'] = array(
|
||||
'Cite' => array( 'Cita' ),
|
||||
);
|
||||
|
||||
/** Japanese (日本語) */
|
||||
$specialPageAliases['ja'] = array(
|
||||
'Cite' => array( '引用' ),
|
||||
);
|
||||
|
||||
/** Korean (한국어) */
|
||||
$specialPageAliases['ko'] = array(
|
||||
'Cite' => array( '인용' ),
|
||||
);
|
||||
|
||||
/** Colognian (Ripoarisch) */
|
||||
$specialPageAliases['ksh'] = array(
|
||||
'Cite' => array( 'Zitteere' ),
|
||||
);
|
||||
|
||||
/** Cornish (kernowek) */
|
||||
$specialPageAliases['kw'] = array(
|
||||
'Cite' => array( 'Devynna' ),
|
||||
);
|
||||
|
||||
/** Ladino (Ladino) */
|
||||
$specialPageAliases['lad'] = array(
|
||||
'Cite' => array( 'MostrarManaderos' ),
|
||||
);
|
||||
|
||||
/** Luxembourgish (Lëtzebuergesch) */
|
||||
$specialPageAliases['lb'] = array(
|
||||
'Cite' => array( 'Zitéierhellëf' ),
|
||||
);
|
||||
|
||||
/** Literary Chinese (文言) */
|
||||
$specialPageAliases['lzh'] = array(
|
||||
'Cite' => array( '引文' ),
|
||||
);
|
||||
|
||||
/** Macedonian (македонски) */
|
||||
$specialPageAliases['mk'] = array(
|
||||
'Cite' => array( 'Навод' ),
|
||||
);
|
||||
|
||||
/** Malayalam (മലയാളം) */
|
||||
$specialPageAliases['ml'] = array(
|
||||
'Cite' => array( 'അവലംബം' ),
|
||||
);
|
||||
|
||||
/** Marathi (मराठी) */
|
||||
$specialPageAliases['mr'] = array(
|
||||
'Cite' => array( 'संदर्भद्या' ),
|
||||
);
|
||||
|
||||
/** Malay (Bahasa Melayu) */
|
||||
$specialPageAliases['ms'] = array(
|
||||
'Cite' => array( 'Petik' ),
|
||||
);
|
||||
|
||||
/** Maltese (Malti) */
|
||||
$specialPageAliases['mt'] = array(
|
||||
'Cite' => array( 'Iċċita' ),
|
||||
);
|
||||
|
||||
/** Nahuatl (Nāhuatl) */
|
||||
$specialPageAliases['nah'] = array(
|
||||
'Cite' => array( 'Tlahtoa', 'Citar' ),
|
||||
);
|
||||
|
||||
/** Norwegian Bokmål (norsk bokmål) */
|
||||
$specialPageAliases['nb'] = array(
|
||||
'Cite' => array( 'Siteringshjelp' ),
|
||||
);
|
||||
|
||||
/** Low German (Plattdüütsch) */
|
||||
$specialPageAliases['nds'] = array(
|
||||
'Cite' => array( 'Ziteerhelp' ),
|
||||
);
|
||||
|
||||
/** Low Saxon (Netherlands) (Nedersaksies) */
|
||||
$specialPageAliases['nds-nl'] = array(
|
||||
'Cite' => array( 'Siteerhulpe' ),
|
||||
);
|
||||
|
||||
/** Dutch (Nederlands) */
|
||||
$specialPageAliases['nl'] = array(
|
||||
'Cite' => array( 'Citeren' ),
|
||||
);
|
||||
|
||||
/** Norwegian Nynorsk (norsk nynorsk) */
|
||||
$specialPageAliases['nn'] = array(
|
||||
'Cite' => array( 'Siter' ),
|
||||
);
|
||||
|
||||
/** Occitan (occitan) */
|
||||
$specialPageAliases['oc'] = array(
|
||||
'Cite' => array( 'Citar' ),
|
||||
);
|
||||
|
||||
/** Polish (polski) */
|
||||
$specialPageAliases['pl'] = array(
|
||||
'Cite' => array( 'Cytuj' ),
|
||||
);
|
||||
|
||||
/** Pashto (پښتو) */
|
||||
$specialPageAliases['ps'] = array(
|
||||
'Cite' => array( 'درک' ),
|
||||
);
|
||||
|
||||
/** Portuguese (português) */
|
||||
$specialPageAliases['pt'] = array(
|
||||
'Cite' => array( 'Citar' ),
|
||||
);
|
||||
|
||||
/** Brazilian Portuguese (português do Brasil) */
|
||||
$specialPageAliases['pt-br'] = array(
|
||||
'Cite' => array( 'Citar' ),
|
||||
);
|
||||
|
||||
/** Romanian (română) */
|
||||
$specialPageAliases['ro'] = array(
|
||||
'Cite' => array( 'Citează' ),
|
||||
);
|
||||
|
||||
/** Russian (русский) */
|
||||
$specialPageAliases['ru'] = array(
|
||||
'Cite' => array( 'Цитата' ),
|
||||
);
|
||||
|
||||
/** Sanskrit (संस्कृतम्) */
|
||||
$specialPageAliases['sa'] = array(
|
||||
'Cite' => array( 'उद्धृत' ),
|
||||
);
|
||||
|
||||
/** Sicilian (sicilianu) */
|
||||
$specialPageAliases['scn'] = array(
|
||||
'Cite' => array( 'Cita' ),
|
||||
);
|
||||
|
||||
/** Slovak (slovenčina) */
|
||||
$specialPageAliases['sk'] = array(
|
||||
'Cite' => array( 'Citovať' ),
|
||||
);
|
||||
|
||||
/** Slovenian (slovenščina) */
|
||||
$specialPageAliases['sl'] = array(
|
||||
'Cite' => array( 'Navedi' ),
|
||||
);
|
||||
|
||||
/** Albanian (shqip) */
|
||||
$specialPageAliases['sq'] = array(
|
||||
'Cite' => array( 'Citim' ),
|
||||
);
|
||||
|
||||
/** Swedish (svenska) */
|
||||
$specialPageAliases['sv'] = array(
|
||||
'Cite' => array( 'Citera' ),
|
||||
);
|
||||
|
||||
/** Swahili (Kiswahili) */
|
||||
$specialPageAliases['sw'] = array(
|
||||
'Cite' => array( 'Taja', 'Hakikisha' ),
|
||||
);
|
||||
|
||||
/** Tetum (tetun) */
|
||||
$specialPageAliases['tet'] = array(
|
||||
'Cite' => array( 'Sita' ),
|
||||
);
|
||||
|
||||
/** Thai (ไทย) */
|
||||
$specialPageAliases['th'] = array(
|
||||
'Cite' => array( 'อ้างอิง' ),
|
||||
);
|
||||
|
||||
/** Tagalog (Tagalog) */
|
||||
$specialPageAliases['tl'] = array(
|
||||
'Cite' => array( 'Sipiin' ),
|
||||
);
|
||||
|
||||
/** Turkish (Türkçe) */
|
||||
$specialPageAliases['tr'] = array(
|
||||
'Cite' => array( 'KaynakGöster' ),
|
||||
);
|
||||
|
||||
/** Urdu (اردو) */
|
||||
$specialPageAliases['ur'] = array(
|
||||
'Cite' => array( 'حوالہ' ),
|
||||
);
|
||||
|
||||
/** vèneto (vèneto) */
|
||||
$specialPageAliases['vec'] = array(
|
||||
'Cite' => array( 'Cita' ),
|
||||
);
|
||||
|
||||
/** Vietnamese (Tiếng Việt) */
|
||||
$specialPageAliases['vi'] = array(
|
||||
'Cite' => array( 'Ghi_chú' ),
|
||||
);
|
||||
|
||||
/** Yiddish (ייִדיש) */
|
||||
$specialPageAliases['yi'] = array(
|
||||
'Cite' => array( 'ציטירן' ),
|
||||
);
|
||||
|
||||
/** Cantonese (粵語) */
|
||||
$specialPageAliases['yue'] = array(
|
||||
'Cite' => array( '引用' ),
|
||||
);
|
||||
|
||||
/** Simplified Chinese (中文(简体)) */
|
||||
$specialPageAliases['zh-hans'] = array(
|
||||
'Cite' => array( '引用' ),
|
||||
);
|
||||
|
||||
/** Traditional Chinese (中文(繁體)) */
|
||||
$specialPageAliases['zh-hant'] = array(
|
||||
'Cite' => array( '引用' ),
|
||||
);
|
6507
sources/mediawiki/extensions/Cite/SpecialCite.i18n.php
Normal file
6507
sources/mediawiki/extensions/Cite/SpecialCite.i18n.php
Normal file
File diff suppressed because it is too large
Load diff
90
sources/mediawiki/extensions/Cite/SpecialCite.php
Normal file
90
sources/mediawiki/extensions/Cite/SpecialCite.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
if ( !defined( 'MEDIAWIKI' ) ) die();
|
||||
/**
|
||||
* A special page extension that adds a special page that generates citations
|
||||
* for pages.
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*
|
||||
* @link http://www.mediawiki.org/wiki/Extension:Cite/Special:Cite.php Documentation
|
||||
*
|
||||
* @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
* @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
|
||||
*/
|
||||
|
||||
$wgExtensionCredits['specialpage'][] = array(
|
||||
'path' => __FILE__,
|
||||
'name' => 'Cite',
|
||||
'author' => 'Ævar Arnfjörð Bjarmason',
|
||||
'descriptionmsg' => 'cite_article_desc',
|
||||
'url' => 'https://www.mediawiki.org/wiki/Extension:Cite/Special:Cite.php'
|
||||
);
|
||||
|
||||
$dir = __DIR__ . '/';
|
||||
# Internationalisation file
|
||||
$wgExtensionMessagesFiles['SpecialCite'] = $dir . 'SpecialCite.i18n.php';
|
||||
$wgExtensionMessagesFiles['SpecialCiteAliases'] = $dir . 'SpecialCite.alias.php';
|
||||
|
||||
$wgHooks['SkinTemplateBuildNavUrlsNav_urlsAfterPermalink'][] = 'wfSpecialCiteNav';
|
||||
$wgHooks['SkinTemplateToolboxEnd'][] = 'wfSpecialCiteToolbox';
|
||||
|
||||
$wgSpecialPages['Cite'] = 'SpecialCite';
|
||||
$wgAutoloadClasses['SpecialCite'] = $dir . 'SpecialCite_body.php';
|
||||
|
||||
// Resources
|
||||
$citeResourceTemplate = array(
|
||||
'localBasePath' => __DIR__ . '/modules',
|
||||
'remoteExtPath' => 'Cite/modules'
|
||||
);
|
||||
|
||||
$wgResourceModules['ext.specialcite'] = $citeResourceTemplate + array(
|
||||
'styles' => 'ext.specialcite.css',
|
||||
'scripts' => array(),
|
||||
'position' => 'bottom',
|
||||
);
|
||||
|
||||
/**
|
||||
* @param $skintemplate SkinTemplate
|
||||
* @param $nav_urls
|
||||
* @param $oldid
|
||||
* @param $revid
|
||||
* @return bool
|
||||
*/
|
||||
function wfSpecialCiteNav( &$skintemplate, &$nav_urls, &$oldid, &$revid ) {
|
||||
// check whether we’re in the right namespace, the $revid has the correct type and is not empty
|
||||
// (what would mean that the current page doesn’t exist)
|
||||
$title = $skintemplate->getTitle();
|
||||
if ( $title->isContentPage() && $revid !== 0 && !empty( $revid ) )
|
||||
$nav_urls['cite'] = array(
|
||||
'args' => array( 'page' => $title->getPrefixedDBkey(), 'id' => $revid )
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* add the cite link to the toolbar
|
||||
*
|
||||
* @param $skin Skin
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function wfSpecialCiteToolbox( &$skin ) {
|
||||
if ( isset( $skin->data['nav_urls']['cite'] ) ) {
|
||||
echo Html::rawElement(
|
||||
'li',
|
||||
array( 'id' => 't-cite' ),
|
||||
Linker::link(
|
||||
SpecialPage::getTitleFor( 'Cite' ),
|
||||
wfMessage( 'cite_article_link' )->text(), // @todo Should be escaped()?
|
||||
# Used message keys: 'tooltip-cite-article', 'accesskey-cite-article'
|
||||
Linker::tooltipAndAccessKeyAttribs( 'cite-article' ),
|
||||
$skin->data['nav_urls']['cite']['args']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
180
sources/mediawiki/extensions/Cite/SpecialCite_body.php
Normal file
180
sources/mediawiki/extensions/Cite/SpecialCite_body.php
Normal file
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
class SpecialCite extends SpecialPage {
|
||||
function __construct() {
|
||||
parent::__construct( 'Cite' );
|
||||
}
|
||||
|
||||
function execute( $par ) {
|
||||
global $wgUseTidy;
|
||||
|
||||
// Having tidy on causes whitespace and <pre> tags to
|
||||
// be generated around the output of the CiteOutput
|
||||
// class TODO FIXME.
|
||||
$wgUseTidy = false;
|
||||
|
||||
$this->setHeaders();
|
||||
$this->outputHeader();
|
||||
|
||||
$page = $par !== null ? $par : $this->getRequest()->getText( 'page' );
|
||||
$title = Title::newFromText( $page );
|
||||
|
||||
$cform = new CiteForm( $title );
|
||||
$cform->execute();
|
||||
|
||||
if ( $title && $title->exists() ) {
|
||||
$id = $this->getRequest()->getInt( 'id' );
|
||||
$cout = new CiteOutput( $title, $id );
|
||||
$cout->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CiteForm {
|
||||
/**
|
||||
* @var Title
|
||||
*/
|
||||
var $mTitle;
|
||||
|
||||
function __construct( &$title ) {
|
||||
$this->mTitle =& $title;
|
||||
}
|
||||
|
||||
function execute() {
|
||||
global $wgOut, $wgScript;
|
||||
|
||||
$wgOut->addHTML(
|
||||
Xml::openElement( 'form',
|
||||
array(
|
||||
'id' => 'specialcite',
|
||||
'method' => 'get',
|
||||
'action' => $wgScript
|
||||
) ) .
|
||||
Html::hidden( 'title', SpecialPage::getTitleFor( 'Cite' )->getPrefixedDBkey() ) .
|
||||
Xml::openElement( 'label' ) .
|
||||
wfMessage( 'cite_page' )->escaped() . ' ' .
|
||||
Xml::element( 'input',
|
||||
array(
|
||||
'type' => 'text',
|
||||
'size' => 30,
|
||||
'name' => 'page',
|
||||
'value' => is_object( $this->mTitle ) ? $this->mTitle->getPrefixedText() : ''
|
||||
),
|
||||
''
|
||||
) .
|
||||
' ' .
|
||||
Xml::element( 'input',
|
||||
array(
|
||||
'type' => 'submit',
|
||||
'value' => wfMessage( 'cite_submit' )->escaped()
|
||||
),
|
||||
''
|
||||
) .
|
||||
Xml::closeElement( 'label' ) .
|
||||
Xml::closeElement( 'form' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CiteOutput {
|
||||
/**
|
||||
* @var Title
|
||||
*/
|
||||
var $mTitle;
|
||||
|
||||
/**
|
||||
* @var Article
|
||||
*/
|
||||
var $mArticle;
|
||||
|
||||
var $mId;
|
||||
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
var $mParser;
|
||||
|
||||
/**
|
||||
* @var ParserOptions
|
||||
*/
|
||||
var $mParserOptions;
|
||||
|
||||
var $mSpTitle;
|
||||
|
||||
function __construct( $title, $id ) {
|
||||
global $wgHooks, $wgParser;
|
||||
|
||||
$this->mTitle = $title;
|
||||
$this->mArticle = new Article( $title );
|
||||
$this->mId = $id;
|
||||
|
||||
$wgHooks['ParserGetVariableValueVarCache'][] = array( $this, 'varCache' );
|
||||
|
||||
$this->genParserOptions();
|
||||
$this->genParser();
|
||||
|
||||
$wgParser->setHook( 'citation', array( $this, 'CiteParse' ) );
|
||||
}
|
||||
|
||||
function execute() {
|
||||
global $wgOut, $wgParser, $wgHooks;
|
||||
|
||||
$wgHooks['ParserGetVariableValueTs'][] = array( $this, 'timestamp' );
|
||||
|
||||
$msg = wfMessage( 'cite_text' )->inContentLanguage()->plain();
|
||||
if ( $msg == '' ) {
|
||||
# With MediaWiki 1.20 the plain text files were deleted and the text moved into SpecialCite.i18n.php
|
||||
# This code is kept for b/c in case an installation has its own file "cite_text-xx"
|
||||
# for a previously not supported language.
|
||||
global $wgContLang, $wgContLanguageCode;
|
||||
$dir = dirname( __FILE__ ) . DIRECTORY_SEPARATOR;
|
||||
$code = $wgContLang->lc( $wgContLanguageCode );
|
||||
if ( file_exists( "${dir}cite_text-$code" ) ) {
|
||||
$msg = file_get_contents( "${dir}cite_text-$code" );
|
||||
} elseif( file_exists( "${dir}cite_text" ) ){
|
||||
$msg = file_get_contents( "${dir}cite_text" );
|
||||
}
|
||||
}
|
||||
$ret = $wgParser->parse( $msg, $this->mTitle, $this->mParserOptions, false, true, $this->getRevId() );
|
||||
$wgOut->addModules( 'ext.specialcite' );
|
||||
$wgOut->addHTML( $ret->getText() );
|
||||
}
|
||||
|
||||
function genParserOptions() {
|
||||
global $wgUser;
|
||||
$this->mParserOptions = ParserOptions::newFromUser( $wgUser );
|
||||
$this->mParserOptions->setDateFormat( MW_DATE_DEFAULT );
|
||||
$this->mParserOptions->setEditSection( false );
|
||||
}
|
||||
|
||||
function genParser() {
|
||||
$this->mParser = new Parser;
|
||||
$this->mSpTitle = SpecialPage::getTitleFor( 'Cite' );
|
||||
}
|
||||
|
||||
function CiteParse( $in, $argv ) {
|
||||
$ret = $this->mParser->parse( $in, $this->mSpTitle, $this->mParserOptions, false );
|
||||
|
||||
return $ret->getText();
|
||||
}
|
||||
|
||||
function varCache() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function timestamp( &$parser, &$ts ) {
|
||||
if ( isset( $parser->mTagHooks['citation'] ) ) {
|
||||
$ts = wfTimestamp( TS_UNIX, $this->mArticle->getTimestamp() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getRevId() {
|
||||
if ( $this->mId ) {
|
||||
return $this->mId;
|
||||
} else {
|
||||
return $this->mTitle->getLatestRevID();
|
||||
}
|
||||
}
|
||||
}
|
449
sources/mediawiki/extensions/Cite/citeParserTests.txt
Normal file
449
sources/mediawiki/extensions/Cite/citeParserTests.txt
Normal file
|
@ -0,0 +1,449 @@
|
|||
# Force the test runner to ensure the extension is loaded
|
||||
!! hooks
|
||||
ref
|
||||
references
|
||||
!! endhooks
|
||||
|
||||
!! test
|
||||
Simple <ref>, no <references/>
|
||||
!! input
|
||||
Wikipedia rocks!<ref>Proceeds of Rockology, vol. XXI</ref>
|
||||
!! result
|
||||
<p>Wikipedia rocks!<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
<br /><strong class="error mw-ext-cite-error">Cite error: <code><ref></code> tags exist, but no <code><references/></code> tag was found</strong>
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Simple <ref>, with <references/>
|
||||
!! input
|
||||
Wikipedia rocks!<ref>Proceeds of Rockology, vol. XXI</ref>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p>Wikipedia rocks!<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">Proceeds of Rockology, vol. XXI</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
|
||||
!! article
|
||||
Template:Simple template
|
||||
!! text
|
||||
A ''simple'' template.
|
||||
!! endarticle
|
||||
|
||||
|
||||
!! test
|
||||
<ref> with a simple template
|
||||
!! input
|
||||
Templating<ref>{{simple template}}</ref>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p>Templating<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">A <i>simple</i> template.</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
<ref> with a <nowiki>
|
||||
!! input
|
||||
Templating<ref><nowiki>{{simple template}}</nowiki></ref>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p>Templating<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">{{simple template}}</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
|
||||
!! test
|
||||
<ref> in a <nowiki>
|
||||
!! input
|
||||
Templating<nowiki><ref>{{simple template}}</ref></nowiki>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p>Templating<ref>{{simple template}}</ref>
|
||||
</p><p><br />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
<ref> in a <!--comment-->
|
||||
!! input
|
||||
Templating<!--<ref>{{simple template}}</ref>-->
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p>Templating
|
||||
</p><p><br />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
<!--comment--> in a <ref> (bug 5384)
|
||||
!! input
|
||||
Templating<ref>Text<!--comment--></ref>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p>Templating<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">Text</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
<references> after <gallery> (bug 6164)
|
||||
!! input
|
||||
<ref>one</ref>
|
||||
|
||||
<gallery>Image:Foobar.jpg</gallery>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p><sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
</p>
|
||||
<ul class="gallery mw-gallery-traditional">
|
||||
<li class="gallerybox" style="width: 155px"><div style="width: 155px">
|
||||
<div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
|
||||
<div class="gallerytext">
|
||||
</div>
|
||||
</div></li>
|
||||
</ul>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">one</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
{{REVISIONID}} on page with <ref> (bug 6299)
|
||||
!! input
|
||||
{{REVISIONID}}<ref>elite</ref>
|
||||
!! result
|
||||
<p>1337<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
<br /><strong class="error mw-ext-cite-error">Cite error: <code><ref></code> tags exist, but no <code><references/></code> tag was found</strong>
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
{{REVISIONID}} on page without <ref> (bug 6299 sanity check)
|
||||
!! input
|
||||
{{REVISIONID}}
|
||||
!! result
|
||||
<p>1337
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Blank ref followed by ref with content
|
||||
!! input
|
||||
<ref name="blank"/>
|
||||
|
||||
<ref name="blank">content</ref>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p><sup id="cite_ref-blank_1-0" class="reference"><a href="#cite_note-blank-1">[1]</a></sup>
|
||||
</p><p><sup id="cite_ref-blank_1-1" class="reference"><a href="#cite_note-blank-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-blank-1"><span class="mw-cite-backlink">↑ <sup><a href="#cite_ref-blank_1-0">1.0</a></sup> <sup><a href="#cite_ref-blank_1-1">1.1</a></sup></span> <span class="reference-text">content</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Regression: non-blank ref "0" followed by ref with content
|
||||
!! input
|
||||
<ref name="blank">0</ref>
|
||||
|
||||
<ref name="blank">content</ref>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p><sup id="cite_ref-blank_1-0" class="reference"><a href="#cite_note-blank-1">[1]</a></sup>
|
||||
</p><p><sup id="cite_ref-blank_1-1" class="reference"><a href="#cite_note-blank-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-blank-1"><span class="mw-cite-backlink">↑ <sup><a href="#cite_ref-blank_1-0">1.0</a></sup> <sup><a href="#cite_ref-blank_1-1">1.1</a></sup></span> <span class="reference-text">0</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Regression sanity check: non-blank ref "1" followed by ref with content
|
||||
!! input
|
||||
<ref name="blank">1</ref>
|
||||
|
||||
<ref name="blank">content</ref>
|
||||
|
||||
<references/>
|
||||
!! result
|
||||
<p><sup id="cite_ref-blank_1-0" class="reference"><a href="#cite_note-blank-1">[1]</a></sup>
|
||||
</p><p><sup id="cite_ref-blank_1-1" class="reference"><a href="#cite_note-blank-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-blank-1"><span class="mw-cite-backlink">↑ <sup><a href="#cite_ref-blank_1-0">1.0</a></sup> <sup><a href="#cite_ref-blank_1-1">1.1</a></sup></span> <span class="reference-text">1</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Ref names containing a number
|
||||
!! input
|
||||
<ref name="test123test">One</ref>
|
||||
<ref name="123test">Two</ref>
|
||||
<ref name="test123">Three</ref>
|
||||
|
||||
<references />
|
||||
!! result
|
||||
<p><sup id="cite_ref-test123test_1-0" class="reference"><a href="#cite_note-test123test-1">[1]</a></sup>
|
||||
<sup id="cite_ref-123test_2-0" class="reference"><a href="#cite_note-123test-2">[2]</a></sup>
|
||||
<sup id="cite_ref-test123_3-0" class="reference"><a href="#cite_note-test123-3">[3]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-test123test-1"><span class="mw-cite-backlink"><a href="#cite_ref-test123test_1-0">↑</a></span> <span class="reference-text">One</span>
|
||||
</li>
|
||||
<li id="cite_note-123test-2"><span class="mw-cite-backlink"><a href="#cite_ref-123test_2-0">↑</a></span> <span class="reference-text">Two</span>
|
||||
</li>
|
||||
<li id="cite_note-test123-3"><span class="mw-cite-backlink"><a href="#cite_ref-test123_3-0">↑</a></span> <span class="reference-text">Three</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Erroneous refs
|
||||
!! input
|
||||
<ref name="0">Zero</ref>
|
||||
|
||||
<ref>Also zero, but differently! (Normal ref)</ref>
|
||||
|
||||
<ref />
|
||||
|
||||
<ref name="foo" name="bar" />
|
||||
|
||||
<ref name="blankwithnoreference" />
|
||||
|
||||
<references name="quasit" />
|
||||
|
||||
<references />
|
||||
!! result
|
||||
<p><strong class="error mw-ext-cite-error">Cite error: Invalid <code><ref></code> tag;
|
||||
name cannot be a simple integer. Use a descriptive title</strong>
|
||||
</p><p><sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
</p><p><strong class="error mw-ext-cite-error">Cite error: Invalid <code><ref></code> tag;
|
||||
refs with no content must have a name</strong>
|
||||
</p><p><sup id="cite_ref-bar_2-0" class="reference"><a href="#cite_note-bar-2">[2]</a></sup>
|
||||
</p><p><sup id="cite_ref-blankwithnoreference_3-0" class="reference"><a href="#cite_note-blankwithnoreference-3">[3]</a></sup>
|
||||
</p><p><strong class="error mw-ext-cite-error">Cite error: Invalid <code><references></code> tag;
|
||||
parameter "group" is allowed only.
|
||||
Use <code><references /></code>, or <code><references group="..." /></code></strong>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">Also zero, but differently! (Normal ref)</span>
|
||||
</li>
|
||||
<li id="cite_note-bar"><span class="mw-cite-backlink"><a href="#cite_ref-bar_0">↑</a></span> <strong class="error mw-ext-cite-error">Cite error: Invalid <code><ref></code> tag;
|
||||
no text was provided for refs named <code>bar</code></strong></li>
|
||||
<li id="cite_note-blankwithnoreference"><span class="mw-cite-backlink"><a href="#cite_ref-blankwithnoreference_0">↑</a></span> <strong class="error mw-ext-cite-error">Cite error: Invalid <code><ref></code> tag;
|
||||
no text was provided for refs named <code>blankwithnoreference</code></strong></li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
|
||||
!! test
|
||||
Simple <ref>, with <references/> in group
|
||||
!! input
|
||||
Wikipedia rocks!<ref>Proceeds of Rockology, vol. XXI</ref>
|
||||
Wikipedia rocks!<ref group=note>Proceeds of Rockology, vol. XXI</ref>
|
||||
|
||||
<references/>
|
||||
<references group=note/>
|
||||
!! result
|
||||
<p>Wikipedia rocks!<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
Wikipedia rocks!<sup id="cite_ref-2" class="reference"><a href="#cite_note-2">[note 1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">Proceeds of Rockology, vol. XXI</span>
|
||||
</li>
|
||||
</ol>
|
||||
<ol class="references">
|
||||
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text">Proceeds of Rockology, vol. XXI</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Simple <ref>, with <references/> in group, with groupname in chinese
|
||||
!! input
|
||||
AAA<ref group="参">ref a</ref>BBB<ref group="注">note b</ref>CCC<ref group="参">ref c</ref>
|
||||
|
||||
;refs
|
||||
<references group="参" />
|
||||
;notes
|
||||
<references group="注" />
|
||||
!! result
|
||||
<p>AAA<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[参 1]</a></sup>BBB<sup id="cite_ref-2" class="reference"><a href="#cite_note-2">[注 1]</a></sup>CCC<sup id="cite_ref-3" class="reference"><a href="#cite_note-3">[参 2]</a></sup>
|
||||
</p>
|
||||
<dl><dt>refs
|
||||
</dt></dl>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">ref a</span>
|
||||
</li>
|
||||
<li id="cite_note-3"><span class="mw-cite-backlink"><a href="#cite_ref-3">↑</a></span> <span class="reference-text">ref c</span>
|
||||
</li>
|
||||
</ol>
|
||||
<dl><dt>notes
|
||||
</dt></dl>
|
||||
<ol class="references">
|
||||
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text">note b</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
<ref> defined in <references>
|
||||
!! input
|
||||
<ref name="foo"/>
|
||||
|
||||
<references>
|
||||
<ref name="foo">BAR</ref>
|
||||
</references>
|
||||
!! result
|
||||
<p><sup id="cite_ref-foo_1-0" class="reference"><a href="#cite_note-foo-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-foo-1"><span class="mw-cite-backlink"><a href="#cite_ref-foo_1-0">↑</a></span> <span class="reference-text">BAR</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
<ref> defined in <references> called with #tag
|
||||
!! input
|
||||
<ref name="foo"/>
|
||||
|
||||
{{#tag:references|
|
||||
<ref name="foo">BAR</ref>
|
||||
}}
|
||||
!! result
|
||||
<p><sup id="cite_ref-foo_1-0" class="reference"><a href="#cite_note-foo-1">[1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-foo-1"><span class="mw-cite-backlink"><a href="#cite_ref-foo_1-0">↑</a></span> <span class="reference-text">BAR</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
<ref> defined in <references> error conditions
|
||||
!! input
|
||||
<ref name="foo" group="2"/>
|
||||
|
||||
<references group="2">
|
||||
<ref name="foo"/>
|
||||
<ref name="unused">BAR</ref>
|
||||
<ref name="foo" group="1">bad group</ref>
|
||||
<ref>BAR BAR</ref>
|
||||
</references>
|
||||
!! result
|
||||
<p><sup id="cite_ref-foo_1-0" class="reference"><a href="#cite_note-foo-1">[2 1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-foo"><span class="mw-cite-backlink"><a href="#cite_ref-foo_0">↑</a></span> <strong class="error mw-ext-cite-error">Cite error: Invalid <code><ref></code> tag;
|
||||
no text was provided for refs named <code>foo</code></strong></li>
|
||||
</ol>
|
||||
<p><strong class="error mw-ext-cite-error">Cite error: <code><ref></code> tag with name "unused" defined in <code><references></code> is not used in prior text.</strong><br />
|
||||
<strong class="error mw-ext-cite-error">Cite error: <code><ref></code> tag in <code><references></code> has conflicting group attribute "1".</strong><br />
|
||||
<strong class="error mw-ext-cite-error">Cite error: <code><ref></code> tag defined in <code><references></code> has no name attribute.</strong>
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! article
|
||||
MediaWiki:cite_link_label_group-klingon
|
||||
!! text
|
||||
wa' cha' wej loS vagh jav Soch chorgh Hut wa'maH
|
||||
!! endarticle
|
||||
|
||||
!! test
|
||||
<ref> with custom group link
|
||||
!! input
|
||||
Wikipedia rocks!<ref group="klingon">Proceeds of Rockology, vol. XXI</ref>
|
||||
|
||||
<references group="klingon"/>
|
||||
!! result
|
||||
<p>Wikipedia rocks!<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[wa']</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">Proceeds of Rockology, vol. XXI</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Bug 31374 regression check: nested strip items
|
||||
!! input
|
||||
{{#tag:ref|note<ref>reference</ref>|group=Note}}
|
||||
<references group=Note />
|
||||
<references />
|
||||
!! result
|
||||
<p><sup id="cite_ref-2" class="reference"><a href="#cite_note-2">[Note 1]</a></sup>
|
||||
</p>
|
||||
<ol class="references">
|
||||
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text">note<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup></span>
|
||||
</li>
|
||||
</ol>
|
||||
<ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">reference</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
!! end
|
||||
|
||||
!! test
|
||||
Bug 13073 regression check: wrapped <references>
|
||||
!! input
|
||||
<ref>
|
||||
foo
|
||||
</ref>
|
||||
<div><references /></div>
|
||||
!! result
|
||||
<p><sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>
|
||||
</p>
|
||||
<div><ol class="references">
|
||||
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">
|
||||
foo</span>
|
||||
</li>
|
||||
</ol></div>
|
||||
|
||||
!! end
|
16
sources/mediawiki/extensions/Cite/modules/ext.cite.css
Normal file
16
sources/mediawiki/extensions/Cite/modules/ext.cite.css
Normal file
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* Per http://developer.yahoo.com/blogs/ydn/clip-hidden-content-better-accessibility-53456.html
|
||||
* and https://en.wikipedia.org/w/index.php?oldid=572888139#Scrolling_past_the_bottom_of_the_page...
|
||||
*/
|
||||
.cite-accessibility-label {
|
||||
position: absolute !important;
|
||||
/* Workaround a Webkit/Blink bug about positioning within columns as many wikis format references with several columns */
|
||||
top: -99999px;
|
||||
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
height: 1px !important;
|
||||
width: 1px !important;
|
||||
overflow: hidden;
|
||||
}
|
38
sources/mediawiki/extensions/Cite/modules/ext.cite.js
Normal file
38
sources/mediawiki/extensions/Cite/modules/ext.cite.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Main JavaScript for the Cite extension. The main purpose of this file
|
||||
* is to add accessibility attributes to the citation links as that can
|
||||
* hardly be done server side (bug 38141).
|
||||
*
|
||||
* @author Marius Hoch <hoo@online.de>
|
||||
*/
|
||||
( function ( mw, $ ) {
|
||||
'use strict';
|
||||
|
||||
mw.hook( 'wikipage.content' ).add( function ( $content ) {
|
||||
var accessibilityLabelOne = mw.msg( 'cite_references_link_accessibility_label' ),
|
||||
accessibilityLabelMany = mw.msg( 'cite_references_link_many_accessibility_label' );
|
||||
|
||||
$content.find( '.mw-cite-backlink' ).each( function () {
|
||||
var $links = $( this ).find( 'a' ),
|
||||
label;
|
||||
|
||||
if ( $links.length > 1 ) {
|
||||
// This citation is used multiple times. Let's only set the accessibility label on the first link, the
|
||||
// following ones should then be self-explaining. This is needed to make sure this isn't getting
|
||||
// too wordy.
|
||||
label = accessibilityLabelMany;
|
||||
} else {
|
||||
label = accessibilityLabelOne;
|
||||
}
|
||||
|
||||
// We can't use aria-label over here as that's not supported consistently across all screen reader / browser
|
||||
// combinations. We have to use visually hidden spans for the accessibility labels instead.
|
||||
$links.eq( 0 ).prepend(
|
||||
$( '<span>' )
|
||||
.addClass( 'cite-accessibility-label' )
|
||||
// Also make sure we have at least one space between the accessibility label and the visual one
|
||||
.text( label + ' ' )
|
||||
);
|
||||
} );
|
||||
} );
|
||||
} )( mediaWiki, jQuery );
|
13
sources/mediawiki/extensions/Cite/modules/ext.cite.popups.js
Normal file
13
sources/mediawiki/extensions/Cite/modules/ext.cite.popups.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
( function ( mw, $ ) {
|
||||
'use strict';
|
||||
|
||||
mw.hook( 'wikipage.content' ).add( function ( $content ) {
|
||||
$content.find( '.biblio-cite-link,sup.reference a' ).tooltip( {
|
||||
bodyHandler: function () {
|
||||
return $content.find( '#' + this.hash.substr( 1 ) + ' > .reference-text' )
|
||||
.html();
|
||||
},
|
||||
showURL: false
|
||||
} );
|
||||
} );
|
||||
} )( mediaWiki, jQuery );
|
|
@ -0,0 +1,6 @@
|
|||
/* Isolation to fix references in case of RTL words at the end of a reference */
|
||||
sup.reference {
|
||||
unicode-bidi: -moz-isolate;
|
||||
unicode-bidi: -webkit-isolate;
|
||||
unicode-bidi: isolate;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
.mw-specialcite-bibliographic {
|
||||
border: 1px solid grey;
|
||||
background: #E6E8FA;
|
||||
width: 90%;
|
||||
padding: 15px 30px 15px 30px;
|
||||
margin: 10px auto;
|
||||
}
|
||||
.mw-specialcite-styles {
|
||||
border: 1px solid grey;
|
||||
width: 90%;
|
||||
padding: 15px 30px 15px 30px;
|
||||
margin: 10px auto;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#tooltip {
|
||||
position: absolute;
|
||||
z-index: 3000;
|
||||
border: 1px solid #111;
|
||||
background-color: #eee;
|
||||
padding: 5px;
|
||||
opacity: 0.85;
|
||||
}
|
||||
#tooltip h3, #tooltip div { margin: 0; }
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* jQuery Tooltip plugin 1.3
|
||||
*
|
||||
* http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
|
||||
* http://docs.jquery.com/Plugins/Tooltip
|
||||
*
|
||||
* Copyright (c) 2006 - 2008 Jörn Zaefferer
|
||||
*
|
||||
* $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
|
||||
;(function($) {
|
||||
|
||||
// the tooltip element
|
||||
var helper = {},
|
||||
// the current tooltipped element
|
||||
current,
|
||||
// the title of the current element, used for restoring
|
||||
title,
|
||||
// timeout id for delayed tooltips
|
||||
tID,
|
||||
// IE 5.5 or 6
|
||||
IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
|
||||
// flag for mouse tracking
|
||||
track = false;
|
||||
|
||||
$.tooltip = {
|
||||
blocked: false,
|
||||
defaults: {
|
||||
delay: 200,
|
||||
fade: false,
|
||||
showURL: true,
|
||||
extraClass: "",
|
||||
top: 15,
|
||||
left: 15,
|
||||
id: "tooltip"
|
||||
},
|
||||
block: function() {
|
||||
$.tooltip.blocked = !$.tooltip.blocked;
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
tooltip: function(settings) {
|
||||
settings = $.extend({}, $.tooltip.defaults, settings);
|
||||
createHelper(settings);
|
||||
return this.each(function() {
|
||||
$.data(this, "tooltip", settings);
|
||||
this.tOpacity = helper.parent.css("opacity");
|
||||
// copy tooltip into its own expando and remove the title
|
||||
this.tooltipText = this.title;
|
||||
$(this).removeAttr("title");
|
||||
// also remove alt attribute to prevent default tooltip in IE
|
||||
this.alt = "";
|
||||
})
|
||||
.mouseover(save)
|
||||
.mouseout(hide)
|
||||
.click(hide);
|
||||
},
|
||||
fixPNG: IE ? function() {
|
||||
return this.each(function () {
|
||||
var image = $(this).css('backgroundImage');
|
||||
if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
|
||||
image = RegExp.$1;
|
||||
$(this).css({
|
||||
'backgroundImage': 'none',
|
||||
'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
|
||||
}).each(function () {
|
||||
var position = $(this).css('position');
|
||||
if (position != 'absolute' && position != 'relative')
|
||||
$(this).css('position', 'relative');
|
||||
});
|
||||
}
|
||||
});
|
||||
} : function() { return this; },
|
||||
unfixPNG: IE ? function() {
|
||||
return this.each(function () {
|
||||
$(this).css({'filter': '', backgroundImage: ''});
|
||||
});
|
||||
} : function() { return this; },
|
||||
hideWhenEmpty: function() {
|
||||
return this.each(function() {
|
||||
$(this)[ $(this).html() ? "show" : "hide" ]();
|
||||
});
|
||||
},
|
||||
url: function() {
|
||||
return this.attr('href') || this.attr('src');
|
||||
}
|
||||
});
|
||||
|
||||
function createHelper(settings) {
|
||||
// there can be only one tooltip helper
|
||||
if( helper.parent )
|
||||
return;
|
||||
// create the helper, h3 for title, div for url
|
||||
helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
|
||||
// add to document
|
||||
.appendTo(document.body)
|
||||
// hide it at first
|
||||
.hide();
|
||||
|
||||
// apply bgiframe if available
|
||||
if ( $.fn.bgiframe )
|
||||
helper.parent.bgiframe();
|
||||
|
||||
// save references to title and url elements
|
||||
helper.title = $('h3', helper.parent);
|
||||
helper.body = $('div.body', helper.parent);
|
||||
helper.url = $('div.url', helper.parent);
|
||||
}
|
||||
|
||||
function settings(element) {
|
||||
return $.data(element, "tooltip");
|
||||
}
|
||||
|
||||
// main event handler to start showing tooltips
|
||||
function handle(event) {
|
||||
// show helper, either with timeout or on instant
|
||||
if( settings(this).delay )
|
||||
tID = setTimeout(show, settings(this).delay);
|
||||
else
|
||||
show();
|
||||
|
||||
// if selected, update the helper position when the mouse moves
|
||||
track = !!settings(this).track;
|
||||
$(document.body).bind('mousemove', update);
|
||||
|
||||
// update at least once
|
||||
update(event);
|
||||
}
|
||||
|
||||
// save elements title before the tooltip is displayed
|
||||
function save() {
|
||||
// if this is the current source, or it has no title (occurs with click event), stop
|
||||
if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
|
||||
return;
|
||||
|
||||
// save current
|
||||
current = this;
|
||||
title = this.tooltipText;
|
||||
|
||||
if ( settings(this).bodyHandler ) {
|
||||
helper.title.hide();
|
||||
var bodyContent = settings(this).bodyHandler.call(this);
|
||||
if (bodyContent.nodeType || bodyContent.jquery) {
|
||||
helper.body.empty().append(bodyContent)
|
||||
} else {
|
||||
helper.body.html( bodyContent );
|
||||
}
|
||||
helper.body.show();
|
||||
} else if ( settings(this).showBody ) {
|
||||
var parts = title.split(settings(this).showBody);
|
||||
helper.title.html(parts.shift()).show();
|
||||
helper.body.empty();
|
||||
for(var i = 0, part; (part = parts[i]); i++) {
|
||||
if(i > 0)
|
||||
helper.body.append("<br/>");
|
||||
helper.body.append(part);
|
||||
}
|
||||
helper.body.hideWhenEmpty();
|
||||
} else {
|
||||
helper.title.html(title).show();
|
||||
helper.body.hide();
|
||||
}
|
||||
|
||||
// if element has href or src, add and show it, otherwise hide it
|
||||
if( settings(this).showURL && $(this).url() )
|
||||
helper.url.html( $(this).url().replace('http://', '') ).show();
|
||||
else
|
||||
helper.url.hide();
|
||||
|
||||
// add an optional class for this tip
|
||||
helper.parent.addClass(settings(this).extraClass);
|
||||
|
||||
// fix PNG background for IE
|
||||
if (settings(this).fixPNG )
|
||||
helper.parent.fixPNG();
|
||||
|
||||
handle.apply(this, arguments);
|
||||
}
|
||||
|
||||
// delete timeout and show helper
|
||||
function show() {
|
||||
tID = null;
|
||||
if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
|
||||
if (helper.parent.is(":animated"))
|
||||
helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
|
||||
else
|
||||
helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
|
||||
} else {
|
||||
helper.parent.show();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* callback for mousemove
|
||||
* updates the helper position
|
||||
* removes itself when no current element
|
||||
*/
|
||||
function update(event) {
|
||||
if($.tooltip.blocked)
|
||||
return;
|
||||
|
||||
if (event && event.target.tagName == "OPTION") {
|
||||
return;
|
||||
}
|
||||
|
||||
// stop updating when tracking is disabled and the tooltip is visible
|
||||
if ( !track && helper.parent.is(":visible")) {
|
||||
$(document.body).unbind('mousemove', update)
|
||||
}
|
||||
|
||||
// if no current element is available, remove this listener
|
||||
if( current == null ) {
|
||||
$(document.body).unbind('mousemove', update);
|
||||
return;
|
||||
}
|
||||
|
||||
// remove position helper classes
|
||||
helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
|
||||
|
||||
var left = helper.parent[0].offsetLeft;
|
||||
var top = helper.parent[0].offsetTop;
|
||||
if (event) {
|
||||
// position the helper 15 pixel to bottom right, starting from mouse position
|
||||
left = event.pageX + settings(current).left;
|
||||
top = event.pageY + settings(current).top;
|
||||
var right='auto';
|
||||
if (settings(current).positionLeft) {
|
||||
right = $(window).width() - left;
|
||||
left = 'auto';
|
||||
}
|
||||
helper.parent.css({
|
||||
left: left,
|
||||
right: right,
|
||||
top: top
|
||||
});
|
||||
}
|
||||
|
||||
var v = viewport(),
|
||||
h = helper.parent[0];
|
||||
// check horizontal position
|
||||
if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
|
||||
left -= h.offsetWidth + 20 + settings(current).left;
|
||||
helper.parent.css({left: left + 'px'}).addClass("viewport-right");
|
||||
}
|
||||
// check vertical position
|
||||
if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
|
||||
top -= h.offsetHeight + 20 + settings(current).top;
|
||||
helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
|
||||
}
|
||||
}
|
||||
|
||||
function viewport() {
|
||||
return {
|
||||
x: $(window).scrollLeft(),
|
||||
y: $(window).scrollTop(),
|
||||
cx: $(window).width(),
|
||||
cy: $(window).height()
|
||||
};
|
||||
}
|
||||
|
||||
// hide helper and restore added classes and the title
|
||||
function hide(event) {
|
||||
if($.tooltip.blocked)
|
||||
return;
|
||||
// clear timeout if possible
|
||||
if(tID)
|
||||
clearTimeout(tID);
|
||||
// no more current element
|
||||
current = null;
|
||||
|
||||
var tsettings = settings(this);
|
||||
function complete() {
|
||||
helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
|
||||
}
|
||||
if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
|
||||
if (helper.parent.is(':animated'))
|
||||
helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
|
||||
else
|
||||
helper.parent.stop().fadeOut(tsettings.fade, complete);
|
||||
} else
|
||||
complete();
|
||||
|
||||
if( settings(this).fixPNG )
|
||||
helper.parent.unfixPNG();
|
||||
}
|
||||
|
||||
})(jQuery);
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* Api module to reload FancyCaptcha
|
||||
*
|
||||
* @ingroup API
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
class ApiFancyCaptchaReload extends ApiBase {
|
||||
public function execute() {
|
||||
# Get a new FancyCaptcha form data
|
||||
$captcha = new FancyCaptcha();
|
||||
$captchaIndex = $captcha->getCaptchaIndex();
|
||||
|
||||
$result = $this->getResult();
|
||||
$result->addValue( null, $this->getModuleName(), array ( 'index' => $captchaIndex ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return 'Get a new FancyCaptcha.';
|
||||
}
|
||||
|
||||
public function getAllowedParams() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getParamDescription() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getExamples() {
|
||||
return array( 'api.php?action=fancycaptchareload&format=xml' );
|
||||
}
|
||||
}
|
55
sources/mediawiki/extensions/ConfirmEdit/Asirra.class.php
Normal file
55
sources/mediawiki/extensions/ConfirmEdit/Asirra.class.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Bachsau
|
||||
* @author Niklas Laxström
|
||||
*/
|
||||
|
||||
class Asirra extends SimpleCaptcha {
|
||||
public $asirra_clientscript = '//challenge.asirra.com/js/AsirraClientSide.js';
|
||||
|
||||
// As we don't have to store anything but some other things to do,
|
||||
// we're going to replace that constructor completely.
|
||||
function __construct() {
|
||||
global $wgExtensionAssetsPath;
|
||||
$this->asirra_localpath = "$wgExtensionAssetsPath/ConfirmEdit";
|
||||
}
|
||||
|
||||
function getForm() {
|
||||
global $wgOut;
|
||||
|
||||
$wgOut->addModules( 'ext.confirmEdit.asirra' );
|
||||
$js = Html::linkedScript( $this->asirra_clientscript );
|
||||
|
||||
$message = Xml::encodeJsVar( wfMessage( 'asirra-createaccount-fail' )->plain() );
|
||||
$js .= Html::inlineScript( <<<JAVASCRIPT
|
||||
var asirra_js_failed = '$message';
|
||||
JAVASCRIPT
|
||||
);
|
||||
$js .= '<noscript>' . wfMessage( 'asirra-nojs' )->parse() . '</noscript>';
|
||||
return $js;
|
||||
}
|
||||
|
||||
function getMessage( $action ) {
|
||||
$name = 'asirra-' . $action;
|
||||
$text = wfMessage( $name )->text();
|
||||
# Obtain a more tailored message, if possible, otherwise, fall
|
||||
# back to the default for edits
|
||||
return wfMessage( $name, $text )->isDisabled() ? wfMessage( 'asirra-edit' )->text() : $text;
|
||||
}
|
||||
|
||||
function passCaptcha() {
|
||||
global $wgRequest;
|
||||
|
||||
$ticket = $wgRequest->getVal( 'Asirra_Ticket' );
|
||||
$api = 'http://challenge.asirra.com/cgi/Asirra?';
|
||||
$params = array(
|
||||
'action' => 'ValidateTicket',
|
||||
'ticket' => $ticket,
|
||||
);
|
||||
|
||||
$response = Http::get( $api . wfArrayToCgi( $params ) );
|
||||
$xml = simplexml_load_string( $response );
|
||||
$result = $xml->xpath( '/AsirraValidation/Result' );
|
||||
return strval( $result[0] ) === 'Pass';
|
||||
}
|
||||
}
|
549
sources/mediawiki/extensions/ConfirmEdit/Asirra.i18n.php
Normal file
549
sources/mediawiki/extensions/ConfirmEdit/Asirra.i18n.php
Normal file
|
@ -0,0 +1,549 @@
|
|||
<?php
|
||||
/**
|
||||
* Internationalisation file for the Asirra module of the ConfirmEdit
|
||||
* extension.
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
|
||||
$messages['en'] = array(
|
||||
'asirra-desc' => 'Asirra module for ConfirmEdit',
|
||||
'asirra-edit' => 'To protect the wiki against automated edit spam, we kindly ask you to select just the cat photos in the box below:',
|
||||
'asirra-addurl' => 'Your edit includes new external links. To protect the wiki against automated edit spam, we kindly ask you to select just the cat photos in the box below:',
|
||||
'asirra-badlogin' => 'To protect the wiki against automated password cracking, we kindly ask you to select just the cat photos in the box below:',
|
||||
'asirra-createaccount' => 'To protect the wiki against automated account creation, we kindly ask you to select just the cat photos in the box below:',
|
||||
'asirra-createaccount-fail' => "Please correctly identify the cats.",
|
||||
'asirra-create' => 'To protect the wiki against automated page creation, we kindly ask you to select just the cat photos in the box below:',
|
||||
'asirra-nojs' => '\'\'\'Please enable JavaScript and resubmit the page.\'\'\'',
|
||||
'asirra-failed' => 'Please identify all cat images',
|
||||
);
|
||||
|
||||
/** Message documentation (Message documentation)
|
||||
* @author 2nd-player
|
||||
* @author Beta16
|
||||
* @author Raymond
|
||||
* @author Shirayuki
|
||||
*/
|
||||
$messages['qqq'] = array(
|
||||
'asirra-desc' => '{{desc|name=Asirra|url=http://www.mediawiki.org/wiki/Extension:Asirra}}',
|
||||
'asirra-edit' => '{{Related|ConfirmEdit-edit}}',
|
||||
'asirra-addurl' => '{{Related|ConfirmEdit-addurl}}',
|
||||
'asirra-badlogin' => '{{Related|ConfirmEdit-badlogin}}',
|
||||
'asirra-createaccount' => '{{Related|ConfirmEdit-createaccount}}',
|
||||
'asirra-createaccount-fail' => 'Used as failure message in JavaScript code.
|
||||
{{Related|ConfirmEdit-createaccount-fail}}',
|
||||
'asirra-create' => '{{Related|ConfirmEdit-create}}',
|
||||
'asirra-nojs' => 'Used in HTML <code><nowiki><noscript></nowiki></code> tag.',
|
||||
'asirra-failed' => 'Used as alert message in JavaScript code.',
|
||||
);
|
||||
|
||||
/** Asturian (asturianu)
|
||||
* @author Xuacu
|
||||
*/
|
||||
$messages['ast'] = array(
|
||||
'asirra-desc' => 'Módulu Asirra pa ConfirmEdit',
|
||||
'asirra-edit' => "Pa protexer la wiki escontra'l spam d'edición automáticu, pidimos-y qu'esbille namái les fotos de gatos del cuadru d'abaxo:",
|
||||
'asirra-addurl' => "La so edición incluye enllaces esternos nuevos. Pa protexer la wiki escontra'l spam automáticu, pidimos-y qu'esbille namái les fotos de gatos del cuadru d'abaxo:",
|
||||
'asirra-badlogin' => "Pa protexer la wiki escontra'l frayamientu de claves automáticu, pidimos-y qu'esbille namái les fotos de gatos del cuadru d'abaxo:",
|
||||
'asirra-createaccount' => "Pa protexer la wiki escontra la creación de cuentes automática, pidimos-y qu'esbille namái les fotos de gatos del cuadru d'abaxo:",
|
||||
'asirra-createaccount-fail' => 'Identifique correutamente los gatos.',
|
||||
'asirra-create' => "Pa protexer la wiki escontra la creación de páxines automática, pidimos-y qu'esbille namái les fotos de gatos del cuadru d'abaxo:",
|
||||
'asirra-nojs' => "'''Por favor active JavaScript y vuelva a unviar la páxina.'''",
|
||||
'asirra-failed' => 'Identifique toles imaxes de gatos',
|
||||
);
|
||||
|
||||
/** Belarusian (Taraškievica orthography) (беларуская (тарашкевіца))
|
||||
* @author EugeneZelenko
|
||||
* @author Jim-by
|
||||
* @author Wizardist
|
||||
*/
|
||||
$messages['be-tarask'] = array(
|
||||
'asirra-desc' => 'Модуль Asirra для ConfirmEdit',
|
||||
'asirra-edit' => 'Для абароны супраць спаму, калі ласка, выберыце толькі фота з катом ў полі ніжэй:', # Fuzzy
|
||||
'asirra-addurl' => 'Вашае рэдагаваньне ўтрымлівае новыя вонкавыя спасылкі. Для абароны супраць спаму, калі ласка, выберыце толькі фота з катом ў полі ніжэй:', # Fuzzy
|
||||
'asirra-badlogin' => 'Для абароны супраць аўтаматычнага падбору паролю, калі ласка, выберыце толькі фота з катом ў полі ніжэй:', # Fuzzy
|
||||
'asirra-createaccount' => 'Для абароны супраць аўтаматычнага стварэньня рахункаў, калі ласка, выберыце толькі фота з катом ў полі ніжэй:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Калі ласка, слушна выберыце катоў.',
|
||||
'asirra-create' => 'Для абароны супраць аўтаматычнага стварэньня старонак, калі ласка, выберыце толькі фота з катом ў полі ніжэй:', # Fuzzy
|
||||
'asirra-nojs' => "'''Калі ласка, дазвольце JavaScript і дашліце старонку зноў.'''",
|
||||
'asirra-failed' => 'Калі ласка, вызначце ўсе выявы з катамі',
|
||||
);
|
||||
|
||||
/** Breton (brezhoneg)
|
||||
* @author Fohanno
|
||||
*/
|
||||
$messages['br'] = array(
|
||||
'asirra-nojs' => "'''Gweredekait JavaScript, mar plij, hag adkasit ar bajenn.'''",
|
||||
);
|
||||
|
||||
/** Czech (česky)
|
||||
* @author Vks
|
||||
*/
|
||||
$messages['cs'] = array(
|
||||
'asirra-createaccount-fail' => 'Prosíme, správně identifikujte kočky.',
|
||||
);
|
||||
|
||||
/** German (Deutsch)
|
||||
* @author Kghbln
|
||||
* @author Metalhead64
|
||||
*/
|
||||
$messages['de'] = array(
|
||||
'asirra-desc' => 'Ermöglicht die Nutzung des Anti-Spam-Moduls Asirra',
|
||||
'asirra-edit' => 'Zum Schutz des Wikis vor automatisiertem Spam bitten wir dich, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:',
|
||||
'asirra-addurl' => 'Deine Bearbeitung enthält neue externe Links. Zum Schutz des Wikis vor automatisiertem Spam bitten wir dich, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:',
|
||||
'asirra-badlogin' => 'Zum Schutz des Wikis gegen automatisiertes Knacken von Passwörtern bitten wir dich, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:',
|
||||
'asirra-createaccount' => 'Zum Schutz des Wikis gegen automatisiertes Erstellen von Benutzerkonten bitten wir dich, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:',
|
||||
'asirra-createaccount-fail' => 'Bitte wähle nur die Fotos mit Katzen aus.',
|
||||
'asirra-create' => 'Zum Schutz des Wikis gegen automatisiertes Erstellen von Seiten bitten wir dich, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:',
|
||||
'asirra-nojs' => "'''Bitte JavaScript aktivieren und die Seiten nochmals Speichern.'''",
|
||||
'asirra-failed' => 'Bitte wähle nur die Fotos mit Katzen aus.',
|
||||
);
|
||||
|
||||
/** German (formal address) (Deutsch (Sie-Form))
|
||||
* @author Kghbln
|
||||
*/
|
||||
$messages['de-formal'] = array(
|
||||
'asirra-addurl' => 'Ihre Bearbeitung enthält neue externe Links. Zum Schutz vor automatisiertem Spam bitten wir Sie, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:', # Fuzzy
|
||||
'asirra-badlogin' => 'Zum Schutz gegen automatisiertes Knacken von Passwörtern bitten wir Sie, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:', # Fuzzy
|
||||
'asirra-createaccount' => 'Zum Schutz gegen automatisiertes Erstellen von Benutzerkonten bitten wir Sie, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Bitte wählen Sie nur die Fotos mit Katzen aus.',
|
||||
'asirra-create' => 'Zum Schutz gegen automatisiertes Erstellen von Seiten bitten wir Sie, nur die Fotos mit Katzen im untenstehenden Feld auszuwählen:', # Fuzzy
|
||||
'asirra-failed' => 'Bitte wählen Sie nur die Fotos mit Katzen aus.',
|
||||
);
|
||||
|
||||
/** Zazaki (Zazaki)
|
||||
* @author Erdemaslancan
|
||||
*/
|
||||
$messages['diq'] = array(
|
||||
'asirra-desc' => 'Qandê Asirra modulê RaştkerdenVurnen',
|
||||
);
|
||||
|
||||
/** Spanish (español)
|
||||
* @author Armando-Martin
|
||||
*/
|
||||
$messages['es'] = array(
|
||||
'asirra-desc' => 'Módulo de Asirra para ConfirmEdit',
|
||||
'asirra-edit' => 'Para ayudar a protegernos contra el spam de edición automática, seleccione sólo las fotos de gatos en el cuadro siguiente:', # Fuzzy
|
||||
'asirra-addurl' => 'Su edición incluye nuevos enlaces externos. Para ayudar a protegernos contra el spam automatizado, por favor, seleccione solo las fotos de gato en el cuadro siguiente:', # Fuzzy
|
||||
'asirra-badlogin' => 'Para ayudar a protegernos del robo automatizado de contraseñas, seleccione sólo las fotos de gatos en el cuadro siguiente:', # Fuzzy
|
||||
'asirra-createaccount' => 'Para ayudar a protegernos contra la creación automatizada de cuentas, seleccione sólo las fotos de gato en el cuadro siguiente:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Identifique correctamente los gatos.',
|
||||
'asirra-create' => 'Para ayudar a protegernos contra la creación automática de páginas, seleccione sólo las fotos de gato en el cuadro siguiente:', # Fuzzy
|
||||
'asirra-nojs' => "'''Por favor active JavaScript y vuelva a la página.'''",
|
||||
'asirra-failed' => 'Identifique todas las imágenes de gatos',
|
||||
);
|
||||
|
||||
/** Finnish (suomi)
|
||||
* @author VezonThunder
|
||||
*/
|
||||
$messages['fi'] = array(
|
||||
'asirra-desc' => 'Asirra-moduuli muokkauksen varmennukseen',
|
||||
'asirra-edit' => 'Suojana automaattisia roskamuokkauksia vastaan sinun on valittava kissan kuvat laatikosta alla:', # Fuzzy
|
||||
'asirra-addurl' => 'Muokkauksesi sisältää uusia ulkoisia linkkejä. Suojana automaattista roskapostia vastaan sinun on valittava kissan kuvat laatikosta alla:', # Fuzzy
|
||||
'asirra-badlogin' => 'Suojana automaattisia salasanamurtoja vastaan sinun on valittava kissan kuvat laatikosta alla:', # Fuzzy
|
||||
'asirra-createaccount' => 'Suojana automaattista tunnusten luontia vastaan sinun on valittava kissan kuvat laatikosta alla:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Tunnista kissat.',
|
||||
'asirra-create' => 'Suojana automaattista sivujen luontia vastaan sinun on valittava kissan kuvat laatikosta alla:', # Fuzzy
|
||||
'asirra-nojs' => "'''Salli JavaScript ja lähetä uudelleen.'''",
|
||||
'asirra-failed' => 'Tunnista kaikki kissan kuvat',
|
||||
);
|
||||
|
||||
/** French (français)
|
||||
* @author Gomoko
|
||||
* @author Nicolas NALLET
|
||||
* @author Seb35
|
||||
*/
|
||||
$messages['fr'] = array(
|
||||
'asirra-desc' => 'Module Asirra pour ConfirmEdit',
|
||||
'asirra-edit' => 'Pour protéger le wiki contre le spam d’édition automatique, nous vous demandons de bien vouloir sélectionner uniquement les photos de chats dans la boîte ci-dessous :',
|
||||
'asirra-addurl' => 'Votre édition contient des liens externes. Pour protéger le wiki contre le spam de modification automatique, nous vous demandons de bien vouloir sélectionner uniquement les photos de chats dans la boîte ci-dessous :',
|
||||
'asirra-badlogin' => 'Pour protéger le wiki des essais automatiques de cassage de mot de passe, nous vous demandons de bien vouloir sélectionner uniquement les photos de chats dans la boîte ci-dessous :',
|
||||
'asirra-createaccount' => 'Pour protéger le wiki contre la création automatique de comptes, nous vous demandons de bien vouloir sélectionner uniquement les photos de chats dans la boîte ci-dessous :',
|
||||
'asirra-createaccount-fail' => 'Veuillez identifier correctement les chats.',
|
||||
'asirra-create' => 'Pour protéger le wiki contre la création automatique de pages, nous vous demandons de bien vouloir sélectionner uniquement les photos de chats dans la boîte ci-dessous :',
|
||||
'asirra-nojs' => "'''Veuillez activer le JavaScript et re-soumettre la page.'''",
|
||||
'asirra-failed' => 'Veuillez identifier toutes les images de chat',
|
||||
);
|
||||
|
||||
/** Galician (galego)
|
||||
* @author Toliño
|
||||
*/
|
||||
$messages['gl'] = array(
|
||||
'asirra-desc' => 'Módulo Asirra para ConfirmEdit',
|
||||
'asirra-edit' => 'Para protexer o wiki contra o spam automático, seleccione só as fotos de gatos na caixa:',
|
||||
'asirra-addurl' => 'A súa edición inclúe novas ligazóns externas. Para protexer o wiki contra o spam automático, seleccione só as fotos de gatos na caixa:',
|
||||
'asirra-badlogin' => 'Para protexer o wiki contra o roubo de contrasinais, seleccione só as fotos de gatos na caixa:',
|
||||
'asirra-createaccount' => 'Para protexer o wiki contra a creación automática de contas, seleccione só as fotos de gatos na caixa:',
|
||||
'asirra-createaccount-fail' => 'Identifique correctamente os gatos.',
|
||||
'asirra-create' => 'Para protexer o wiki contra a creación automática de páxinas, seleccione só as fotos de gatos na caixa:',
|
||||
'asirra-nojs' => "'''Active o JavaScript e volva enviar a páxina.'''",
|
||||
'asirra-failed' => 'Identifique todas as fotos de gatos',
|
||||
);
|
||||
|
||||
/** Upper Sorbian (hornjoserbsce)
|
||||
* @author Michawiki
|
||||
*/
|
||||
$messages['hsb'] = array(
|
||||
'asirra-desc' => 'Modul Asirra za ConfirmEdit',
|
||||
'asirra-edit' => 'Za škit přećiwo awtomatizowanemu spamej, prošu wubjer jenož fota kóčkow w slědowacym polu:', # Fuzzy
|
||||
'asirra-addurl' => 'Twoja změna wobsahuje nowe eksterne wotkazy. Za škit přećiwo awtomatizowanemu spamej, prošu wubjer jenož fota kóčkow w slědowacym polu:', # Fuzzy
|
||||
'asirra-badlogin' => 'Za škit přećiwo awtomatizowanemu złamanju hesłow, prošu wubjer jenož fota kóčkow w slědowacym polu:', # Fuzzy
|
||||
'asirra-createaccount' => 'Za škit přećiwo awtomatiskemu wutworjenju konta, prošu wubjer jenož fota kóčkow w slědowacym polu:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Prošu identifikuj kóčki.',
|
||||
'asirra-create' => 'Za škit přećiwo awtomatiskemu wutworjenju strony, prošu wubjer jenož fota kóčkow w slědowacym polu:', # Fuzzy
|
||||
'asirra-nojs' => "'''Prošu zmóžń JavaScript a składuj stronu hišće raz.'''",
|
||||
'asirra-failed' => 'Prošu identifikuj wšě wobrazy z kóčkami',
|
||||
);
|
||||
|
||||
/** Interlingua (interlingua)
|
||||
* @author McDutchie
|
||||
*/
|
||||
$messages['ia'] = array(
|
||||
'asirra-desc' => 'Modulo de Asirra pro ConfirmEdit',
|
||||
'asirra-edit' => 'Pro adjutar a proteger le wiki contra le spam automatisate, per favor selige solmente le photos de cattos in le quadro sequente:',
|
||||
'asirra-addurl' => 'Iste modification include nove ligamines externe. Pro adjutar a proteger le wiki contra le spam automatisate, per favor selige solmente le photos de cattos in le quadro sequente:',
|
||||
'asirra-badlogin' => 'Pro adjutar a proteger le wiki contra le furto automatisate de contrasignos, per favor selige solmente le photos de cattos in le quadro sequente:',
|
||||
'asirra-createaccount' => 'Pro adjutar a proteger le wiki contra le creation automatisate de contos, per favor selige solmente le photos de cattos in le quadro sequente:',
|
||||
'asirra-createaccount-fail' => 'Per favor identifica correctemente le cattos.',
|
||||
'asirra-create' => 'Pro adjutar a proteger le wiki contra le creation automatisate de paginas, per favor selige solmente le photos de cattos in le quadro sequente:',
|
||||
'asirra-nojs' => "'''Per favor activa JavaScript e resubmitte le pagina.'''",
|
||||
'asirra-failed' => 'Per favor identifica tote le imagines de cattos',
|
||||
);
|
||||
|
||||
/** Italian (italiano)
|
||||
* @author Beta16
|
||||
*/
|
||||
$messages['it'] = array(
|
||||
'asirra-desc' => 'Modulo ASIRRA per ConfirmEdit',
|
||||
'asirra-edit' => 'Per proteggere il wiki dalle modifiche automatiche che aggiungono spam, ti chiediamo gentilmente di selezionare solo le foto di gatti nel riquadro sottostante:',
|
||||
'asirra-addurl' => 'La tua modifica aggiunge qualche nuovo collegamento esterno. Per proteggere il wiki dallo spam automatico, ti chiediamo gentilmente di selezionare solo le foto di gatti nel riquadro sottostante:',
|
||||
'asirra-badlogin' => 'Per proteggere il wiki dalla forzatura automatica delle password, ti chiediamo gentilmente di selezionare solo le foto di gatti nel riquadro sottostante:',
|
||||
'asirra-createaccount' => 'Per proteggere il wiki dalla creazione automatica di nuovi accessi, ti chiediamo gentilmente di selezionare solo le foto di gatti nel riquadro sottostante:',
|
||||
'asirra-createaccount-fail' => 'Identifica correttamente i gatti.',
|
||||
'asirra-create' => 'Per proteggere il wiki dalla creazione automatica di pagine, ti chiediamo gentilmente di selezionare solo le foto di gatti nel riquadro sottostante:',
|
||||
'asirra-nojs' => "'''Attiva JavaScript ed invia di nuovo la pagina.'''",
|
||||
'asirra-failed' => 'Identifica tutte le immagini di gatti',
|
||||
);
|
||||
|
||||
/** Japanese (日本語)
|
||||
* @author 2nd-player
|
||||
* @author Shirayuki
|
||||
*/
|
||||
$messages['ja'] = array(
|
||||
'asirra-desc' => 'ConfirmEdit 用 Asirra モジュール',
|
||||
'asirra-edit' => 'ウィキでの自動編集のスパム攻撃を防ぐため、お手数をおかけしますが猫が写っている画像を以下から選択してください:',
|
||||
'asirra-addurl' => 'あなたは新しい外部リンクを追加しようとしています。ウィキへの自動スパム攻撃を防ぐため、お手数をおかけしますが猫が写っている画像を以下から選択してください:',
|
||||
'asirra-badlogin' => 'ウィキへの自動パスワードクラック攻撃を防ぐため、お手数をおかけしますが猫が写っている画像を以下から選択してください:',
|
||||
'asirra-createaccount' => 'ウィキでのアカウント自動作成を防ぐため、お手数をおかけしますが猫が写っている画像を以下から選択してください:',
|
||||
'asirra-createaccount-fail' => '猫を正しく選択してください。',
|
||||
'asirra-create' => 'ウィキでのページ自動作成を防ぐため、お手数をおかけしますが猫が写っている画像を以下から選択してください:',
|
||||
'asirra-nojs' => "'''JavaScript を有効にしてページを再読込してください。'''",
|
||||
'asirra-failed' => '猫が写っている画像をすべて選択してください',
|
||||
);
|
||||
|
||||
/** Korean (한국어)
|
||||
* @author 아라
|
||||
*/
|
||||
$messages['ko'] = array(
|
||||
'asirra-desc' => 'ConfirmEdit에 대한 Asirra 모듈',
|
||||
'asirra-edit' => '자동화된 편집 스팸으로부터 보호하기 위해, 아래 상자에 있는 고양이 사진을 선택하세요:', # Fuzzy
|
||||
'asirra-addurl' => '편집에 새로운 바깥 링크가 포함되어 있습니다. 자동화된 스팸으로부터 보호하기 위해, 아래 상자에 있는 고양이 사진을 선택하세요:', # Fuzzy
|
||||
'asirra-badlogin' => '비밀번호 깨기로부터 보호하기 위해, 아래 상자에 있는 고양이 사진을 선택하세요:', # Fuzzy
|
||||
'asirra-createaccount' => '자동화된 계정 만들기로부터 보호하기 위해, 아래 상자에 있는 고양이 사진을 선택하세요:', # Fuzzy
|
||||
'asirra-createaccount-fail' => '고양이를 올바르게 선택하세요.',
|
||||
'asirra-create' => '자동화된 문서 만들기로부터 보호하기 위해, 아래 상자에 있는 고양이 사진을 선택하세요:', # Fuzzy
|
||||
'asirra-nojs' => "'''자바스크립트를 활성화하고 문서를 다시 제출하세요.'''",
|
||||
'asirra-failed' => '고양이 그림을 모두 선택하세요',
|
||||
);
|
||||
|
||||
/** Colognian (Ripoarisch)
|
||||
* @author Purodha
|
||||
*/
|
||||
$messages['ksh'] = array(
|
||||
'asirra-desc' => 'Dä Zohsaz <i lang="en">Asirra</i> för et Zohsazprojramm <i lang="en">ConfirmEdit</i>.',
|
||||
'asirra-edit' => 'Heh dat Wiki well sesch jääje <i lang="en">SPAM</i> schöze. Dröm moß mer beim Ändere noch en Prööfong aflääje, dat mer ene Minsch un kei Projramm es. Söhk bloß de Katzebelder em Kaßte us:', # Fuzzy
|
||||
'asirra-addurl' => 'Heh dat Wiki well sesch jääje <i lang="en">SPAM</i> schöze. Dröm moß mer, wam_mer lengks noh ußerhallef enfööje well, noch en Prööfong aflääje, dat mer ene Minsch un kei Projramm es. Söhk bloß de Katzebelder em Kaßte us:', # Fuzzy
|
||||
'asirra-badlogin' => 'Heh dat Wiki well sesch jääje et automattesche Paßwoot_Knacke schöze. Dröm moß mer heh nor_en Prööfong aflääje, dat mer ene Minsch un kei Projramm es. Söhk bloß de Katzebelder em Kaßte us:', # Fuzzy
|
||||
'asirra-createaccount' => 'Heh dat Wiki well sesch jääje automattesch aanjelaate „Metmaacher“ schöze. Dröm moß mer heh nor_en Prööfong aflääje, dat mer ene Minsch un kei Projramm es. Söhk bloß de Katzebelder em Kaßte us:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Bes esu jood un don de Kazebelder ußwähle.',
|
||||
'asirra-create' => 'Heh dat Wiki well sesch jääje automattesch neu aanjelaate Sigge schöze. Dröm moß mer heh nor_en Prööfong aflääje, dat mer ene Minsch un kei Projramm es. Söhk bloß de Katzebelder em Kaßte us:', # Fuzzy
|
||||
'asirra-nojs' => "'''Bes esu jood un donn JavaSkrep en Dingem Brauser aanschallde un scheck heh di Sigg norr_ens af.'''",
|
||||
'asirra-failed' => 'Bes esu jood un don all de Kazebelder ußwähle.',
|
||||
);
|
||||
|
||||
/** Luxembourgish (Lëtzebuergesch)
|
||||
* @author Robby
|
||||
*/
|
||||
$messages['lb'] = array(
|
||||
'asirra-desc' => 'Asirra-Modul fir ConfirmEdit',
|
||||
'asirra-edit' => "Fir d'Wiki géint automatiséierte Spam ze schützen froe mir Iech just d'Fotoe mat Kazen, déi Dir an der Këscht ënnendrënner gesitt, erauszesichen:",
|
||||
'asirra-addurl' => "An Ärer Ännerung sinn nei extern Linken. Fir d'Wiki géint automatiséierte Spam ze schützen, froe mir Iech d'Kategorie vun de Fotoen an der Këscht ënnendrënner erauszesichen:",
|
||||
'asirra-createaccount-fail' => "Identifizéiert d'Kaze w.e.g. richteg.",
|
||||
'asirra-nojs' => "'''Aktivéiert w.e.g. JavaScript a schéckt d'Säit nachemol.'''",
|
||||
'asirra-failed' => 'Identifizéiert w.e.g. all Biller wou Kazen drop sinn',
|
||||
);
|
||||
|
||||
/** Macedonian (македонски)
|
||||
* @author Bjankuloski06
|
||||
*/
|
||||
$messages['mk'] = array(
|
||||
'asirra-desc' => 'Asirra-модул за ПотврдиУредување',
|
||||
'asirra-edit' => 'Како заштитна мерка против автоматизиран спам, би ве замолиле да ги изберете само сликите со мачка прикажани во полето:',
|
||||
'asirra-addurl' => 'Во вашите измени има нови надворешни врски. Како заштитна мерка против автоматизиран спам, би ве замолиле да ги изберете само сликите со мачка прикажани во полето:',
|
||||
'asirra-badlogin' => 'Како заштитна мерка против автоматизирано провалување на лозинки, би ве замолиле да ги изберете само сликите со мачка прикажани во полето:',
|
||||
'asirra-createaccount' => 'Како заштитна мерка против автоматизирано создавање на сметки, би ве замолиле да ги изберете само сликите со мачка прикажани во полето:',
|
||||
'asirra-createaccount-fail' => 'Посочете кои од следниве се мачки.',
|
||||
'asirra-create' => 'Како заштитна мерка против автоматизирано создавање на страници, би ве замолиле да ги изберете само сликите со мачка прикажани во полето:',
|
||||
'asirra-nojs' => "'''Овозможете JavaScript и поднесете ја страницата повторно.'''",
|
||||
'asirra-failed' => 'Изберете ги сликите што имаат мачка',
|
||||
);
|
||||
|
||||
/** Malay (Bahasa Melayu)
|
||||
* @author Anakmalaysia
|
||||
*/
|
||||
$messages['ms'] = array(
|
||||
'asirra-desc' => 'Modul Asirra untuk ConfirmEdit',
|
||||
'asirra-edit' => 'Untuk mencegah suntingan spam automatik, sila pilih gambar-gambar kucing sahaja dalam petak di bawah:', # Fuzzy
|
||||
'asirra-addurl' => 'Suntingan anda mengandungi pautan luar yang baru. Untuk mencegah spam janaan automatik, sila pilih gambar-gambar kucing sahaja dalam petak di bawah:', # Fuzzy
|
||||
'asirra-badlogin' => 'Untuk mencegah pemecahan kata laluan automatik, sila pilih gambar-gambar kucing sahaja dalam petak di bawah:', # Fuzzy
|
||||
'asirra-createaccount' => 'Untuk mencegah pembukaan akaun automatik, sila pilih gambar-gambar kucing sahaja dalam petak di bawah:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Sila kenal pasti kucing-kucing dengan betul.',
|
||||
'asirra-create' => 'Untuk mencegah pembukaan halaman automatik, sila pilih gambar-gambar kucing sahaja dalam petak di bawah:', # Fuzzy
|
||||
'asirra-nojs' => "'''Sila hidupkan JavaScript dan hantar semula halaman ini.'''",
|
||||
'asirra-failed' => 'Sila kenal pasti semua gambar kucing',
|
||||
);
|
||||
|
||||
/** Maltese (Malti)
|
||||
* @author Chrisportelli
|
||||
*/
|
||||
$messages['mt'] = array(
|
||||
'asirra-desc' => 'Modulu ASIRRA għal ConfirmEdit',
|
||||
'asirra-edit' => "Sabiex tgħinna nipproteġu kontra l-modifiki li jżidu spam, jekk jogħġbok agħżel ir-ritratti tal-qtates fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'asirra-addurl' => "Il-modifika tiegħek tinkludi ħoloq esterni ġodda. Sabiex tipproteġi kontra spam awtomatiku, jekk jogħġbok agħżel ir-ritratti tal-qtates fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'asirra-badlogin' => "Sabiex tgħinna nipproteġu kontra l-infurzar awtomatiku tal-passwords, jekk jogħġbok agħżel ir-ritratti tal-qtates fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'asirra-createaccount' => "Sabiex tgħinna nipproteġu kontra l-ħolqien awtomatiku ta' kontijiet ġodda, jekk jogħġbok agħżel ir-ritratti tal-qtates fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Sib il-qtates.',
|
||||
'asirra-create' => "Sabiex tgħinna nipproteġu kontra l-ħolqien awtomatiku ta' paġni, jekk jogħġbok agħżel ir-ritratti tal-qtates fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'asirra-nojs' => "'''Jekk jogħġbok attiva l-JavaScript u erġa' ibgħat din il-paġna.'''",
|
||||
'asirra-failed' => 'Sib l-istampi kollha tal-qtates',
|
||||
);
|
||||
|
||||
/** Norwegian Bokmål (norsk bokmål)
|
||||
* @author Event
|
||||
*/
|
||||
$messages['nb'] = array(
|
||||
'asirra-desc' => 'Assirra-modulen for ConfirmEdit',
|
||||
'asirra-edit' => 'Som beskyttelse mot automatisk redigert spam, vennligst velg kun kattebildene i boksen under:', # Fuzzy
|
||||
'asirra-addurl' => 'Din redigering inneholder nye eksterne lenker. Som beskyttelse mot automatisk redigert spam, vennligst velg kun kattebildene i boksen under:', # Fuzzy
|
||||
'asirra-badlogin' => 'Som beskyttelse mot automatisk passordknekking, vennligst velg kun kattebildene i boksen under:', # Fuzzy
|
||||
'asirra-createaccount' => 'Som beskyttelse mot automatisk opprettelse av brukerkonto, vennligst velg kun kattebildene i boksen under:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Vennligst angi hva som er katter.',
|
||||
'asirra-create' => 'Som beskyttelse mot automatisk opprettelse av sider, vennligst velg kun kattebildene i boksen under:', # Fuzzy
|
||||
'asirra-nojs' => "'''Vennligst åpne for JavaScript og lagre siden en gang til.'''",
|
||||
'asirra-failed' => 'Vennligst merk alle kattebilder',
|
||||
);
|
||||
|
||||
/** Dutch (Nederlands)
|
||||
* @author HanV
|
||||
* @author SPQRobin
|
||||
* @author Siebrand
|
||||
*/
|
||||
$messages['nl'] = array(
|
||||
'asirra-desc' => 'Asirra-module voor ConfirmEdit',
|
||||
'asirra-edit' => 'Kies ter bescherming tegen geautomatiseerde spam de afbeeldingen met een poes in het onderstaande venster:',
|
||||
'asirra-addurl' => "Uw bewerking bevat nieuwe externe koppelingen. Selecteer de foto's van katten in het vak hieronder om de wiki te beschermen tegen geautomatiseerde spam:",
|
||||
'asirra-badlogin' => 'Kies ter bescherming tegen het automatisch kraken van wachtwoorden de afbeeldingen met een poes in het onderstaande venster:',
|
||||
'asirra-createaccount' => 'Kies om het automatisch aanmaken van gebruikers tegen te gaan de afbeeldingen met een poes in het onderstaande venster:',
|
||||
'asirra-createaccount-fail' => 'Identificeer de katten juist.',
|
||||
'asirra-create' => 'Kies om het automatisch aanmaken van een pagina tegen te gaan de afbeeldingen met een poes in het onderstaande venster:',
|
||||
'asirra-nojs' => "'''Schakel JavaScript in en probeer de pagina opnieuw op te slaan.'''",
|
||||
'asirra-failed' => 'Identificeer alle afbeeldingen van katten.',
|
||||
);
|
||||
|
||||
/** Nederlands (informeel) (Nederlands (informeel))
|
||||
* @author Siebrand
|
||||
*/
|
||||
$messages['nl-informal'] = array(
|
||||
'asirra-addurl' => "Je bewerking bevat nieuwe externe koppelingen. Selecteer de foto's van katten in het vak hieronder om te helpen beschermen tegen geautomatiseerde spam:", # Fuzzy
|
||||
);
|
||||
|
||||
/** Polish (polski)
|
||||
* @author BeginaFelicysym
|
||||
*/
|
||||
$messages['pl'] = array(
|
||||
'asirra-desc' => 'Moduł Asirra dla ConfirmEdit',
|
||||
'asirra-edit' => 'Aby uchronić się przed automatami wprowadzającymi spam, proszę wybrać tylko zdjęcia kotów w poniższym polu:', # Fuzzy
|
||||
'asirra-addurl' => 'Wprowadzony przez ciebie tekst zawiera linki zewnętrzne. Aby uchronić nas przed automatycznym spamem, proszę wskazać tylko zdjęcia kotów w poniższym polu:', # Fuzzy
|
||||
'asirra-badlogin' => 'Aby uchronić się przed zautomatyzowanym łamaniem haseł, proszę wybrać tylko zdjęcia kotów w poniższym polu:', # Fuzzy
|
||||
'asirra-createaccount' => 'Aby uchronić się przed automatycznym tworzeniem kont, proszę wybrać tylko zdjęcia kotów w poniższym polu:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Prosimy prawidłowo zidentyfikować koty.',
|
||||
'asirra-create' => 'Aby uchronić się przed automatycznym tworzeniem stron, proszę wybrać tylko zdjęcia kotów w poniższym polu:', # Fuzzy
|
||||
'asirra-nojs' => "'''Prosimy włączyć obsługę języka JavaScript i ponowne przesłanie strony.'''",
|
||||
'asirra-failed' => 'Prosimy wskazać wszystkie obrazy kotów',
|
||||
);
|
||||
|
||||
/** Piedmontese (Piemontèis)
|
||||
* @author Borichèt
|
||||
* @author Dragonòt
|
||||
*/
|
||||
$messages['pms'] = array(
|
||||
'asirra-desc' => 'Mòdul Asirra për ConfirmEdit',
|
||||
'asirra-edit' => "Për giuté a protege contra la rumenta dle modìfiche automàtiche, për piasì ch'a selession-a mach le fòto ëd gat ant ël quàder sì-sota:", # Fuzzy
|
||||
'asirra-addurl' => "Soa modìfica a conten dle liure esterne neuve. Për giuté a protege contra la rumenta dle modìfiche automàtiche, për piasì ch'a selession-a mach le fòto ëd gat ant ël quàder sì-sota:", # Fuzzy
|
||||
'asirra-badlogin' => "Për giuté a protege contra la forsadura automatisà ëd le ciav, për piasì ch'a selession-a mach la fòto dël gat ant ël quàder sì-sota:", # Fuzzy
|
||||
'asirra-createaccount' => "Për giuté a protege contra la creassion automatisà ëd cont, për piasì ch'a selession-a mach la fòto dël gat ant ël quàder sì-sota:", # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Për piasì identifica coretament ij gat.',
|
||||
'asirra-create' => "Për giuté a protege contra la creassion automatisà ëd pàgine, për piasì ch'a selession-a mach le fòto ëd gat ant ël quàder sì-sota:", # Fuzzy
|
||||
'asirra-nojs' => "'''Për piasì, ch'a abìlita JavaScript e ch'a spedissa torna la pàgina.'''",
|
||||
'asirra-failed' => 'Për piasì identìfica tute le figure ëd gat',
|
||||
);
|
||||
|
||||
/** Portuguese (português)
|
||||
* @author Hamilton Abreu
|
||||
* @author Luckas
|
||||
*/
|
||||
$messages['pt'] = array(
|
||||
'asirra-desc' => 'Módulo Asirra para o ConfirmEdit',
|
||||
'asirra-edit' => "Como prevenção contra sistemas automatizados de inserção de ''spam'', selecione só as fotografias de gatos na caixa abaixo:", # Fuzzy
|
||||
'asirra-addurl' => "A sua edição contém links externos novos. Como prevenção contra sistemas automatizados de inserção de ''spam'', selecione só as fotografias de gatos na caixa abaixo:", # Fuzzy
|
||||
'asirra-badlogin' => 'Como prevenção com sistemas automatizados de descoberta de palavras-chave, selecione só as fotografias de gatos na caixa abaixo:', # Fuzzy
|
||||
'asirra-createaccount' => 'Como prevenção contra sistemas automatizados de criação de contas, selecione só as fotografias de gatos na caixa abaixo:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Identifique corretamente os gatos, por favor.',
|
||||
'asirra-create' => 'Como prevenção contra sistemas automatizados de criação de páginas, selecione só as fotografias de gatos na caixa abaixo:', # Fuzzy
|
||||
'asirra-nojs' => "'''Possibilite o uso de JavaScript e reenvie a página, por favor.'''",
|
||||
);
|
||||
|
||||
/** tarandíne (tarandíne)
|
||||
* @author Joetaras
|
||||
*/
|
||||
$messages['roa-tara'] = array(
|
||||
'asirra-desc' => 'Module Asirra pe confermà le cangiaminde',
|
||||
'asirra-edit' => "Pe darne 'na màne a proteggere condre le cangiaminde automatece de le rummate, pe piacere scacchie ìa categorije de le fote jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'asirra-addurl' => "Le cangiaminde tune 'ngludone collegaminde de fore nuève. Pe darne 'na màne a proteggere condre le cangiaminde automatece de le rummate, pe piacere scacchie 'a categorije d'a fote 'ndruche jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'asirra-badlogin' => "Pe darne 'na màne a proteggere condre le futteminde automatece de le passuord, pe piacere scacchie 'a categorije de le fote jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'asirra-createaccount' => "Pe darne 'na màne a proteggere condre le ccrejaziune automatece de le cunde, pe piacere scacchie 'a categorije de le fote jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Pe piacere idendifiche correttamende le categorije.',
|
||||
'asirra-create' => "Pe darne 'na màne a proteggere condre le ccrejaziune automatece de le pàggene, pe piacere scacchie 'a categorije de le fote jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'asirra-nojs' => "'''Pe piacere abbilite JavaScript e conferme arrete 'a pàgene.'''",
|
||||
'asirra-failed' => 'Pe piacere idendifiche tutte le categorije de le immaggine',
|
||||
);
|
||||
|
||||
/** Russian (русский)
|
||||
* @author DCamer
|
||||
* @author Lockal
|
||||
* @author Okras
|
||||
*/
|
||||
$messages['ru'] = array(
|
||||
'asirra-desc' => 'Модуль Asirra для ConfirmEdit',
|
||||
'asirra-edit' => 'В целях защиты проекта от автоматического спама в правках, просим вас выбрать среди нижеприведённых изображений только фотографии кошек:',
|
||||
'asirra-addurl' => 'Ваша правка содержит новые внешние ссылки. В целях защиты проекта от автоматического спама в правках просим вас выбрать среди нижеприведённых изображений только фотографии кошек:',
|
||||
'asirra-badlogin' => 'В целях защиты от автоматического подбора пароля просим вас выбрать среди нижеприведённых изображений только фотографии кошек:',
|
||||
'asirra-createaccount' => 'В целях защиты от автоматического создания учётных записей просим вас выбрать среди нижеприведённых изображений только фотографии кошек:',
|
||||
'asirra-createaccount-fail' => 'Пожалуйста правильно идентифицируйте котов.',
|
||||
'asirra-create' => 'В целях защиты от автоматического создания страниц просим вас выбрать среди нижеприведённых изображений только фотографии кошек:',
|
||||
'asirra-nojs' => "'''Пожалуйста, включите JavaScript и обновите страницу.'''",
|
||||
'asirra-failed' => 'Пожалуйста, идентифицируйте все фотографии кота',
|
||||
);
|
||||
|
||||
/** Sinhala (සිංහල)
|
||||
* @author පසිඳු කාවින්ද
|
||||
*/
|
||||
$messages['si'] = array(
|
||||
'asirra-desc' => 'ConfirmEdit සඳහා Asirra මොඩියුලය',
|
||||
'asirra-failed' => 'කරුණාකර සියලුම cat පින්තූරයන් හඳුනාගන්න',
|
||||
);
|
||||
|
||||
/** Swedish (svenska)
|
||||
* @author Jopparn
|
||||
* @author Rotsee
|
||||
* @author WikiPhoenix
|
||||
*/
|
||||
$messages['sv'] = array(
|
||||
'asirra-edit' => 'För att skydda wikin mot spam ber vi dig att markera de fotografier som föreställer katter i rutan nedan:',
|
||||
'asirra-addurl' => 'Din redigering innehåller nya externa länkar. För att skydda wikin mot automatiserat redigerings-spam ber vi dig att endast markera fotografierna på katter i rutan nedan:',
|
||||
'asirra-badlogin' => 'För att skydda wikin mot automatiserade försök att knäcka lösenord ber vi dig att endast markera fotografierna på katter i rutan nedan:',
|
||||
'asirra-createaccount' => 'För att skydda wikin mot automatiserat kontoskapande ber vi dig att endast markera fotografierna på katter i rutan nedan:',
|
||||
'asirra-create' => 'För att skydda wikin mot automatiserat sidskapande ber vi dig att endast markera fotografierna på katter i rutan nedan:',
|
||||
'asirra-nojs' => "'''Var god aktivera JavaScript och hämta sidan igen.'''",
|
||||
'asirra-failed' => 'Var god identifiera alla kattbilder',
|
||||
);
|
||||
|
||||
/** Tagalog (Tagalog)
|
||||
* @author AnakngAraw
|
||||
*/
|
||||
$messages['tl'] = array(
|
||||
'asirra-desc' => 'Modyul ng Asirra para sa ConfirmEdit',
|
||||
'asirra-edit' => 'Upang makatulong sa pagprutekta laban sa kusang basurang pamamatnugot, paki piliin iyong mga litrato lamang ng pusa na nasa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'asirra-addurl' => 'Ang pagbabago mo ay nagsasama ng bagong panlabas na mga kawing. Upang makatulong sa pagprutekta laban sa kusang paglusob ng basurang-liham, paki piliin iyong mga litrato lamang ng pusa na nasa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'asirra-badlogin' => 'Upang makatulong sa pagprutekta laban sa kusang pag-alam ng hudyat, paki piliin lamang iyong mga litrato ng pusa na nasa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'asirra-createaccount' => 'Upang makatulong sa pagprutekta laban sa kusang paglikha ng akawnt, paki piliin lamang iyong mga litrato ng pusa na nasa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Paki kilalanin ng tama ang mga pusa.',
|
||||
'asirra-create' => 'Upang makatulong sa pagprutekta laban sa kusang paglikha ng pahina, paki piliin lamang iyong mga litrato ng pusa na nasa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'asirra-nojs' => "'''Paki paganahin ang JavaScript at muling ipasa ang pahina.'''",
|
||||
'asirra-failed' => 'Paki kilalanin ang lahat ng mga imahe ng pusa',
|
||||
);
|
||||
|
||||
/** Ukrainian (українська)
|
||||
* @author Andriykopanytsia
|
||||
* @author Base
|
||||
*/
|
||||
$messages['uk'] = array(
|
||||
'asirra-desc' => 'Модуль Asirra для ConfirmEdit',
|
||||
'asirra-edit' => 'З метою захисту вікі від автоматичного спаму у статтях, просимо вас обрати фотографії кота, у блоці нижче:',
|
||||
'asirra-addurl' => 'Ваше повідомлення включає нові зовнішні посилання. З метою захисту вікі проти автоматичного спаму у статтях, просимо вас обрати фотографії кота, у блоці нижче:',
|
||||
'asirra-badlogin' => 'З метою захисту вікі проти автоматичного підбору паролю, просимо вас обрати фотографії кота у блоці нижче:',
|
||||
'asirra-createaccount' => 'З метою захисту вікі проти автоматичного створення облікових записів просимо вас обрати фотографії кота у блоці нижче:',
|
||||
'asirra-createaccount-fail' => 'Будь ласка, правильно ідентифікуйте котів.',
|
||||
'asirra-create' => 'З метою захисту вікі проти автоматичного створення статей просимо вас обрати фотографії кота у блоці нижче:',
|
||||
'asirra-nojs' => "'''Будь ласка увімкніть JavaScript і оновіть сторінку.'''",
|
||||
'asirra-failed' => 'Будь ласка, ідентифікуйте усі фотографії кота',
|
||||
);
|
||||
|
||||
/** Walloon (walon)
|
||||
* @author Srtxg
|
||||
*/
|
||||
$messages['wa'] = array(
|
||||
'asirra-desc' => "Module Asirra pol passete d' acertinaedje des candjmints (ConfirmEdit)",
|
||||
'asirra-edit' => "Po s' mete a houte des des robots di spam, nos vs dimandans d' acertiner ki vos estoz bén ene djin, po çoula tchoezixhoz seulmint les imådjes avou des tchets e l' boesse chal pa dzo:", # Fuzzy
|
||||
'asirra-addurl' => "Dins vos candjmints i gn a des dfoûtrinnès hårdêyes (URL).
|
||||
Po s' mete a houte des des robots di spam, nos vs dimandans d' acertiner ki vos estoz bén ene djin, po çoula tchoezixhoz seulmint les imådjes avou des tchets e l' boesse chal pa dzo:", # Fuzzy
|
||||
'asirra-badlogin' => "Po s' mete a houte des des robots ki sayèt d' adviner les screts, nos vs dimandans d' acertiner ki vos estoz bén ene djin, po çoula tchoezixhoz seulmint les imådjes avou des tchets e l' boesse chal pa dzo:", # Fuzzy
|
||||
'asirra-createaccount' => "Po s' mete a houte des des robots k' ahivèt des contes otomaticmint, nos vs dimandans d' acertiner ki vos estoz bén ene djin, po çoula tchoezixhoz seulmint les imådjes avou des tchets e l' boesse chal pa dzo:", # Fuzzy
|
||||
'asirra-createaccount-fail' => 'Tchoezixhoz comifåt les tchets (les biesses ki gnawèt).',
|
||||
'asirra-create' => "Po s' mete a houte des des robots k' ahivèt des pådjes otomaticmint, nos vs dimandans d' acertiner ki vos estoz bén ene djin, po çoula tchoezixhoz seulmint les imådjes avou des tchets e l' boesse chal pa dzo:", # Fuzzy
|
||||
'asirra-nojs' => "'''Metoz s' i vs plait en alaedje li JavaScrit et s' revoyî l' pådje.'''",
|
||||
'asirra-failed' => 'Idintifyî totes les imådjes avou des tchets',
|
||||
);
|
||||
|
||||
/** Simplified Chinese (中文(简体))
|
||||
* @author Fantasticfears
|
||||
* @author Hzy980512
|
||||
*/
|
||||
$messages['zh-hans'] = array(
|
||||
'asirra-desc' => 'ConfirmEdit的Asirra模块',
|
||||
'asirra-edit' => '为了防止垃圾编辑攻击,请在下面的方框中选出猫的图片:',
|
||||
'asirra-addurl' => '您的编辑包含新的外部链接。为了帮助防止垃圾编辑攻击,请在下面的方框中选出猫的图片:',
|
||||
'asirra-badlogin' => '为防止自动程序破解密码,请在下面的方框中选出猫的图片:',
|
||||
'asirra-createaccount' => '为了防止自动程序创建帐户,请在下面的方框中选出猫的图片:',
|
||||
'asirra-createaccount-fail' => '请正确辨认出猫的图片。',
|
||||
'asirra-create' => '为了防止自动程序创建页面,请在下面的方框中选出猫的图片:',
|
||||
'asirra-nojs' => "'''请启动JavaScript后再提交页面。'''",
|
||||
'asirra-failed' => '请选出所有猫的图片',
|
||||
);
|
||||
|
||||
/** Traditional Chinese (中文(繁體))
|
||||
*/
|
||||
$messages['zh-hant'] = array(
|
||||
'asirra-desc' => 'ConfirmEdit的Asirra模塊',
|
||||
'asirra-edit' => '為了防止垃圾編輯攻擊,請在下面的方框中選出貓的圖片:', # Fuzzy
|
||||
'asirra-addurl' => '您的編輯包含新的外部鏈接。為了幫助防止自動垃圾郵件,請在下面的方框中選出貓的圖片:', # Fuzzy
|
||||
'asirra-badlogin' => '為防止自動程序破解密碼,請在下面的方框中選出貓的圖片:', # Fuzzy
|
||||
'asirra-createaccount' => '為了防止自動程序創建帳戶,請在下面的方框中選出貓的圖片:', # Fuzzy
|
||||
'asirra-createaccount-fail' => '請正確辨認出貓的圖片。',
|
||||
'asirra-create' => '為了防止自動程序創建頁面,請在下面的方框中選出貓的圖片:', # Fuzzy
|
||||
'asirra-nojs' => "'''請啟動JavaScript後再提交頁面。'''",
|
||||
'asirra-failed' => '請選出所有貓的圖片',
|
||||
);
|
42
sources/mediawiki/extensions/ConfirmEdit/Asirra.php
Normal file
42
sources/mediawiki/extensions/ConfirmEdit/Asirra.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
/**
|
||||
* Asirra CAPTCHA module for the ConfirmEdit MediaWiki extension.
|
||||
* @author Bachsau
|
||||
* @author Niklas Laxström
|
||||
*
|
||||
* Makes use of the Asirra (Animal Species Image Recognition for
|
||||
* Restricting Access) CAPTCHA service, developed by John Douceur, Jeremy
|
||||
* Elson and Jon Howell at Microsoft Research.
|
||||
*
|
||||
* Asirra uses a large set of images from http://petfinder.com.
|
||||
*
|
||||
* For more information about Asirra, see:
|
||||
* http://research.microsoft.com/en-us/um/redmond/projects/asirra/
|
||||
*
|
||||
* This MediaWiki code is released into the public domain, without any
|
||||
* warranty. YOU CAN DO WITH IT WHATEVER YOU LIKE!
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$dir = __DIR__;
|
||||
require_once( $dir . '/ConfirmEdit.php' );
|
||||
|
||||
$wgCaptchaClass = 'Asirra';
|
||||
$wgExtensionMessagesFiles['Asirra'] = $dir . '/Asirra.i18n.php';
|
||||
$wgAutoloadClasses['Asirra'] = $dir . '/Asirra.class.php';
|
||||
|
||||
$wgResourceModules['ext.confirmEdit.asirra'] = array(
|
||||
'localBasePath' => $dir . '/resources',
|
||||
'remoteExtPath' => 'ConfirmEdit/resources',
|
||||
'scripts' => 'ext.confirmEdit.asirra.js',
|
||||
'messages' => array(
|
||||
'asirra-failed',
|
||||
),
|
||||
);
|
||||
|
736
sources/mediawiki/extensions/ConfirmEdit/Captcha.php
Normal file
736
sources/mediawiki/extensions/ConfirmEdit/Captcha.php
Normal file
|
@ -0,0 +1,736 @@
|
|||
<?php
|
||||
|
||||
class SimpleCaptcha {
|
||||
function getCaptcha() {
|
||||
$a = mt_rand( 0, 100 );
|
||||
$b = mt_rand( 0, 10 );
|
||||
|
||||
/* Minus sign is used in the question. UTF-8,
|
||||
since the api uses text/plain, not text/html */
|
||||
$op = mt_rand( 0, 1 ) ? '+' : '−';
|
||||
|
||||
// No space before and after $op, to ensure correct
|
||||
// directionality.
|
||||
$test = "$a$op$b";
|
||||
$answer = ( $op == '+' ) ? ( $a + $b ) : ( $a - $b );
|
||||
return array( 'question' => $test, 'answer' => $answer );
|
||||
}
|
||||
|
||||
function addCaptchaAPI( &$resultArr ) {
|
||||
$captcha = $this->getCaptcha();
|
||||
$index = $this->storeCaptcha( $captcha );
|
||||
$resultArr['captcha']['type'] = 'simple';
|
||||
$resultArr['captcha']['mime'] = 'text/plain';
|
||||
$resultArr['captcha']['id'] = $index;
|
||||
$resultArr['captcha']['question'] = $captcha['question'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a captcha prompt into the edit form.
|
||||
* This sample implementation generates a simple arithmetic operation;
|
||||
* it would be easy to defeat by machine.
|
||||
*
|
||||
* Override this!
|
||||
*
|
||||
* @return string HTML
|
||||
*/
|
||||
function getForm() {
|
||||
$captcha = $this->getCaptcha();
|
||||
$index = $this->storeCaptcha( $captcha );
|
||||
|
||||
return "<p><label for=\"wpCaptchaWord\">{$captcha['question']}</label> = " .
|
||||
Xml::element( 'input', array(
|
||||
'name' => 'wpCaptchaWord',
|
||||
'id' => 'wpCaptchaWord',
|
||||
'size' => 5,
|
||||
'autocomplete' => 'off',
|
||||
'tabindex' => 1 ) ) . // tab in before the edit textarea
|
||||
"</p>\n" .
|
||||
Xml::element( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'wpCaptchaId',
|
||||
'id' => 'wpCaptchaId',
|
||||
'value' => $index ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the captcha prompt into an edit form.
|
||||
* @param OutputPage $out
|
||||
*/
|
||||
function editCallback( &$out ) {
|
||||
$out->addWikiText( $this->getMessage( $this->action ) );
|
||||
$out->addHTML( $this->getForm() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a message asking the user to enter a captcha on edit
|
||||
* The result will be treated as wiki text
|
||||
*
|
||||
* @param $action string Action being performed
|
||||
* @return string
|
||||
*/
|
||||
function getMessage( $action ) {
|
||||
$name = 'captcha-' . $action;
|
||||
$text = wfMessage( $name )->text();
|
||||
# Obtain a more tailored message, if possible, otherwise, fall back to
|
||||
# the default for edits
|
||||
return wfMessage( $name, $text )->isDisabled() ? wfMessage( 'captcha-edit' )->text() : $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject whazawhoo
|
||||
* @fixme if multiple thingies insert a header, could break
|
||||
* @param $form HTMLForm
|
||||
* @return bool true to keep running callbacks
|
||||
*/
|
||||
function injectEmailUser( &$form ) {
|
||||
global $wgCaptchaTriggers, $wgOut, $wgUser;
|
||||
if ( $wgCaptchaTriggers['sendemail'] ) {
|
||||
if ( $wgUser->isAllowed( 'skipcaptcha' ) ) {
|
||||
wfDebug( "ConfirmEdit: user group allows skipping captcha on email sending\n" );
|
||||
return true;
|
||||
}
|
||||
$form->addFooterText(
|
||||
"<div class='captcha'>" .
|
||||
$wgOut->parse( $this->getMessage( 'sendemail' ) ) .
|
||||
$this->getForm() .
|
||||
"</div>\n" );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject whazawhoo
|
||||
* @fixme if multiple thingies insert a header, could break
|
||||
* @param QuickTemplate $template
|
||||
* @return bool true to keep running callbacks
|
||||
*/
|
||||
function injectUserCreate( &$template ) {
|
||||
global $wgCaptchaTriggers, $wgOut, $wgUser;
|
||||
if ( $wgCaptchaTriggers['createaccount'] ) {
|
||||
if ( $wgUser->isAllowed( 'skipcaptcha' ) ) {
|
||||
wfDebug( "ConfirmEdit: user group allows skipping captcha on account creation\n" );
|
||||
return true;
|
||||
}
|
||||
$template->set( 'header',
|
||||
"<div class='captcha'>" .
|
||||
$wgOut->parse( $this->getMessage( 'createaccount' ) ) .
|
||||
$this->getForm() .
|
||||
"</div>\n" );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a captcha into the user login form after a failed
|
||||
* password attempt as a speedbump for mass attacks.
|
||||
* @fixme if multiple thingies insert a header, could break
|
||||
* @param $template QuickTemplate
|
||||
* @return bool true to keep running callbacks
|
||||
*/
|
||||
function injectUserLogin( &$template ) {
|
||||
if ( $this->isBadLoginTriggered() ) {
|
||||
global $wgOut;
|
||||
$template->set( 'header',
|
||||
"<div class='captcha'>" .
|
||||
$wgOut->parse( $this->getMessage( 'badlogin' ) ) .
|
||||
$this->getForm() .
|
||||
"</div>\n" );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a bad login attempt is made, increment an expiring counter
|
||||
* in the memcache cloud. Later checks for this may trigger a
|
||||
* captcha display to prevent too many hits from the same place.
|
||||
* @param User $user
|
||||
* @param string $password
|
||||
* @param int $retval authentication return value
|
||||
* @return bool true to keep running callbacks
|
||||
*/
|
||||
function triggerUserLogin( $user, $password, $retval ) {
|
||||
global $wgCaptchaTriggers, $wgCaptchaBadLoginExpiration, $wgMemc;
|
||||
if ( $retval == LoginForm::WRONG_PASS && $wgCaptchaTriggers['badlogin'] ) {
|
||||
$key = $this->badLoginKey();
|
||||
$count = $wgMemc->get( $key );
|
||||
if ( !$count ) {
|
||||
$wgMemc->add( $key, 0, $wgCaptchaBadLoginExpiration );
|
||||
}
|
||||
|
||||
$wgMemc->incr( $key );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a bad login has already been registered for this
|
||||
* IP address. If so, require a captcha.
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function isBadLoginTriggered() {
|
||||
global $wgMemc, $wgCaptchaTriggers, $wgCaptchaBadLoginAttempts;
|
||||
return $wgCaptchaTriggers['badlogin'] && intval( $wgMemc->get( $this->badLoginKey() ) ) >= $wgCaptchaBadLoginAttempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the IP is allowed to skip captchas
|
||||
*/
|
||||
function isIPWhitelisted() {
|
||||
global $wgCaptchaWhitelistIP;
|
||||
|
||||
if ( $wgCaptchaWhitelistIP ) {
|
||||
global $wgRequest;
|
||||
|
||||
$ip = $wgRequest->getIP();
|
||||
|
||||
foreach ( $wgCaptchaWhitelistIP as $range ) {
|
||||
if ( IP::isInRange( $ip, $range ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal cache key for badlogin checks.
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function badLoginKey() {
|
||||
global $wgRequest;
|
||||
$ip = $wgRequest->getIP();
|
||||
return wfMemcKey( 'captcha', 'badlogin', 'ip', $ip );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the submitted form matches the captcha session data provided
|
||||
* by the plugin when the form was generated.
|
||||
*
|
||||
* Override this!
|
||||
*
|
||||
* @param string $answer
|
||||
* @param array $info
|
||||
* @return bool
|
||||
*/
|
||||
function keyMatch( $answer, $info ) {
|
||||
return $answer == $info['answer'];
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
|
||||
/**
|
||||
* @param EditPage $editPage
|
||||
* @param string $action (edit/create/addurl...)
|
||||
* @return bool true if action triggers captcha on editPage's namespace
|
||||
*/
|
||||
function captchaTriggers( &$editPage, $action ) {
|
||||
global $wgCaptchaTriggers, $wgCaptchaTriggersOnNamespace;
|
||||
// Special config for this NS?
|
||||
if ( isset( $wgCaptchaTriggersOnNamespace[$editPage->mTitle->getNamespace()][$action] ) )
|
||||
return $wgCaptchaTriggersOnNamespace[$editPage->mTitle->getNamespace()][$action];
|
||||
|
||||
return ( !empty( $wgCaptchaTriggers[$action] ) ); // Default
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $editPage EditPage
|
||||
* @param $newtext string
|
||||
* @param $section string
|
||||
* @param $merged bool
|
||||
* @return bool true if the captcha should run
|
||||
*/
|
||||
function shouldCheck( &$editPage, $newtext, $section, $merged = false ) {
|
||||
$this->trigger = '';
|
||||
$title = $editPage->mArticle->getTitle();
|
||||
|
||||
global $wgUser;
|
||||
if ( $wgUser->isAllowed( 'skipcaptcha' ) ) {
|
||||
wfDebug( "ConfirmEdit: user group allows skipping captcha\n" );
|
||||
return false;
|
||||
}
|
||||
if ( $this->isIPWhitelisted() )
|
||||
return false;
|
||||
|
||||
|
||||
global $wgEmailAuthentication, $ceAllowConfirmedEmail;
|
||||
if ( $wgEmailAuthentication && $ceAllowConfirmedEmail &&
|
||||
$wgUser->isEmailConfirmed() ) {
|
||||
wfDebug( "ConfirmEdit: user has confirmed mail, skipping captcha\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->captchaTriggers( $editPage, 'edit' ) ) {
|
||||
// Check on all edits
|
||||
global $wgUser;
|
||||
$this->trigger = sprintf( "edit trigger by '%s' at [[%s]]",
|
||||
$wgUser->getName(),
|
||||
$title->getPrefixedText() );
|
||||
$this->action = 'edit';
|
||||
wfDebug( "ConfirmEdit: checking all edits...\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $this->captchaTriggers( $editPage, 'create' ) && !$editPage->mTitle->exists() ) {
|
||||
// Check if creating a page
|
||||
global $wgUser;
|
||||
$this->trigger = sprintf( "Create trigger by '%s' at [[%s]]",
|
||||
$wgUser->getName(),
|
||||
$title->getPrefixedText() );
|
||||
$this->action = 'create';
|
||||
wfDebug( "ConfirmEdit: checking on page creation...\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $this->captchaTriggers( $editPage, 'addurl' ) ) {
|
||||
// Only check edits that add URLs
|
||||
if ( $merged ) {
|
||||
// Get links from the database
|
||||
$oldLinks = $this->getLinksFromTracker( $title );
|
||||
// Share a parse operation with Article::doEdit()
|
||||
$editInfo = $editPage->mArticle->prepareTextForEdit( $newtext );
|
||||
$newLinks = array_keys( $editInfo->output->getExternalLinks() );
|
||||
} else {
|
||||
// Get link changes in the slowest way known to man
|
||||
$oldtext = $this->loadText( $editPage, $section );
|
||||
$oldLinks = $this->findLinks( $editPage, $oldtext );
|
||||
$newLinks = $this->findLinks( $editPage, $newtext );
|
||||
}
|
||||
|
||||
$unknownLinks = array_filter( $newLinks, array( &$this, 'filterLink' ) );
|
||||
$addedLinks = array_diff( $unknownLinks, $oldLinks );
|
||||
$numLinks = count( $addedLinks );
|
||||
|
||||
if ( $numLinks > 0 ) {
|
||||
global $wgUser;
|
||||
$this->trigger = sprintf( "%dx url trigger by '%s' at [[%s]]: %s",
|
||||
$numLinks,
|
||||
$wgUser->getName(),
|
||||
$title->getPrefixedText(),
|
||||
implode( ", ", $addedLinks ) );
|
||||
$this->action = 'addurl';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
global $wgCaptchaRegexes;
|
||||
if ( $wgCaptchaRegexes ) {
|
||||
// Custom regex checks. Reuse $oldtext if set above.
|
||||
$oldtext = isset( $oldtext ) ? $oldtext : $this->loadText( $editPage, $section );
|
||||
|
||||
foreach ( $wgCaptchaRegexes as $regex ) {
|
||||
$newMatches = array();
|
||||
if ( preg_match_all( $regex, $newtext, $newMatches ) ) {
|
||||
$oldMatches = array();
|
||||
preg_match_all( $regex, $oldtext, $oldMatches );
|
||||
|
||||
$addedMatches = array_diff( $newMatches[0], $oldMatches[0] );
|
||||
|
||||
$numHits = count( $addedMatches );
|
||||
if ( $numHits > 0 ) {
|
||||
global $wgUser;
|
||||
$this->trigger = sprintf( "%dx %s at [[%s]]: %s",
|
||||
$numHits,
|
||||
$regex,
|
||||
$wgUser->getName(),
|
||||
$title->getPrefixedText(),
|
||||
implode( ", ", $addedMatches ) );
|
||||
$this->action = 'edit';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter callback function for URL whitelisting
|
||||
* @param $url string to check
|
||||
* @return bool true if unknown, false if whitelisted
|
||||
* @access private
|
||||
*/
|
||||
function filterLink( $url ) {
|
||||
global $wgCaptchaWhitelist;
|
||||
$source = wfMessage( 'captcha-addurl-whitelist' )->inContentLanguage()->text();
|
||||
|
||||
$whitelist = wfMessage( 'captcha-addurl-whitelist', $source )->isDisabled()
|
||||
? false
|
||||
: $this->buildRegexes( explode( "\n", $source ) );
|
||||
|
||||
$cwl = $wgCaptchaWhitelist !== false ? preg_match( $wgCaptchaWhitelist, $url ) : false;
|
||||
$wl = $whitelist !== false ? preg_match( $whitelist, $url ) : false;
|
||||
|
||||
return !( $cwl || $wl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build regex from whitelist
|
||||
* @param $lines string from [[MediaWiki:Captcha-addurl-whitelist]]
|
||||
* @return string Regex or bool false if whitelist is empty
|
||||
* @access private
|
||||
*/
|
||||
function buildRegexes( $lines ) {
|
||||
# Code duplicated from the SpamBlacklist extension (r19197)
|
||||
|
||||
# Strip comments and whitespace, then remove blanks
|
||||
$lines = array_filter( array_map( 'trim', preg_replace( '/#.*$/', '', $lines ) ) );
|
||||
|
||||
# No lines, don't make a regex which will match everything
|
||||
if ( count( $lines ) == 0 ) {
|
||||
wfDebug( "No lines\n" );
|
||||
return false;
|
||||
} else {
|
||||
# Make regex
|
||||
# It's faster using the S modifier even though it will usually only be run once
|
||||
// $regex = 'http://+[a-z0-9_\-.]*(' . implode( '|', $lines ) . ')';
|
||||
// return '/' . str_replace( '/', '\/', preg_replace('|\\\*/|', '/', $regex) ) . '/Si';
|
||||
$regexes = '';
|
||||
$regexStart = '/^https?:\/\/+[a-z0-9_\-.]*(';
|
||||
$regexEnd = ')/Si';
|
||||
$regexMax = 4096;
|
||||
$build = false;
|
||||
foreach ( $lines as $line ) {
|
||||
// FIXME: not very robust size check, but should work. :)
|
||||
if ( $build === false ) {
|
||||
$build = $line;
|
||||
} elseif ( strlen( $build ) + strlen( $line ) > $regexMax ) {
|
||||
$regexes .= $regexStart .
|
||||
str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build ) ) .
|
||||
$regexEnd;
|
||||
$build = $line;
|
||||
} else {
|
||||
$build .= '|' . $line;
|
||||
}
|
||||
}
|
||||
if ( $build !== false ) {
|
||||
$regexes .= $regexStart .
|
||||
str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build ) ) .
|
||||
$regexEnd;
|
||||
}
|
||||
return $regexes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load external links from the externallinks table
|
||||
* @param $title Title
|
||||
* @return Array
|
||||
*/
|
||||
function getLinksFromTracker( $title ) {
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
$id = $title->getArticleID(); // should be zero queries
|
||||
$res = $dbr->select( 'externallinks', array( 'el_to' ),
|
||||
array( 'el_from' => $id ), __METHOD__ );
|
||||
$links = array();
|
||||
foreach ( $res as $row ) {
|
||||
$links[] = $row->el_to;
|
||||
}
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backend function for confirmEdit() and confirmEditAPI()
|
||||
* @param $editPage EditPage
|
||||
* @param $newtext string
|
||||
* @param $section
|
||||
* @param $merged bool
|
||||
* @return bool false if the CAPTCHA is rejected, true otherwise
|
||||
*/
|
||||
private function doConfirmEdit( $editPage, $newtext, $section, $merged = false ) {
|
||||
global $wgRequest;
|
||||
if ( $wgRequest->getVal( 'captchaid' ) ) {
|
||||
$wgRequest->setVal( 'wpCaptchaId', $wgRequest->getVal( 'captchaid' ) );
|
||||
}
|
||||
if ( $wgRequest->getVal( 'captchaword' ) ) {
|
||||
$wgRequest->setVal( 'wpCaptchaWord', $wgRequest->getVal( 'captchaword' ) );
|
||||
}
|
||||
if ( $this->shouldCheck( $editPage, $newtext, $section, $merged ) ) {
|
||||
return $this->passCaptcha();
|
||||
} else {
|
||||
wfDebug( "ConfirmEdit: no need to show captcha.\n" );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The main callback run on edit attempts.
|
||||
* @param EditPage $editPage
|
||||
* @param string $newtext
|
||||
* @param string $section
|
||||
* @param bool $merged
|
||||
* @return bool true to continue saving, false to abort and show a captcha form
|
||||
*/
|
||||
function confirmEdit( $editPage, $newtext, $section, $merged = false ) {
|
||||
if ( defined( 'MW_API' ) ) {
|
||||
# API mode
|
||||
# The CAPTCHA was already checked and approved
|
||||
return true;
|
||||
}
|
||||
if ( !$this->doConfirmEdit( $editPage, $newtext, $section, $merged ) ) {
|
||||
$editPage->showEditForm( array( &$this, 'editCallback' ) );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A more efficient edit filter callback based on the text after section merging
|
||||
* @param EditPage $editPage
|
||||
* @param string $newtext
|
||||
* @return bool
|
||||
*/
|
||||
function confirmEditMerged( $editPage, $newtext ) {
|
||||
return $this->confirmEdit( $editPage, $newtext, false, true );
|
||||
}
|
||||
|
||||
function confirmEditAPI( $editPage, $newtext, &$resultArr ) {
|
||||
if ( !$this->doConfirmEdit( $editPage, $newtext, false, false ) ) {
|
||||
$this->addCaptchaAPI( $resultArr );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for user creation form submissions.
|
||||
* @param User $u
|
||||
* @param string $message
|
||||
* @return bool true to continue, false to abort user creation
|
||||
*/
|
||||
function confirmUserCreate( $u, &$message ) {
|
||||
global $wgCaptchaTriggers, $wgUser;
|
||||
if ( $wgCaptchaTriggers['createaccount'] ) {
|
||||
if ( $wgUser->isAllowed( 'skipcaptcha' ) ) {
|
||||
wfDebug( "ConfirmEdit: user group allows skipping captcha on account creation\n" );
|
||||
return true;
|
||||
}
|
||||
if ( $this->isIPWhitelisted() )
|
||||
return true;
|
||||
|
||||
$this->trigger = "new account '" . $u->getName() . "'";
|
||||
if ( !$this->passCaptcha() ) {
|
||||
$message = wfMessage( 'captcha-createaccount-fail' )->text();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for user login form submissions.
|
||||
* @param $u User
|
||||
* @param $pass
|
||||
* @param $retval
|
||||
* @return bool true to continue, false to abort user creation
|
||||
*/
|
||||
function confirmUserLogin( $u, $pass, &$retval ) {
|
||||
if ( $this->isBadLoginTriggered() ) {
|
||||
if ( $this->isIPWhitelisted() )
|
||||
return true;
|
||||
|
||||
$this->trigger = "post-badlogin login '" . $u->getName() . "'";
|
||||
if ( !$this->passCaptcha() ) {
|
||||
// Emulate a bad-password return to confuse the shit out of attackers
|
||||
$retval = LoginForm::WRONG_PASS;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the captcha on Special:EmailUser
|
||||
* @param $from MailAddress
|
||||
* @param $to MailAddress
|
||||
* @param $subject String
|
||||
* @param $text String
|
||||
* @param $error String reference
|
||||
* @return Bool true to continue saving, false to abort and show a captcha form
|
||||
*/
|
||||
function confirmEmailUser( $from, $to, $subject, $text, &$error ) {
|
||||
global $wgCaptchaTriggers, $wgUser;
|
||||
if ( $wgCaptchaTriggers['sendemail'] ) {
|
||||
if ( $wgUser->isAllowed( 'skipcaptcha' ) ) {
|
||||
wfDebug( "ConfirmEdit: user group allows skipping captcha on email sending\n" );
|
||||
return true;
|
||||
}
|
||||
if ( $this->isIPWhitelisted() )
|
||||
return true;
|
||||
|
||||
if ( defined( 'MW_API' ) ) {
|
||||
# API mode
|
||||
# Asking for captchas in the API is really silly
|
||||
$error = wfMessage( 'captcha-disabledinapi' )->text();
|
||||
return false;
|
||||
}
|
||||
$this->trigger = "{$wgUser->getName()} sending email";
|
||||
if ( !$this->passCaptcha() ) {
|
||||
$error = wfMessage( 'captcha-sendemail-fail' )->text();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $module ApiBase
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAPICaptchaModule( $module ) {
|
||||
return $module instanceof ApiEditPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $module ApiBase
|
||||
* @param $params array
|
||||
* @param $flags int
|
||||
* @return bool
|
||||
*/
|
||||
public function APIGetAllowedParams( &$module, &$params, $flags ) {
|
||||
if ( $flags && $this->isAPICaptchaModule( $module ) ) {
|
||||
$params['captchaword'] = null;
|
||||
$params['captchaid'] = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $module ApiBase
|
||||
* @param $desc array
|
||||
* @return bool
|
||||
*/
|
||||
public function APIGetParamDescription( &$module, &$desc ) {
|
||||
if ( $this->isAPICaptchaModule( $module ) ) {
|
||||
$desc['captchaid'] = 'CAPTCHA ID from previous request';
|
||||
$desc['captchaword'] = 'Answer to the CAPTCHA';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a required captcha run, test form input for correct
|
||||
* input on the open session.
|
||||
* @return bool if passed, false if failed or new session
|
||||
*/
|
||||
function passCaptcha() {
|
||||
$info = $this->retrieveCaptcha();
|
||||
if ( $info ) {
|
||||
global $wgRequest;
|
||||
if ( $this->keyMatch( $wgRequest->getVal( 'wpCaptchaWord' ), $info ) ) {
|
||||
$this->log( "passed" );
|
||||
$this->clearCaptcha( $info );
|
||||
return true;
|
||||
} else {
|
||||
$this->clearCaptcha( $info );
|
||||
$this->log( "bad form input" );
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->log( "new captcha session" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the status and any triggering info for debugging or statistics
|
||||
* @param string $message
|
||||
*/
|
||||
function log( $message ) {
|
||||
wfDebugLog( 'captcha', 'ConfirmEdit: ' . $message . '; ' . $this->trigger );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a captcha session ID and save the info in PHP's session storage.
|
||||
* (Requires the user to have cookies enabled to get through the captcha.)
|
||||
*
|
||||
* A random ID is used so legit users can make edits in multiple tabs or
|
||||
* windows without being unnecessarily hobbled by a serial order requirement.
|
||||
* Pass the returned id value into the edit form as wpCaptchaId.
|
||||
*
|
||||
* @param array $info data to store
|
||||
* @return string captcha ID key
|
||||
*/
|
||||
function storeCaptcha( $info ) {
|
||||
if ( !isset( $info['index'] ) ) {
|
||||
// Assign random index if we're not udpating
|
||||
$info['index'] = strval( mt_rand() );
|
||||
}
|
||||
CaptchaStore::get()->store( $info['index'], $info );
|
||||
return $info['index'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch this session's captcha info.
|
||||
* @return mixed array of info, or false if missing
|
||||
*/
|
||||
function retrieveCaptcha() {
|
||||
global $wgRequest;
|
||||
$index = $wgRequest->getVal( 'wpCaptchaId' );
|
||||
return CaptchaStore::get()->retrieve( $index );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out existing captcha info from the session, to ensure
|
||||
* it can't be reused.
|
||||
*/
|
||||
function clearCaptcha( $info ) {
|
||||
CaptchaStore::get()->clear( $info['index'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current version of the page or section being edited...
|
||||
* @param EditPage $editPage
|
||||
* @param string $section
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function loadText( $editPage, $section ) {
|
||||
$rev = Revision::newFromTitle( $editPage->mTitle, false, Revision::READ_LATEST );
|
||||
if ( is_null( $rev ) ) {
|
||||
return "";
|
||||
} else {
|
||||
$text = $rev->getText();
|
||||
if ( $section != '' ) {
|
||||
global $wgParser;
|
||||
return $wgParser->getSection( $text, $section );
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a list of all recognized HTTP links in the text.
|
||||
* @param $editpage EditPage
|
||||
* @param $text string
|
||||
* @return array of strings
|
||||
*/
|
||||
function findLinks( &$editpage, $text ) {
|
||||
global $wgParser, $wgUser;
|
||||
|
||||
$options = new ParserOptions();
|
||||
$text = $wgParser->preSaveTransform( $text, $editpage->mTitle, $wgUser, $options );
|
||||
$out = $wgParser->parse( $text, $editpage->mTitle, $options );
|
||||
|
||||
return array_keys( $out->getExternalLinks() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a page explaining what this wacky thing is.
|
||||
*/
|
||||
function showHelp() {
|
||||
global $wgOut;
|
||||
$wgOut->setPageTitle( wfMessage( 'captchahelp-title' )->text() );
|
||||
$wgOut->addWikiMsg( 'captchahelp-text' );
|
||||
if ( CaptchaStore::get()->cookiesNeeded() ) {
|
||||
$wgOut->addWikiMsg( 'captchahelp-cookies-needed' );
|
||||
}
|
||||
}
|
||||
}
|
116
sources/mediawiki/extensions/ConfirmEdit/CaptchaStore.php
Normal file
116
sources/mediawiki/extensions/ConfirmEdit/CaptchaStore.php
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
abstract class CaptchaStore {
|
||||
/**
|
||||
* Store the correct answer for a given captcha
|
||||
* @param $index String
|
||||
* @param $info String the captcha result
|
||||
*/
|
||||
public abstract function store( $index, $info );
|
||||
|
||||
/**
|
||||
* Retrieve the answer for a given captcha
|
||||
* @param $index String
|
||||
* @return String
|
||||
*/
|
||||
public abstract function retrieve( $index );
|
||||
|
||||
/**
|
||||
* Delete a result once the captcha has been used, so it cannot be reused
|
||||
* @param $index
|
||||
*/
|
||||
public abstract function clear( $index );
|
||||
|
||||
/**
|
||||
* Whether this type of CaptchaStore needs cookies
|
||||
* @return Bool
|
||||
*/
|
||||
public abstract function cookiesNeeded();
|
||||
|
||||
/**
|
||||
* The singleton instance
|
||||
* @var CaptchaStore
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Get somewhere to store captcha data that will persist between requests
|
||||
*
|
||||
* @throws MWException
|
||||
* @return CaptchaStore
|
||||
*/
|
||||
public final static function get() {
|
||||
if ( !self::$instance instanceof self ) {
|
||||
global $wgCaptchaStorageClass;
|
||||
if ( in_array( 'CaptchaStore', class_parents( $wgCaptchaStorageClass ) ) ) {
|
||||
self::$instance = new $wgCaptchaStorageClass;
|
||||
} else {
|
||||
throw new MWException( "Invalid CaptchaStore class $wgCaptchaStorageClass" );
|
||||
}
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected constructor: no creating instances except through the factory method above
|
||||
*/
|
||||
protected function __construct() {}
|
||||
}
|
||||
|
||||
class CaptchaSessionStore extends CaptchaStore {
|
||||
|
||||
protected function __construct() {
|
||||
// Make sure the session is started
|
||||
if ( session_id() === '' ) {
|
||||
wfSetupSession();
|
||||
}
|
||||
}
|
||||
|
||||
function store( $index, $info ) {
|
||||
$_SESSION['captcha' . $info['index']] = $info;
|
||||
}
|
||||
|
||||
function retrieve( $index ) {
|
||||
if ( isset( $_SESSION['captcha' . $index] ) ) {
|
||||
return $_SESSION['captcha' . $index];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function clear( $index ) {
|
||||
unset( $_SESSION['captcha' . $index] );
|
||||
}
|
||||
|
||||
function cookiesNeeded() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CaptchaCacheStore extends CaptchaStore {
|
||||
|
||||
function store( $index, $info ) {
|
||||
global $wgMemc, $wgCaptchaSessionExpiration;
|
||||
$wgMemc->set( wfMemcKey( 'captcha', $index ), $info,
|
||||
$wgCaptchaSessionExpiration );
|
||||
}
|
||||
|
||||
function retrieve( $index ) {
|
||||
global $wgMemc;
|
||||
$info = $wgMemc->get( wfMemcKey( 'captcha', $index ) );
|
||||
if ( $info ) {
|
||||
return $info;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function clear( $index ) {
|
||||
global $wgMemc;
|
||||
$wgMemc->delete( wfMemcKey( 'captcha', $index ) );
|
||||
}
|
||||
|
||||
function cookiesNeeded() {
|
||||
return false;
|
||||
}
|
||||
}
|
120
sources/mediawiki/extensions/ConfirmEdit/ConfirmEdit.alias.php
Normal file
120
sources/mediawiki/extensions/ConfirmEdit/ConfirmEdit.alias.php
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
/**
|
||||
* Aliases for special pages
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
// @codingStandardsIgnoreFile
|
||||
|
||||
$specialPageAliases = array();
|
||||
|
||||
/** English (English) */
|
||||
$specialPageAliases['en'] = array(
|
||||
'Captcha' => array( 'Captcha' ),
|
||||
);
|
||||
|
||||
/** Arabic (العربية) */
|
||||
$specialPageAliases['ar'] = array(
|
||||
'Captcha' => array( 'كابتشا' ),
|
||||
);
|
||||
|
||||
/** Egyptian Spoken Arabic (مصرى) */
|
||||
$specialPageAliases['arz'] = array(
|
||||
'Captcha' => array( 'كابتشا' ),
|
||||
);
|
||||
|
||||
/** Min Dong Chinese (Mìng-dĕ̤ng-ngṳ̄) */
|
||||
$specialPageAliases['cdo'] = array(
|
||||
'Captcha' => array( '驗證碼' ),
|
||||
);
|
||||
|
||||
/** Zazaki (Zazaki) */
|
||||
$specialPageAliases['diq'] = array(
|
||||
'Captcha' => array( 'Kodaİtimadi' ),
|
||||
);
|
||||
|
||||
/** Esperanto (Esperanto) */
|
||||
$specialPageAliases['eo'] = array(
|
||||
'Captcha' => array( 'Kontraŭspamilo' ),
|
||||
);
|
||||
|
||||
/** Estonian (eesti) */
|
||||
$specialPageAliases['et'] = array(
|
||||
'Captcha' => array( 'Robotilõks' ),
|
||||
);
|
||||
|
||||
/** Persian (فارسی) */
|
||||
$specialPageAliases['fa'] = array(
|
||||
'Captcha' => array( 'کپچا' ),
|
||||
);
|
||||
|
||||
/** Finnish (suomi) */
|
||||
$specialPageAliases['fi'] = array(
|
||||
'Captcha' => array( 'Ihmiskäyttäjävarmistus' ),
|
||||
);
|
||||
|
||||
/** Galician (galego) */
|
||||
$specialPageAliases['gl'] = array(
|
||||
'Captcha' => array( 'Captcha' ),
|
||||
);
|
||||
|
||||
/** Hindi (हिन्दी) */
|
||||
$specialPageAliases['hi'] = array(
|
||||
'Captcha' => array( 'कैप्चा', 'कैपचा' ),
|
||||
);
|
||||
|
||||
/** Japanese (日本語) */
|
||||
$specialPageAliases['ja'] = array(
|
||||
'Captcha' => array( '画像認証' ),
|
||||
);
|
||||
|
||||
/** Korean (한국어) */
|
||||
$specialPageAliases['ko'] = array(
|
||||
'Captcha' => array( '캡차' ),
|
||||
);
|
||||
|
||||
/** Colognian (Ripoarisch) */
|
||||
$specialPageAliases['ksh'] = array(
|
||||
'Captcha' => array( 'Kaptscha' ),
|
||||
);
|
||||
|
||||
/** Cornish (kernowek) */
|
||||
$specialPageAliases['kw'] = array(
|
||||
'Captcha' => array( 'Captcha' ),
|
||||
);
|
||||
|
||||
/** Macedonian (македонски) */
|
||||
$specialPageAliases['mk'] = array(
|
||||
'Captcha' => array( 'Captcha' ),
|
||||
);
|
||||
|
||||
/** Malayalam (മലയാളം) */
|
||||
$specialPageAliases['ml'] = array(
|
||||
'Captcha' => array( 'ക്യാപ്ച' ),
|
||||
);
|
||||
|
||||
/** Serbian (Cyrillic script) (српски (ћирилица)) */
|
||||
$specialPageAliases['sr-ec'] = array(
|
||||
'Captcha' => array( 'Потврдни_код' ),
|
||||
);
|
||||
|
||||
/** Turkish (Türkçe) */
|
||||
$specialPageAliases['tr'] = array(
|
||||
'Captcha' => array( 'GüvenlikKodu' ),
|
||||
);
|
||||
|
||||
/** Cantonese (粵語) */
|
||||
$specialPageAliases['yue'] = array(
|
||||
'Captcha' => array( '驗證碼' ),
|
||||
);
|
||||
|
||||
/** Simplified Chinese (中文(简体)) */
|
||||
$specialPageAliases['zh-hans'] = array(
|
||||
'Captcha' => array( '验证码' ),
|
||||
);
|
||||
|
||||
/** Traditional Chinese (中文(繁體)) */
|
||||
$specialPageAliases['zh-hant'] = array(
|
||||
'Captcha' => array( '驗證碼' ),
|
||||
);
|
4299
sources/mediawiki/extensions/ConfirmEdit/ConfirmEdit.i18n.php
Normal file
4299
sources/mediawiki/extensions/ConfirmEdit/ConfirmEdit.i18n.php
Normal file
File diff suppressed because it is too large
Load diff
216
sources/mediawiki/extensions/ConfirmEdit/ConfirmEdit.php
Normal file
216
sources/mediawiki/extensions/ConfirmEdit/ConfirmEdit.php
Normal file
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ConfirmEdit MediaWiki extension.
|
||||
*
|
||||
* This is a framework that holds a variety of CAPTCHA tools. The
|
||||
* default one, 'SimpleCaptcha', is not intended as a production-
|
||||
* level CAPTCHA system, and another one of the options provided
|
||||
* should be used in its place for any real usages.
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brion Vibber <brion@wikimedia.org>
|
||||
* http://www.mediawiki.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$wgExtensionFunctions[] = 'confirmEditSetup';
|
||||
$wgExtensionCredits['antispam'][] = array(
|
||||
'path' => __FILE__,
|
||||
'name' => 'ConfirmEdit',
|
||||
'author' => array( 'Brion Vibber', '...' ),
|
||||
'url' => 'https://www.mediawiki.org/wiki/Extension:ConfirmEdit',
|
||||
'version' => '1.2',
|
||||
'descriptionmsg' => 'captcha-desc',
|
||||
);
|
||||
|
||||
/**
|
||||
* The 'skipcaptcha' permission key can be given out to
|
||||
* let known-good users perform triggering actions without
|
||||
* having to go through the captcha.
|
||||
*
|
||||
* By default, sysops and registered bot accounts will be
|
||||
* able to skip, while others have to go through it.
|
||||
*/
|
||||
$wgGroupPermissions['*' ]['skipcaptcha'] = false;
|
||||
$wgGroupPermissions['user' ]['skipcaptcha'] = false;
|
||||
$wgGroupPermissions['autoconfirmed']['skipcaptcha'] = false;
|
||||
$wgGroupPermissions['bot' ]['skipcaptcha'] = true; // registered bots
|
||||
$wgGroupPermissions['sysop' ]['skipcaptcha'] = true;
|
||||
$wgAvailableRights[] = 'skipcaptcha';
|
||||
|
||||
/**
|
||||
* List of IP ranges to allow to skip the captcha, similar to the group setting:
|
||||
* "$wgGroupPermission[...]['skipcaptcha'] = true"
|
||||
*
|
||||
* Specific IP addresses or CIDR-style ranges may be used,
|
||||
* for instance:
|
||||
* $wgCaptchaWhitelistIP = array('192.168.1.0/24', '10.1.0.0/16');
|
||||
*/
|
||||
$wgCaptchaWhitelistIP = false;
|
||||
|
||||
$wgCaptcha = null;
|
||||
$wgCaptchaClass = 'SimpleCaptcha';
|
||||
|
||||
/**
|
||||
* Actions which can trigger a captcha
|
||||
*
|
||||
* If the 'edit' trigger is on, *every* edit will trigger the captcha.
|
||||
* This may be useful for protecting against vandalbot attacks.
|
||||
*
|
||||
* If using the default 'addurl' trigger, the captcha will trigger on
|
||||
* edits that include URLs that aren't in the current version of the page.
|
||||
* This should catch automated linkspammers without annoying people when
|
||||
* they make more typical edits.
|
||||
*
|
||||
* The captcha code should not use $wgCaptchaTriggers, but CaptchaTriggers()
|
||||
* which also takes into account per namespace triggering.
|
||||
*/
|
||||
$wgCaptchaTriggers = array();
|
||||
$wgCaptchaTriggers['edit'] = false; // Would check on every edit
|
||||
$wgCaptchaTriggers['create'] = false; // Check on page creation.
|
||||
$wgCaptchaTriggers['sendemail'] = false; // Special:Emailuser
|
||||
$wgCaptchaTriggers['addurl'] = true; // Check on edits that add URLs
|
||||
$wgCaptchaTriggers['createaccount'] = true; // Special:Userlogin&type=signup
|
||||
$wgCaptchaTriggers['badlogin'] = true; // Special:Userlogin after failure
|
||||
|
||||
/**
|
||||
* You may wish to apply special rules for captcha triggering on some namespaces.
|
||||
* $wgCaptchaTriggersOnNamespace[<namespace id>][<trigger>] forces an always on /
|
||||
* always off configuration with that trigger for the given namespace.
|
||||
* Leave unset to use the global options ($wgCaptchaTriggers).
|
||||
*
|
||||
* Shall not be used with 'createaccount' (it is not checked).
|
||||
*/
|
||||
$wgCaptchaTriggersOnNamespace = array();
|
||||
|
||||
# Example:
|
||||
# $wgCaptchaTriggersOnNamespace[NS_TALK]['create'] = false; //Allow creation of talk pages without captchas.
|
||||
# $wgCaptchaTriggersOnNamespace[NS_PROJECT]['edit'] = true; //Show captcha whenever editing Project pages.
|
||||
|
||||
/**
|
||||
* Indicate how to store per-session data required to match up the
|
||||
* internal captcha data with the editor.
|
||||
*
|
||||
* 'CaptchaSessionStore' uses PHP's session storage, which is cookie-based
|
||||
* and may fail for anons with cookies disabled.
|
||||
*
|
||||
* 'CaptchaCacheStore' uses $wgMemc, which avoids the cookie dependency
|
||||
* but may be fragile depending on cache configuration.
|
||||
*/
|
||||
$wgCaptchaStorageClass = 'CaptchaSessionStore';
|
||||
|
||||
/**
|
||||
* Number of seconds a captcha session should last in the data cache
|
||||
* before expiring when managing through CaptchaCacheStore class.
|
||||
*
|
||||
* Default is a half hour.
|
||||
*/
|
||||
$wgCaptchaSessionExpiration = 30 * 60;
|
||||
|
||||
/**
|
||||
* Number of seconds after a bad login that a captcha will be shown to
|
||||
* that client on the login form to slow down password-guessing bots.
|
||||
*
|
||||
* Has no effect if 'badlogin' is disabled in $wgCaptchaTriggers or
|
||||
* if there is not a caching engine enabled.
|
||||
*
|
||||
* Default is five minutes.
|
||||
*/
|
||||
$wgCaptchaBadLoginExpiration = 5 * 60;
|
||||
|
||||
/**
|
||||
* Allow users who have confirmed their email addresses to post
|
||||
* URL links without being harassed by the captcha.
|
||||
*/
|
||||
$ceAllowConfirmedEmail = false;
|
||||
|
||||
/**
|
||||
* Number of bad login attempts before triggering the captcha. 0 means the
|
||||
* captcha is presented on the first login.
|
||||
*/
|
||||
$wgCaptchaBadLoginAttempts = 3;
|
||||
|
||||
/**
|
||||
* Regex to whitelist URLs to known-good sites...
|
||||
* For instance:
|
||||
* $wgCaptchaWhitelist = '#^https?://([a-z0-9-]+\\.)?(wikimedia|wikipedia)\.org/#i';
|
||||
* Local admins can define a whitelist under [[MediaWiki:captcha-addurl-whitelist]]
|
||||
*/
|
||||
$wgCaptchaWhitelist = false;
|
||||
|
||||
/**
|
||||
* Additional regexes to check for. Use full regexes; can match things
|
||||
* other than URLs such as junk edits.
|
||||
*
|
||||
* If the new version matches one and the old version doesn't,
|
||||
* toss up the captcha screen.
|
||||
*
|
||||
* @fixme Add a message for local admins to add items as well.
|
||||
*/
|
||||
$wgCaptchaRegexes = array();
|
||||
|
||||
/** Register special page */
|
||||
$wgSpecialPages['Captcha'] = 'CaptchaSpecialPage';
|
||||
|
||||
$wgConfirmEditIP = __DIR__;
|
||||
$wgExtensionMessagesFiles['ConfirmEdit'] = "$wgConfirmEditIP/ConfirmEdit.i18n.php";
|
||||
$wgExtensionMessagesFiles['ConfirmEditAlias'] = "$wgConfirmEditIP/ConfirmEdit.alias.php";
|
||||
|
||||
$wgHooks['EditFilterMerged'][] = 'ConfirmEditHooks::confirmEditMerged';
|
||||
$wgHooks['UserCreateForm'][] = 'ConfirmEditHooks::injectUserCreate';
|
||||
$wgHooks['AbortNewAccount'][] = 'ConfirmEditHooks::confirmUserCreate';
|
||||
$wgHooks['LoginAuthenticateAudit'][] = 'ConfirmEditHooks::triggerUserLogin';
|
||||
$wgHooks['UserLoginForm'][] = 'ConfirmEditHooks::injectUserLogin';
|
||||
$wgHooks['AbortLogin'][] = 'ConfirmEditHooks::confirmUserLogin';
|
||||
$wgHooks['EmailUserForm'][] = 'ConfirmEditHooks::injectEmailUser';
|
||||
$wgHooks['EmailUser'][] = 'ConfirmEditHooks::confirmEmailUser';
|
||||
# Register API hook
|
||||
$wgHooks['APIEditBeforeSave'][] = 'ConfirmEditHooks::confirmEditAPI';
|
||||
$wgHooks['APIGetAllowedParams'][] = 'ConfirmEditHooks::APIGetAllowedParams';
|
||||
$wgHooks['APIGetParamDescription'][] = 'ConfirmEditHooks::APIGetParamDescription';
|
||||
|
||||
$wgAutoloadClasses['ConfirmEditHooks'] = "$wgConfirmEditIP/ConfirmEditHooks.php";
|
||||
$wgAutoloadClasses['SimpleCaptcha'] = "$wgConfirmEditIP/Captcha.php";
|
||||
$wgAutoloadClasses['CaptchaStore'] = "$wgConfirmEditIP/CaptchaStore.php";
|
||||
$wgAutoloadClasses['CaptchaSessionStore'] = "$wgConfirmEditIP/CaptchaStore.php";
|
||||
$wgAutoloadClasses['CaptchaCacheStore'] = "$wgConfirmEditIP/CaptchaStore.php";
|
||||
$wgAutoloadClasses['CaptchaSpecialPage'] = "$wgConfirmEditIP/ConfirmEditHooks.php";
|
||||
$wgAutoloadClasses['HTMLCaptchaField'] = "$wgConfirmEditIP/HTMLCaptchaField.php";
|
||||
|
||||
/**
|
||||
* Set up $wgWhitelistRead
|
||||
*/
|
||||
function confirmEditSetup() {
|
||||
global $wgGroupPermissions, $wgCaptchaTriggers;
|
||||
if ( !$wgGroupPermissions['*']['read'] && $wgCaptchaTriggers['badlogin'] ) {
|
||||
// We need to ensure that the captcha interface is accessible
|
||||
// so that unauthenticated users can actually get in after a
|
||||
// mistaken password typing.
|
||||
global $wgWhitelistRead;
|
||||
$image = SpecialPage::getTitleFor( 'Captcha', 'image' );
|
||||
$help = SpecialPage::getTitleFor( 'Captcha', 'help' );
|
||||
$wgWhitelistRead[] = $image->getPrefixedText();
|
||||
$wgWhitelistRead[] = $help->getPrefixedText();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
class ConfirmEditHooks {
|
||||
/**
|
||||
* Get the global Captcha instance
|
||||
*
|
||||
* @return Captcha|SimpleCaptcha
|
||||
*/
|
||||
static function getInstance() {
|
||||
global $wgCaptcha, $wgCaptchaClass;
|
||||
|
||||
static $done = false;
|
||||
|
||||
if ( !$done ) {
|
||||
$done = true;
|
||||
$wgCaptcha = new $wgCaptchaClass;
|
||||
}
|
||||
|
||||
return $wgCaptcha;
|
||||
}
|
||||
|
||||
static function confirmEditMerged( $editPage, $newtext ) {
|
||||
return self::getInstance()->confirmEditMerged( $editPage, $newtext );
|
||||
}
|
||||
|
||||
static function confirmEditAPI( $editPage, $newtext, &$resultArr ) {
|
||||
return self::getInstance()->confirmEditAPI( $editPage, $newtext, $resultArr );
|
||||
}
|
||||
|
||||
static function injectUserCreate( &$template ) {
|
||||
return self::getInstance()->injectUserCreate( $template );
|
||||
}
|
||||
|
||||
static function confirmUserCreate( $u, &$message ) {
|
||||
return self::getInstance()->confirmUserCreate( $u, $message );
|
||||
}
|
||||
|
||||
static function triggerUserLogin( $user, $password, $retval ) {
|
||||
return self::getInstance()->triggerUserLogin( $user, $password, $retval );
|
||||
}
|
||||
|
||||
static function injectUserLogin( &$template ) {
|
||||
return self::getInstance()->injectUserLogin( $template );
|
||||
}
|
||||
|
||||
static function confirmUserLogin( $u, $pass, &$retval ) {
|
||||
return self::getInstance()->confirmUserLogin( $u, $pass, $retval );
|
||||
}
|
||||
|
||||
static function injectEmailUser( &$form ) {
|
||||
return self::getInstance()->injectEmailUser( $form );
|
||||
}
|
||||
|
||||
static function confirmEmailUser( $from, $to, $subject, $text, &$error ) {
|
||||
return self::getInstance()->confirmEmailUser( $from, $to, $subject, $text, $error );
|
||||
}
|
||||
|
||||
// Default $flags to 1 for backwards-compatible behavior
|
||||
public static function APIGetAllowedParams( &$module, &$params, $flags = 1 ) {
|
||||
return self::getInstance()->APIGetAllowedParams( $module, $params, $flags );
|
||||
}
|
||||
|
||||
public static function APIGetParamDescription( &$module, &$desc ) {
|
||||
return self::getInstance()->APIGetParamDescription( $module, $desc );
|
||||
}
|
||||
}
|
||||
|
||||
class CaptchaSpecialPage extends UnlistedSpecialPage {
|
||||
public function __construct() {
|
||||
parent::__construct( 'Captcha' );
|
||||
}
|
||||
|
||||
function execute( $par ) {
|
||||
$this->setHeaders();
|
||||
|
||||
$instance = ConfirmEditHooks::getInstance();
|
||||
|
||||
switch( $par ) {
|
||||
case "image":
|
||||
if ( method_exists( $instance, 'showImage' ) ) {
|
||||
return $instance->showImage();
|
||||
}
|
||||
case "help":
|
||||
default:
|
||||
return $instance->showHelp();
|
||||
}
|
||||
}
|
||||
}
|
407
sources/mediawiki/extensions/ConfirmEdit/FancyCaptcha.class.php
Normal file
407
sources/mediawiki/extensions/ConfirmEdit/FancyCaptcha.class.php
Normal file
|
@ -0,0 +1,407 @@
|
|||
<?php
|
||||
|
||||
class FancyCaptcha extends SimpleCaptcha {
|
||||
/**
|
||||
* @return FileBackend
|
||||
*/
|
||||
public function getBackend() {
|
||||
global $wgCaptchaFileBackend, $wgCaptchaDirectory;
|
||||
|
||||
if ( $wgCaptchaFileBackend ) {
|
||||
return FileBackendGroup::singleton()->get( $wgCaptchaFileBackend );
|
||||
} else {
|
||||
static $backend = null;
|
||||
if ( !$backend ) {
|
||||
$backend = new FSFileBackend( array(
|
||||
'name' => 'captcha-backend',
|
||||
'lockManager' => 'nullLockManager',
|
||||
'containerPaths' => array( 'captcha-render' => $wgCaptchaDirectory ),
|
||||
'fileMode' => 777
|
||||
) );
|
||||
}
|
||||
return $backend;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer Estimate of the number of captchas files
|
||||
*/
|
||||
public function estimateCaptchaCount() {
|
||||
global $wgCaptchaDirectoryLevels;
|
||||
|
||||
$factor = 1;
|
||||
$sampleDir = $this->getBackend()->getRootStoragePath() . '/captcha-render';
|
||||
if ( $wgCaptchaDirectoryLevels >= 1 ) { // 1/16 sample if 16 shards
|
||||
$sampleDir .= '/' . dechex( mt_rand( 0, 15 ) );
|
||||
$factor = 16;
|
||||
}
|
||||
if ( $wgCaptchaDirectoryLevels >= 3 ) { // 1/256 sample if 4096 shards
|
||||
$sampleDir .= '/' . dechex( mt_rand( 0, 15 ) );
|
||||
$factor = 256;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
foreach ( $this->getBackend()->getFileList( array( 'dir' => $sampleDir ) ) as $file ) {
|
||||
++$count;
|
||||
}
|
||||
|
||||
return ( $count * $factor );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the submitted form matches the captcha session data provided
|
||||
* by the plugin when the form was generated.
|
||||
*
|
||||
* @param string $answer
|
||||
* @param array $info
|
||||
* @return bool
|
||||
*/
|
||||
function keyMatch( $answer, $info ) {
|
||||
global $wgCaptchaSecret;
|
||||
|
||||
$digest = $wgCaptchaSecret . $info['salt'] . $answer . $wgCaptchaSecret . $info['salt'];
|
||||
$answerHash = substr( md5( $digest ), 0, 16 );
|
||||
|
||||
if ( $answerHash == $info['hash'] ) {
|
||||
wfDebug( "FancyCaptcha: answer hash matches expected {$info['hash']}\n" );
|
||||
return true;
|
||||
} else {
|
||||
wfDebug( "FancyCaptcha: answer hashes to $answerHash, expected {$info['hash']}\n" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function addCaptchaAPI( &$resultArr ) {
|
||||
$info = $this->pickImage();
|
||||
if ( !$info ) {
|
||||
$resultArr['captcha']['error'] = 'Out of images';
|
||||
return;
|
||||
}
|
||||
$index = $this->storeCaptcha( $info );
|
||||
$title = SpecialPage::getTitleFor( 'Captcha', 'image' );
|
||||
$resultArr['captcha']['type'] = 'image';
|
||||
$resultArr['captcha']['mime'] = 'image/png';
|
||||
$resultArr['captcha']['id'] = $index;
|
||||
$resultArr['captcha']['url'] = $title->getLocalUrl( 'wpCaptchaId=' . urlencode( $index ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the captcha prompt into the edit form.
|
||||
*/
|
||||
function getForm() {
|
||||
global $wgOut, $wgExtensionAssetsPath, $wgEnableAPI;
|
||||
|
||||
// Uses addModuleStyles so it is loaded when JS is disabled.
|
||||
$wgOut->addModuleStyles( 'ext.confirmEdit.fancyCaptcha.styles' );
|
||||
|
||||
$title = SpecialPage::getTitleFor( 'Captcha', 'image' );
|
||||
$index = $this->getCaptchaIndex();
|
||||
|
||||
if ( $wgEnableAPI ) {
|
||||
// Loaded only if JS is enabled
|
||||
$wgOut->addModules( 'ext.confirmEdit.fancyCaptcha' );
|
||||
|
||||
$captchaReload = Html::element(
|
||||
'small',
|
||||
array(
|
||||
'class' => 'confirmedit-captcha-reload fancycaptcha-reload'
|
||||
),
|
||||
wfMessage( 'fancycaptcha-reload-text' )->text()
|
||||
);
|
||||
} else {
|
||||
$captchaReload = '';
|
||||
}
|
||||
|
||||
return "<div class='fancycaptcha-wrapper'><div class='fancycaptcha-image-container'>" .
|
||||
Html::element( 'img', array(
|
||||
'class' => 'fancycaptcha-image',
|
||||
'src' => $title->getLocalUrl( 'wpCaptchaId=' . urlencode( $index ) ),
|
||||
'alt' => ''
|
||||
)
|
||||
) .
|
||||
$captchaReload .
|
||||
"</div>\n" .
|
||||
'<p>' .
|
||||
Html::element( 'label', array(
|
||||
'for' => 'wpCaptchaWord',
|
||||
),
|
||||
parent::getMessage( 'label' ) . wfMessage( 'colon-separator' )->text()
|
||||
) .
|
||||
Html::element( 'input', array(
|
||||
'name' => 'wpCaptchaWord',
|
||||
'id' => 'wpCaptchaWord',
|
||||
'type' => 'text',
|
||||
'size' => '12', // max_length in captcha.py plus fudge factor
|
||||
'autocomplete' => 'off',
|
||||
'autocorrect' => 'off',
|
||||
'autocapitalize' => 'off',
|
||||
'required' => 'required',
|
||||
'tabindex' => 1
|
||||
)
|
||||
) . // tab in before the edit textarea
|
||||
Html::element( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'wpCaptchaId',
|
||||
'id' => 'wpCaptchaId',
|
||||
'value' => $index
|
||||
)
|
||||
) .
|
||||
"</p>\n" .
|
||||
"</div>\n";;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get captcha index key
|
||||
* @return string captcha ID key
|
||||
*/
|
||||
function getCaptchaIndex() {
|
||||
$info = $this->pickImage();
|
||||
if ( !$info ) {
|
||||
throw new MWException( "Ran out of captcha images" );
|
||||
}
|
||||
|
||||
// Generate a random key for use of this captcha image in this session.
|
||||
// This is needed so multiple edits in separate tabs or windows can
|
||||
// go through without extra pain.
|
||||
$index = $this->storeCaptcha( $info );
|
||||
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a previously generated captcha image from the queue.
|
||||
* @return mixed tuple of (salt key, text hash) or false if no image to find
|
||||
*/
|
||||
protected function pickImage() {
|
||||
global $wgCaptchaDirectoryLevels;
|
||||
|
||||
$lockouts = 0; // number of times another process claimed a file before this one
|
||||
$baseDir = $this->getBackend()->getRootStoragePath() . '/captcha-render';
|
||||
return $this->pickImageDir( $baseDir, $wgCaptchaDirectoryLevels, $lockouts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $directory string
|
||||
* @param $levels integer
|
||||
* @param $lockouts integer
|
||||
* @return Array|bool
|
||||
*/
|
||||
protected function pickImageDir( $directory, $levels, &$lockouts ) {
|
||||
global $wgMemc;
|
||||
|
||||
if ( $levels <= 0 ) { // $directory has regular files
|
||||
return $this->pickImageFromDir( $directory, $lockouts );
|
||||
}
|
||||
|
||||
$backend = $this->getBackend();
|
||||
|
||||
$key = "fancycaptcha:dirlist:{$backend->getWikiId()}:" . sha1( $directory );
|
||||
$dirs = $wgMemc->get( $key ); // check cache
|
||||
if ( !is_array( $dirs ) || !count( $dirs ) ) { // cache miss
|
||||
$dirs = array(); // subdirs actually present...
|
||||
foreach ( $backend->getTopDirectoryList( array( 'dir' => $directory ) ) as $entry ) {
|
||||
if ( ctype_xdigit( $entry ) && strlen( $entry ) == 1 ) {
|
||||
$dirs[] = $entry;
|
||||
}
|
||||
}
|
||||
wfDebug( "Cache miss for $directory subdirectory listing.\n" );
|
||||
if ( count( $dirs ) ) {
|
||||
$wgMemc->set( $key, $dirs, 86400 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !count( $dirs ) ) {
|
||||
// Remove this directory if empty so callers don't keep looking here
|
||||
$backend->clean( array( 'dir' => $directory ) );
|
||||
return false; // none found
|
||||
}
|
||||
|
||||
$place = mt_rand( 0, count( $dirs ) - 1 ); // pick a random subdir
|
||||
// In case all dirs are not filled, cycle through next digits...
|
||||
for ( $j = 0; $j < count( $dirs ); $j++ ) {
|
||||
$char = $dirs[( $place + $j ) % count( $dirs )];
|
||||
$info = $this->pickImageDir( "$directory/$char", $levels - 1, $lockouts );
|
||||
if ( $info ) {
|
||||
return $info; // found a captcha
|
||||
} else {
|
||||
wfDebug( "Could not find captcha in $directory.\n" );
|
||||
$wgMemc->delete( $key ); // files changed on disk?
|
||||
}
|
||||
}
|
||||
|
||||
return false; // didn't find any images in this directory... empty?
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $directory string
|
||||
* @param $lockouts integer
|
||||
* @return Array|bool
|
||||
*/
|
||||
protected function pickImageFromDir( $directory, &$lockouts ) {
|
||||
global $wgMemc;
|
||||
|
||||
$backend = $this->getBackend();
|
||||
|
||||
$key = "fancycaptcha:filelist:{$backend->getWikiId()}:" . sha1( $directory );
|
||||
$files = $wgMemc->get( $key ); // check cache
|
||||
if ( !is_array( $files ) || !count( $files ) ) { // cache miss
|
||||
$files = array(); // captcha files
|
||||
foreach ( $backend->getTopFileList( array( 'dir' => $directory ) ) as $entry ) {
|
||||
$files[] = $entry;
|
||||
if ( count( $files ) >= 500 ) { // sanity
|
||||
wfDebug( 'Skipping some captchas; $wgCaptchaDirectoryLevels set too low?.' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( count( $files ) ) {
|
||||
$wgMemc->set( $key, $files, 86400 );
|
||||
}
|
||||
wfDebug( "Cache miss for $directory captcha listing.\n" );
|
||||
}
|
||||
|
||||
if ( !count( $files ) ) {
|
||||
// Remove this directory if empty so callers don't keep looking here
|
||||
$backend->clean( array( 'dir' => $directory ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
$info = $this->pickImageFromList( $directory, $files, $lockouts );
|
||||
if ( !$info ) {
|
||||
wfDebug( "Could not find captcha in $directory.\n" );
|
||||
$wgMemc->delete( $key ); // files changed on disk?
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $directory string
|
||||
* @param $files array
|
||||
* @param $lockouts integer
|
||||
* @return boolean
|
||||
*/
|
||||
protected function pickImageFromList( $directory, array $files, &$lockouts ) {
|
||||
global $wgMemc, $wgCaptchaDeleteOnSolve;
|
||||
|
||||
if ( !count( $files ) ) {
|
||||
return false; // none found
|
||||
}
|
||||
|
||||
$backend = $this->getBackend();
|
||||
$place = mt_rand( 0, count( $files ) - 1 ); // pick a random file
|
||||
$misses = 0; // number of files in listing that don't actually exist
|
||||
for ( $j = 0; $j < count( $files ); $j++ ) {
|
||||
$entry = $files[( $place + $j ) % count( $files )];
|
||||
if ( preg_match( '/^image_([0-9a-f]+)_([0-9a-f]+)\\.png$/', $entry, $matches ) ) {
|
||||
if ( $wgCaptchaDeleteOnSolve ) { // captcha will be deleted when solved
|
||||
$key = "fancycaptcha:filelock:{$backend->getWikiId()}:" . sha1( $entry );
|
||||
// Try to claim this captcha for 10 minutes (for the user to solve)...
|
||||
if ( ++$lockouts <= 10 && !$wgMemc->add( $key, '1', 600 ) ) {
|
||||
continue; // could not acquire (skip it to avoid race conditions)
|
||||
}
|
||||
}
|
||||
if ( !$backend->fileExists( array( 'src' => "$directory/$entry" ) ) ) {
|
||||
if ( ++$misses >= 5 ) { // too many files in the listing don't exist
|
||||
break; // listing cache too stale? break out so it will be cleared
|
||||
}
|
||||
continue; // try next file
|
||||
}
|
||||
return array(
|
||||
'salt' => $matches[1],
|
||||
'hash' => $matches[2],
|
||||
'viewed' => false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false; // none found
|
||||
}
|
||||
|
||||
function showImage() {
|
||||
global $wgOut;
|
||||
|
||||
$wgOut->disable();
|
||||
|
||||
$info = $this->retrieveCaptcha();
|
||||
if ( $info ) {
|
||||
$timestamp = new MWTimestamp();
|
||||
$info['viewed'] = $timestamp->getTimestamp();
|
||||
$this->storeCaptcha( $info );
|
||||
|
||||
$salt = $info['salt'];
|
||||
$hash = $info['hash'];
|
||||
|
||||
return $this->getBackend()->streamFile( array(
|
||||
'src' => $this->imagePath( $salt, $hash ),
|
||||
'headers' => array( "Cache-Control: private, s-maxage=0, max-age=3600" )
|
||||
) )->isOK();
|
||||
}
|
||||
|
||||
wfHttpError( 500, 'Internal Error', 'Requested bogus captcha image' );
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $salt string
|
||||
* @param $hash string
|
||||
* @return string
|
||||
*/
|
||||
public function imagePath( $salt, $hash ) {
|
||||
global $wgCaptchaDirectoryLevels;
|
||||
|
||||
$file = $this->getBackend()->getRootStoragePath() . '/captcha-render/';
|
||||
for ( $i = 0; $i < $wgCaptchaDirectoryLevels; $i++ ) {
|
||||
$file .= $hash{ $i } . '/';
|
||||
}
|
||||
$file .= "image_{$salt}_{$hash}.png";
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $basename string
|
||||
* @return Array (salt, hash)
|
||||
* @throws MWException
|
||||
*/
|
||||
public function hashFromImageName( $basename ) {
|
||||
if ( preg_match( '/^image_([0-9a-f]+)_([0-9a-f]+)\\.png$/', $basename, $matches ) ) {
|
||||
return array( $matches[1], $matches[2] );
|
||||
} else {
|
||||
throw new MWException( "Invalid filename '$basename'.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a message asking the user to enter a captcha on edit
|
||||
* The result will be treated as wiki text
|
||||
*
|
||||
* @param $action string Action being performed
|
||||
* @return string
|
||||
*/
|
||||
function getMessage( $action ) {
|
||||
$name = 'fancycaptcha-' . $action;
|
||||
$text = wfMessage( $name )->text();
|
||||
# Obtain a more tailored message, if possible, otherwise, fall back to
|
||||
# the default for edits
|
||||
return wfMessage( $name, $text )->isDisabled() ?
|
||||
wfMessage( 'fancycaptcha-edit' )->text() : $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a solved captcha image, if $wgCaptchaDeleteOnSolve is true.
|
||||
*/
|
||||
function passCaptcha() {
|
||||
global $wgCaptchaDeleteOnSolve;
|
||||
|
||||
$info = $this->retrieveCaptcha(); // get the captcha info before it gets deleted
|
||||
$pass = parent::passCaptcha();
|
||||
|
||||
if ( $pass && $wgCaptchaDeleteOnSolve ) {
|
||||
$this->getBackend()->quickDelete( array(
|
||||
'src' => $this->imagePath( $info['salt'], $info['hash'] )
|
||||
) );
|
||||
}
|
||||
|
||||
return $pass;
|
||||
}
|
||||
}
|
1753
sources/mediawiki/extensions/ConfirmEdit/FancyCaptcha.i18n.php
Normal file
1753
sources/mediawiki/extensions/ConfirmEdit/FancyCaptcha.i18n.php
Normal file
File diff suppressed because it is too large
Load diff
76
sources/mediawiki/extensions/ConfirmEdit/FancyCaptcha.php
Normal file
76
sources/mediawiki/extensions/ConfirmEdit/FancyCaptcha.php
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
/**
|
||||
* Experimental image-based captcha plugin, using images generated by an
|
||||
* external tool.
|
||||
*
|
||||
* Copyright (C) 2005, 2006 Brion Vibber <brion@pobox.com>
|
||||
* http://www.mediawiki.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$dir = __DIR__;
|
||||
require_once $dir . '/ConfirmEdit.php';
|
||||
$wgCaptchaClass = 'FancyCaptcha';
|
||||
|
||||
/**
|
||||
* The name of a file backend ($wgFileBackends) to be used for storing files.
|
||||
* Defaults to FSFileBackend using $wgCaptchaDirectory as a base path.
|
||||
*/
|
||||
$wgCaptchaFileBackend = '';
|
||||
|
||||
global $wgCaptchaDirectory;
|
||||
$wgCaptchaDirectory = "$wgUploadDirectory/captcha"; // bad default :D
|
||||
|
||||
global $wgCaptchaDirectoryLevels;
|
||||
$wgCaptchaDirectoryLevels = 0; // To break into subdirectories
|
||||
|
||||
global $wgCaptchaSecret;
|
||||
$wgCaptchaSecret = "CHANGE_THIS_SECRET!";
|
||||
|
||||
/**
|
||||
* By default the FancyCaptcha rotates among all available captchas.
|
||||
* Setting $wgCaptchaDeleteOnSolve to true will delete the captcha
|
||||
* files when they are correctly solved. Thus the user will need
|
||||
* something like a cron creating new thumbnails to avoid drying up.
|
||||
*/
|
||||
$wgCaptchaDeleteOnSolve = false;
|
||||
|
||||
$wgExtensionMessagesFiles['FancyCaptcha'] = $dir . '/FancyCaptcha.i18n.php';
|
||||
$wgAutoloadClasses['FancyCaptcha'] = $dir . '/FancyCaptcha.class.php';
|
||||
|
||||
$wgResourceModules['ext.confirmEdit.fancyCaptcha.styles'] = array(
|
||||
'localBasePath' => $dir . '/resources',
|
||||
'remoteExtPath' => 'ConfirmEdit/resources',
|
||||
'styles' => 'ext.confirmEdit.fancyCaptcha.css',
|
||||
);
|
||||
|
||||
$wgResourceModules['ext.confirmEdit.fancyCaptcha'] = array(
|
||||
'localBasePath' => $dir . '/resources',
|
||||
'remoteExtPath' => 'ConfirmEdit/resources',
|
||||
'scripts' => 'ext.confirmEdit.fancyCaptcha.js',
|
||||
'dependencies' => 'mediawiki.api',
|
||||
);
|
||||
|
||||
$wgAutoloadClasses['ApiFancyCaptchaReload'] = $dir . '/ApiFancyCaptchaReload.php';
|
||||
$wgAPIModules['fancycaptchareload'] = 'ApiFancyCaptchaReload';
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/**
|
||||
* HTMLFormField for inserting Captchas into a form.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
class HTMLCaptchaField extends HTMLFormField {
|
||||
/**
|
||||
* @var Captcha
|
||||
*/
|
||||
private $captcha;
|
||||
|
||||
public $prefix = '';
|
||||
|
||||
/**
|
||||
* @var Bool|Array
|
||||
*/
|
||||
private $validationResult;
|
||||
|
||||
public function __construct( $params ) {
|
||||
parent::__construct( $params );
|
||||
|
||||
// For differentiating the type of form, mainly
|
||||
if ( isset( $params['prefix'] ) ) {
|
||||
$this->prefix = $params['prefix'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the captcha body. Don't include any of the surrounding table cells/rows
|
||||
*
|
||||
* @param $value String
|
||||
* @return String
|
||||
*/
|
||||
public function getInputHTML( $value ) {
|
||||
# TODO
|
||||
}
|
||||
|
||||
public function validate( $data, $alldata ) {
|
||||
// We sent back the exists status of the captcha before. If it *doesn't* exist
|
||||
// we actually want to validate this as true, because we don't want an angry red
|
||||
// error message, just for the user to put the captcha in again
|
||||
if ( $data === false ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $request WebRequest
|
||||
* @return void
|
||||
*/
|
||||
public function loadDataFromRequest( $request ) {
|
||||
$this->captcha = Captcha::factory();
|
||||
$this->captcha->loadFromRequest( $request, $this );
|
||||
if ( !$this->captcha->exists() ) {
|
||||
// The captcha doesn't exist; probably because it's already been used and
|
||||
// then deleted for security. Load the field up with a new captcha which
|
||||
// will be shown to the user when the validation of said new object fails
|
||||
$this->captcha = Captcha::newRandom();
|
||||
}
|
||||
|
||||
// This will be useful as the difference between "the captcha doesn't exist" and
|
||||
// "you answered the captcha wrongly"
|
||||
return $this->captcha->exists();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
class MathCaptcha extends SimpleCaptcha {
|
||||
|
||||
/** Validate a captcha response */
|
||||
function keyMatch( $answer, $info ) {
|
||||
return (int)$answer == (int)$info['answer'];
|
||||
}
|
||||
|
||||
function addCaptchaAPI( &$resultArr ) {
|
||||
list( $sum, $answer ) = $this->pickSum();
|
||||
$index = $this->storeCaptcha( array( 'answer' => $answer ) );
|
||||
$resultArr['captcha']['type'] = 'math';
|
||||
$resultArr['captcha']['mime'] = 'text/tex';
|
||||
$resultArr['captcha']['id'] = $index;
|
||||
$resultArr['captcha']['question'] = $sum;
|
||||
}
|
||||
|
||||
/** Produce a nice little form */
|
||||
function getForm() {
|
||||
list( $sum, $answer ) = $this->pickSum();
|
||||
$index = $this->storeCaptcha( array( 'answer' => $answer ) );
|
||||
|
||||
$form = '<table><tr><td>' . $this->fetchMath( $sum ) . '</td>';
|
||||
$form .= '<td>' . Html::input( 'wpCaptchaWord', false, false, array( 'tabindex' => '1', 'autocomplete' => 'off', 'required' ) ) . '</td></tr></table>';
|
||||
$form .= Html::hidden( 'wpCaptchaId', $index );
|
||||
return $form;
|
||||
}
|
||||
|
||||
/** Pick a random sum */
|
||||
function pickSum() {
|
||||
$a = mt_rand( 0, 100 );
|
||||
$b = mt_rand( 0, 10 );
|
||||
$op = mt_rand( 0, 1 ) ? '+' : '-';
|
||||
$sum = "{$a} {$op} {$b} = ";
|
||||
$ans = $op == '+' ? ( $a + $b ) : ( $a - $b );
|
||||
return array( $sum, $ans );
|
||||
}
|
||||
|
||||
/** Fetch the math */
|
||||
function fetchMath( $sum ) {
|
||||
if ( class_exists( 'MathRenderer' ) ) {
|
||||
$math = MathRenderer::getRenderer( $sum, array(), MW_MATH_PNG );
|
||||
} else {
|
||||
throw new MWException( 'MathCaptcha requires the Math extension for MediaWiki versions 1.18 and above.' );
|
||||
}
|
||||
$html = $math->render();
|
||||
return preg_replace( '/alt=".*?"/', '', $html );
|
||||
}
|
||||
}
|
22
sources/mediawiki/extensions/ConfirmEdit/MathCaptcha.php
Normal file
22
sources/mediawiki/extensions/ConfirmEdit/MathCaptcha.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Captcha class using simple sums and the math renderer
|
||||
* Not brilliant, but enough to dissuade casual spam bots
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
* @author Rob Church <robchur@gmail.com>
|
||||
* @copyright © 2006 Rob Church
|
||||
* @licence GNU General Public Licence 2.0
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$dir = __DIR__;
|
||||
require_once $dir . '/ConfirmEdit.php';
|
||||
$wgCaptchaClass = 'MathCaptcha';
|
||||
|
||||
$wgAutoloadClasses['MathCaptcha'] = $dir . '/MathCaptcha.class.php';
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* QuestyCaptcha class
|
||||
*
|
||||
* @file
|
||||
* @author Benjamin Lees <emufarmers@gmail.com>
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
class QuestyCaptcha extends SimpleCaptcha {
|
||||
|
||||
/** Validate a captcha response */
|
||||
function keyMatch( $answer, $info ) {
|
||||
if ( is_array( $info['answer'] ) ) {
|
||||
return in_array( strtolower( $answer ), $info['answer'] );
|
||||
} else {
|
||||
return strtolower( $answer ) == strtolower( $info['answer'] );
|
||||
}
|
||||
}
|
||||
|
||||
function addCaptchaAPI( &$resultArr ) {
|
||||
$captcha = $this->getCaptcha();
|
||||
$index = $this->storeCaptcha( $captcha );
|
||||
$resultArr['captcha']['type'] = 'question';
|
||||
$resultArr['captcha']['mime'] = 'text/plain';
|
||||
$resultArr['captcha']['id'] = $index;
|
||||
$resultArr['captcha']['question'] = $captcha['question'];
|
||||
}
|
||||
|
||||
function getCaptcha() {
|
||||
global $wgCaptchaQuestions;
|
||||
return $wgCaptchaQuestions[mt_rand( 0, count( $wgCaptchaQuestions ) - 1 )]; // pick a question, any question
|
||||
}
|
||||
|
||||
function getForm() {
|
||||
$captcha = $this->getCaptcha();
|
||||
if ( !$captcha ) {
|
||||
die( "No questions found; set some in LocalSettings.php using the format from QuestyCaptcha.php." );
|
||||
}
|
||||
$index = $this->storeCaptcha( $captcha );
|
||||
return "<p><label for=\"wpCaptchaWord\">{$captcha['question']}</label> " .
|
||||
Html::element( 'input', array(
|
||||
'name' => 'wpCaptchaWord',
|
||||
'id' => 'wpCaptchaWord',
|
||||
'required',
|
||||
'autocomplete' => 'off',
|
||||
'tabindex' => 1 ) ) . // tab in before the edit textarea
|
||||
"</p>\n" .
|
||||
Xml::element( 'input', array(
|
||||
'type' => 'hidden',
|
||||
'name' => 'wpCaptchaId',
|
||||
'id' => 'wpCaptchaId',
|
||||
'value' => $index ) );
|
||||
}
|
||||
|
||||
function getMessage( $action ) {
|
||||
$name = 'questycaptcha-' . $action;
|
||||
$text = wfMessage( $name )->text();
|
||||
# Obtain a more tailored message, if possible, otherwise, fall back to
|
||||
# the default for edits
|
||||
return wfMessage( $name, $text )->isDisabled() ? wfMessage( 'questycaptcha-edit' )->text() : $text;
|
||||
}
|
||||
|
||||
function showHelp() {
|
||||
global $wgOut;
|
||||
$wgOut->setPageTitle( wfMessage( 'captchahelp-title' )->text() );
|
||||
$wgOut->addWikiMsg( 'questycaptchahelp-text' );
|
||||
if ( CaptchaStore::get()->cookiesNeeded() ) {
|
||||
$wgOut->addWikiMsg( 'captchahelp-cookies-needed' );
|
||||
}
|
||||
}
|
||||
}
|
1401
sources/mediawiki/extensions/ConfirmEdit/QuestyCaptcha.i18n.php
Normal file
1401
sources/mediawiki/extensions/ConfirmEdit/QuestyCaptcha.i18n.php
Normal file
File diff suppressed because it is too large
Load diff
46
sources/mediawiki/extensions/ConfirmEdit/QuestyCaptcha.php
Normal file
46
sources/mediawiki/extensions/ConfirmEdit/QuestyCaptcha.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* A question-based captcha plugin.
|
||||
*
|
||||
* Copyright (C) 2009 Benjamin Lees <emufarmers@gmail.com>
|
||||
* http://www.mediawiki.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$dir = __DIR__;
|
||||
require_once $dir . '/ConfirmEdit.php';
|
||||
$wgCaptchaClass = 'QuestyCaptcha';
|
||||
|
||||
global $wgCaptchaQuestions;
|
||||
$wgCaptchaQuestions = array();
|
||||
|
||||
// Add your questions in LocalSettings.php using this format
|
||||
// $wgCaptchaQuestions[] = array( 'question' => "A question?", 'answer' => "An answer!" );
|
||||
// $wgCaptchaQuestions[] = array( 'question' => 'How much wood would a woodchuck chuck if a woodchuck could chuck wood?', 'answer' => 'as much wood as...' );
|
||||
// $wgCaptchaQuestions[] = array( 'question' => "What is this wiki's name?", 'answer' => "$wgSitename" );
|
||||
// You can also provide several acceptable answers to a given question (the answers shall be in lowercase):
|
||||
// $wgCaptchaQuestions[] = array( 'question' => "2 + 2 ?", 'answer' => array( '4', 'four' ) );
|
||||
|
||||
$wgExtensionMessagesFiles['QuestyCaptcha'] = $dir . '/QuestyCaptcha.i18n.php';
|
||||
$wgAutoloadClasses['QuestyCaptcha'] = $dir . '/QuestyCaptcha.class.php';
|
48
sources/mediawiki/extensions/ConfirmEdit/README
Normal file
48
sources/mediawiki/extensions/ConfirmEdit/README
Normal file
|
@ -0,0 +1,48 @@
|
|||
ConfirmEdit extension for MediaWiki
|
||||
|
||||
This extension provides various CAPTCHA tools for MediaWiki, to allow
|
||||
for protection against spambots and other automated tools.
|
||||
|
||||
For more information, see the extension homepage at:
|
||||
http://www.mediawiki.org/wiki/Extension:ConfirmEdit
|
||||
|
||||
== Overview ==
|
||||
|
||||
The following modules are included in ConfirmEdit:
|
||||
|
||||
* SimpleCaptcha - users have to solve an arithmetic math problem
|
||||
* MathCaptcha - users have to solve a math problem that's displayed as
|
||||
an image
|
||||
* FancyCaptcha - users have to identify a series of characters, displayed
|
||||
in a stylized way
|
||||
* QuestyCaptcha - users have to answer a question, out of a series of
|
||||
questions defined by the administrator(s)
|
||||
* ReCaptcha - users have to identify a series of characters, either
|
||||
visually or audially, from a widget provided by the reCAPTCHA service
|
||||
* Asirra - users have to identify the cats in a set of photos of cats
|
||||
and dogs, from a widget provided by the Microsoft Asirra service
|
||||
|
||||
== License ==
|
||||
|
||||
ConfirmEdit is published under the GPL license.
|
||||
|
||||
== Authors ==
|
||||
|
||||
The main framework, and the SimpleCaptcha and FancyCaptcha modules, were
|
||||
written by Brion Vibber.
|
||||
|
||||
The MathCaptcha module was written by Rob Church.
|
||||
|
||||
The QuestyCaptcha module was written by Benjamin Lees.
|
||||
|
||||
The reCAPTCHA module was written by Mike Crawford and Ben Maurer.
|
||||
|
||||
The Asirra module was written by Bachsau.
|
||||
|
||||
Additional maintenance work was done by Yaron Koren.
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= Version 1.2
|
||||
Fixes bug 46132 - ConfirmEdit fatal error when using MathCaptcha and current Math extension.
|
||||
See <https://bugzilla.wikimedia.org/show_bug.cgi?id=46132>.
|
101
sources/mediawiki/extensions/ConfirmEdit/ReCaptcha.class.php
Normal file
101
sources/mediawiki/extensions/ConfirmEdit/ReCaptcha.class.php
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
class ReCaptcha extends SimpleCaptcha {
|
||||
// reCAPTHCA error code returned from recaptcha_check_answer
|
||||
private $recaptcha_error = null;
|
||||
|
||||
/**
|
||||
* Displays the reCAPTCHA widget.
|
||||
* If $this->recaptcha_error is set, it will display an error in the widget.
|
||||
*
|
||||
*/
|
||||
function getForm() {
|
||||
global $wgReCaptchaPublicKey, $wgReCaptchaTheme;
|
||||
|
||||
$useHttps = ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] == 'on' );
|
||||
$js = 'var RecaptchaOptions = ' . Xml::encodeJsVar( array( 'theme' => $wgReCaptchaTheme, 'tabindex' => 1 ) );
|
||||
|
||||
return Html::inlineScript( $js ) . recaptcha_get_html( $wgReCaptchaPublicKey, $this->recaptcha_error, $useHttps );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the library function recaptcha_check_answer to verify the users input.
|
||||
* Sets $this->recaptcha_error if the user is incorrect.
|
||||
* @return boolean
|
||||
*
|
||||
*/
|
||||
function passCaptcha() {
|
||||
global $wgReCaptchaPrivateKey, $wgRequest;
|
||||
|
||||
// API is hardwired to return wpCaptchaId and wpCaptchaWord, so use that if the standard two are empty
|
||||
$challenge = $wgRequest->getVal( 'recaptcha_challenge_field', $wgRequest->getVal( 'wpCaptchaId' ) );
|
||||
$response = $wgRequest->getVal( 'recaptcha_response_field', $wgRequest->getVal( 'wpCaptchaWord' ) );
|
||||
|
||||
if ( $response === null ) {
|
||||
// new captcha session
|
||||
return false;
|
||||
}
|
||||
|
||||
$ip = $wgRequest->getIP();
|
||||
|
||||
$recaptcha_response = recaptcha_check_answer(
|
||||
$wgReCaptchaPrivateKey,
|
||||
$ip,
|
||||
$challenge,
|
||||
$response
|
||||
);
|
||||
|
||||
if ( !$recaptcha_response->is_valid ) {
|
||||
$this->recaptcha_error = $recaptcha_response->error;
|
||||
return false;
|
||||
}
|
||||
|
||||
$recaptcha_error = null;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function addCaptchaAPI( &$resultArr ) {
|
||||
global $wgReCaptchaPublicKey;
|
||||
|
||||
$resultArr['captcha']['type'] = 'recaptcha';
|
||||
$resultArr['captcha']['mime'] = 'image/png';
|
||||
$resultArr['captcha']['key'] = $wgReCaptchaPublicKey;
|
||||
$resultArr['captcha']['error'] = $this->recaptcha_error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a message asking the user to enter a captcha on edit
|
||||
* The result will be treated as wiki text
|
||||
*
|
||||
* @param $action string Action being performed
|
||||
* @return string
|
||||
*/
|
||||
function getMessage( $action ) {
|
||||
$name = 'recaptcha-' . $action;
|
||||
$text = wfMessage( $name )->text();
|
||||
|
||||
# Obtain a more tailored message, if possible, otherwise, fall back to
|
||||
# the default for edits
|
||||
return wfMessage( $name, $text )->isDisabled() ? wfMessage( 'recaptcha-edit' )->text() : $text;
|
||||
}
|
||||
|
||||
public function APIGetAllowedParams( &$module, &$params, $flags ) {
|
||||
if ( $flags && $this->isAPICaptchaModule( $module ) ) {
|
||||
$params['recaptcha_challenge_field'] = null;
|
||||
$params['recaptcha_response_field'] = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function APIGetParamDescription( &$module, &$desc ) {
|
||||
if ( $this->isAPICaptchaModule( $module ) ) {
|
||||
$desc['recaptcha_challenge_field'] = 'Field from the ReCaptcha widget';
|
||||
$desc['recaptcha_response_field'] = 'Field from the ReCaptcha widget';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
596
sources/mediawiki/extensions/ConfirmEdit/ReCaptcha.i18n.php
Normal file
596
sources/mediawiki/extensions/ConfirmEdit/ReCaptcha.i18n.php
Normal file
|
@ -0,0 +1,596 @@
|
|||
<?php
|
||||
/**
|
||||
* Internationalisation file for the reCAPTCHA module of the ConfirmEdit
|
||||
* extension.
|
||||
*
|
||||
* @addtogroup Extensions
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
|
||||
$messages['en'] = array(
|
||||
'recaptcha-desc' => 'reCAPTCHA module for Confirm Edit',
|
||||
'recaptcha-edit' => 'To protect the wiki against automated edit spam, we kindly ask you to type the two words you see in the box below:',
|
||||
'recaptcha-addurl' => 'Your edit includes new external links. To protect the wiki against automated spam, we kindly ask you to type the two words you see in the box below:',
|
||||
'recaptcha-badlogin' => 'To protect the wiki against automated password cracking, we kindly ask you to type the two words you see in the box below:',
|
||||
'recaptcha-createaccount' => 'To protect the wiki against automated account creation, we kindly ask you to type the two words you see in the box below:',
|
||||
'recaptcha-createaccount-fail' => "Incorrect or missing reCAPTCHA answer.",
|
||||
'recaptcha-create' => 'To protect the wiki against automated page creation, we kindly ask you to type the two words you see in the box below:',
|
||||
);
|
||||
|
||||
/** Message documentation (Message documentation)
|
||||
* @author Raymond
|
||||
* @author Shirayuki
|
||||
* @author Umherirrender
|
||||
*/
|
||||
$messages['qqq'] = array(
|
||||
'recaptcha-desc' => '{{Optional}}
|
||||
{{desc}}',
|
||||
'recaptcha-edit' => '{{Related|ConfirmEdit-edit}}',
|
||||
'recaptcha-addurl' => '{{Related|ConfirmEdit-addurl}}',
|
||||
'recaptcha-badlogin' => '{{Related|ConfirmEdit-badlogin}}',
|
||||
'recaptcha-createaccount' => '{{Related|ConfirmEdit-createaccount}}',
|
||||
'recaptcha-createaccount-fail' => '{{Related|ConfirmEdit-createaccount-fail}}',
|
||||
'recaptcha-create' => '{{Related|ConfirmEdit-create}}',
|
||||
);
|
||||
|
||||
/** Arabic (العربية)
|
||||
* @author Alexknight12
|
||||
* @author Ciphers
|
||||
* @author Meno25
|
||||
*/
|
||||
$messages['ar'] = array(
|
||||
'recaptcha-desc' => 'موديل reCAPTCHA لConfirm Edit',
|
||||
'recaptcha-edit' => 'للمساعدة في الحماية ضد التحرير السبام، يرجى كتابة الكلمتين التي تراها في المربع أدناه :', # Fuzzy
|
||||
'recaptcha-addurl' => 'إن تعديلك يتضمن وصلات خارجية جديدة. للمساعدة في الحماية ضد السبام، يرجى كتابة الكلمتين التي تراها في المربع أدناه :', # Fuzzy
|
||||
'recaptcha-badlogin' => 'للمساعدة في الحماية ضد الكسر الآلي لكلمة السر، يرجى كتابة الكلمتين اللتين تراهما في المربع أدناه :', # Fuzzy
|
||||
'recaptcha-createaccount' => 'للمساعدة في الحماية ضد الإنشاء الآلي للحسابات، رجاء اكتب الكلمتين اللتين تراهما في المربع أدناه:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'جواب reCAPTCHA غير صحيح أو مفقود.',
|
||||
'recaptcha-create' => 'للمساعدة في الحماية ضد الإنشاء الآلي للصفحات، يرجى كتابة الكلمتين اللتين تراهما في المربع أدناه :', # Fuzzy
|
||||
);
|
||||
|
||||
/** Asturian (asturianu)
|
||||
* @author Xuacu
|
||||
*/
|
||||
$messages['ast'] = array(
|
||||
'recaptcha-edit' => "Pa protexer la wiki escontra'l spam d'edición automáticu, pidimos-y qu'escriba les dos pallabres que se ven na caxella d'abaxo:",
|
||||
'recaptcha-addurl' => "La so edición incluye enllaces esternos nuevos. Pa protexer la wiki escontra'l spam automáticu, pidimos-y qu'escriba les dos pallabres que se ven na caxella d'abaxo:",
|
||||
'recaptcha-badlogin' => "Pa protexer la wiki escontra'l descifráu de claves automáticu, pidimos-y qu'escriba les dos pallabres que se ven na caxella d'abaxo:",
|
||||
'recaptcha-createaccount' => "Pa protexer la wiki escontra la creación de cuentes automática, pidimos-y qu'escriba les dos pallabres que se ven na caxella d'abaxo:",
|
||||
'recaptcha-createaccount-fail' => 'Falta la rempuesta a la entruga de reCAPTCHA o ye incorreuta',
|
||||
'recaptcha-create' => "Pa protexer la wiki escontra la creación de páxines automática, pidimos-y qu'escriba les dos pallabres que se ven na caxella d'abaxo:",
|
||||
);
|
||||
|
||||
/** Belarusian (Taraškievica orthography) (беларуская (тарашкевіца))
|
||||
* @author EugeneZelenko
|
||||
* @author Jim-by
|
||||
*/
|
||||
$messages['be-tarask'] = array(
|
||||
'recaptcha-edit' => 'Для абароны супраць спаму, калі ласка, увядзіце два словы, якія Вы бачыце ў полі ніжэй:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Вашае рэдагаваньне ўтрымлівае новыя вонкавыя спасылкі. Для абароны супраць спаму, калі ласка, увядзіце два словы, якія Вы бачыце ў полі ніжэй:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Для абароны супраць узлому паролю, калі ласка, увядзіце два словы, якія Вы бачыце ў полі ніжэй:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Для абароны супраць аўтаматычнага стварэньня рахункаў, калі ласка, увядзіце два словы, якія Вы бачыце ў полі ніжэй:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Адказ reCAPTCHA няслушны ці адсутнічае.',
|
||||
'recaptcha-create' => 'Для абароны супраць аўтаматычнага стварэньня старонак, калі ласка, увядзіце два словы, якія Вы бачыце ў полі ніжэй:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Breton (brezhoneg)
|
||||
* @author Fohanno
|
||||
* @author Fulup
|
||||
*/
|
||||
$messages['br'] = array(
|
||||
'recaptcha-edit' => "Evit sikour en em wareziñ diouzh ar stroboù emgefre, merkit an daou c'her a welit er voest dindan :",
|
||||
'recaptcha-addurl' => "Liamm diavaez nevez zo bet degaset ganeoc'h. Evit sikour en em wareziñ diouzh ar stroboù, merkit an daou c'her a welit er voest dindan :",
|
||||
'recaptcha-badlogin' => "Da sikour en em wareziñ diouzh an diskuliañ gerioù-tremen emgefre dre daolioù-esae, merkit an daou c'her a welit er voest dindan :", # Fuzzy
|
||||
'recaptcha-createaccount' => "Da sikour en em wareziñ diouzh ar c'hrouiñ kontoù emgefre, merkit an daou c'her a welit er voest dindan :", # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Respont reCAPTHCA faziek pe ezvezant.',
|
||||
'recaptcha-create' => "Da sikour en em wareziñ diouzh ar c'hrouiñ pajennoù emgefre, merkit an daou c'her a welit er voest dindan :", # Fuzzy
|
||||
);
|
||||
|
||||
/** Bosnian (bosanski)
|
||||
* @author CERminator
|
||||
*/
|
||||
$messages['bs'] = array(
|
||||
'recaptcha-edit' => 'Da bismo pomogli protiv automatiziranog spam uređivanja, molimo upišite dvije riječi koje vidite u kutiju ispod:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Vaše izmjene uključuju nove vanjske linkove. Da bismo pomogli protiv automatiziranog spama, molimo upišite dvije riječi koje vidite u kutiju ispod.', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Da bismo pomogli protiv automatiziranog probijanja šifre, molimo upišite dvije riječi koje vidite u kutiju ispod:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Da bismo pomogli protiv automatiziranog pravljenja računa, molimo upišite dvije riječi koje vidite u kutiju ispod:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Neispravan ili nedostajući reCAPTCHA odgovor.',
|
||||
'recaptcha-create' => 'Da bismo pomogli protiv automatiziranog pravljenja stranica, molimo upišite dvije riječi koje vidite u kutiju ispod:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Czech (česky)
|
||||
* @author Jkjk
|
||||
* @author Mormegil
|
||||
*/
|
||||
$messages['cs'] = array(
|
||||
'recaptcha-desc' => 'Podpora reCAPTCHA pro rozšíření Confirm Edit',
|
||||
'recaptcha-edit' => 'V zájmu ochrany před automatickým spamováním opište dvě slova, která vidíte na obrázku:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Vaše editace obsahuje nové externí odkazy. V zájmu ochrany před automatickým spamováním opište dvě slova, která vidíte na obrázku:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'V zájmu ochrany proti automatickým pokusům uhodnout heslo opište dvě slova, která vidíte na obrázku:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'V rámci ochrany před automatickým vytvářením účtů opište dvě slova, která vidíte na obrázku:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Nesprávná nebo chybějící odpověď na reCAPTCHA.',
|
||||
'recaptcha-create' => 'V zájmu ochrany před automatickým zakládáním stránek opište dvě slova, která vidíte na obrázku:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Welsh (Cymraeg)
|
||||
* @author Lloffiwr
|
||||
*/
|
||||
$messages['cy'] = array(
|
||||
'recaptcha-edit' => "Er mwyn arbed y wici rhag i olygyddion awtomatig osod sbam, byddwch gystal â theipio'r ddau air sydd i'w gweld yn y blwch isod:",
|
||||
'recaptcha-addurl' => "Mae'ch golygiad yn cynnwys cysylltiadau allanol newydd. Er mwyn arbed y wici rhag sbam awtomatig, byddwch gystal â theipio'r ddau air sydd i'w gweld yn y blwch isod:",
|
||||
'recaptcha-badlogin' => "Er mwyn arbed y wici rhag peiriannau sy'n datrys cyfrineiriau'n awtomatig, byddwch gystal â theipio'r ddau air sydd i'w gweld yn y blwch isod:",
|
||||
'recaptcha-createaccount' => "Er mwyn arbed y wici rhag peiriannau sy'n dechrau cyfrifon yn awtomatig, byddwch gystal â theipio'r ddau air sydd i'w gweld yn y blwch isod:",
|
||||
'recaptcha-createaccount-fail' => "Mae'r ateb i'r pos CAPTCHA yn anghywir neu yn eisiau.",
|
||||
'recaptcha-create' => "Er mwyn arbed y wici rhag peiriannau sy'n dechrau tudalennau yn awtomatig, byddwch gystal â theipio'r ddau air sydd i'w gweld yn y blwch isod:",
|
||||
);
|
||||
|
||||
/** German (Deutsch)
|
||||
* @author Kghbln
|
||||
* @author Metalhead64
|
||||
* @author Umherirrender
|
||||
*/
|
||||
$messages['de'] = array(
|
||||
'recaptcha-desc' => 'reCAPTCHA-Module für die Erweiterung „Confirm Edit“',
|
||||
'recaptcha-edit' => 'Zum Schutz des Wikis vor automatisiertem Spam bitten wir dich, die beiden folgenden Wörter in das untenstehende Feld einzugeben:',
|
||||
'recaptcha-addurl' => 'Deine Bearbeitung enthält neue externe Links. Zum Schutz des Wikis vor automatisiertem Spam bitten wir dich, die beiden folgenden Wörter in das folgende Feld einzugeben:',
|
||||
'recaptcha-badlogin' => 'Zum Schutz des Wikis gegen automatisiertes Knacken von Passwörtern bitten wir dich, die beiden folgenden Wörter in das folgende Feld einzugeben:',
|
||||
'recaptcha-createaccount' => 'Zum Schutz des Wikis gegen die automatisierte Erstellung von Benutzerkonten bitten wir dich, die folgenden beiden Wörter in das untenstehende Feld einzugeben:',
|
||||
'recaptcha-createaccount-fail' => 'Fehlerhafte oder fehlende reCAPTCHA Antwort.',
|
||||
'recaptcha-create' => 'Zum Schutz des Wikis gegen automatisierte Erstellung von Seiten bitten wir dich, die beiden folgenden Wörter in das folgende Feld einzugeben:',
|
||||
);
|
||||
|
||||
/** German (formal address) (Deutsch (Sie-Form))
|
||||
* @author Kghbln
|
||||
*/
|
||||
$messages['de-formal'] = array(
|
||||
'recaptcha-createaccount' => 'Zum Schutz gegen die automatisierte Erstellung von Benutzerkonten bitten wir Sie, die folgenden beiden Wörter in das untenstehende Feld einzugeben:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Lower Sorbian (dolnoserbski)
|
||||
* @author Michawiki
|
||||
*/
|
||||
$messages['dsb'] = array(
|
||||
'recaptcha-createaccount-fail' => 'Wopacne abo felujuce wótegrono reCAPTCHA.',
|
||||
);
|
||||
|
||||
/** Spanish (español)
|
||||
* @author Fitoschido
|
||||
*/
|
||||
$messages['es'] = array(
|
||||
'recaptcha-edit' => 'Para protegernos de la publicidad automatizada, escribe las dos palabras visibles en el cuadro de abajo:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Tu edición incluye nuevos enlaces externos. Para ayudar a protegernos contra el spam automatizado, por favor, escribe las dos palabras que ves en el cuadro a continuación:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Para protegernos del robo automatizado de contraseñas, escribe las dos palabras visibles en el cuadro de abajo:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Para protegernos de la creación automática de cuentas, escribe las dos palabras que ves en el cuadro de abajo:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'ReCAPTCHA incorrecto o sin responder.',
|
||||
'recaptcha-create' => 'Para protegernos de la creación automática de páginas, escribe las dos palabras que ves en el cuadro de abajo:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Finnish (suomi)
|
||||
* @author Nedergard
|
||||
* @author VezonThunder
|
||||
*/
|
||||
$messages['fi'] = array(
|
||||
'recaptcha-edit' => 'Suojana automaattisia roskamuokkauksia vastaan sinun on syötettävä kaksi näkemääsi sanaa laatikkoon alla:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Muokkauksesi sisältää uusia ulkoisia linkkejä. Suojana automaattista roskapostia vastaan sinun on syötettävä kaksi näkemääsi sanaa laatikkoon alla:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Suojana automaattisia salasanamurtoja vastaan sinun on syötettävä kaksi näkemääsi sanaa laatikkoon alla:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Suojana automaattista tunnusten luontia vastaan sinun on syötettävä kaksi näkemääsi sanaa laatikkoon alla:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Väärä tai puuttuva reCAPTCHA-vastaus.',
|
||||
'recaptcha-create' => 'Suojana automaattista sivujen luontia vastaan sinun on syötettävä kaksi näkemääsi sanaa laatikkoon alla:', # Fuzzy
|
||||
);
|
||||
|
||||
/** French (français)
|
||||
* @author Gomoko
|
||||
* @author Urhixidur
|
||||
*/
|
||||
$messages['fr'] = array(
|
||||
'recaptcha-edit' => 'Afin de protéger le wiki du spam des modifications automatisées, nous vous demandons de bien vouloir écrire les deux mots visibles dans le cadre ci-dessous :',
|
||||
'recaptcha-addurl' => 'Votre contribution contient des liens vers un site externe. Pour protéger le wiki contre le spam automatisé, nous vous demandons de bien vouloir écrire les deux mots visibles dans le cadre qui suit :',
|
||||
'recaptcha-badlogin' => 'Pour protéger le wiki des essais automatiques de cassage de mot de passe, nous vous demandons de bien vouloir écrire les deux mots visibles dans le cadre qui suit:',
|
||||
'recaptcha-createaccount' => 'Pour protéger le wiki des créations automatiques de compte, nous vous demandons de bien vouloir écrire les deux mots visibles dans le cadre qui suit :',
|
||||
'recaptcha-createaccount-fail' => 'Réponse de reCAPTCHA fausse ou manquante.',
|
||||
'recaptcha-create' => 'Pour protéger le wiki des créations automatiques de pages, nous vous demandons de bien vouloir écrire les deux mots visibles dans le cadre qui suit :',
|
||||
);
|
||||
|
||||
/** Galician (galego)
|
||||
* @author Toliño
|
||||
*/
|
||||
$messages['gl'] = array(
|
||||
'recaptcha-desc' => 'Módulo de reCAPTCHA para Confirm Edit',
|
||||
'recaptcha-edit' => 'Para protexer o wiki contra o spam automático, introduza as dúas palabras que vexa na caixa:',
|
||||
'recaptcha-addurl' => 'A súa edición inclúe novas ligazóns externas. Para protexer o wiki contra o spam automático, introduza as dúas palabras que vexa na caixa:',
|
||||
'recaptcha-badlogin' => 'Para protexer o wiki contra o roubo de contrasinais, introduza as dúas palabras que vexa na caixa:',
|
||||
'recaptcha-createaccount' => 'Para protexer o wiki contra a creación automática de contas, introduza as dúas palabras que vexa na caixa:',
|
||||
'recaptcha-createaccount-fail' => 'Falta a resposta ao reCAPTCHA ou esta é incorrecta.',
|
||||
'recaptcha-create' => 'Para protexer o wiki contra a creación automática de páxinas, introduza as dúas palabras que vexa na caixa:',
|
||||
);
|
||||
|
||||
/** Swiss German (Alemannisch)
|
||||
* @author Als-Holder
|
||||
*/
|
||||
$messages['gsw'] = array(
|
||||
'recaptcha-edit' => 'Zum Schutz vor automatisiertem Spam, gib bitte di beide Werter in s Fäld unten yy:', # Fuzzy
|
||||
'recaptcha-addurl' => 'In Dyre Bearbeitg het s neji extärni Links. Zum Schutz vor automatisiertem Spam, gib bitte di beide Werter in s Fäld unten yy:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Zum Schutz gege automatisiert Knacken vu Passwerter, gib bitte di beide Werter in s Fäld unten yy:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Zum Schutz gege s automatisiert Aalege vu Benutzerkonte, gib bitte di beide Werter in s Fäld unten yy:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'D reCAPTCHA-Antwort isch fählerhaft oder si fählt.',
|
||||
'recaptcha-create' => 'Zum Schutz gege s automatisiert Aalege vu Syte, gib bitte di beide Werter in s Fäld unten yy:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Hebrew (עברית)
|
||||
*/
|
||||
$messages['he'] = array(
|
||||
'recaptcha-edit' => 'אינכם משתמש רשום.כהגנה מפני ספאם אוטומטי, אנא הקלידו את שתי המילים שלהלן. תודה.', # Fuzzy
|
||||
'recaptcha-addurl' => 'אינכם משתמש רשום.כהגנה מפני ספאם אוטומטי, אנא הקלידו את שתי המילים שלהלן. תודה.', # Fuzzy
|
||||
'recaptcha-badlogin' => 'כהגנה מפני מפצחי סיסמאות אוטומטיים אנא הקלידו את שתי המילים שלהלן:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'כהגנה מפני יצירת חשבונות פיקטיביים ע"י אוטומטים אנא הקלידו את שתי המילים שלהלן:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'לא הוקלדו מילות האישור, או שהוקלדו מילים לא נכונות. נסו שנית.',
|
||||
'recaptcha-create' => 'אינכם משתמש רשום.כהגנה מפני ספאם אוטומטי, אנא הקלידו את שתי המילים שלהלן. תודה.', # Fuzzy
|
||||
);
|
||||
|
||||
/** Upper Sorbian (hornjoserbsce)
|
||||
* @author Michawiki
|
||||
*/
|
||||
$messages['hsb'] = array(
|
||||
'recaptcha-edit' => 'Za škit přećiwo awtomatizowanemu spamej, prošu zapisaj dwě słowje, kotrejž w slědowacym polu widźiš:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Twoja změna wobsahuje nowe eksterne wotkazy. Za škit přećiwo awtomatizowanemu spamej, prošu zapisaj dwě słowje, kotrerjž w slědowacym polu widźiš:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Za škit přećiwo awtomatizowanemu złamanju hesłow, zapisaj prošu wobě słowje, kotrejž widźiš, do slědowaceho pola:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Za škit přećiwo awtomatiskemu wutworjenju konta, prošu zapisaj tej wobě słowje, kotrejž w slědowacym polu widźiš:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Wopačna abo falowaca wotmołwa reCAPTCHA.',
|
||||
'recaptcha-create' => 'Za škit přećiwo awtomatiskemu wutworjenju strony, prošu zapisaj tej wobě słowje, kotrejž w slědowacym polu widźiš:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Interlingua (interlingua)
|
||||
* @author McDutchie
|
||||
*/
|
||||
$messages['ia'] = array(
|
||||
'recaptcha-edit' => 'Pro adjutar a proteger le wiki contra le spam automatisate, per favor dactylographa le duo parolas que tu vide in le quadro sequente:',
|
||||
'recaptcha-addurl' => 'Iste modification include nove ligamines externe. Pro adjutar a proteger le wiki contra le spam automatisate, per favor dactylographa le duo parolas que tu vide in le quadro sequente:',
|
||||
'recaptcha-badlogin' => 'Pro adjutar a proteger le wiki contra le furto automatisate de contrasignos, per favor dactylographa le duo parolas que tu vide in le quadro sequente:',
|
||||
'recaptcha-createaccount' => 'Pro adjutar a proteger le wiki contra le creation automatisate de contos, per favor dactylographa le duo parolas que tu vide in le quadro sequente:',
|
||||
'recaptcha-createaccount-fail' => 'Responsa reCAPTCHA incorrecte o mancante.',
|
||||
'recaptcha-create' => 'Pro adjutar a proteger le wiki contra le creation automatisate de paginas, per favor dactylographa le duo parolas que tu vide in le quadro sequente:',
|
||||
);
|
||||
|
||||
/** Indonesian (Bahasa Indonesia)
|
||||
* @author IvanLanin
|
||||
*/
|
||||
$messages['id'] = array(
|
||||
'recaptcha-edit' => 'Untuk membantu pelindungan terhadap spam penyuntingan otomatis, silakan ketik dua kata yang Anda lihat dalam kotak di bawah ini:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Suntingan Anda menyertakan pranala eksternal baru. Untuk membantu pelindungan terhadap spam otomatis, silakan ketik dua kata yang Anda lihat dalam kotak di bawah ini:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Untuk membantu pelindungan terhadap perengkahan sandi otomatis, silakan ketik dua kata yang Anda lihat dalam kotak di bawah ini:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Untuk membantu pelindungan terhadap pembuatan akun otomatis, silakan ketik dua kata yang Anda lihat dalam kotak di bawah ini:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Jawaban reCAPTCHA tidak benar atau tidak dimasukkan.',
|
||||
'recaptcha-create' => 'Untuk membantu pelindungan terhadap pembuatan halaman otomatis, silakan ketik dua kata yang Anda lihat dalam kotak di bawah ini:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Italian (italiano)
|
||||
* @author Beta16
|
||||
* @author Nemo bis
|
||||
*/
|
||||
$messages['it'] = array(
|
||||
'recaptcha-edit' => 'Per proteggere il wiki dalle modifiche automatiche che aggiungono spam, ti chiediamo gentilmente di scrivere le due parole mostrate nel riquadro sottostante:',
|
||||
'recaptcha-addurl' => 'La tua modifica aggiunge qualche nuovo collegamento esterno. Per proteggere il wiki dallo spam automatico, ti chiediamo gentilmente di scrivere le due parole mostrate nel riquadro sottostante:',
|
||||
'recaptcha-badlogin' => 'Per proteggere il wiki dalla forzatura automatica delle password, ti chiediamo gentilmente di scrivere le due parole mostrate nel riquadro sottostante:',
|
||||
'recaptcha-createaccount' => 'Per proteggere il wiki dalla creazione automatica di nuovi accessi, ti chiediamo gentilmente di scrivere le due parole mostrate nel riquadro sottostante:',
|
||||
'recaptcha-createaccount-fail' => 'Risposta reCAPTCHA mancante o errata.',
|
||||
'recaptcha-create' => 'Per proteggere il wiki dalla creazione automatica di pagine, ti chiediamo gentilmente di scrivere le due parole mostrate nel riquadro sottostante:',
|
||||
);
|
||||
|
||||
/** Japanese (日本語)
|
||||
* @author Shirayuki
|
||||
*/
|
||||
$messages['ja'] = array(
|
||||
'recaptcha-desc' => 'Confirm Edit 用 reCAPTCHA モジュール',
|
||||
'recaptcha-edit' => 'ウィキへの自動編集スパム攻撃を防ぐため、お手数をおかけしますが下の画像に表示されている 2 つの単語を入力してください:',
|
||||
'recaptcha-addurl' => 'あなたは新しい外部リンクを追加しようとしています。ウィキへの自動スパム攻撃を防ぐため、お手数をおかけしますが下の画像に表示されている 2 つの単語を入力してください:',
|
||||
'recaptcha-badlogin' => 'ウィキへの自動パスワードクラック攻撃を防ぐため、お手数をおかけしますが下の画像に表示されている 2 つの単語を入力してください:',
|
||||
'recaptcha-createaccount' => 'ウィキでのアカウント自動作成を防ぐため、お手数をおかけしますが下の画像に表示されている 2 つの単語を入力してください:',
|
||||
'recaptcha-createaccount-fail' => '文字列が正しくない、または入力されていません。',
|
||||
'recaptcha-create' => 'ウィキでのページの自動作成を防ぐため、お手数をおかけしますが下の画像に表示されている 2 つの単語を入力してください:',
|
||||
);
|
||||
|
||||
/** Korean (한국어)
|
||||
* @author 아라
|
||||
*/
|
||||
$messages['ko'] = array(
|
||||
'recaptcha-desc' => '편집 확인에 대한 reCAPCHA 모듈',
|
||||
'recaptcha-edit' => '자동화된 편집 스팸으로부터 보호하기 위해, 아래 상자에 보이는 두 낱말을 입력하세요:', # Fuzzy
|
||||
'recaptcha-addurl' => '편집에 새로운 바깥 링크가 포함되어 있습니다. 자동화된 스팸으로부터 보호하기 위해, 아래 상자에 보이는 두 낱말을 입력하세요:', # Fuzzy
|
||||
'recaptcha-badlogin' => '자동화된 비밀번호 깨기로부터 보호하기 위해, 아래 상자에 보이는 두 낱말을 입력하세요:', # Fuzzy
|
||||
'recaptcha-createaccount' => '자동화된 계정 만들기로부터 보호하기 위해, 아래 상자에 보이는 두 낱말을 입력하세요:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'reCAPTCHA 답이 올바르지 않거나 없습니다.',
|
||||
'recaptcha-create' => '자동화된 문서 만들기로부터 보호하기 위해, 아래 상자에 보이는 두 낱말을 입력하세요:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Colognian (Ripoarisch)
|
||||
* @author Purodha
|
||||
*/
|
||||
$messages['ksh'] = array(
|
||||
'recaptcha-edit' => 'Schrief di zwei Wööt en dä Kaste onge erin.
|
||||
Dat sull jääje et automattesche Ändere un SPAM em Wiki schöze.', # Fuzzy
|
||||
'recaptcha-addurl' => 'Schrief di zwei Wööt en dä Kaste onge erin.
|
||||
Dat sull jääje automattesch en et Wiki jebraate SPAM schöze, nohdämm en Dingem Beidraach {{PLURAL:$1|ene neue Lengk dren es|neue Lengks dren sin|kein neue Lengks dren sin}}.', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Schrief di zwei Wööt en dä Kaste onge erin.
|
||||
Dat sull jääje et automattesche Paßwoot Knacke em Wiki schöze.', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Schrief di zwei Wööt en dä Kaste onge erin.
|
||||
Dat sull jääje SPAM un automattesch aanjelaate Zohjäng nohm Wiki schöze.', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Dat wohr en verkehte udder jaa kei Antwoot op dat Kaptscha.', # Fuzzy
|
||||
'recaptcha-create' => 'Schrief di zwei Wööt en dä Kaste onge erin.
|
||||
Dat sull jääje SPAM un automattesch aanjelaate Sigge em Wiki schöze.', # Fuzzy
|
||||
);
|
||||
|
||||
/** Luxembourgish (Lëtzebuergesch)
|
||||
* @author Robby
|
||||
*/
|
||||
$messages['lb'] = array(
|
||||
'recaptcha-edit' => "Fir d'Wiki géint automatiséierte Spam ze schützen, froe mir Iech déi zwee Wierder déi Dir gesitt an d'Këscht ënnendrënner anzeginn:",
|
||||
'recaptcha-addurl' => "An Ärer Ännerung sinn nei extern Linken! Fir dës Wikie géint automatiséierte Spam ze schütze, froe mir Iech déi zwee Wierder déi Dir gesitt an d'Këscht ënnendrënner anzeginn:",
|
||||
'recaptcha-badlogin' => "Fir d'Wiki géint d'automatiséiert Hacke vu Passwierder ze schützen, froe mir Iech déi zwee Wierder déi Dir gesitt an d'Këscht ënnendrënner anzeginn:",
|
||||
'recaptcha-createaccount' => "Fir d'Wiki géint d'automatiséiert Uleeë vu Benotzerkonten ze schützen, froe mir Iech déi zwee Wierder déi Dir gesitt an d'Këscht ënnendrënner anzeginn:",
|
||||
'recaptcha-createaccount-fail' => 'reCAPTCHA Äntwert feelt oder ass net korrekt.',
|
||||
'recaptcha-create' => "Fir d'Wiki géint d'automatiséiert Uleeë vu Säiten ze schützen, froe mir Iech déi zwee Wierder déi Dir gesitt an d'Këscht ënnendrënner anzeginn:",
|
||||
);
|
||||
|
||||
/** Macedonian (македонски)
|
||||
* @author Bjankuloski06
|
||||
*/
|
||||
$messages['mk'] = array(
|
||||
'recaptcha-desc' => 'Модул reCAPTCHA за потврда на уредувања',
|
||||
'recaptcha-edit' => 'Како заштитна мерка против автоматизиран спам, би ве замолиле да ги внесете двата збора прикажани во полето:',
|
||||
'recaptcha-addurl' => 'Во вашите измени има нови надворешни врски. Како заштитна мерка против автоматизиран спам, би ве замолиле да внесете двата збора прикажани во полето:',
|
||||
'recaptcha-badlogin' => 'Како заштитна мерка против автоматизирано провалување на лозинки, би ве замолиле да внесете двата збора прикажани во полето:',
|
||||
'recaptcha-createaccount' => 'Како заштитна мерка против автоматизирано создавање на сметки, би ве замолиле да внесете двата збора прикажани во полето:',
|
||||
'recaptcha-createaccount-fail' => 'reCAPTCHA доби погрешен одговор или одговорот недостасува.',
|
||||
'recaptcha-create' => 'Како заштитна мерка против автоматизирано создавање на страници, би ве замолиле да внесете двата збора прикажани во полето:',
|
||||
);
|
||||
|
||||
/** Malay (Bahasa Melayu)
|
||||
* @author Anakmalaysia
|
||||
*/
|
||||
$messages['ms'] = array(
|
||||
'recaptcha-edit' => 'Untuk membanteras kegiatan spam automatik, sila taipkan dua perkataan yang anda lihat dalam petak di bawah:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Suntingan anda termasuk pautan luar baru. Untuk membanteras kegiatan spam automatik, sila taipkan dua perkataan yang anda lihat dalam petak di bawah:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Untuk membanteras kegiatan meneka kata laluan secara automatik, sila taipkan dua perkataan yang anda lihat dalam petak di bawah:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Untuk membanteras kegiatan membuka akaun secara automatik, sila taipkan dua perkataan yang anda lihat dalam petak di bawah:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Jawapan reCAPTCHA tidak betul atau tidak ada.',
|
||||
'recaptcha-create' => 'Untuk membanteras kegiatan mencipta laman secara automatik, sila taipkan dua perkataan yang anda lihat dalam petak di bawah:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Maltese (Malti)
|
||||
* @author Chrisportelli
|
||||
*/
|
||||
$messages['mt'] = array(
|
||||
'recaptcha-edit' => "Sabiex tgħinna nipproteġu kontra l-modifiki li jżidu spam, jekk jogħġbok ikteb iż-żewġ kelmiet li tara fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'recaptcha-addurl' => "Il-modifika tiegħek tinkludi ħoloq esterni ġodda. Sabiex tipproteġi kontra spam awtomatiku, jekk jogħġbok ikteb iż-żewġ kelmiet li tara fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'recaptcha-badlogin' => "Sabiex tgħinna nipproteġu kontra l-infurzar awtomatiku tal-passwords, jekk jogħġbok ikteb iż-żewġ kelmiet li tara fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'recaptcha-createaccount' => "Sabiex tgħinna nipproteġu kontra l-ħolqien awtomatiku ta' kontijiet ġodda, jekk jogħġbok ikteb iż-żewġ kelmiet li tara fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Tweġiba reCAPTCHA ħażina jew nieqsa.',
|
||||
'recaptcha-create' => "Sabiex tgħinna nipproteġu kontra l-ħolqien awtomatiku ta' paġni, jekk jogħġbok ikteb iż-żewġ kelmiet li tara fil-kaxxa t'hawn taħt:", # Fuzzy
|
||||
);
|
||||
|
||||
/** Norwegian Bokmål (norsk bokmål)
|
||||
* @author Event
|
||||
*/
|
||||
$messages['nb'] = array(
|
||||
'recaptcha-edit' => 'Som beskyttelse mot automatisk redigert spam, vennligst skriv inn de to ordene du ser i boksen under:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Din redigering inneholder nye eksterne lenker. Som beskyttelse mot automatisk spam, vennligst skriv inn de to ordene du ser i boksen under:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Som beskyttelse mot automatisk passordknekking, vennligst skriv inn de to ordene du ser i boksen under:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Som beskyttelse mot automatisk opprettelse av brukerkonto, vennligst skriv inn de to ordene du ser i boksen under:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Feil eller manglende reCAPTCHA-svar.',
|
||||
'recaptcha-create' => 'Som beskyttelse mot automatisk opprettelse av side, vennligst skriv inn de to ordene du ser i boksen under:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Dutch (Nederlands)
|
||||
* @author HanV
|
||||
* @author Siebrand
|
||||
*/
|
||||
$messages['nl'] = array(
|
||||
'recaptcha-edit' => 'Voer ter bescherming tegen geautomatiseerde spam de twee woorden in die u in het onderstaande venster ziet:',
|
||||
'recaptcha-addurl' => 'Uw bewerking bevat nieuwe externe koppelingen. Voer ter bescherming tegen geautomatiseerde spam de twee woorden in die u ziet in het onderstaande venster:',
|
||||
'recaptcha-badlogin' => 'Voer ter bescherming tegen het automatisch kraken van wachtwoorden de twee woorden in die u ziet in het invoervenster:',
|
||||
'recaptcha-createaccount' => 'Om het automatisch aanmaken van gebruikers tegen te gaan moet u de twee woorden in het onderstaande venster invoeren:',
|
||||
'recaptcha-createaccount-fail' => 'Het reCAPTCHA-antwoord is onjuist of niet ingevoerd.',
|
||||
'recaptcha-create' => 'Om het automatisch aanmaken van een pagina tegen te gaan moet u de twee woorden invoeren die in het onderstaande veld staan:',
|
||||
);
|
||||
|
||||
/** Nederlands (informeel) (Nederlands (informeel))
|
||||
* @author Siebrand
|
||||
*/
|
||||
$messages['nl-informal'] = array(
|
||||
'recaptcha-edit' => 'Voer ter bescherming tegen geautomatiseerde spam de twee woorden die je ziet in het invoervenster in:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Je bewerking bevat nieuwe externe koppelingen. Voer ter bescherming tegen geautomatiseerde spam de twee woorden die je ziet in het invoervenster in:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Voer ter bescherming tegen het automatisch kraken van wachtwoorden de twee woorden die je ziet in het invoervenster in:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Om het automatisch aanmaken van gebruikers tegen te gaan moet je de twee woorden die je ziet invoeren:', # Fuzzy
|
||||
'recaptcha-create' => "Om het automatisch aanmaken van pagina's tegen te gaan moet je de twee woorden die je ziet invoeren:", # Fuzzy
|
||||
);
|
||||
|
||||
/** Occitan (occitan)
|
||||
* @author Cedric31
|
||||
*/
|
||||
$messages['oc'] = array(
|
||||
'recaptcha-createaccount-fail' => 'Responsa de reCAPTCHA faussa o mancanta.',
|
||||
);
|
||||
|
||||
/** Polish (polski)
|
||||
* @author WTM
|
||||
*/
|
||||
$messages['pl'] = array(
|
||||
'recaptcha-edit' => 'Aby uchronić nas przed robotami, proszę wpisać dwa widoczne słowa w poniższym polu:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Twoja edycja zawiera linki zewnętrzne. Aby uchronić nas przed robotami, proszę wpisać dwa widoczne słowa w poniższym polu:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Aby uchronić nas przed złamaniem automatycznym haseł, proszę wpisać dwa widoczne słowa w poniższym polu:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Aby uchronić nas przed automatycznym tworzeniem użytkowników, proszę wpisać dwa widoczne słowa w poniższym polu:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Odpowiedź na reCAPTCHA jest fałszywa lub brakująca.',
|
||||
'recaptcha-create' => 'Aby uchronić nas przed tworzeniem stron przez robotów, proszę wpisać dwa widoczne słowa w poniższym polu:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Piedmontese (Piemontèis)
|
||||
* @author Borichèt
|
||||
* @author Dragonòt
|
||||
*/
|
||||
$messages['pms'] = array(
|
||||
'recaptcha-edit' => "Për giuté a protege contra la rumenta dle modìfiche automàtiche, për piasì ch'a scriva le doe paròle ch'a s-ciàira ant ël quàder sì-sota:", # Fuzzy
|
||||
'recaptcha-addurl' => "Soa modìfica a conten d'anliure esterne neuv. Për giuté a protege contra la rumenta dle modìfiche automàtiche, për piasì ch'a scriva le doe paròle ch'a s-ciàira ant ël quàder sì-sota:", # Fuzzy
|
||||
'recaptcha-badlogin' => "Për giuté a protege contra la forsadura automatisà ëd le ciav, për piasì ch'a scriva le doe paròle ch'a s-ciàira ant ël formolari sì-sota:", # Fuzzy
|
||||
'recaptcha-createaccount' => "Për giuté a protege contra la creassion automatisà ëd cont, për piasì ch'a scriva le doe paròle ch'a s-ciàira ant ël formolari sì-sota:", # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Rispòsta ëd reCAPTCHA fàussa o mancanta.',
|
||||
'recaptcha-create' => "Për giuté a protege contra la creassion automatisà ëd pàgine, për piasì ch'a scriv le doe paròle ch'a s-ciàira ant la casela sì-sota:", # Fuzzy
|
||||
);
|
||||
|
||||
/** Portuguese (português)
|
||||
* @author Hamilton Abreu
|
||||
*/
|
||||
$messages['pt'] = array(
|
||||
'recaptcha-edit' => 'Para proteger-nos de spam, por favor escreva as duas palavras visíveis abaixo:', # Fuzzy
|
||||
'recaptcha-addurl' => "A sua edição contém links externos novos. Como prevenção contra sistemas automatizados de inserção de ''spam'', escreva as duas palavras visíveis na caixa abaixo:", # Fuzzy
|
||||
'recaptcha-badlogin' => 'Para proteger-nos de robots que tentam adivinhar senhas, por favor escreva as duas palavras visíveis abaixo:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Para proteger-nos de criação automática de contas, por favor escreva as duas palavras visíveis abaixo:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'A resposta ao reCAPTCHA é errada.',
|
||||
'recaptcha-create' => 'Para proteger-nos da criação automática de páginas, por favor escreva as duas palavras visíveis abaixo:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Brazilian Portuguese (português do Brasil)
|
||||
*/
|
||||
$messages['pt-br'] = array(
|
||||
'recaptcha-edit' => 'Para ajudar a prevenir contra vandalismos, por favor digite as duas palavras que você vê na caixa abaixo:', # Fuzzy
|
||||
'recaptcha-addurl' => 'A sua edição inclui ligações externas. Para ajudar a prevenir contra vandalismos, por favor digite as duas palavras que você vê na caixa abaixo:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Para ajudar a prevenir contra tentativas de desbloquear senhas, por favor digite as duas palavras que você vê na caixa abaixo:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Para ajudar a prevenir contra criação automatizada de usuários, por favor digite as duas palavras que você vê na caixa abaixo:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Resposta incorreta ao reCAPTCHA.',
|
||||
'recaptcha-create' => 'Para ajudar a prevenir contra criação automatizada de páginas, por favor digite as duas palavras que você vê na caixa abaixo:', # Fuzzy
|
||||
);
|
||||
|
||||
/** tarandíne (tarandíne)
|
||||
* @author Joetaras
|
||||
*/
|
||||
$messages['roa-tara'] = array(
|
||||
'recaptcha-edit' => "Pe darne 'na màne a proteggere condre le cangiaminde automatece de le rummate, pe piacere scrive le doje parole ca 'ndruche jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'recaptcha-addurl' => "Le cangiaminde tune 'ngludone collegaminde de fore nuève. Pe darne 'na màne a proteggere condre le cangiaminde automatece de le rummate, pe piacere scrive le doje parole ca 'ndruche jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'recaptcha-badlogin' => "Pe darne 'na màne a proteggere condre le futteminde automatece de le passuord, pe piacere scrive le doje parole ca 'ndruche jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'recaptcha-createaccount' => "Pe darne 'na màne a proteggere condre le ccrejaziune automatece de le cunde, pe piacere scrive le doje parole ca 'ndruche jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Resposte reCAPTCHA ingorrette o mangande.',
|
||||
'recaptcha-create' => "Pe darne 'na màne a proteggere condre le ccrejaziune automatece de le pàggene, pe piacere scrive le doje parole ca 'ndruche jndr'à buatte aqquà sotte:", # Fuzzy
|
||||
);
|
||||
|
||||
/** Russian (русский)
|
||||
* @author Okras
|
||||
* @author Александр Сигачёв
|
||||
*/
|
||||
$messages['ru'] = array(
|
||||
'recaptcha-edit' => 'В целях защиты от автоматического спама в правках просим вас ввести два слова, которые вы видите ниже:',
|
||||
'recaptcha-addurl' => 'Ваша правка содержит новые внешние ссылки. В целях защиты от автоматического спама просим вас ввести два слова, которые вы видите в рамке ниже:',
|
||||
'recaptcha-badlogin' => 'В целях защиты от автоматического подбора пароля просим вас ввести два слова, которые вы видите в рамке ниже:',
|
||||
'recaptcha-createaccount' => 'В целях защиты от автоматического создания учётных записей просим вас ввести два слова, которые вы видите в рамке ниже:',
|
||||
'recaptcha-createaccount-fail' => 'Ответ reCAPTCHA неправильный или отсутствует.',
|
||||
'recaptcha-create' => 'В целях защиты от автоматического создания страниц просим вас ввести два слова, которые вы видите в рамке ниже:',
|
||||
);
|
||||
|
||||
/** Sinhala (සිංහල)
|
||||
* @author පසිඳු කාවින්ද
|
||||
*/
|
||||
$messages['si'] = array(
|
||||
'recaptcha-createaccount-fail' => 'වැරදි හෝ දක්නට නොමැති reCAPTCHA පිළිතුර.',
|
||||
);
|
||||
|
||||
/** Serbian (Cyrillic script) (српски (ћирилица))
|
||||
* @author Rancher
|
||||
*/
|
||||
$messages['sr-ec'] = array(
|
||||
'recaptcha-desc' => 'Модул reCAPTCHA за потврду уређивања',
|
||||
);
|
||||
|
||||
/** Serbian (Latin script) (srpski (latinica))
|
||||
*/
|
||||
$messages['sr-el'] = array(
|
||||
'recaptcha-desc' => 'Modul reCAPTCHA za potvrdu uređivanja',
|
||||
);
|
||||
|
||||
/** Swedish (svenska)
|
||||
* @author WikiPhoenix
|
||||
*/
|
||||
$messages['sv'] = array(
|
||||
'recaptcha-edit' => 'För att skydda wikin mot automatiskt redigerings-spam ber vi dig att skriva de två orden du ser i rutan nedan.',
|
||||
'recaptcha-addurl' => 'Din redigering innehåller nya externa länkar. För att skydda wikin mot automatiserat spam ber vi dig att skriva de två ordern du ser i rutan nedan:',
|
||||
'recaptcha-badlogin' => 'För att skydda wikin mot automatiserade försök att knäcka lösenord ber vi dig att skriva in de två orden du ser i rutan nedan:',
|
||||
'recaptcha-createaccount' => 'För att skydda wikin mot automatiskt kontoskapande ber vi dig att skriva de två orden som du ser i rutan nedan:',
|
||||
'recaptcha-createaccount-fail' => 'Du har angivit ett felaktig svar för reCAPTCHA.',
|
||||
'recaptcha-create' => 'För att skydda wikin mot automatiserade sidskapande ber vi dig att skriva in de två orden du ser i rutan nedan:',
|
||||
);
|
||||
|
||||
/** Swahili (Kiswahili)
|
||||
* @author Lloffiwr
|
||||
*/
|
||||
$messages['sw'] = array(
|
||||
'recaptcha-edit' => 'Ili kusaidia kuzuia mashine zisihariri, tafadhali andika maneno mawili yanayoonekana katika kisanduku pakipo chini:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Haririo lako lina viungo vipya vya nje. Ili kusaidia katika kuzuisha viungo visivyotakiwa visiwekwe na mashine, tafadhali andika maneno mawili yanayoonekana katika kisanduku pakipo chini:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Ili kusaidia katika kuzuia neno lako la siri lisigunduliwe na mashine, tafadhali andika maneno mawili yanayoonekana katika kisanduku pakipo chini:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Ili kusaidia kuzuia akaunti zisifunguliwe nyingi na mashine, tafadhali andika maneno mawili yanayoonekana katika kisanduku pakipo chini:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Jibu la swali la CAPTCHA si sahihi au halipo.', # Fuzzy
|
||||
'recaptcha-create' => 'Ili kusaidia kuzuia kurasa zisianzishwe nyingi na mashine, tafadhali andika maneno mawili yanayoonekana katika kisanduku pakipo chini:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Tagalog (Tagalog)
|
||||
* @author AnakngAraw
|
||||
*/
|
||||
$messages['tl'] = array(
|
||||
'recaptcha-desc' => 'Modulo ng reCAPTCHA para sa Pagtiyak ng Pagbago',
|
||||
'recaptcha-edit' => 'Upang makatulong sa pagprutekta laban sa kusang basurang pamamatnugot, paki imakinilya ang dalawang mga salitang nakikita mo sa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'recaptcha-addurl' => 'Ang pagbabago mo ay nagsasama ng bagong panlabas na mga kawing. Upang makatulong sa pagprutekta laban sa kusang paglusob ng basurang-liham, paki imakinilya ang dalawang mga salitang nakikita sa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'recaptcha-badlogin' => 'Upang makatulong sa pagsasanggalang laban sa kusang panghuhula ng hudyat, paki imakinilya ang dalawang mga salitang nakikita mo sa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'recaptcha-createaccount' => 'Upang makatulong sa pagprutekta laban sa kusang paglikha ng akawnt, paki imakinilya ang dalawang mga salitang nakikita mo sa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => 'Hindi tama o nawawalang sagot sa reCAPTCHA.',
|
||||
'recaptcha-create' => 'Upang makatulong sa pagprutekta laban sa kusang paglikha ng pahina, paki imakinilya ang dalawang mga salitang nakikita mo sa loob ng kahong nasa ibaba:', # Fuzzy
|
||||
);
|
||||
|
||||
/** Ukrainian (українська)
|
||||
* @author Andriykopanytsia
|
||||
* @author Base
|
||||
* @author Тест
|
||||
*/
|
||||
$messages['uk'] = array(
|
||||
'recaptcha-edit' => 'Для запобігання автоматичному спаму у редагуваннях просимо вас ввести два слова, які Ви бачите у блоці нижче:',
|
||||
'recaptcha-addurl' => 'Ваше редагування містить зовнішні посилання. Для запобігання автоматичному спаму у редагуваннях просимо вас ввести два слова, які Ви бачите у блоці нижче:',
|
||||
'recaptcha-badlogin' => 'Для запобігання автоматичному підбору паролю просимо вас ввести два слова, які Ви бачите у блоці нижче:',
|
||||
'recaptcha-createaccount' => 'Для запобігання автоматичному створенню облікових записів просимо вас ввести два слова, які Ви бачите у блоці нижче:',
|
||||
'recaptcha-createaccount-fail' => 'Відповідь reCAPTCHA неправильна або відсутня.',
|
||||
'recaptcha-create' => 'З метою захисту вікі від автоматичного створення сторінки просимо вас ввести два слова, які ви бачите у блоці нижче:',
|
||||
);
|
||||
|
||||
/** Vietnamese (Tiếng Việt)
|
||||
* @author Minh Nguyen
|
||||
*/
|
||||
$messages['vi'] = array(
|
||||
'recaptcha-desc' => 'Mô đun reCAPTCHA cho Confirm Edit',
|
||||
'recaptcha-edit' => 'Để giúp tránh các sửa đổi spam tự động, xin vui lòng gõ hai từ mà bạn nhìn thấy vào hộp dưới đây:',
|
||||
'recaptcha-addurl' => 'Sửa đổi của bạn có chứa liên kết ngoài mới. Để giúp tránh các sửa đổi spam tự động, xin vui lòng gõ hai từ mà bạn nhìn vào hộp dưới đây:',
|
||||
'recaptcha-badlogin' => 'Để giúp tránh bẻ khóa mật khẩu tự động, xin vui lòng gõ hai từ mà bạn nhìn vào hộp dưới đây:',
|
||||
'recaptcha-createaccount' => 'Để giúp tránh việc mở tài khoản tự động, xin vui lòng gõ hai từ mà bạn nhìn vào hộp dưới đây:',
|
||||
'recaptcha-createaccount-fail' => 'Thiếu câu trả lời reCAPTCHA hoặc câu trả lời không đúng.',
|
||||
'recaptcha-create' => 'Để giúp tránh việc tạo trang tự động, xin vui lòng gõ hai từ mà bạn nhìn vào hộp dưới đây:',
|
||||
);
|
||||
|
||||
/** Simplified Chinese (中文(简体))
|
||||
* @author Hydra
|
||||
* @author Hzy980512
|
||||
* @author Onecountry
|
||||
*/
|
||||
$messages['zh-hans'] = array(
|
||||
'recaptcha-edit' => '为了避免垃圾用户自动编辑,请键入下面框中的两个单词:',
|
||||
'recaptcha-addurl' => '您的编辑包含新的外部链接。为了避免垃圾用户自动编辑,请键入下面框中的两个单词:',
|
||||
'recaptcha-badlogin' => '为避免自动密码破解,请键入下面框中的两个单词:',
|
||||
'recaptcha-createaccount' => '为了避免创建自动垃圾用户,请键入下面框中的两个单词:',
|
||||
'recaptcha-createaccount-fail' => 'reCAPTCHA 答案不正确或未填写。',
|
||||
'recaptcha-create' => '为了避免垃圾用户自动创建页面,请键入下面框中的两个单词:',
|
||||
);
|
||||
|
||||
/** Traditional Chinese (中文(繁體))
|
||||
* @author StephDC
|
||||
*/
|
||||
$messages['zh-hant'] = array(
|
||||
'recaptcha-edit' => '為了防止wiki被自動編輯的垃圾損害,我們請您鍵入您在下面的框中看到的這兩個單詞:',
|
||||
'recaptcha-addurl' => '您的編輯包含新的外部鏈接。為了幫助防止自動垃圾郵件,請鍵入您在下面的框中看到這兩個詞:', # Fuzzy
|
||||
'recaptcha-badlogin' => '為幫助防止自動密碼破解,請鍵入您看到下面的框中的兩個字:', # Fuzzy
|
||||
'recaptcha-createaccount' => '為了幫助防止創建自動化的帳戶,請鍵入您在下面的框中看到的這兩個字:', # Fuzzy
|
||||
'recaptcha-createaccount-fail' => '不正確或缺失的 reCAPTCHA 答案。',
|
||||
'recaptcha-create' => '為了幫助防止自動的頁創建,請鍵入您在下面的框中看到這兩個詞:', # Fuzzy
|
||||
);
|
64
sources/mediawiki/extensions/ConfirmEdit/ReCaptcha.php
Normal file
64
sources/mediawiki/extensions/ConfirmEdit/ReCaptcha.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Captcha class using the reCAPTCHA widget.
|
||||
* Stop Spam. Read Books.
|
||||
*
|
||||
* @addtogroup Extensions
|
||||
* @author Mike Crawford <mike.crawford@gmail.com>
|
||||
* @copyright Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
|
||||
* @licence MIT/X11
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$dir = __DIR__;
|
||||
require_once $dir . '/ConfirmEdit.php';
|
||||
$wgCaptchaClass = 'ReCaptcha';
|
||||
|
||||
$wgExtensionMessagesFiles['ReCaptcha'] = $dir . '/ReCaptcha.i18n.php';
|
||||
|
||||
$wgAutoloadClasses['ReCaptcha'] = $dir . '/ReCaptcha.class.php';
|
||||
|
||||
require_once( 'recaptchalib.php' );
|
||||
|
||||
// Set these in LocalSettings.php
|
||||
$wgReCaptchaPublicKey = '';
|
||||
$wgReCaptchaPrivateKey = '';
|
||||
// For backwards compatibility
|
||||
$recaptcha_public_key = '';
|
||||
$recaptcha_private_key = '';
|
||||
|
||||
/**
|
||||
* Sets the theme for ReCaptcha
|
||||
*
|
||||
* See http://code.google.com/apis/recaptcha/docs/customization.html
|
||||
*/
|
||||
$wgReCaptchaTheme = 'red';
|
||||
|
||||
$wgExtensionFunctions[] = 'efReCaptcha';
|
||||
|
||||
/**
|
||||
* Make sure the keys are defined.
|
||||
*/
|
||||
function efReCaptcha() {
|
||||
global $wgReCaptchaPublicKey, $wgReCaptchaPrivateKey;
|
||||
global $recaptcha_public_key, $recaptcha_private_key;
|
||||
global $wgServerName;
|
||||
|
||||
// Backwards compatibility
|
||||
if ( $wgReCaptchaPublicKey == '' ) {
|
||||
$wgReCaptchaPublicKey = $recaptcha_public_key;
|
||||
}
|
||||
if ( $wgReCaptchaPrivateKey == '' ) {
|
||||
$wgReCaptchaPrivateKey = $recaptcha_private_key;
|
||||
}
|
||||
|
||||
if ( $wgReCaptchaPublicKey == '' || $wgReCaptchaPrivateKey == '' ) {
|
||||
die ( 'You need to set $wgReCaptchaPrivateKey and $wgReCaptchaPublicKey in LocalSettings.php to ' .
|
||||
"use the reCAPTCHA plugin. You can sign up for a key <a href='" .
|
||||
htmlentities( recaptcha_get_signup_url ( $wgServerName, "mediawiki" ) ) . "'>here</a>." );
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue