merge latest master.
some tests fail due to logical changes, will fix that in a follow-up Change-Id: I8a5e4087ecf674fbcf6327c5d168cd401be12400
This commit is contained in:
parent
cc5cc79148
commit
b6fe213226
270 changed files with 12862 additions and 10581 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -13,7 +13,7 @@ nbproject*
|
|||
project.index
|
||||
|
||||
# MediaWiki install & usage
|
||||
cache/*.cdb
|
||||
cache
|
||||
images/[0-9a-f]
|
||||
images/archive
|
||||
images/deleted
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ resources/jquery/jquery.xmldom.js
|
|||
resources/jquery.effects
|
||||
resources/jquery.tipsy
|
||||
resources/jquery.ui
|
||||
resources/mediawiki.libs/mediawiki.libs.jpegmeta.js
|
||||
resources/mediawiki.libs
|
||||
tests/jasmine/lib/jasmine-1.0.1/jasmine-html.js
|
||||
tests/jasmine/lib/jasmine-1.0.1/jasmine.js
|
||||
|
|
|
|||
|
|
@ -26,5 +26,5 @@
|
|||
"jquery": true,
|
||||
|
||||
"nomen": true,
|
||||
"onevar": false
|
||||
"onevar": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
|
|||
This only affects installations which have $wgAllowCopyUploads set to true.
|
||||
* Removed f-prot support from $wgAntivirusSetup.
|
||||
* New variable $wgDBerrorLogTZ to provide dates in the error log in a
|
||||
different timezone than the wiki timezone set by $wgLocalTimezone.
|
||||
different timezone than the wiki timezone set by $wgLocaltimezone.
|
||||
* New variables $wgDBssl and $wgDBcompress to enable SSL and compression for database
|
||||
connections, if either are available for the selected DB type.
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
|
|||
* &useskin=default will now always display the default skin. Useful for users with a
|
||||
preference for the non-default skin to look at something using the default skin.
|
||||
* (bug 27619) Remove preference option to display broken links as link?
|
||||
* (bug 34896) Update jQuery JSON plugin to v2.3 (2011-09-17).
|
||||
* (bug 34896) jQuery JSON plugin upgraded to v2.3 (2011-09-17).
|
||||
* (bug 34302) Add CSS classes to email fields in user preferences.
|
||||
* Introduced $wgDebugDBTransactions to trace transaction status (currently PostgreSQL only).
|
||||
* (bug 23795) Add parser itself to ParserMakeImageParams hook.
|
||||
|
|
@ -65,9 +65,9 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
|
|||
* (bug 35685) api.php URL and other entry point URLs are now listed on
|
||||
Special:Version
|
||||
* Edit notices can now be translated.
|
||||
* (bug 35680) jQuery upgraded to 1.7.2.
|
||||
* jQuery UI upgraded to 1.8.22.
|
||||
* (bug 35705) QUnit upgraded from v1.2.0 to v1.8.0.
|
||||
* jQuery upgraded to 1.7.2
|
||||
* jQuery UI upgraded to 1.8.23.
|
||||
* QUnit upgraded from v1.2.0 to v1.10.0.
|
||||
* (bug 37604) jquery.cookie upgraded to 2011 version.
|
||||
* (bug 22887) Add warning and tracking category for preprocessor errors
|
||||
* (bug 31704) Allow selection of associated namespace on the watchlist
|
||||
|
|
@ -124,7 +124,6 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
|
|||
* HTMLForm mutators can now be chained (they return $this)
|
||||
* A new message, "api-error-filetype-banned-type", is available for formatting
|
||||
API upload errors due to the file extension blacklist.
|
||||
* jsMessage: Redesigned in Vector/Monobook as floating bubble with auto-hide.
|
||||
* New hook 'ParserTestGlobals' allows to set globals before running parser tests.
|
||||
* Allow importing pages as subpage.
|
||||
* Add lang and hreflang attributes to language links on Login page.
|
||||
|
|
@ -132,10 +131,19 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
|
|||
* Show change tags when transclude Special:Recentchanges(linked) or Special:Newpages.
|
||||
* (bug 23226) Add |class= parameter to image links in order to add class(es) to HTML img tag.
|
||||
* (bug 39431) SVG animated status is now shown in long description
|
||||
* (bug 39376) jquery.form upgraded to 3.14
|
||||
* (bug 39376) jquery.form upgraded to 3.14.
|
||||
* SVG files will now show the actual width in the SVG's specified units
|
||||
in the metadata box.
|
||||
* Added ResourceLoader module "jquery.jStorage".
|
||||
* (bug 39273) Added AJAX support for "Show changes" (diff) in LivePreview.
|
||||
* Added ResourceLoader module "jquery.badge".
|
||||
* mw.util.$content now points to the overall content area in the skin rather than just
|
||||
page text content area. If you need the old behaviour please use $( '#mw-content-text').
|
||||
* jsMessage has been replaced with a floating bubble notification system complete
|
||||
with auto-hide, multi-message support, and message replacement tags.
|
||||
* jquery.messageBox which appears to be unused by both core and extensions has
|
||||
been removed.
|
||||
* (bug 34939) made link parsking insensitive ([HttP://])
|
||||
|
||||
=== Bug fixes in 1.20 ===
|
||||
* (bug 30245) Use the correct way to construct a log page title.
|
||||
|
|
@ -227,13 +235,16 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
|
|||
* (bug 27111) Cascading foreign file repos now fetch shared descriptions properly.
|
||||
* EXIF below sea level GPS altitude data is now shown correctly.
|
||||
* (bug 39284) jquery.tablesorter should not consider "."" or "?"" to be a currency.
|
||||
* (bug 39273) "Show changes" should not be incorrectly displayed in the Live Preview state.
|
||||
* Made body-content lang attribute honor the variant language when it is set.
|
||||
|
||||
=== API changes in 1.20 ===
|
||||
* (bug 34316) Add ability to retrieve maximum upload size from MediaWiki API.
|
||||
* (bug 34313) MediaWiki API intro message about "HTML format" should mention
|
||||
the format parameter.
|
||||
* (bug 32384) Allow descending order for list=watchlistraw.
|
||||
* (bug 31883) Limit of bkusers of list=blocks and titles of action=query is not documented in API help.
|
||||
* (bug 31883) Limit of bkusers of list=blocks and titles of action=query is
|
||||
not documented in API help.
|
||||
* (bug 32492) API now allows editing using pageid.
|
||||
* (bug 32497) API now allows changing of protection level using pageid.
|
||||
* (bug 32498) API now allows comparing pages using pageids.
|
||||
|
|
@ -262,8 +273,9 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
|
|||
* Watchlist notification timestamp may be queried by page and may be updated via the API.
|
||||
* (bug 38904) prop=revisions&rvstart=... no longer blows up when continuing.
|
||||
* (bug 39032) ApiQuery generates help in constructor.
|
||||
* (bug 11142) Improve file extension blacklist error reporting in API upload
|
||||
* (bug 39635) PostgreSQL LOCK IN SHARE MODE option is a syntax error
|
||||
* (bug 11142) Improve file extension blacklist error reporting in API upload.
|
||||
* (bug 39635) PostgreSQL LOCK IN SHARE MODE option is a syntax error.
|
||||
* (bug 36329) Accesskey tooltips for Firefox 14 on Mac should use "ctrl-option-" prefix.
|
||||
|
||||
=== Languages updated in 1.20 ===
|
||||
|
||||
|
|
@ -298,6 +310,8 @@ changes to languages because of Bugzilla reports.
|
|||
* Deprecated DatabaseBase functions newFromParams(), newFromType(), set(),
|
||||
quote_ident(), and escapeLike() were removed.
|
||||
* Use of __DIR__ instead of dirname( __FILE__ ).
|
||||
* OutputPage::wrapWikiMsg() no longer supports the 'options' parameter. It was
|
||||
not used and complicated migration to Message class.
|
||||
|
||||
== Compatibility ==
|
||||
|
||||
|
|
|
|||
|
|
@ -402,6 +402,11 @@ is the User object. In the hook, just add your callback to the
|
|||
$tokenFunctions array and return true (returning false makes no sense)
|
||||
$tokenFunctions: array(action => callback)
|
||||
|
||||
'ApiMain::onException': Called by ApiMain::executeActionWithErrorHandling()
|
||||
when an exception is thrown during API action execution.
|
||||
$apiMain: Calling ApiMain instance.
|
||||
$e: Exception object.
|
||||
|
||||
'ApiRsdServiceApis': Add or remove APIs from the RSD services list.
|
||||
Each service should have its own entry in the $apis array and have a
|
||||
unique name, passed as key for the array that represents the service data.
|
||||
|
|
|
|||
|
|
@ -176,6 +176,15 @@ class AuthPlugin {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should MediaWiki store passwords in its local database?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allowSetLocalPassword() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given password in the authentication database.
|
||||
* As a special case, the password may be set to null to request
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ $wgAutoloadLocalClasses = array(
|
|||
'StubObject' => 'includes/StubObject.php',
|
||||
'StubUserLang' => 'includes/StubObject.php',
|
||||
'TablePager' => 'includes/Pager.php',
|
||||
'MWTimestamp' => 'includes/Timestamp.php',
|
||||
'Title' => 'includes/Title.php',
|
||||
'TitleArray' => 'includes/TitleArray.php',
|
||||
'TitleArrayFromResult' => 'includes/TitleArray.php',
|
||||
|
|
|
|||
|
|
@ -143,10 +143,18 @@ class CacheHelper implements ICacheHelper {
|
|||
* Function that gets called when initialization is done.
|
||||
*
|
||||
* @since 1.20
|
||||
* @var function
|
||||
* @var callable
|
||||
*/
|
||||
protected $onInitHandler = false;
|
||||
|
||||
/**
|
||||
* Elements to build a cache key with.
|
||||
*
|
||||
* @since 1.20
|
||||
* @var array
|
||||
*/
|
||||
protected $cacheKey = array();
|
||||
|
||||
/**
|
||||
* Sets if the cache should be enabled or not.
|
||||
*
|
||||
|
|
@ -338,8 +346,13 @@ class CacheHelper implements ICacheHelper {
|
|||
* @since 1.20
|
||||
*
|
||||
* @return string
|
||||
* @throws MWException
|
||||
*/
|
||||
protected function getCacheKeyString() {
|
||||
if ( $this->cacheKey === array() ) {
|
||||
throw new MWException( 'No cache key set, so cannot obtain or save the CacheHelper values.' );
|
||||
}
|
||||
|
||||
return call_user_func_array( 'wfMemcKey', $this->cacheKey );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1027,13 +1027,8 @@ class WikitextContent extends TextContent {
|
|||
return $with; # XXX: copy first?
|
||||
} if ( $section == 'new' ) {
|
||||
# Inserting a new section
|
||||
if ( $sectionTitle ) {
|
||||
$subject = wfMessage( 'newsectionheaderdefaultlevel' )
|
||||
->inContentLanguage()->params( $sectionTitle )->text();
|
||||
$subject .= "\n\n";
|
||||
} else {
|
||||
$subject = '';
|
||||
}
|
||||
$subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' )
|
||||
->rawParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
|
||||
if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) {
|
||||
$text = strlen( trim( $oldtext ) ) > 0
|
||||
? "{$oldtext}\n\n{$subject}{$text}"
|
||||
|
|
|
|||
|
|
@ -632,10 +632,11 @@ abstract class ContentHandler {
|
|||
{
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
250
|
||||
- strlen( wfMsgForContent( 'autoredircomment' ) )
|
||||
- strlen( wfMessage( 'autoredircomment' )->inContentLanguage()->text() )
|
||||
- strlen( $rt->getFullText() ) );
|
||||
|
||||
return wfMsgForContent( 'autoredircomment', $rt->getFullText(), $truncatedtext );
|
||||
return wfMessage( 'autoredircomment', $rt->getFullText() )
|
||||
->rawParams( $truncatedtext )->inContentLanguage()->text();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -645,14 +646,15 @@ abstract class ContentHandler {
|
|||
// the summary.
|
||||
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
200 - strlen( wfMsgForContent( 'autosumm-new' ) ) );
|
||||
200 - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) );
|
||||
|
||||
return wfMsgForContent( 'autosumm-new', $truncatedtext );
|
||||
return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
|
||||
->inContentLanguage()->text();
|
||||
}
|
||||
|
||||
// Blanking auto-summaries
|
||||
if ( !empty( $oldContent ) && $oldContent->getSize() > 0 && $newContent->getSize() == 0 ) {
|
||||
return wfMsgForContent( 'autosumm-blank' );
|
||||
return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
|
||||
} elseif ( !empty( $oldContent )
|
||||
&& $oldContent->getSize() > 10 * $newContent->getSize()
|
||||
&& $newContent->getSize() < 500 )
|
||||
|
|
@ -660,14 +662,14 @@ abstract class ContentHandler {
|
|||
// Removing more than 90% of the article
|
||||
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
200 - strlen( wfMsgForContent( 'autosumm-replace' ) ) );
|
||||
200 - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) );
|
||||
|
||||
return wfMsgForContent( 'autosumm-replace', $truncatedtext );
|
||||
return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
|
||||
->inContentLanguage()->text();
|
||||
}
|
||||
|
||||
// If we reach this point, there's no applicable auto-summary for our
|
||||
// case, so our auto-summary is empty.
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
@ -749,12 +751,16 @@ abstract class ContentHandler {
|
|||
if ( $blank ) {
|
||||
// The current revision is blank and the one before is also
|
||||
// blank. It's just not our lucky day
|
||||
$reason = wfMsgForContent( 'exbeforeblank', '$1' );
|
||||
$reason = wfMessage( 'exbeforeblank', '$1' )->inContentLanguage()->text();
|
||||
} else {
|
||||
if ( $onlyAuthor ) {
|
||||
$reason = wfMsgForContent( 'excontentauthor', '$1', $onlyAuthor );
|
||||
$reason = wfMessage(
|
||||
'excontentauthor',
|
||||
'$1',
|
||||
$onlyAuthor
|
||||
)->inContentLanguage()->text();
|
||||
} else {
|
||||
$reason = wfMsgForContent( 'excontent', '$1' );
|
||||
$reason = wfMessage( 'excontent', '$1' )->inContentLanguage()->text();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -399,7 +399,9 @@ $wgImgAuthPublicTest = true;
|
|||
*
|
||||
* - articleUrl Equivalent to $wgArticlePath, e.g. http://en.wikipedia.org/wiki/$1
|
||||
* - fetchDescription Fetch the text of the remote file description page. Equivalent to
|
||||
* $wgFetchCommonsDescriptions.
|
||||
* $wgFetchCommonsDescriptions.
|
||||
* - abbrvThreshold File names over this size will use the short form of thumbnail names.
|
||||
* Short thumbnail names only have the width, parameters, and the extension.
|
||||
*
|
||||
* ForeignDBRepo:
|
||||
* - dbType, dbServer, dbUser, dbPassword, dbName, dbFlags
|
||||
|
|
@ -509,7 +511,7 @@ $wgSharedUploadDBprefix = '';
|
|||
$wgCacheSharedUploads = true;
|
||||
|
||||
/**
|
||||
* Allow for upload to be copied from an URL. Requires Special:Upload?source=web
|
||||
* Allow for upload to be copied from an URL.
|
||||
* The timeout for copy uploads is set by $wgHTTPTimeout.
|
||||
* You have to assign the user right 'upload_by_url' to a user group, to use this.
|
||||
*/
|
||||
|
|
@ -523,6 +525,8 @@ $wgAllowAsyncCopyUploads = false;
|
|||
|
||||
/**
|
||||
* A list of domains copy uploads can come from
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
$wgCopyUploadsDomains = array();
|
||||
|
||||
|
|
@ -1457,7 +1461,7 @@ $wgDBerrorLog = false;
|
|||
|
||||
/**
|
||||
* Timezone to use in the error log.
|
||||
* Defaults to the wiki timezone ($wgLocalTimezone).
|
||||
* Defaults to the wiki timezone ($wgLocaltimezone).
|
||||
*
|
||||
* A list of useable timezones can found at:
|
||||
* http://php.net/manual/en/timezones.php
|
||||
|
|
@ -1704,6 +1708,8 @@ $wgSessionCacheType = CACHE_ANYTHING;
|
|||
* which are used when parsing certain text and interface messages.
|
||||
*
|
||||
* For available types see $wgMainCacheType.
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
$wgLanguageConverterCacheType = CACHE_ANYTHING;
|
||||
|
||||
|
|
@ -2054,6 +2060,8 @@ $wgMaxSquidPurgeTitles = 400;
|
|||
* );
|
||||
* @endcode
|
||||
*
|
||||
* @since 1.20
|
||||
*
|
||||
* @see $wgHTCPMulticastTTL
|
||||
*/
|
||||
$wgHTCPMulticastRouting = array();
|
||||
|
|
@ -2638,6 +2646,18 @@ $wgBreakFrames = false;
|
|||
*/
|
||||
$wgEditPageFrameOptions = 'DENY';
|
||||
|
||||
/**
|
||||
* Disallow framing of API pages directly, by setting the X-Frame-Options
|
||||
* header. Since the API returns CSRF tokens, allowing the results to be
|
||||
* framed can compromise your user's account security.
|
||||
* Options are:
|
||||
* - 'DENY': Do not allow framing. This is recommended for most wikis.
|
||||
* - 'SAMEORIGIN': Allow framing by pages on the same domain.
|
||||
* - false: Allow all framing.
|
||||
*/
|
||||
|
||||
$wgApiFrameOptions = 'DENY';
|
||||
|
||||
/**
|
||||
* Disable output compression (enabled by default if zlib is available)
|
||||
*/
|
||||
|
|
@ -2748,6 +2768,8 @@ $wgSend404Code = true;
|
|||
* The $wgShowRollbackEditCount variable is used to show how many edits will be
|
||||
* rollback. The numeric value of the varible are the limit up to are counted.
|
||||
* If the value is false or 0, the edits are not counted.
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
$wgShowRollbackEditCount = 10;
|
||||
|
||||
|
|
@ -4385,6 +4407,8 @@ $wgDebugComments = false;
|
|||
|
||||
/**
|
||||
* Extensive database transaction state debugging
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
$wgDebugDBTransactions = false;
|
||||
|
||||
|
|
@ -4902,6 +4926,8 @@ $wgUpgradeKey = false;
|
|||
* The value is the replacement for the key (it can contain $1, etc.)
|
||||
* %h will be replaced by the short SHA-1 (7 first chars) and %H by the
|
||||
* full SHA-1 of the HEAD revision.
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
$wgGitRepositoryViewers = array(
|
||||
'https://gerrit.wikimedia.org/r/p/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
|
||||
|
|
@ -5774,11 +5800,6 @@ $wgActions = array(
|
|||
*/
|
||||
$wgDisabledActions = array();
|
||||
|
||||
/**
|
||||
* Allow the "info" action, very inefficient at the moment
|
||||
*/
|
||||
$wgAllowPageInfo = false;
|
||||
|
||||
/** @} */ # end actions }
|
||||
|
||||
/*************************************************************************//**
|
||||
|
|
@ -6231,6 +6252,8 @@ $wgContentHandlerUseDB = true;
|
|||
|
||||
/**
|
||||
* Whether the user must enter their password to change their e-mail address
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
$wgRequirePasswordforEmailChange = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -2052,10 +2052,6 @@ class EditPage {
|
|||
|
||||
$wgOut->addHTML( $this->editFormTextAfterContent );
|
||||
|
||||
$wgOut->addWikiText( $this->getCopywarn() );
|
||||
|
||||
$wgOut->addHTML( $this->editFormTextAfterWarn );
|
||||
|
||||
$this->showStandardInputs();
|
||||
|
||||
$this->showFormAfterText();
|
||||
|
|
@ -2666,6 +2662,11 @@ HTML
|
|||
$checkboxes = $this->getCheckboxes( $tabindex,
|
||||
array( 'minor' => $this->minoredit, 'watch' => $this->watchthis ) );
|
||||
$wgOut->addHTML( "<div class='editCheckboxes'>" . implode( $checkboxes, "\n" ) . "</div>\n" );
|
||||
|
||||
// Show copyright warning.
|
||||
$wgOut->addWikiText( $this->getCopywarn() );
|
||||
$wgOut->addHTML( $this->editFormTextAfterWarn );
|
||||
|
||||
$wgOut->addHTML( "<div class='editButtons'>\n" );
|
||||
$wgOut->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
|
||||
|
||||
|
|
@ -2677,7 +2678,8 @@ HTML
|
|||
$edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' .
|
||||
wfMessage( 'edithelp' )->escaped() . '</a> ' .
|
||||
wfMessage( 'newwindow' )->escaped();
|
||||
$wgOut->addHTML( " <span class='editHelp'>{$cancel}{$edithelp}</span>\n" );
|
||||
$wgOut->addHTML( " <span class='cancelLink'>{$cancel}</span>\n" );
|
||||
$wgOut->addHTML( " <span class='editHelp'>{$edithelp}</span>\n" );
|
||||
$wgOut->addHTML( "</div><!-- editButtons -->\n</div><!-- editOptions -->\n" );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -730,8 +730,57 @@ function wfUrlProtocolsWithoutProtRel() {
|
|||
* @return Array: bits of the URL in an associative array, per PHP docs
|
||||
*/
|
||||
function wfParseUrl( $url ) {
|
||||
$obj = new Uri( $url );
|
||||
return $obj->getComponents();
|
||||
global $wgUrlProtocols; // Allow all protocols defined in DefaultSettings/LocalSettings.php
|
||||
|
||||
// Protocol-relative URLs are handled really badly by parse_url(). It's so bad that the easiest
|
||||
// way to handle them is to just prepend 'http:' and strip the protocol out later
|
||||
$wasRelative = substr( $url, 0, 2 ) == '//';
|
||||
if ( $wasRelative ) {
|
||||
$url = "http:$url";
|
||||
}
|
||||
wfSuppressWarnings();
|
||||
$bits = parse_url( $url );
|
||||
wfRestoreWarnings();
|
||||
// parse_url() returns an array without scheme for some invalid URLs, e.g.
|
||||
// parse_url("%0Ahttp://example.com") == array( 'host' => '%0Ahttp', 'path' => 'example.com' )
|
||||
if ( !$bits || !isset( $bits['scheme'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse_url() incorrectly handles schemes case-sensitively. Convert it to lowercase.
|
||||
$bits['scheme'] = strtolower( $bits['scheme'] );
|
||||
|
||||
// most of the protocols are followed by ://, but mailto: and sometimes news: not, check for it
|
||||
if ( in_array( $bits['scheme'] . '://', $wgUrlProtocols ) ) {
|
||||
$bits['delimiter'] = '://';
|
||||
} elseif ( in_array( $bits['scheme'] . ':', $wgUrlProtocols ) ) {
|
||||
$bits['delimiter'] = ':';
|
||||
// parse_url detects for news: and mailto: the host part of an url as path
|
||||
// We have to correct this wrong detection
|
||||
if ( isset( $bits['path'] ) ) {
|
||||
$bits['host'] = $bits['path'];
|
||||
$bits['path'] = '';
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Provide an empty host for eg. file:/// urls (see bug 28627) */
|
||||
if ( !isset( $bits['host'] ) ) {
|
||||
$bits['host'] = '';
|
||||
|
||||
/* parse_url loses the third / for file:///c:/ urls (but not on variants) */
|
||||
if ( substr( $bits['path'], 0, 1 ) !== '/' ) {
|
||||
$bits['path'] = '/' . $bits['path'];
|
||||
}
|
||||
}
|
||||
|
||||
// If the URL was protocol-relative, fix scheme and delimiter
|
||||
if ( $wasRelative ) {
|
||||
$bits['scheme'] = '';
|
||||
$bits['delimiter'] = '//';
|
||||
}
|
||||
return $bits;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1795,16 +1844,15 @@ function wfBacktrace() {
|
|||
* wfGetCaller( 3 ) is the parent of that.
|
||||
*
|
||||
* @param $level Int
|
||||
* @return Bool|string
|
||||
* @return string
|
||||
*/
|
||||
function wfGetCaller( $level = 2 ) {
|
||||
$backtrace = wfDebugBacktrace( $level + 1 );
|
||||
if ( isset( $backtrace[$level] ) ) {
|
||||
return wfFormatStackFrame( $backtrace[$level] );
|
||||
} else {
|
||||
$caller = 'unknown';
|
||||
return 'unknown';
|
||||
}
|
||||
return $caller;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1828,7 +1876,7 @@ function wfGetAllCallers( $limit = 3 ) {
|
|||
* Return a string representation of frame
|
||||
*
|
||||
* @param $frame Array
|
||||
* @return Bool
|
||||
* @return string
|
||||
*/
|
||||
function wfFormatStackFrame( $frame ) {
|
||||
return isset( $frame['class'] ) ?
|
||||
|
|
@ -2318,6 +2366,7 @@ define( 'TS_ISO_8601_BASIC', 9 );
|
|||
/**
|
||||
* Get a timestamp string in one of various formats
|
||||
*
|
||||
* @deprecated
|
||||
* @param $outputtype Mixed: A timestamp in one of the supported formats, the
|
||||
* function will autodetect which format is supplied and act
|
||||
* accordingly.
|
||||
|
|
@ -2325,118 +2374,8 @@ define( 'TS_ISO_8601_BASIC', 9 );
|
|||
* @return Mixed: String / false The same date in the format specified in $outputtype or false
|
||||
*/
|
||||
function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
|
||||
$uts = 0;
|
||||
$da = array();
|
||||
$strtime = '';
|
||||
|
||||
if ( !$ts ) { // We want to catch 0, '', null... but not date strings starting with a letter.
|
||||
$uts = time();
|
||||
$strtime = "@$uts";
|
||||
} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
|
||||
# TS_DB
|
||||
} elseif ( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
|
||||
# TS_EXIF
|
||||
} elseif ( preg_match( '/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D', $ts, $da ) ) {
|
||||
# TS_MW
|
||||
} elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) {
|
||||
# TS_UNIX
|
||||
$uts = $ts;
|
||||
$strtime = "@$ts"; // http://php.net/manual/en/datetime.formats.compound.php
|
||||
} elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
|
||||
# TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
|
||||
$strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
|
||||
str_replace( '+00:00', 'UTC', $ts ) );
|
||||
} elseif ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
|
||||
# TS_ISO_8601
|
||||
} elseif ( preg_match( '/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
|
||||
#TS_ISO_8601_BASIC
|
||||
} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d*[\+\- ](\d\d)$/', $ts, $da ) ) {
|
||||
# TS_POSTGRES
|
||||
} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/', $ts, $da ) ) {
|
||||
# TS_POSTGRES
|
||||
} elseif (preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.\d\d\d$/', $ts, $da ) ) {
|
||||
# TS_DB2
|
||||
} elseif ( preg_match( '/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' . # Day of week
|
||||
'\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' . # dd Mon yyyy
|
||||
'[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S', $ts ) ) { # hh:mm:ss
|
||||
# TS_RFC2822, accepting a trailing comment. See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html / r77171
|
||||
# The regex is a superset of rfc2822 for readability
|
||||
$strtime = strtok( $ts, ';' );
|
||||
} elseif ( preg_match( '/^[A-Z][a-z]{5,8}, \d\d-[A-Z][a-z]{2}-\d{2} \d\d:\d\d:\d\d/', $ts ) ) {
|
||||
# TS_RFC850
|
||||
$strtime = $ts;
|
||||
} elseif ( preg_match( '/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d\d:\d\d:\d\d \d{4}/', $ts ) ) {
|
||||
# asctime
|
||||
$strtime = $ts;
|
||||
} else {
|
||||
# Bogus value...
|
||||
wfDebug("wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static $formats = array(
|
||||
TS_UNIX => 'U',
|
||||
TS_MW => 'YmdHis',
|
||||
TS_DB => 'Y-m-d H:i:s',
|
||||
TS_ISO_8601 => 'Y-m-d\TH:i:s\Z',
|
||||
TS_ISO_8601_BASIC => 'Ymd\THis\Z',
|
||||
TS_EXIF => 'Y:m:d H:i:s', // This shouldn't ever be used, but is included for completeness
|
||||
TS_RFC2822 => 'D, d M Y H:i:s',
|
||||
TS_ORACLE => 'd-m-Y H:i:s.000000', // Was 'd-M-y h.i.s A' . ' +00:00' before r51500
|
||||
TS_POSTGRES => 'Y-m-d H:i:s',
|
||||
TS_DB2 => 'Y-m-d H:i:s',
|
||||
);
|
||||
|
||||
if ( !isset( $formats[$outputtype] ) ) {
|
||||
throw new MWException( 'wfTimestamp() called with illegal output type.' );
|
||||
}
|
||||
|
||||
if ( function_exists( "date_create" ) ) {
|
||||
if ( count( $da ) ) {
|
||||
$ds = sprintf("%04d-%02d-%02dT%02d:%02d:%02d.00+00:00",
|
||||
(int)$da[1], (int)$da[2], (int)$da[3],
|
||||
(int)$da[4], (int)$da[5], (int)$da[6]);
|
||||
|
||||
$d = date_create( $ds, new DateTimeZone( 'GMT' ) );
|
||||
} elseif ( $strtime ) {
|
||||
$d = date_create( $strtime, new DateTimeZone( 'GMT' ) );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !$d ) {
|
||||
wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
$output = $d->format( $formats[$outputtype] );
|
||||
} else {
|
||||
if ( count( $da ) ) {
|
||||
// Warning! gmmktime() acts oddly if the month or day is set to 0
|
||||
// We may want to handle that explicitly at some point
|
||||
$uts = gmmktime( (int)$da[4], (int)$da[5], (int)$da[6],
|
||||
(int)$da[2], (int)$da[3], (int)$da[1] );
|
||||
} elseif ( $strtime ) {
|
||||
$uts = strtotime( $strtime );
|
||||
}
|
||||
|
||||
if ( $uts === false ) {
|
||||
wfDebug("wfTimestamp() can't parse the timestamp (non 32-bit time? Update php): $outputtype; $ts\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( TS_UNIX == $outputtype ) {
|
||||
return $uts;
|
||||
}
|
||||
$output = gmdate( $formats[$outputtype], $uts );
|
||||
}
|
||||
|
||||
if ( ( $outputtype == TS_RFC2822 ) || ( $outputtype == TS_POSTGRES ) ) {
|
||||
$output .= ' GMT';
|
||||
}
|
||||
|
||||
return $output;
|
||||
$timestamp = new MWTimestamp( $ts );
|
||||
return $timestamp->getTimestamp( $outputtype );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -325,7 +325,11 @@ class Html {
|
|||
|
||||
foreach ( $attribs as $attrib => $value ) {
|
||||
$lcattrib = strtolower( $attrib );
|
||||
$value = strval( $value );
|
||||
if( is_array( $value ) ) {
|
||||
$value = implode( ' ', $value );
|
||||
} else {
|
||||
$value = strval( $value );
|
||||
}
|
||||
|
||||
# Simple checks using $attribDefaults
|
||||
if ( isset( $attribDefaults[$element][$lcattrib] ) &&
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class ImagePage extends Article {
|
|||
if ( $this->mPage->getID() ) {
|
||||
# NS_FILE is in the user language, but this section (the actual wikitext)
|
||||
# should be in page content language
|
||||
$pageLang = $this->getTitle()->getPageLanguage();
|
||||
$pageLang = $this->getTitle()->getPageViewLanguage();
|
||||
$out->addHTML( Xml::openElement( 'div', array( 'id' => 'mw-imagepage-content',
|
||||
'lang' => $pageLang->getHtmlCode(), 'dir' => $pageLang->getDir(),
|
||||
'class' => 'mw-content-'.$pageLang->getDir() ) ) );
|
||||
|
|
|
|||
|
|
@ -865,31 +865,31 @@ class Linker {
|
|||
* Make a "broken" link to an image
|
||||
*
|
||||
* @param $title Title object
|
||||
* @param $html String: link label in htmlescaped text form
|
||||
* @param $label String: link label (plain text)
|
||||
* @param $query String: query string
|
||||
* @param $trail String: link trail (HTML fragment)
|
||||
* @param $prefix String: link prefix (HTML fragment)
|
||||
* @param $unused1 Unused parameter kept for b/c
|
||||
* @param $unused2 Unused parameter kept for b/c
|
||||
* @param $time Boolean: a file of a certain timestamp was requested
|
||||
* @return String
|
||||
*/
|
||||
public static function makeBrokenImageLinkObj( $title, $html = '', $query = '', $trail = '', $prefix = '', $time = false ) {
|
||||
public static function makeBrokenImageLinkObj( $title, $label = '', $query = '', $unused1 = '', $unused2 = '', $time = false ) {
|
||||
global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
|
||||
if ( ! $title instanceof Title ) {
|
||||
return "<!-- ERROR -->{$prefix}{$html}{$trail}";
|
||||
return "<!-- ERROR -->" . htmlspecialchars( $label );
|
||||
}
|
||||
wfProfileIn( __METHOD__ );
|
||||
if ( $label == '' ) {
|
||||
$label = $title->getPrefixedText();
|
||||
}
|
||||
$encLabel = htmlspecialchars( $label );
|
||||
$currentExists = $time ? ( wfFindFile( $title ) != false ) : false;
|
||||
|
||||
list( $inside, $trail ) = self::splitTrail( $trail );
|
||||
if ( $html == '' )
|
||||
$html = htmlspecialchars( $title->getPrefixedText() );
|
||||
|
||||
if ( ( $wgUploadMissingFileUrl || $wgUploadNavigationUrl || $wgEnableUploads ) && !$currentExists ) {
|
||||
$redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect( $title );
|
||||
|
||||
if ( $redir ) {
|
||||
wfProfileOut( __METHOD__ );
|
||||
return self::linkKnown( $title, "$prefix$html$inside", array(), wfCgiToArray( $query ) ) . $trail;
|
||||
return self::linkKnown( $title, $encLabel, array(), wfCgiToArray( $query ) );
|
||||
}
|
||||
|
||||
$href = self::getUploadUrl( $title, $query );
|
||||
|
|
@ -897,10 +897,10 @@ class Linker {
|
|||
wfProfileOut( __METHOD__ );
|
||||
return '<a href="' . htmlspecialchars( $href ) . '" class="new" title="' .
|
||||
htmlspecialchars( $title->getPrefixedText(), ENT_QUOTES ) . '">' .
|
||||
"$prefix$html$inside</a>$trail";
|
||||
$encLabel . '</a>';
|
||||
} else {
|
||||
wfProfileOut( __METHOD__ );
|
||||
return self::linkKnown( $title, "$prefix$html$inside", array(), wfCgiToArray( $query ) ) . $trail;
|
||||
return self::linkKnown( $title, $encLabel, array(), wfCgiToArray( $query ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class LinksUpdate extends SqlDataUpdate {
|
|||
* @param $recursive Boolean: queue jobs for recursive updates?
|
||||
*/
|
||||
function __construct( $title, $parserOutput, $recursive = true ) {
|
||||
parent::__construct( );
|
||||
parent::__construct( false ); // no implicit transaction
|
||||
|
||||
if ( !( $title instanceof Title ) ) {
|
||||
throw new MWException( "The calling convention to LinksUpdate::LinksUpdate() has changed. " .
|
||||
|
|
@ -824,7 +824,7 @@ class LinksDeletionUpdate extends SqlDataUpdate {
|
|||
* @param $page WikiPage Page we are updating
|
||||
*/
|
||||
function __construct( Title $title ) {
|
||||
parent::__construct( );
|
||||
parent::__construct( false ); // no implicit transaction
|
||||
|
||||
$this->mTitle = $title;
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class LocalisationCache {
|
|||
'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
|
||||
'defaultDateFormat', 'extraUserToggles', 'specialPageAliases',
|
||||
'imageFiles', 'preloadedMessages', 'namespaceGenderAliases',
|
||||
'digitGroupingPattern', 'pluralRules'
|
||||
'digitGroupingPattern', 'pluralRules', 'compiledPluralRules',
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -118,7 +118,7 @@ class LocalisationCache {
|
|||
* by a fallback sequence.
|
||||
*/
|
||||
static public $mergeableMapKeys = array( 'messages', 'namespaceNames',
|
||||
'dateFormats', 'imageFiles', 'preloadedMessages', 'pluralRules'
|
||||
'dateFormats', 'imageFiles', 'preloadedMessages'
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
@ -498,6 +498,9 @@ class LocalisationCache {
|
|||
*/
|
||||
public function getCompiledPluralRules( $code ) {
|
||||
$rules = $this->getPluralRules( $code );
|
||||
if ( $rules === null ) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
$compiledRules = CLDRPluralRuleEvaluator::compile( $rules );
|
||||
} catch( CLDRPluralRuleError $e ) {
|
||||
|
|
@ -524,17 +527,18 @@ class LocalisationCache {
|
|||
}
|
||||
}
|
||||
if ( !isset( $this->pluralRules[$code] ) ) {
|
||||
return array();
|
||||
return null;
|
||||
} else {
|
||||
return $this->pluralRules[$code];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load a plural XML file with the given filename, compile the relevant
|
||||
* rules, and save the compiled rules in a process-local cache.
|
||||
*/
|
||||
private function loadPluralFile( $fileName ) {
|
||||
protected function loadPluralFile( $fileName ) {
|
||||
$doc = new DOMDocument;
|
||||
$doc->load( $fileName );
|
||||
$rulesets = $doc->getElementsByTagName( "pluralRules" );
|
||||
|
|
@ -551,6 +555,30 @@ class LocalisationCache {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the data from the source files for a given language, and register
|
||||
* the relevant dependencies in the $deps array. If the localisation
|
||||
* exists, the data array is returned, otherwise false is returned.
|
||||
*/
|
||||
protected function readSourceFilesAndRegisterDeps( $code, &$deps ) {
|
||||
$fileName = Language::getMessagesFileName( $code );
|
||||
if ( !file_exists( $fileName ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$deps[] = new FileDependency( $fileName );
|
||||
$data = $this->readPHPFile( $fileName, 'core' );
|
||||
|
||||
# Load CLDR plural rules for JavaScript
|
||||
$data['pluralRules'] = $this->getPluralRules( $code );
|
||||
# And for PHP
|
||||
$data['compiledPluralRules'] = $this->getCompiledPluralRules( $code );
|
||||
|
||||
$deps['plurals'] = new FileDependency( __DIR__ . "/../languages/data/plurals.xml" );
|
||||
$deps['plurals-mw'] = new FileDependency( __DIR__ . "/../languages/data/plurals-mediawiki.xml" );
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two localisation values, a primary and a fallback, overwriting the
|
||||
* primary value in place.
|
||||
|
|
@ -649,13 +677,11 @@ class LocalisationCache {
|
|||
$deps = array();
|
||||
|
||||
# Load the primary localisation from the source file
|
||||
$fileName = Language::getMessagesFileName( $code );
|
||||
if ( !file_exists( $fileName ) ) {
|
||||
$data = $this->readSourceFilesAndRegisterDeps( $code, $deps );
|
||||
if ( $data === false ) {
|
||||
wfDebug( __METHOD__ . ": no localisation file for $code, using fallback to en\n" );
|
||||
$coreData['fallback'] = 'en';
|
||||
} else {
|
||||
$deps[] = new FileDependency( $fileName );
|
||||
$data = $this->readPHPFile( $fileName, 'core' );
|
||||
wfDebug( __METHOD__ . ": got localisation for $code from source\n" );
|
||||
|
||||
# Merge primary localisation
|
||||
|
|
@ -684,15 +710,11 @@ class LocalisationCache {
|
|||
foreach ( $coreData['fallbackSequence'] as $fbCode ) {
|
||||
# Load the secondary localisation from the source file to
|
||||
# avoid infinite cycles on cyclic fallbacks
|
||||
$fbFilename = Language::getMessagesFileName( $fbCode );
|
||||
|
||||
if ( !file_exists( $fbFilename ) ) {
|
||||
$fbData = $this->readSourceFilesAndRegisterDeps( $fbCode, $deps );
|
||||
if ( $fbData === false ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$deps[] = new FileDependency( $fbFilename );
|
||||
$fbData = $this->readPHPFile( $fbFilename, 'core' );
|
||||
|
||||
foreach ( self::$allKeys as $key ) {
|
||||
if ( !isset( $fbData[$key] ) ) {
|
||||
continue;
|
||||
|
|
@ -749,15 +771,19 @@ class LocalisationCache {
|
|||
# Decouple the reference to prevent accidental damage
|
||||
unset( $page );
|
||||
|
||||
# If there were no plural rules, return an empty array
|
||||
if ( $allData['pluralRules'] === null ) {
|
||||
$allData['pluralRules'] = array();
|
||||
}
|
||||
if ( $allData['compiledPluralRules'] === null ) {
|
||||
$allData['compiledPluralRules'] = array();
|
||||
}
|
||||
|
||||
# Set the list keys
|
||||
$allData['list'] = array();
|
||||
foreach ( self::$splitKeys as $key ) {
|
||||
$allData['list'][$key] = array_keys( $allData[$key] );
|
||||
}
|
||||
# Load CLDR plural rules for JavaScript
|
||||
$allData['pluralRules'] = $this->getPluralRules( $code );
|
||||
# And for PHP
|
||||
$allData['compiledPluralRules'] = $this->getCompiledPluralRules( $code );
|
||||
# Run hooks
|
||||
wfRunHooks( 'LocalisationCacheRecache', array( $this, $code, &$allData ) );
|
||||
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ class MessageBlobStore {
|
|||
*/
|
||||
private static function reencodeBlob( $blob, $key, $lang ) {
|
||||
$decoded = FormatJson::decode( $blob, true );
|
||||
$decoded[$key] = wfMessage( $key )->inLanguage( $lang )->text();
|
||||
$decoded[$key] = wfMessage( $key )->inLanguage( $lang )->plain();
|
||||
|
||||
return FormatJson::encode( (object)$decoded );
|
||||
}
|
||||
|
|
@ -353,7 +353,7 @@ class MessageBlobStore {
|
|||
$messages = array();
|
||||
|
||||
foreach ( $module->getMessages() as $key ) {
|
||||
$messages[$key] = wfMessage( $key )->inLanguage( $lang )->text();
|
||||
$messages[$key] = wfMessage( $key )->inLanguage( $lang )->plain();
|
||||
}
|
||||
|
||||
return FormatJson::encode( (object)$messages );
|
||||
|
|
|
|||
|
|
@ -3541,9 +3541,6 @@ $templates
|
|||
* message names, or arrays, in which case the first element is the message name,
|
||||
* and subsequent elements are the parameters to that message.
|
||||
*
|
||||
* The special named parameter 'options' in a message specification array is passed
|
||||
* through to the $options parameter of wfMsgExt().
|
||||
*
|
||||
* Don't use this for messages that are not in users interface language.
|
||||
*
|
||||
* For example:
|
||||
|
|
@ -3569,14 +3566,17 @@ $templates
|
|||
$args = $spec;
|
||||
$name = array_shift( $args );
|
||||
if ( isset( $args['options'] ) ) {
|
||||
$options = $args['options'];
|
||||
unset( $args['options'] );
|
||||
wfDeprecated(
|
||||
'Adding "options" to ' . __METHOD__ . ' is no longer supported',
|
||||
'1.20'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$args = array();
|
||||
$name = $spec;
|
||||
}
|
||||
$s = str_replace( '$' . ( $n + 1 ), wfMsgExt( $name, $options, $args ), $s );
|
||||
$s = str_replace( '$' . ( $n + 1 ), $this->msg( $name, $args )->plain(), $s );
|
||||
}
|
||||
$this->addWikiText( $s );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,7 @@ class Sanitizer {
|
|||
|
||||
# Stupid hack
|
||||
$encValue = preg_replace_callback(
|
||||
'/(' . wfUrlProtocols() . ')/',
|
||||
'/((?i)' . wfUrlProtocols() . ')/',
|
||||
array( 'Sanitizer', 'armorLinksCallback' ),
|
||||
$encValue );
|
||||
return $encValue;
|
||||
|
|
|
|||
|
|
@ -332,9 +332,6 @@ if ( !$wgEnotifMinorEdits ) {
|
|||
foreach( $wgDisabledActions as $action ){
|
||||
$wgActions[$action] = false;
|
||||
}
|
||||
if( !$wgAllowPageInfo ){
|
||||
$wgActions['info'] = false;
|
||||
}
|
||||
|
||||
if ( !$wgHtml5Version && $wgHtml5 && $wgAllowRdfaAttributes ) {
|
||||
# see http://www.w3.org/TR/rdfa-in-html/#document-conformance
|
||||
|
|
|
|||
|
|
@ -1063,7 +1063,7 @@ abstract class Skin extends ContextSource {
|
|||
* @return String URL
|
||||
*/
|
||||
static function makeInternalOrExternalUrl( $name ) {
|
||||
if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $name ) ) {
|
||||
if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $name ) ) {
|
||||
return $name;
|
||||
} else {
|
||||
return self::makeUrl( $name );
|
||||
|
|
@ -1227,7 +1227,7 @@ abstract class Skin extends ContextSource {
|
|||
$text = $line[1];
|
||||
}
|
||||
|
||||
if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $link ) ) {
|
||||
if ( preg_match( '/^(?i:' . wfUrlProtocols() . ')/', $link ) ) {
|
||||
$href = $link;
|
||||
|
||||
// Parser::getExternalLinkAttribs won't work here because of the Namespace things
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ class SkinTemplate extends Skin {
|
|||
if ( !in_array( $title->getNamespace(), array( NS_SPECIAL, NS_FILE ) ) &&
|
||||
in_array( $request->getVal( 'action', 'view' ), array( 'view', 'historysubmit' ) ) &&
|
||||
( $title->exists() || $title->getNamespace() == NS_MEDIAWIKI ) ) {
|
||||
$pageLang = $title->getPageLanguage();
|
||||
$pageLang = $title->getPageViewLanguage();
|
||||
$realBodyAttribs['lang'] = $pageLang->getHtmlCode();
|
||||
$realBodyAttribs['dir'] = $pageLang->getDir();
|
||||
$realBodyAttribs['class'] = 'mw-content-'.$pageLang->getDir();
|
||||
|
|
|
|||
|
|
@ -36,11 +36,16 @@ abstract class SqlDataUpdate extends DataUpdate {
|
|||
protected $mOptions; //!< SELECT options to be used (array)
|
||||
|
||||
private $mHasTransaction; //!< bool whether a transaction is open on this object (internal use only!)
|
||||
protected $mUseTransaction; //!< bool whether this update should be wrapped in a transaction
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
**/
|
||||
public function __construct( ) {
|
||||
*
|
||||
* @param bool $withTransaction whether this update should be wrapped in a transaction (default: true).
|
||||
* A transaction is only started if no transaction is already in progress,
|
||||
* see beginTransaction() for details.
|
||||
**/
|
||||
public function __construct( $withTransaction = true ) {
|
||||
global $wgAntiLockFlags;
|
||||
|
||||
parent::__construct( );
|
||||
|
|
@ -51,17 +56,23 @@ abstract class SqlDataUpdate extends DataUpdate {
|
|||
$this->mOptions = array( 'FOR UPDATE' );
|
||||
}
|
||||
|
||||
// @todo: get connection only when it's needed? make sure that doesn't break anything, especially transactions!
|
||||
$this->mDb = wfGetDB( DB_MASTER );
|
||||
|
||||
$this->mWithTransaction = $withTransaction;
|
||||
$this->mHasTransaction = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a database transaction.
|
||||
* Begin a database transaction, if $withTransaction was given as true in the constructor for this SqlDataUpdate.
|
||||
*
|
||||
* Because nested transactions are not supportred by the Database class, this implementation
|
||||
* checkes Database::trxLevel() and only opens a transaction if none is yet active.
|
||||
* Because nested transactions are not supported by the Database class, this implementation
|
||||
* checks Database::trxLevel() and only opens a transaction if none is already active.
|
||||
*/
|
||||
public function beginTransaction() {
|
||||
$this->mDb = wfGetDB( DB_MASTER );
|
||||
if ( !$this->mWithTransaction ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: nested transactions are not supported, only start a transaction if none is open
|
||||
if ( $this->mDb->trxLevel() === 0 ) {
|
||||
|
|
@ -76,6 +87,7 @@ abstract class SqlDataUpdate extends DataUpdate {
|
|||
public function commitTransaction() {
|
||||
if ( $this->mHasTransaction ) {
|
||||
$this->mDb->commit( get_class( $this ) . '::commitTransaction' );
|
||||
$this->mHasTransaction = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,6 +97,7 @@ abstract class SqlDataUpdate extends DataUpdate {
|
|||
public function abortTransaction() {
|
||||
if ( $this->mHasTransaction ) { //XXX: actually... maybe always?
|
||||
$this->mDb->rollback( get_class( $this ) . '::abortTransaction' );
|
||||
$this->mHasTransaction = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,8 +79,6 @@ class StreamFile {
|
|||
public static function prepareForStream(
|
||||
$path, $info, $headers = array(), $sendErrors = true
|
||||
) {
|
||||
global $wgLanguageCode;
|
||||
|
||||
if ( !is_array( $info ) ) {
|
||||
if ( $sendErrors ) {
|
||||
header( 'HTTP/1.0 404 Not Found' );
|
||||
|
|
@ -121,9 +119,6 @@ class StreamFile {
|
|||
return false;
|
||||
}
|
||||
|
||||
header( "Content-Disposition: inline;filename*=utf-8'$wgLanguageCode'" .
|
||||
urlencode( basename( $path ) ) );
|
||||
|
||||
// Send additional headers
|
||||
foreach ( $headers as $header ) {
|
||||
header( $header );
|
||||
|
|
|
|||
225
includes/Timestamp.php
Normal file
225
includes/Timestamp.php
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
<?php
|
||||
/**
|
||||
* Creation and parsing of MW-style timestamps.
|
||||
*
|
||||
* 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
|
||||
* @since 1.20
|
||||
* @author Tyler Romeo, 2012
|
||||
*/
|
||||
|
||||
/**
|
||||
* Library for creating and parsing MW-style timestamps. Based on the JS
|
||||
* library that does the same thing.
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
class MWTimestamp {
|
||||
/**
|
||||
* Standard gmdate() formats for the different timestamp types.
|
||||
*/
|
||||
private static $formats = array(
|
||||
TS_UNIX => 'U',
|
||||
TS_MW => 'YmdHis',
|
||||
TS_DB => 'Y-m-d H:i:s',
|
||||
TS_ISO_8601 => 'Y-m-d\TH:i:s\Z',
|
||||
TS_ISO_8601_BASIC => 'Ymd\THis\Z',
|
||||
TS_EXIF => 'Y:m:d H:i:s', // This shouldn't ever be used, but is included for completeness
|
||||
TS_RFC2822 => 'D, d M Y H:i:s',
|
||||
TS_ORACLE => 'd-m-Y H:i:s.000000', // Was 'd-M-y h.i.s A' . ' +00:00' before r51500
|
||||
TS_POSTGRES => 'Y-m-d H:i:s',
|
||||
TS_DB2 => 'Y-m-d H:i:s',
|
||||
);
|
||||
|
||||
/**
|
||||
* Different units for human readable timestamps.
|
||||
* @see MWTimestamp::getHumanTimestamp
|
||||
*/
|
||||
private static $units = array(
|
||||
"milliseconds" => 1,
|
||||
"seconds" => 1000, // 1000 milliseconds per second
|
||||
"minutes" => 60, // 60 seconds per minute
|
||||
"hours" => 60, // 60 minutes per hour
|
||||
"days" => 24 // 24 hours per day
|
||||
);
|
||||
|
||||
/**
|
||||
* The actual timestamp being wrapped. Either a DateTime
|
||||
* object or a string with a Unix timestamp depending on
|
||||
* PHP.
|
||||
*/
|
||||
private $timestamp;
|
||||
|
||||
/**
|
||||
* Make a new timestamp and set it to the specified time,
|
||||
* or the current time if unspecified.
|
||||
*
|
||||
* @param $timestamp Timestamp to set, or false for current time
|
||||
*/
|
||||
public function __construct( $timestamp = false ) {
|
||||
$this->setTimestamp( $timestamp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timestamp to the specified time, or the current time if unspecified.
|
||||
*
|
||||
* Parse the given timestamp into either a DateTime object or a Unix teimstamp,
|
||||
* and then store it.
|
||||
*
|
||||
* @param $ts Timestamp to store, or false for now
|
||||
*/
|
||||
public function setTimestamp( $ts = false ) {
|
||||
$uts = 0;
|
||||
$da = array();
|
||||
$strtime = '';
|
||||
|
||||
if ( !$ts ) { // We want to catch 0, '', null... but not date strings starting with a letter.
|
||||
$uts = time();
|
||||
$strtime = "@$uts";
|
||||
} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
|
||||
# TS_DB
|
||||
} elseif ( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
|
||||
# TS_EXIF
|
||||
} elseif ( preg_match( '/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D', $ts, $da ) ) {
|
||||
# TS_MW
|
||||
} elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) {
|
||||
# TS_UNIX
|
||||
$uts = $ts;
|
||||
$strtime = "@$ts"; // http://php.net/manual/en/datetime.formats.compound.php
|
||||
} elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
|
||||
# TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
|
||||
$strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
|
||||
str_replace( '+00:00', 'UTC', $ts ) );
|
||||
} elseif ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
|
||||
# TS_ISO_8601
|
||||
} elseif ( preg_match( '/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
|
||||
#TS_ISO_8601_BASIC
|
||||
} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d*[\+\- ](\d\d)$/', $ts, $da ) ) {
|
||||
# TS_POSTGRES
|
||||
} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/', $ts, $da ) ) {
|
||||
# TS_POSTGRES
|
||||
} elseif (preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.\d\d\d$/', $ts, $da ) ) {
|
||||
# TS_DB2
|
||||
} elseif ( preg_match( '/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' . # Day of week
|
||||
'\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' . # dd Mon yyyy
|
||||
'[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S', $ts ) ) { # hh:mm:ss
|
||||
# TS_RFC2822, accepting a trailing comment. See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html / r77171
|
||||
# The regex is a superset of rfc2822 for readability
|
||||
$strtime = strtok( $ts, ';' );
|
||||
} elseif ( preg_match( '/^[A-Z][a-z]{5,8}, \d\d-[A-Z][a-z]{2}-\d{2} \d\d:\d\d:\d\d/', $ts ) ) {
|
||||
# TS_RFC850
|
||||
$strtime = $ts;
|
||||
} elseif ( preg_match( '/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d\d:\d\d:\d\d \d{4}/', $ts ) ) {
|
||||
# asctime
|
||||
$strtime = $ts;
|
||||
} else {
|
||||
throw new TimestampException( __METHOD__ . " : Invalid timestamp - $ts" );
|
||||
}
|
||||
|
||||
if( !$strtime ) {
|
||||
$da = array_map( 'intval', $da );
|
||||
$da[0] = "%04d-%02d-%02dT%02d:%02d:%02d.00+00:00";
|
||||
$strtime = call_user_func_array( "sprintf", $da );
|
||||
}
|
||||
|
||||
if( function_exists( "date_create" ) ) {
|
||||
try {
|
||||
$final = new DateTime( $strtime, new DateTimeZone( 'GMT' ) );
|
||||
} catch(Exception $e) {
|
||||
throw new TimestampException( __METHOD__ . 'Invalid timestamp format.' );
|
||||
}
|
||||
} else {
|
||||
$final = strtotime( $strtime );
|
||||
}
|
||||
|
||||
if( $final === false ) {
|
||||
throw new TimestampException( __METHOD__ . 'Invalid timestamp format.' );
|
||||
}
|
||||
$this->timestamp = $final;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the timestamp represented by this object in a certain form.
|
||||
*
|
||||
* Convert the internal timestamp to the specified format and then
|
||||
* return it.
|
||||
*
|
||||
* @param $style Output format for timestamp
|
||||
* @return string The formatted timestamp
|
||||
*/
|
||||
public function getTimestamp( $style = TS_UNIX ) {
|
||||
if( !isset( self::$formats[$style] ) ) {
|
||||
throw new TimestampException( __METHOD__ . ' : Illegal timestamp output type.' );
|
||||
}
|
||||
|
||||
if( is_object( $this->timestamp ) ) {
|
||||
// DateTime object was used, call DateTime::format.
|
||||
$output = $this->timestamp->format( self::$formats[$style] );
|
||||
} elseif( TS_UNIX == $style ) {
|
||||
// Unix timestamp was used and is wanted, just return it.
|
||||
$output = $this->timestamp;
|
||||
} else {
|
||||
// Unix timestamp was used, use gmdate().
|
||||
$output = gmdate( self::$formats[$style], $this->timestamp );
|
||||
}
|
||||
|
||||
if ( ( $style == TS_RFC2822 ) || ( $style == TS_POSTGRES ) ) {
|
||||
$output .= ' GMT';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the timestamp in a human-friendly relative format, e.g., "3 days ago".
|
||||
*
|
||||
* Determine the difference between the timestamp and the current time, and
|
||||
* generate a readable timestamp by returning "<N> <units> ago", where the
|
||||
* largest possible unit is used.
|
||||
*
|
||||
* @return string Formatted timestamp
|
||||
*/
|
||||
public function getHumanTimestamp() {
|
||||
$then = $this->getTimestamp( TS_UNIX );
|
||||
$now = time();
|
||||
$timeago = ($now - $then) * 1000;
|
||||
$message = false;
|
||||
|
||||
foreach( self::$units as $unit => $factor ) {
|
||||
$next = $timeago / $factor;
|
||||
if( $next < 1 ) {
|
||||
break;
|
||||
} else {
|
||||
$timeago = $next;
|
||||
$message = array( $unit, floor( $timeago ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( $message ) {
|
||||
$initial = call_user_func_array( 'wfMessage', $message );
|
||||
return wfMessage( 'ago', $initial );
|
||||
} else {
|
||||
return wfMessage( 'just-now' );
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return $this->getTimestamp();
|
||||
}
|
||||
}
|
||||
|
||||
class TimestampException extends MWException {}
|
||||
|
|
@ -369,7 +369,7 @@ class Title {
|
|||
* @return Title the new object
|
||||
*/
|
||||
public static function newMainPage() {
|
||||
$title = Title::newFromText( wfMsgForContent( 'mainpage' ) );
|
||||
$title = Title::newFromText( wfMessage( 'mainpage' )->inContentLanguage()->text() );
|
||||
// Don't give fatal errors if the message is broken
|
||||
if ( !$title ) {
|
||||
$title = Title::newFromText( 'Main Page' );
|
||||
|
|
@ -1604,7 +1604,7 @@ class Title {
|
|||
* queries by skipping checks for cascading protections and user blocks.
|
||||
* @param $ignoreErrors Array of Strings Set this to a list of message keys
|
||||
* whose corresponding errors may be ignored.
|
||||
* @return Array of arguments to wfMsg to explain permissions problems.
|
||||
* @return Array of arguments to wfMessage to explain permissions problems.
|
||||
*/
|
||||
public function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true, $ignoreErrors = array() ) {
|
||||
$errors = $this->getUserPermissionsErrorsInternal( $action, $user, $doExpensiveQueries );
|
||||
|
|
@ -1761,7 +1761,7 @@ class Title {
|
|||
# Check $wgNamespaceProtection for restricted namespaces
|
||||
if ( $this->isNamespaceProtected( $user ) ) {
|
||||
$ns = $this->mNamespace == NS_MAIN ?
|
||||
wfMsg( 'nstab-main' ) : $this->getNsText();
|
||||
wfMessage( 'nstab-main' )->text() : $this->getNsText();
|
||||
$errors[] = $this->mNamespace == NS_MEDIAWIKI ?
|
||||
array( 'protectedinterface' ) : array( 'namespaceprotected', $ns );
|
||||
}
|
||||
|
|
@ -1960,7 +1960,7 @@ class Title {
|
|||
$id = $user->blockedBy();
|
||||
$reason = $user->blockedFor();
|
||||
if ( $reason == '' ) {
|
||||
$reason = wfMsg( 'blockednoreason' );
|
||||
$reason = wfMessage( 'blockednoreason' )->text();
|
||||
}
|
||||
$ip = $user->getRequest()->getIP();
|
||||
|
||||
|
|
@ -2118,7 +2118,7 @@ class Title {
|
|||
* @param $user User to check
|
||||
* @param $doExpensiveQueries Bool Set this to false to avoid doing unnecessary queries.
|
||||
* @param $short Bool Set this to true to stop after the first permission error.
|
||||
* @return Array of arrays of the arguments to wfMsg to explain permissions problems.
|
||||
* @return Array of arrays of the arguments to wfMessage to explain permissions problems.
|
||||
*/
|
||||
protected function getUserPermissionsErrorsInternal( $action, $user, $doExpensiveQueries = true, $short = false ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
|
@ -3584,9 +3584,13 @@ class Title {
|
|||
);
|
||||
# Update the protection log
|
||||
$log = new LogPage( 'protect' );
|
||||
$comment = wfMsgForContent( 'prot_1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() );
|
||||
$comment = wfMessage(
|
||||
'prot_1movedto2',
|
||||
$this->getPrefixedText(),
|
||||
$nt->getPrefixedText()
|
||||
)->inContentLanguage()->text();
|
||||
if ( $reason ) {
|
||||
$comment .= wfMsgForContent( 'colon-separator' ) . $reason;
|
||||
$comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
|
||||
}
|
||||
// @todo FIXME: $params?
|
||||
$log->addEntry( 'move_prot', $nt, $comment, array( $this->getPrefixedText() ) );
|
||||
|
|
@ -3644,7 +3648,7 @@ class Title {
|
|||
$formatter->setContext( RequestContext::newExtraneousContext( $this ) );
|
||||
$comment = $formatter->getPlainActionText();
|
||||
if ( $reason ) {
|
||||
$comment .= wfMsgForContent( 'colon-separator' ) . $reason;
|
||||
$comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
|
||||
}
|
||||
# Truncate for whole multibyte characters.
|
||||
$comment = $wgContLang->truncate( $comment, 255 );
|
||||
|
|
@ -3865,7 +3869,7 @@ class Title {
|
|||
return false;
|
||||
}
|
||||
# Get the article text
|
||||
$rev = Revision::newFromTitle( $nt );
|
||||
$rev = Revision::newFromTitle( $nt, false, Revision::READ_LATEST );
|
||||
if( !is_object( $rev ) ){
|
||||
return false;
|
||||
}
|
||||
|
|
@ -4159,11 +4163,11 @@ class Title {
|
|||
if ( in_array( 'include_old', $options ) ) {
|
||||
$old_cmp = '>=';
|
||||
}
|
||||
if ( in_array( 'include_new', $options ) ) {
|
||||
$new_cmp = '<=';
|
||||
}
|
||||
if ( in_array( 'include_both', $options ) ) {
|
||||
$old_cmp = '>=';
|
||||
if ( in_array( 'include_new', $options ) ) {
|
||||
$new_cmp = '<=';
|
||||
}
|
||||
if ( in_array( 'include_both', $options ) ) {
|
||||
$old_cmp = '>=';
|
||||
$new_cmp = '<=';
|
||||
}
|
||||
// No DB query needed if $old and $new are the same or successive revisions:
|
||||
|
|
@ -4174,7 +4178,7 @@ class Title {
|
|||
return ( $old_cmp === '>' && $new_cmp === '<' ) ? 0 : 1;
|
||||
}
|
||||
return ( $old->getRawUserText() === $new->getRawUserText() ) ? 1 : 2;
|
||||
}
|
||||
}
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
$res = $dbr->select( 'revision', 'DISTINCT rev_user_text',
|
||||
array(
|
||||
|
|
@ -4572,9 +4576,9 @@ class Title {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the language in which the content of this page is written.
|
||||
* Defaults to $wgContLang, but in certain cases it can be e.g.
|
||||
* $wgLang (such as special pages, which are in the user language).
|
||||
* Get the language in which the content of this page is written in
|
||||
* wikitext. Defaults to $wgContLang, but in certain cases it can be
|
||||
* e.g. $wgLang (such as special pages, which are in the user language).
|
||||
*
|
||||
* @since 1.18
|
||||
* @return Language
|
||||
|
|
@ -4599,4 +4603,29 @@ class Title {
|
|||
wfRunHooks( 'PageContentLanguage', array( $this, &$pageLang, $wgLang ) );
|
||||
return wfGetLangObj( $pageLang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language in which the content of this page is written when
|
||||
* viewed by user. Defaults to $wgContLang, but in certain cases it can be
|
||||
* e.g. $wgLang (such as special pages, which are in the user language).
|
||||
*
|
||||
* @since 1.20
|
||||
* @return Language
|
||||
*/
|
||||
public function getPageViewLanguage() {
|
||||
$pageLang = $this->getPageLanguage();
|
||||
// If this is nothing special (so the content is converted when viewed)
|
||||
if ( !$this->isSpecialPage()
|
||||
&& !$this->isCssOrJsPage() && !$this->isCssJsSubpage()
|
||||
&& $this->getNamespace() !== NS_MEDIAWIKI
|
||||
) {
|
||||
// If the user chooses a variant, the content is actually
|
||||
// in a language whose code is the variant code.
|
||||
$variant = $pageLang->getPreferredVariant();
|
||||
if ( $pageLang->getCode() !== $variant ) {
|
||||
$pageLang = Language::factory( $variant );
|
||||
}
|
||||
}
|
||||
return $pageLang;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ class User {
|
|||
// Certain names may be reserved for batch processes.
|
||||
foreach ( $reservedUsernames as $reserved ) {
|
||||
if ( substr( $reserved, 0, 4 ) == 'msg:' ) {
|
||||
$reserved = wfMsgForContent( substr( $reserved, 4 ) );
|
||||
$reserved = wfMessage( substr( $reserved, 4 ) )->inContentLanguage()->text();
|
||||
}
|
||||
if ( $reserved == $name ) {
|
||||
return false;
|
||||
|
|
@ -1305,13 +1305,13 @@ class User {
|
|||
# Local list
|
||||
if ( self::isLocallyBlockedProxy( $ip ) ) {
|
||||
$block = new Block;
|
||||
$block->setBlocker( wfMsg( 'proxyblocker' ) );
|
||||
$block->mReason = wfMsg( 'proxyblockreason' );
|
||||
$block->setBlocker( wfMessage( 'proxyblocker' )->text() );
|
||||
$block->mReason = wfMessage( 'proxyblockreason' )->text();
|
||||
$block->setTarget( $ip );
|
||||
} elseif ( $this->isAnon() && $this->isDnsBlacklisted( $ip ) ) {
|
||||
$block = new Block;
|
||||
$block->setBlocker( wfMsg( 'sorbs' ) );
|
||||
$block->mReason = wfMsg( 'sorbsreason' );
|
||||
$block->setBlocker( wfMessage( 'sorbs' )->text() );
|
||||
$block->mReason = wfMessage( 'sorbsreason' )->text();
|
||||
$block->setTarget( $ip );
|
||||
}
|
||||
}
|
||||
|
|
@ -2016,7 +2016,7 @@ class User {
|
|||
|
||||
if( $str !== null ) {
|
||||
if( !$wgAuth->allowPasswordChange() ) {
|
||||
throw new PasswordError( wfMsg( 'password-change-forbidden' ) );
|
||||
throw new PasswordError( wfMessage( 'password-change-forbidden' )->text() );
|
||||
}
|
||||
|
||||
if( !$this->isValidPassword( $str ) ) {
|
||||
|
|
@ -2029,12 +2029,12 @@ class User {
|
|||
$message = $valid;
|
||||
$params = array( $wgMinimalPasswordLength );
|
||||
}
|
||||
throw new PasswordError( wfMsgExt( $message, array( 'parsemag' ), $params ) );
|
||||
throw new PasswordError( wfMessage( $message, $params )->text() );
|
||||
}
|
||||
}
|
||||
|
||||
if( !$wgAuth->setPassword( $this, $str ) ) {
|
||||
throw new PasswordError( wfMsg( 'externaldberror' ) );
|
||||
throw new PasswordError( wfMessage( 'externaldberror' )->text() );
|
||||
}
|
||||
|
||||
$this->setInternalPassword( $str );
|
||||
|
|
@ -2891,11 +2891,16 @@ class User {
|
|||
* @todo Only rarely do all these fields need to be set!
|
||||
*/
|
||||
public function saveSettings() {
|
||||
global $wgAuth;
|
||||
|
||||
$this->load();
|
||||
if ( wfReadOnly() ) { return; }
|
||||
if ( 0 == $this->mId ) { return; }
|
||||
|
||||
$this->mTouched = self::newTouchedTimestamp();
|
||||
if ( !$wgAuth->allowSetLocalPassword() ) {
|
||||
$this->mPassword = '';
|
||||
}
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->update( 'user',
|
||||
|
|
@ -3353,15 +3358,15 @@ class User {
|
|||
$message = 'confirmemail_body_' . $type;
|
||||
}
|
||||
|
||||
return $this->sendMail( wfMsg( 'confirmemail_subject' ),
|
||||
wfMsg( $message,
|
||||
return $this->sendMail( wfMessage( 'confirmemail_subject' )->text(),
|
||||
wfMessage( $message,
|
||||
$this->getRequest()->getIP(),
|
||||
$this->getName(),
|
||||
$url,
|
||||
$wgLang->timeanddate( $expiration, false ),
|
||||
$invalidateURL,
|
||||
$wgLang->date( $expiration, false ),
|
||||
$wgLang->time( $expiration, false ) ) );
|
||||
$wgLang->time( $expiration, false ) )->text() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -4013,10 +4018,10 @@ class User {
|
|||
$action = 'create2';
|
||||
if ( $byEmail ) {
|
||||
if ( $reason === '' ) {
|
||||
$reason = wfMsgForContent( 'newuserlog-byemail' );
|
||||
$reason = wfMessage( 'newuserlog-byemail' )->inContentLanguage()->text();
|
||||
} else {
|
||||
$reason = $wgContLang->commaList( array(
|
||||
$reason, wfMsgForContent( 'newuserlog-byemail' ) ) );
|
||||
$reason, wfMessage( 'newuserlog-byemail' )->inContentLanguage()->text() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4185,8 +4190,8 @@ class User {
|
|||
/*
|
||||
if ( $wgMinimalPasswordLength > 1 ) {
|
||||
$ret['pattern'] = '.{' . intval( $wgMinimalPasswordLength ) . ',}';
|
||||
$ret['title'] = wfMsgExt( 'passwordtooshort', 'parsemag',
|
||||
$wgMinimalPasswordLength );
|
||||
$ret['title'] = wfMessage( 'passwordtooshort' )
|
||||
->numParams( $wgMinimalPasswordLength )->text();
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -623,32 +623,36 @@ class EmailNotification {
|
|||
|
||||
if ( $this->oldid ) {
|
||||
// Always show a link to the diff which triggered the mail. See bug 32210.
|
||||
$keys['$NEWPAGE'] = wfMsgForContent( 'enotif_lastdiff',
|
||||
$this->title->getCanonicalUrl( 'diff=next&oldid=' . $this->oldid ) );
|
||||
$keys['$NEWPAGE'] = wfMessage( 'enotif_lastdiff',
|
||||
$this->title->getCanonicalUrl( 'diff=next&oldid=' . $this->oldid ) )
|
||||
->inContentLanguage()->text();
|
||||
if ( !$wgEnotifImpersonal ) {
|
||||
// For personal mail, also show a link to the diff of all changes
|
||||
// since last visited.
|
||||
$keys['$NEWPAGE'] .= " \n" . wfMsgForContent( 'enotif_lastvisited',
|
||||
$this->title->getCanonicalUrl( 'diff=0&oldid=' . $this->oldid ) );
|
||||
$keys['$NEWPAGE'] .= " \n" . wfMessage( 'enotif_lastvisited',
|
||||
$this->title->getCanonicalUrl( 'diff=0&oldid=' . $this->oldid ) )
|
||||
->inContentLanguage()->text();
|
||||
}
|
||||
$keys['$OLDID'] = $this->oldid;
|
||||
$keys['$CHANGEDORCREATED'] = wfMsgForContent( 'changed' );
|
||||
$keys['$CHANGEDORCREATED'] = wfMessage( 'changed' )->inContentLanguage()->text();
|
||||
} else {
|
||||
$keys['$NEWPAGE'] = wfMsgForContent( 'enotif_newpagetext' );
|
||||
$keys['$NEWPAGE'] = wfMessage( 'enotif_newpagetext' )->inContentLanguage()->text();
|
||||
# clear $OLDID placeholder in the message template
|
||||
$keys['$OLDID'] = '';
|
||||
$keys['$CHANGEDORCREATED'] = wfMsgForContent( 'created' );
|
||||
$keys['$CHANGEDORCREATED'] = wfMessage( 'created' )->inContentLanguage()->text();
|
||||
}
|
||||
|
||||
$keys['$PAGETITLE'] = $this->title->getPrefixedText();
|
||||
$keys['$PAGETITLE_URL'] = $this->title->getCanonicalUrl();
|
||||
$keys['$PAGEMINOREDIT'] = $this->minorEdit ? wfMsgForContent( 'minoredit' ) : '';
|
||||
$keys['$PAGEMINOREDIT'] = $this->minorEdit ?
|
||||
wfMessage( 'minoredit' )->inContentLanguage()->text() : '';
|
||||
$keys['$UNWATCHURL'] = $this->title->getCanonicalUrl( 'action=unwatch' );
|
||||
|
||||
if ( $this->editor->isAnon() ) {
|
||||
# real anon (user:xxx.xxx.xxx.xxx)
|
||||
$keys['$PAGEEDITOR'] = wfMsgForContent( 'enotif_anon_editor', $this->editor->getName() );
|
||||
$keys['$PAGEEDITOR_EMAIL'] = wfMsgForContent( 'noemailtitle' );
|
||||
$keys['$PAGEEDITOR'] = wfMessage( 'enotif_anon_editor', $this->editor->getName() )
|
||||
->inContentLanguage()->text();
|
||||
$keys['$PAGEEDITOR_EMAIL'] = wfMessage( 'noemailtitle' )->inContentLanguage()->text();
|
||||
} else {
|
||||
$keys['$PAGEEDITOR'] = $wgEnotifUseRealName ? $this->editor->getRealName() : $this->editor->getName();
|
||||
$emailPage = SpecialPage::getSafeTitleFor( 'Emailuser', $this->editor->getName() );
|
||||
|
|
@ -662,12 +666,12 @@ class EmailNotification {
|
|||
|
||||
# Now build message's subject and body
|
||||
|
||||
$subject = wfMsgExt( 'enotif_subject', 'content' );
|
||||
$subject = wfMessage( 'enotif_subject' )->inContentLanguage()->plain();
|
||||
$subject = strtr( $subject, $keys );
|
||||
$subject = MessageCache::singleton()->transform( $subject, false, null, $this->title );
|
||||
$this->subject = strtr( $subject, $postTransformKeys );
|
||||
|
||||
$body = wfMsgExt( 'enotif_body', 'content' );
|
||||
$body = wfMessage( 'enotif_body' )->inContentLanguage()->plain();
|
||||
$body = strtr( $body, $keys );
|
||||
$body = MessageCache::singleton()->transform( $body, false, null, $this->title );
|
||||
$this->body = wordwrap( strtr( $body, $postTransformKeys ), 72 );
|
||||
|
|
@ -769,7 +773,7 @@ class EmailNotification {
|
|||
array( '$WATCHINGUSERNAME',
|
||||
'$PAGEEDITDATE',
|
||||
'$PAGEEDITTIME' ),
|
||||
array( wfMsgForContent( 'enotif_impersonal_salutation' ),
|
||||
array( wfMessage( 'enotif_impersonal_salutation' )->inContentLanguage()->text(),
|
||||
$wgContLang->date( $this->timestamp, false, false ),
|
||||
$wgContLang->time( $this->timestamp, false, false ) ),
|
||||
$this->body );
|
||||
|
|
|
|||
|
|
@ -134,12 +134,12 @@ class WikiXmlError extends WikiError {
|
|||
/** @return string */
|
||||
function getMessage() {
|
||||
// '$1 at line $2, col $3 (byte $4): $5',
|
||||
return wfMsgHtml( 'xml-error-string',
|
||||
return wfMessage( 'xml-error-string',
|
||||
$this->mMessage,
|
||||
$this->mLine,
|
||||
$this->mColumn,
|
||||
$this->mByte . $this->mContext,
|
||||
xml_error_string( $this->mXmlError ) );
|
||||
xml_error_string( $this->mXmlError ) )->escaped();
|
||||
}
|
||||
|
||||
function _extractContext( $context, $offset ) {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
* Create a WikiPage object of the appropriate class for the given title.
|
||||
*
|
||||
* @param $title Title
|
||||
* @throws MWException
|
||||
* @return WikiPage object of the appropriate type
|
||||
*/
|
||||
public static function factory( Title $title ) {
|
||||
|
|
@ -775,7 +776,7 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
* Determine whether a page would be suitable for being counted as an
|
||||
* article in the site_stats table based on the title & its content
|
||||
*
|
||||
* @param $editInfo Object or false: object returned by prepareTextForEdit(),
|
||||
* @param $editInfo Object|bool (false): object returned by prepareTextForEdit(),
|
||||
* if false, the current database state will be used
|
||||
* @return Boolean
|
||||
*/
|
||||
|
|
@ -1527,9 +1528,10 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
* edit-already-exists error will be returned. These two conditions are also possible with
|
||||
* auto-detection due to MediaWiki's performance-optimised locking strategy.
|
||||
*
|
||||
* @param $baseRevId int the revision ID this edit was based off, if any
|
||||
* @param bool|int $baseRevId int the revision ID this edit was based off, if any
|
||||
* @param $user User the user doing the edit
|
||||
*
|
||||
* @throws MWException
|
||||
* @return Status object. Possible errors:
|
||||
* edit-hook-aborted: The ArticleSave hook aborted the edit but didn't set the fatal flag of $status
|
||||
* edit-gone-missing: In update mode, but the article didn't exist
|
||||
|
|
@ -2239,12 +2241,15 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
if ( $restrictions != '' ) {
|
||||
$protectDescription .= $wgContLang->getDirMark() . "[$action=$restrictions] (";
|
||||
if ( $encodedExpiry[$action] != 'infinity' ) {
|
||||
$protectDescription .= wfMsgForContent( 'protect-expiring',
|
||||
$protectDescription .= wfMessage(
|
||||
'protect-expiring',
|
||||
$wgContLang->timeanddate( $expiry[$action], false, false ) ,
|
||||
$wgContLang->date( $expiry[$action], false, false ) ,
|
||||
$wgContLang->time( $expiry[$action], false, false ) );
|
||||
$wgContLang->time( $expiry[$action], false, false )
|
||||
)->inContentLanguage()->text();
|
||||
} else {
|
||||
$protectDescription .= wfMsgForContent( 'protect-expiry-indefinite' );
|
||||
$protectDescription .= wfMessage( 'protect-expiry-indefinite' )
|
||||
->inContentLanguage()->text();
|
||||
}
|
||||
|
||||
$protectDescription .= ') ';
|
||||
|
|
@ -2285,7 +2290,12 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
}
|
||||
|
||||
# Prepare a null revision to be added to the history
|
||||
$editComment = $wgContLang->ucfirst( wfMsgForContent( $revCommentMsg, $this->mTitle->getPrefixedText() ) );
|
||||
$editComment = $wgContLang->ucfirst(
|
||||
wfMessage(
|
||||
$revCommentMsg,
|
||||
$this->mTitle->getPrefixedText()
|
||||
)->inContentLanguage()->text()
|
||||
);
|
||||
if ( $reason ) {
|
||||
$editComment .= ": $reason";
|
||||
}
|
||||
|
|
@ -2293,7 +2303,9 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
$editComment .= " ($protectDescription)";
|
||||
}
|
||||
if ( $cascade ) {
|
||||
$editComment .= ' [' . wfMsgForContent( 'protect-summary-cascade' ) . ']';
|
||||
// FIXME: Should use 'brackets' message.
|
||||
$editComment .= ' [' . wfMessage( 'protect-summary-cascade' )
|
||||
->inContentLanguage()->text() . ']';
|
||||
}
|
||||
|
||||
# Insert a null revision
|
||||
|
|
@ -2360,6 +2372,7 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
* Take an array of page restrictions and flatten it to a string
|
||||
* suitable for insertion into the page_restrictions field.
|
||||
* @param $limit Array
|
||||
* @throws MWException
|
||||
* @return String
|
||||
*/
|
||||
protected static function flattenRestrictions( $limit ) {
|
||||
|
|
@ -2705,9 +2718,9 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
$target = Revision::newFromId( $s->rev_id );
|
||||
if ( empty( $summary ) ) {
|
||||
if ( $from == '' ) { // no public user name
|
||||
$summary = wfMsgForContent( 'revertpage-nouser' );
|
||||
$summary = wfMessage( 'revertpage-nouser' )->inContentLanguage()->text();
|
||||
} else {
|
||||
$summary = wfMsgForContent( 'revertpage' );
|
||||
$summary = wfMessage( 'revertpage' )->inContentLanguage()->text();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3146,6 +3159,7 @@ class WikiPage extends Page implements IDBAccessObject {
|
|||
|
||||
/**
|
||||
* @deprecated since 1.18
|
||||
* @param $oldid int
|
||||
* @return bool
|
||||
*/
|
||||
public function useParserCache( $oldid ) {
|
||||
|
|
|
|||
|
|
@ -15802,6 +15802,7 @@ $zh2TW = array(
|
|||
'彩线' => '綵線',
|
||||
'彩船' => '綵船',
|
||||
'彩衣' => '綵衣',
|
||||
'綫' => '線',
|
||||
'缉凶' => '緝凶',
|
||||
'緝兇' => '緝凶',
|
||||
'緝凶' => '緝凶',
|
||||
|
|
@ -15937,6 +15938,30 @@ $zh2TW = array(
|
|||
);
|
||||
|
||||
$zh2HK = array(
|
||||
'505線' => '505綫',
|
||||
'505线' => '505綫',
|
||||
'507線' => '507綫',
|
||||
'507线' => '507綫',
|
||||
'610線' => '610綫',
|
||||
'610线' => '610綫',
|
||||
'614P線' => '614P綫',
|
||||
'614P线' => '614P綫',
|
||||
'614线' => '614綫',
|
||||
'614線' => '614綫',
|
||||
'615P線' => '615P綫',
|
||||
'615P线' => '615P綫',
|
||||
'615线' => '615綫',
|
||||
'615線' => '615綫',
|
||||
'705线' => '705綫',
|
||||
'705線' => '705綫',
|
||||
'706线' => '706綫',
|
||||
'706線' => '706綫',
|
||||
'751P線' => '751P綫',
|
||||
'751P线' => '751P綫',
|
||||
'751線' => '751綫',
|
||||
'751线' => '751綫',
|
||||
'761P线' => '761P綫',
|
||||
'761P線' => '761P綫',
|
||||
'“' => '「',
|
||||
'”' => '」',
|
||||
'‘' => '『',
|
||||
|
|
@ -16173,6 +16198,8 @@ $zh2HK = array(
|
|||
'動著者' => '動著者',
|
||||
'動著述' => '動著述',
|
||||
'動著錄' => '動著錄',
|
||||
'北环线' => '北環綫',
|
||||
'北環線' => '北環綫',
|
||||
'医院里' => '医院裏',
|
||||
'波札那' => '博茨瓦納',
|
||||
'珍妮弗·卡普里亚蒂' => '卡佩雅蒂',
|
||||
|
|
@ -16420,6 +16447,8 @@ $zh2HK = array(
|
|||
'寫著者' => '寫著者',
|
||||
'寫著述' => '寫著述',
|
||||
'寫著錄' => '寫著錄',
|
||||
'将军澳线' => '將軍澳綫',
|
||||
'將軍澳線' => '將軍澳綫',
|
||||
'专辑里' => '專輯裏',
|
||||
'專輯裡' => '專輯裏',
|
||||
'尋著' => '尋着',
|
||||
|
|
@ -16950,6 +16979,10 @@ $zh2HK = array(
|
|||
'本著錄' => '本著錄',
|
||||
'村子里' => '村子裏',
|
||||
'村子裡' => '村子裏',
|
||||
'东涌线' => '東涌綫',
|
||||
'東涌線' => '東涌綫',
|
||||
'東鐵線' => '東鐵綫',
|
||||
'东铁线' => '東鐵綫',
|
||||
'枕著' => '枕着',
|
||||
'枕著作' => '枕著作',
|
||||
'枕著名' => '枕著名',
|
||||
|
|
@ -16983,6 +17016,8 @@ $zh2HK = array(
|
|||
'樂著錄' => '樂著錄',
|
||||
'寶獅' => '標致',
|
||||
'標誌著' => '標誌着',
|
||||
'機場快線' => '機場快綫',
|
||||
'机场快线' => '機場快綫',
|
||||
'機器人' => '機械人',
|
||||
'机器人' => '機械人',
|
||||
'历史里' => '歷史裏',
|
||||
|
|
@ -17015,8 +17050,12 @@ $zh2HK = array(
|
|||
'沉著者' => '沉著者',
|
||||
'沉著述' => '沉著述',
|
||||
'沉著錄' => '沉著錄',
|
||||
'沙中线' => '沙中綫',
|
||||
'沙中線' => '沙中綫',
|
||||
'沙地阿拉伯' => '沙特阿拉伯',
|
||||
'沙烏地阿拉伯' => '沙特阿拉伯',
|
||||
'沙田至中環線' => '沙田至中環綫',
|
||||
'沙田至中环线' => '沙田至中環綫',
|
||||
'马拉特·萨芬' => '沙芬',
|
||||
'沿著' => '沿着',
|
||||
'沿著作' => '沿著作',
|
||||
|
|
@ -17074,6 +17113,8 @@ $zh2HK = array(
|
|||
'涼著錄' => '涼著錄',
|
||||
'深淵裡' => '深淵裏',
|
||||
'深渊里' => '深渊裏',
|
||||
'港岛线' => '港島綫',
|
||||
'港島線' => '港島綫',
|
||||
'渴著' => '渴着',
|
||||
'渴著作' => '渴著作',
|
||||
'渴著名' => '渴著名',
|
||||
|
|
@ -17114,6 +17155,14 @@ $zh2HK = array(
|
|||
'潤著者' => '潤著者',
|
||||
'潤著述' => '潤著述',
|
||||
'潤著錄' => '潤著錄',
|
||||
'無線劇集' => '無綫劇集',
|
||||
'无线剧集' => '無綫劇集',
|
||||
'無線收費' => '無綫收費',
|
||||
'无线收费' => '無綫收費',
|
||||
'无线节目' => '無綫節目',
|
||||
'無線節目' => '無綫節目',
|
||||
'无线电视' => '無綫電視',
|
||||
'無線電視' => '無綫電視',
|
||||
'菸' => '煙',
|
||||
'照著' => '照着',
|
||||
'照著作' => '照著作',
|
||||
|
|
@ -17547,6 +17596,8 @@ $zh2HK = array(
|
|||
'苦著錄' => '苦著錄',
|
||||
'苦里' => '苦裏',
|
||||
'苦裡' => '苦裏',
|
||||
'荃湾线' => '荃灣綫',
|
||||
'荃灣線' => '荃灣綫',
|
||||
'莫三比克' => '莫桑比克',
|
||||
'賴索托' => '萊索托',
|
||||
'馬自達' => '萬事得',
|
||||
|
|
@ -17630,6 +17681,8 @@ $zh2HK = array(
|
|||
'裹著者' => '裹著者',
|
||||
'裹著述' => '裹著述',
|
||||
'裹著錄' => '裹著錄',
|
||||
'西铁线' => '西鐵綫',
|
||||
'西鐵線' => '西鐵綫',
|
||||
'見著' => '見着',
|
||||
'見著作' => '見著作',
|
||||
'見著名' => '見著名',
|
||||
|
|
@ -17638,6 +17691,8 @@ $zh2HK = array(
|
|||
'見著者' => '見著者',
|
||||
'見著述' => '見著述',
|
||||
'見著錄' => '見著錄',
|
||||
'觀塘線' => '觀塘綫',
|
||||
'观塘线' => '觀塘綫',
|
||||
'記著' => '記着',
|
||||
'記著作' => '記著作',
|
||||
'記著名' => '記著名',
|
||||
|
|
@ -17821,6 +17876,8 @@ $zh2HK = array(
|
|||
'辦著錄' => '辦著錄',
|
||||
'近角聪信' => '近角聰信',
|
||||
'近角聰信' => '近角聰信',
|
||||
'迪士尼线' => '迪士尼綫',
|
||||
'迪士尼線' => '迪士尼綫',
|
||||
'迫著' => '迫着',
|
||||
'追著' => '追着',
|
||||
'追著作' => '追著作',
|
||||
|
|
@ -18080,6 +18137,8 @@ $zh2HK = array(
|
|||
'馬爾地夫' => '馬爾代夫',
|
||||
'馬利共和國' => '馬里共和國',
|
||||
'土豆' => '馬鈴薯',
|
||||
'馬鞍山線' => '馬鞍山綫',
|
||||
'马鞍山线' => '馬鞍山綫',
|
||||
'駕著' => '駕着',
|
||||
'駕著作' => '駕著作',
|
||||
'駕著名' => '駕著名',
|
||||
|
|
@ -18456,4 +18515,4 @@ $zh2SG = array(
|
|||
'笨豬跳' => '绑紧跳',
|
||||
'蹦极跳' => '绑紧跳',
|
||||
'笑星' => '谐星',
|
||||
);
|
||||
);
|
||||
|
|
@ -84,6 +84,11 @@ class InfoAction extends FormlessAction {
|
|||
$content = '';
|
||||
$table = '';
|
||||
|
||||
// Header
|
||||
if ( !$this->msg( 'pageinfo-header' )->isDisabled() ) {
|
||||
$content .= $this->msg( 'pageinfo-header ' )->parse();
|
||||
}
|
||||
|
||||
// Basic information
|
||||
$content = $this->addHeader( $content, $this->msg( 'pageinfo-header-basic' )->text() );
|
||||
|
||||
|
|
@ -304,6 +309,11 @@ class InfoAction extends FormlessAction {
|
|||
$content = $this->addTable( $content, $table );
|
||||
}
|
||||
|
||||
// Footer
|
||||
if ( !$this->msg( 'pageinfo-footer' )->isDisabled() ) {
|
||||
$content .= $this->msg( 'pageinfo-footer' )->parse();
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,9 @@ class ApiEditPage extends ApiBase {
|
|||
if ( $titleObj->isRedirect() ) {
|
||||
$oldTitle = $titleObj;
|
||||
|
||||
$titles = Revision::newFromTitle( $oldTitle )->getContent( Revision::FOR_THIS_USER )->getRedirectChain();
|
||||
$titles = Revision::newFromTitle( $oldTitle, false, Revision::READ_LATEST )
|
||||
->getContent( Revision::FOR_THIS_USER )
|
||||
->getRedirectChain();
|
||||
// array_shift( $titles );
|
||||
|
||||
$redirValues = array();
|
||||
|
|
@ -237,7 +239,7 @@ class ApiEditPage extends ApiBase {
|
|||
if ( !is_null( $params['summary'] ) ) {
|
||||
$requestArray['wpSummary'] = $params['summary'];
|
||||
}
|
||||
|
||||
|
||||
if ( !is_null( $params['sectiontitle'] ) ) {
|
||||
$requestArray['wpSectionTitle'] = $params['sectiontitle'];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,12 @@ abstract class ApiFormatBase extends ApiBase {
|
|||
|
||||
$this->getMain()->getRequest()->response()->header( "Content-Type: $mime; charset=utf-8" );
|
||||
|
||||
//Set X-Frame-Options API results (bug 39180)
|
||||
global $wgApiFrameOptions;
|
||||
if ( $wgApiFrameOptions ) {
|
||||
$this->getMain()->getRequest()->response()->header( "X-Frame-Options: $wgApiFrameOptions" );
|
||||
}
|
||||
|
||||
if ( $isHtml ) {
|
||||
?>
|
||||
<!DOCTYPE HTML>
|
||||
|
|
@ -265,7 +271,7 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
|
|||
// identify URLs
|
||||
$protos = wfUrlProtocolsWithoutProtRel();
|
||||
// This regex hacks around bug 13218 (" included in the URL)
|
||||
$text = preg_replace( "#(($protos).*?)(")?([ \\'\"<>\n]|<|>|")#", '<a href="\\1">\\1</a>\\3\\4', $text );
|
||||
$text = preg_replace( "#(((?i)$protos).*?)(")?([ \\'\"<>\n]|<|>|")#", '<a href="\\1">\\1</a>\\3\\4', $text );
|
||||
// identify requests to api.php
|
||||
$text = preg_replace( "#api\\.php\\?[^ <\n\t]+#", '<a href="\\0">\\0</a>', $text );
|
||||
if ( $this->mHelp ) {
|
||||
|
|
|
|||
|
|
@ -369,6 +369,9 @@ class ApiMain extends ApiBase {
|
|||
try {
|
||||
$this->executeAction();
|
||||
} catch ( Exception $e ) {
|
||||
// Allow extra cleanup and logging
|
||||
wfRunHooks( 'ApiMain::onException', array( $this, $e ) );
|
||||
|
||||
// Log it
|
||||
if ( !( $e instanceof UsageException ) ) {
|
||||
wfDebugLog( 'exception', $e->getLogMessage() );
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
|
|||
if ( $fld_groups ) {
|
||||
if ( !isset( $lastUserData['groups'] ) ) {
|
||||
if ( $lastUserObj ) {
|
||||
$lastUserData['groups'] = ApiQueryUsers::getAutoGroups( $lastUserObj );
|
||||
$lastUserData['groups'] = $lastUserObj->getAutomaticGroups();
|
||||
} else {
|
||||
// This should not normally happen
|
||||
$lastUserData['groups'] = array();
|
||||
|
|
@ -267,7 +267,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
|
|||
}
|
||||
|
||||
if ( $fld_implicitgroups && !isset( $lastUserData['implicitgroups'] ) && $lastUserObj ) {
|
||||
$lastUserData['implicitgroups'] = ApiQueryUsers::getAutoGroups( $lastUserObj );
|
||||
$lastUserData['implicitgroups'] = $lastUserObj->getAutomaticGroups();
|
||||
$result->setIndexedTagName( $lastUserData['implicitgroups'], 'g' );
|
||||
}
|
||||
if ( $fld_rights ) {
|
||||
|
|
|
|||
|
|
@ -76,14 +76,12 @@ class ApiQueryUserInfo extends ApiQueryBase {
|
|||
}
|
||||
|
||||
if ( isset( $this->prop['groups'] ) ) {
|
||||
$autolist = ApiQueryUsers::getAutoGroups( $user );
|
||||
|
||||
$vals['groups'] = array_merge( $autolist, $user->getGroups() );
|
||||
$vals['groups'] = $user->getEffectiveGroups();
|
||||
$result->setIndexedTagName( $vals['groups'], 'g' ); // even if empty
|
||||
}
|
||||
|
||||
if ( isset( $this->prop['implicitgroups'] ) ) {
|
||||
$vals['implicitgroups'] = ApiQueryUsers::getAutoGroups( $user );
|
||||
$vals['implicitgroups'] = $user->getAutomaticGroups();
|
||||
$result->setIndexedTagName( $vals['implicitgroups'], 'g' ); // even if empty
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class ApiQueryUsers extends ApiQueryBase {
|
|||
|
||||
if ( isset( $this->prop['groups'] ) ) {
|
||||
if ( !isset( $data[$name]['groups'] ) ) {
|
||||
$data[$name]['groups'] = self::getAutoGroups( $user );
|
||||
$data[$name]['groups'] = $user->getAutomaticGroups();
|
||||
}
|
||||
|
||||
if ( !is_null( $row->ug_group ) ) {
|
||||
|
|
@ -148,7 +148,7 @@ class ApiQueryUsers extends ApiQueryBase {
|
|||
}
|
||||
|
||||
if ( isset( $this->prop['implicitgroups'] ) && !isset( $data[$name]['implicitgroups'] ) ) {
|
||||
$data[$name]['implicitgroups'] = self::getAutoGroups( $user );
|
||||
$data[$name]['implicitgroups'] = $user->getAutomaticGroups();
|
||||
}
|
||||
|
||||
if ( isset( $this->prop['rights'] ) ) {
|
||||
|
|
@ -249,20 +249,15 @@ class ApiQueryUsers extends ApiQueryBase {
|
|||
|
||||
/**
|
||||
* Gets all the groups that a user is automatically a member of (implicit groups)
|
||||
*
|
||||
* @deprecated since 1.20; call User::getAutomaticGroups() directly.
|
||||
* @param $user User
|
||||
* @return array
|
||||
*/
|
||||
public static function getAutoGroups( $user ) {
|
||||
// FIXME this logic is duplicated from User::getEffectiveGroups(), centralize this
|
||||
$groups = array();
|
||||
$groups[] = '*';
|
||||
wfDeprecated( __METHOD__, '1.20' );
|
||||
|
||||
if ( !$user->isAnon() ) {
|
||||
$groups[] = 'user';
|
||||
$groups = array_merge( $groups, Autopromote::getAutopromoteGroups( $user ) );
|
||||
}
|
||||
|
||||
return $groups;
|
||||
return $user->getAutomaticGroups();
|
||||
}
|
||||
|
||||
public function getCacheMode( $params ) {
|
||||
|
|
|
|||
4
includes/cache/MessageCache.php
vendored
4
includes/cache/MessageCache.php
vendored
|
|
@ -766,7 +766,9 @@ class MessageCache {
|
|||
}
|
||||
|
||||
# Try loading it from the database
|
||||
$revision = Revision::newFromTitle( Title::makeTitle( NS_MEDIAWIKI, $title ) );
|
||||
$revision = Revision::newFromTitle(
|
||||
Title::makeTitle( NS_MEDIAWIKI, $title ), false, Revision::READ_LATEST
|
||||
);
|
||||
if ( $revision ) {
|
||||
$content = $revision->getContent();
|
||||
if ( !$content ) {
|
||||
|
|
|
|||
|
|
@ -225,12 +225,12 @@ abstract class DatabaseBase implements DatabaseType {
|
|||
|
||||
protected $mServer, $mUser, $mPassword, $mDBname;
|
||||
|
||||
/**
|
||||
* @var DatabaseBase
|
||||
*/
|
||||
protected $mConn = null;
|
||||
protected $mOpened = false;
|
||||
|
||||
/** @var Array */
|
||||
protected $trxIdleCallbacks = array();
|
||||
|
||||
protected $mTablePrefix;
|
||||
protected $mFlags;
|
||||
protected $mTrxLevel = 0;
|
||||
|
|
@ -1103,7 +1103,10 @@ abstract class DatabaseBase implements DatabaseType {
|
|||
}
|
||||
|
||||
if ( isset( $options['HAVING'] ) ) {
|
||||
$preLimitTail .= " HAVING {$options['HAVING']}";
|
||||
$having = is_array( $options['HAVING'] )
|
||||
? $this->makeList( $options['HAVING'], LIST_AND )
|
||||
: $options['HAVING'];
|
||||
$preLimitTail .= " HAVING {$having}";
|
||||
}
|
||||
|
||||
if ( isset( $options['ORDER BY'] ) ) {
|
||||
|
|
@ -1264,7 +1267,9 @@ abstract class DatabaseBase implements DatabaseType {
|
|||
* - GROUP BY: May be either an SQL fragment string naming a field or
|
||||
* expression to group by, or an array of such SQL fragments.
|
||||
*
|
||||
* - HAVING: A string containing a HAVING clause.
|
||||
* - HAVING: May be either an string containing a HAVING clause or an array of
|
||||
* conditions building the HAVING clause. If an array is given, the conditions
|
||||
* constructed from each element are combined with AND.
|
||||
*
|
||||
* - ORDER BY: May be either an SQL fragment giving a field name or
|
||||
* expression to order by, or an array of such SQL fragments.
|
||||
|
|
@ -2825,12 +2830,62 @@ abstract class DatabaseBase implements DatabaseType {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run an anonymous function as soon as there is no transaction pending.
|
||||
* If there is a transaction and it is rolled back, then the callback is cancelled.
|
||||
* Callbacks must commit any transactions that they begin.
|
||||
*
|
||||
* This is useful for updates to different systems or separate transactions are needed.
|
||||
*
|
||||
* @param Closure $callback
|
||||
* @return void
|
||||
*/
|
||||
final public function onTransactionIdle( Closure $callback ) {
|
||||
if ( $this->mTrxLevel ) {
|
||||
$this->trxIdleCallbacks[] = $callback;
|
||||
} else {
|
||||
$callback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually run the "on transaction idle" callbacks
|
||||
*/
|
||||
protected function runOnTransactionIdleCallbacks() {
|
||||
$e = null; // last exception
|
||||
do { // callbacks may add callbacks :)
|
||||
$callbacks = $this->trxIdleCallbacks;
|
||||
$this->trxIdleCallbacks = array(); // recursion guard
|
||||
foreach ( $callbacks as $callback ) {
|
||||
try {
|
||||
$callback();
|
||||
} catch ( Exception $e ) {}
|
||||
}
|
||||
} while ( count( $this->trxIdleCallbacks ) );
|
||||
|
||||
if ( $e instanceof Exception ) {
|
||||
throw $e; // re-throw any last exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a transaction
|
||||
*
|
||||
* @param $fname string
|
||||
*/
|
||||
public function begin( $fname = 'DatabaseBase::begin' ) {
|
||||
final public function begin( $fname = 'DatabaseBase::begin' ) {
|
||||
if ( $this->mTrxLevel ) { // implicit commit
|
||||
$this->doCommit( $fname );
|
||||
$this->runOnTransactionIdleCallbacks();
|
||||
}
|
||||
$this->doBegin( $fname );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DatabaseBase::begin()
|
||||
* @param type $fname
|
||||
*/
|
||||
protected function doBegin( $fname ) {
|
||||
$this->query( 'BEGIN', $fname );
|
||||
$this->mTrxLevel = 1;
|
||||
}
|
||||
|
|
@ -2840,7 +2895,16 @@ abstract class DatabaseBase implements DatabaseType {
|
|||
*
|
||||
* @param $fname string
|
||||
*/
|
||||
public function commit( $fname = 'DatabaseBase::commit' ) {
|
||||
final public function commit( $fname = 'DatabaseBase::commit' ) {
|
||||
$this->doCommit( $fname );
|
||||
$this->runOnTransactionIdleCallbacks();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DatabaseBase::commit()
|
||||
* @param type $fname
|
||||
*/
|
||||
protected function doCommit( $fname ) {
|
||||
if ( $this->mTrxLevel ) {
|
||||
$this->query( 'COMMIT', $fname );
|
||||
$this->mTrxLevel = 0;
|
||||
|
|
@ -2853,7 +2917,16 @@ abstract class DatabaseBase implements DatabaseType {
|
|||
*
|
||||
* @param $fname string
|
||||
*/
|
||||
public function rollback( $fname = 'DatabaseBase::rollback' ) {
|
||||
final public function rollback( $fname = 'DatabaseBase::rollback' ) {
|
||||
$this->doRollback( $fname );
|
||||
$this->trxIdleCallbacks = array(); // cancel
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DatabaseBase::rollback()
|
||||
* @param type $fname
|
||||
*/
|
||||
protected function doRollback( $fname ) {
|
||||
if ( $this->mTrxLevel ) {
|
||||
$this->query( 'ROLLBACK', $fname, true );
|
||||
$this->mTrxLevel = 0;
|
||||
|
|
|
|||
|
|
@ -807,7 +807,7 @@ class DatabaseIbm_db2 extends DatabaseBase {
|
|||
/**
|
||||
* Start a transaction (mandatory)
|
||||
*/
|
||||
public function begin( $fname = 'DatabaseIbm_db2::begin' ) {
|
||||
protected function doBegin( $fname = 'DatabaseIbm_db2::begin' ) {
|
||||
// BEGIN is implicit for DB2
|
||||
// However, it requires that AutoCommit be off.
|
||||
|
||||
|
|
@ -823,7 +823,7 @@ class DatabaseIbm_db2 extends DatabaseBase {
|
|||
* End a transaction
|
||||
* Must have a preceding begin()
|
||||
*/
|
||||
public function commit( $fname = 'DatabaseIbm_db2::commit' ) {
|
||||
protected function doCommit( $fname = 'DatabaseIbm_db2::commit' ) {
|
||||
db2_commit( $this->mConn );
|
||||
|
||||
// Some MediaWiki code is still transaction-less (?).
|
||||
|
|
@ -837,7 +837,7 @@ class DatabaseIbm_db2 extends DatabaseBase {
|
|||
/**
|
||||
* Cancel a transaction
|
||||
*/
|
||||
public function rollback( $fname = 'DatabaseIbm_db2::rollback' ) {
|
||||
protected function doRollback( $fname = 'DatabaseIbm_db2::rollback' ) {
|
||||
db2_rollback( $this->mConn );
|
||||
// turn auto-commit back on
|
||||
// not sure if this is appropriate
|
||||
|
|
|
|||
|
|
@ -694,7 +694,7 @@ class DatabaseMssql extends DatabaseBase {
|
|||
/**
|
||||
* Begin a transaction, committing any previously open transaction
|
||||
*/
|
||||
function begin( $fname = 'DatabaseMssql::begin' ) {
|
||||
protected function doBegin( $fname = 'DatabaseMssql::begin' ) {
|
||||
sqlsrv_begin_transaction( $this->mConn );
|
||||
$this->mTrxLevel = 1;
|
||||
}
|
||||
|
|
@ -702,7 +702,7 @@ class DatabaseMssql extends DatabaseBase {
|
|||
/**
|
||||
* End a transaction
|
||||
*/
|
||||
function commit( $fname = 'DatabaseMssql::commit' ) {
|
||||
protected function doCommit( $fname = 'DatabaseMssql::commit' ) {
|
||||
sqlsrv_commit( $this->mConn );
|
||||
$this->mTrxLevel = 0;
|
||||
}
|
||||
|
|
@ -711,7 +711,7 @@ class DatabaseMssql extends DatabaseBase {
|
|||
* Rollback a transaction.
|
||||
* No-op on non-transactional databases.
|
||||
*/
|
||||
function rollback( $fname = 'DatabaseMssql::rollback' ) {
|
||||
protected function doRollback( $fname = 'DatabaseMssql::rollback' ) {
|
||||
sqlsrv_rollback( $this->mConn );
|
||||
$this->mTrxLevel = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class DatabaseMysql extends DatabaseBase {
|
|||
* @throws DBConnectionError
|
||||
*/
|
||||
function open( $server, $user, $password, $dbName ) {
|
||||
global $wgAllDBsAreLocalhost;
|
||||
global $wgAllDBsAreLocalhost, $wgDBmysql5, $wgSQLMode;
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
# Load mysql.so if we don't have it
|
||||
|
|
@ -91,7 +91,7 @@ class DatabaseMysql extends DatabaseBase {
|
|||
$connFlags |= MYSQL_CLIENT_COMPRESS;
|
||||
}
|
||||
|
||||
wfProfileIn("dbconnect-$server");
|
||||
wfProfileIn( "dbconnect-$server" );
|
||||
|
||||
# The kernel's default SYN retransmission period is far too slow for us,
|
||||
# so we use a short timeout plus a manual retry. Retrying means that a small
|
||||
|
|
@ -118,60 +118,54 @@ class DatabaseMysql extends DatabaseBase {
|
|||
#wfLogDBError("Connect loop error $iplus of $max ($server): " . mysql_errno() . " - " . mysql_error()."\n");
|
||||
#}
|
||||
}
|
||||
$phpError = $this->restoreErrorHandler();
|
||||
$error = $this->restoreErrorHandler();
|
||||
|
||||
wfProfileOut( "dbconnect-$server" );
|
||||
|
||||
# Always log connection errors
|
||||
if ( !$this->mConn ) {
|
||||
$error = $phpError;
|
||||
if ( !$error ) {
|
||||
$error = $this->lastError();
|
||||
}
|
||||
wfLogDBError( "Error connecting to {$this->mServer}: $error\n" );
|
||||
wfDebug( "DB connection error\n" );
|
||||
wfDebug( "Server: $server, User: $user, Password: " .
|
||||
wfDebug( "DB connection error\n" .
|
||||
"Server: $server, User: $user, Password: " .
|
||||
substr( $password, 0, 3 ) . "..., error: " . $error . "\n" );
|
||||
|
||||
wfProfileOut( __METHOD__ );
|
||||
$this->reportConnectionError( $error );
|
||||
}
|
||||
|
||||
wfProfileOut("dbconnect-$server");
|
||||
|
||||
if ( $dbName != '' && $this->mConn !== false ) {
|
||||
if ( $dbName != '' ) {
|
||||
wfSuppressWarnings();
|
||||
$success = mysql_select_db( $dbName, $this->mConn );
|
||||
wfRestoreWarnings();
|
||||
if ( !$success ) {
|
||||
$error = "Error selecting database $dbName on server {$this->mServer} " .
|
||||
"from client host " . wfHostname() . "\n";
|
||||
wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
|
||||
wfDebug( $error );
|
||||
wfLogDBError( "Error selecting database $dbName on server {$this->mServer}\n" );
|
||||
wfDebug( "Error selecting database $dbName on server {$this->mServer} " .
|
||||
"from client host " . wfHostname() . "\n" );
|
||||
|
||||
wfProfileOut( __METHOD__ );
|
||||
$this->reportConnectionError( "Error selecting database $dbName" );
|
||||
}
|
||||
} else {
|
||||
# Delay USE query
|
||||
$success = (bool)$this->mConn;
|
||||
}
|
||||
|
||||
if ( $success ) {
|
||||
// Tell the server we're communicating with it in UTF-8.
|
||||
// This may engage various charset conversions.
|
||||
global $wgDBmysql5;
|
||||
if( $wgDBmysql5 ) {
|
||||
$this->query( 'SET NAMES utf8', __METHOD__ );
|
||||
} else {
|
||||
$this->query( 'SET NAMES binary', __METHOD__ );
|
||||
}
|
||||
// Set SQL mode, default is turning them all off, can be overridden or skipped with null
|
||||
global $wgSQLMode;
|
||||
if ( is_string( $wgSQLMode ) ) {
|
||||
$mode = $this->addQuotes( $wgSQLMode );
|
||||
$this->query( "SET sql_mode = $mode", __METHOD__ );
|
||||
}
|
||||
|
||||
// Turn off strict mode if it is on
|
||||
// Tell the server we're communicating with it in UTF-8.
|
||||
// This may engage various charset conversions.
|
||||
if( $wgDBmysql5 ) {
|
||||
$this->query( 'SET NAMES utf8', __METHOD__ );
|
||||
} else {
|
||||
$this->reportConnectionError( $phpError );
|
||||
$this->query( 'SET NAMES binary', __METHOD__ );
|
||||
}
|
||||
// Set SQL mode, default is turning them all off, can be overridden or skipped with null
|
||||
if ( is_string( $wgSQLMode ) ) {
|
||||
$mode = $this->addQuotes( $wgSQLMode );
|
||||
$this->query( "SET sql_mode = $mode", __METHOD__ );
|
||||
}
|
||||
|
||||
$this->mOpened = $success;
|
||||
$this->mOpened = true;
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $success;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -209,7 +203,13 @@ class DatabaseMysql extends DatabaseBase {
|
|||
wfSuppressWarnings();
|
||||
$row = mysql_fetch_object( $res );
|
||||
wfRestoreWarnings();
|
||||
if( $this->lastErrno() ) {
|
||||
|
||||
$errno = $this->lastErrno();
|
||||
// Unfortunately, mysql_fetch_object does not reset the last errno.
|
||||
// Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as
|
||||
// these are the only errors mysql_fetch_object can cause.
|
||||
// See http://dev.mysql.com/doc/refman/5.0/es/mysql-fetch-row.html.
|
||||
if( $errno == 2000 || $errno == 2013 ) {
|
||||
throw new DBUnexpectedError( $this, 'Error in fetchObject(): ' . htmlspecialchars( $this->lastError() ) );
|
||||
}
|
||||
return $row;
|
||||
|
|
@ -227,7 +227,13 @@ class DatabaseMysql extends DatabaseBase {
|
|||
wfSuppressWarnings();
|
||||
$row = mysql_fetch_array( $res );
|
||||
wfRestoreWarnings();
|
||||
if ( $this->lastErrno() ) {
|
||||
|
||||
$errno = $this->lastErrno();
|
||||
// Unfortunately, mysql_fetch_array does not reset the last errno.
|
||||
// Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as
|
||||
// these are the only errors mysql_fetch_object can cause.
|
||||
// See http://dev.mysql.com/doc/refman/5.0/es/mysql-fetch-row.html.
|
||||
if( $errno == 2000 || $errno == 2013 ) {
|
||||
throw new DBUnexpectedError( $this, 'Error in fetchRow(): ' . htmlspecialchars( $this->lastError() ) );
|
||||
}
|
||||
return $row;
|
||||
|
|
|
|||
|
|
@ -955,12 +955,12 @@ class DatabaseOracle extends DatabaseBase {
|
|||
return $this->fieldInfoMulti ($table, $field);
|
||||
}
|
||||
|
||||
function begin( $fname = 'DatabaseOracle::begin' ) {
|
||||
protected function doBegin( $fname = 'DatabaseOracle::begin' ) {
|
||||
$this->mTrxLevel = 1;
|
||||
$this->doQuery( 'SET CONSTRAINTS ALL DEFERRED' );
|
||||
}
|
||||
|
||||
function commit( $fname = 'DatabaseOracle::commit' ) {
|
||||
protected function doCommit( $fname = 'DatabaseOracle::commit' ) {
|
||||
if ( $this->mTrxLevel ) {
|
||||
$ret = oci_commit( $this->mConn );
|
||||
if ( !$ret ) {
|
||||
|
|
@ -971,7 +971,7 @@ class DatabaseOracle extends DatabaseBase {
|
|||
}
|
||||
}
|
||||
|
||||
function rollback( $fname = 'DatabaseOracle::rollback' ) {
|
||||
protected function doRollback( $fname = 'DatabaseOracle::rollback' ) {
|
||||
if ( $this->mTrxLevel ) {
|
||||
oci_rollback( $this->mConn );
|
||||
$this->mTrxLevel = 0;
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ class DatabaseSqlite extends DatabaseBase {
|
|||
return false;
|
||||
}
|
||||
|
||||
function begin( $fname = '' ) {
|
||||
protected function doBegin( $fname = '' ) {
|
||||
if ( $this->mTrxLevel == 1 ) {
|
||||
$this->commit( __METHOD__ );
|
||||
}
|
||||
|
|
@ -653,7 +653,7 @@ class DatabaseSqlite extends DatabaseBase {
|
|||
$this->mTrxLevel = 1;
|
||||
}
|
||||
|
||||
function commit( $fname = '' ) {
|
||||
protected function doCommit( $fname = '' ) {
|
||||
if ( $this->mTrxLevel == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -661,7 +661,7 @@ class DatabaseSqlite extends DatabaseBase {
|
|||
$this->mTrxLevel = 0;
|
||||
}
|
||||
|
||||
function rollback( $fname = '' ) {
|
||||
protected function doRollback( $fname = '' ) {
|
||||
if ( $this->mTrxLevel == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -685,7 +685,7 @@ class FSFileBackend extends FileBackendStore {
|
|||
|
||||
// Create a new temporary file with the same extension...
|
||||
$ext = FileBackend::extensionFromPath( $params['src'] );
|
||||
$tmpFile = TempFSFile::factory( wfBaseName( $source ) . '_', $ext );
|
||||
$tmpFile = TempFSFile::factory( 'localcopy_', $ext );
|
||||
if ( !$tmpFile ) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@
|
|||
* All "storage paths" are of the format "mwstore://<backend>/<container>/<path>".
|
||||
* The "<path>" portion is a relative path that uses UNIX file system (FS)
|
||||
* notation, though any particular backend may not actually be using a local
|
||||
* filesystem.
|
||||
* Therefore, the relative paths are only virtual.
|
||||
* filesystem. Therefore, the relative paths are only virtual.
|
||||
*
|
||||
* Backend contents are stored under wiki-specific container names by default.
|
||||
* For legacy reasons, this has no effect for the FS backend class, and per-wiki
|
||||
|
|
@ -171,7 +170,8 @@ abstract class FileBackend {
|
|||
* 'dst' => <storage path>,
|
||||
* 'content' => <string of new file contents>,
|
||||
* 'overwrite' => <boolean>,
|
||||
* 'overwriteSame' => <boolean>
|
||||
* 'overwriteSame' => <boolean>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* );
|
||||
* @endcode
|
||||
*
|
||||
|
|
@ -182,7 +182,8 @@ abstract class FileBackend {
|
|||
* 'src' => <file system path>,
|
||||
* 'dst' => <storage path>,
|
||||
* 'overwrite' => <boolean>,
|
||||
* 'overwriteSame' => <boolean>
|
||||
* 'overwriteSame' => <boolean>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
|
|
@ -193,7 +194,8 @@ abstract class FileBackend {
|
|||
* 'src' => <storage path>,
|
||||
* 'dst' => <storage path>,
|
||||
* 'overwrite' => <boolean>,
|
||||
* 'overwriteSame' => <boolean>
|
||||
* 'overwriteSame' => <boolean>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
|
|
@ -204,7 +206,8 @@ abstract class FileBackend {
|
|||
* 'src' => <storage path>,
|
||||
* 'dst' => <storage path>,
|
||||
* 'overwrite' => <boolean>,
|
||||
* 'overwriteSame' => <boolean>
|
||||
* 'overwriteSame' => <boolean>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
|
|
@ -231,6 +234,10 @@ abstract class FileBackend {
|
|||
* - overwriteSame : An error will not be given if a file already
|
||||
* exists at the destination that has the same
|
||||
* contents as the new contents to be written there.
|
||||
* - disposition : When supplied, the backend will add a Content-Disposition
|
||||
* header when GETs/HEADs of the destination file are made.
|
||||
* Backends that don't support file metadata will ignore this.
|
||||
* See http://tools.ietf.org/html/rfc6266 (since 1.20).
|
||||
*
|
||||
* $opts is an associative of boolean flags, including:
|
||||
* - force : Operation precondition errors no longer trigger an abort.
|
||||
|
|
@ -400,7 +407,8 @@ abstract class FileBackend {
|
|||
* array(
|
||||
* 'op' => 'create',
|
||||
* 'dst' => <storage path>,
|
||||
* 'content' => <string of new file contents>
|
||||
* 'content' => <string of new file contents>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* )
|
||||
* @endcode
|
||||
* b) Copy a file system file into storage
|
||||
|
|
@ -408,7 +416,8 @@ abstract class FileBackend {
|
|||
* array(
|
||||
* 'op' => 'store',
|
||||
* 'src' => <file system path>,
|
||||
* 'dst' => <storage path>
|
||||
* 'dst' => <storage path>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* )
|
||||
* @endcode
|
||||
* c) Copy a file within storage
|
||||
|
|
@ -416,7 +425,8 @@ abstract class FileBackend {
|
|||
* array(
|
||||
* 'op' => 'copy',
|
||||
* 'src' => <storage path>,
|
||||
* 'dst' => <storage path>
|
||||
* 'dst' => <storage path>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* )
|
||||
* @endcode
|
||||
* d) Move a file within storage
|
||||
|
|
@ -424,7 +434,8 @@ abstract class FileBackend {
|
|||
* array(
|
||||
* 'op' => 'move',
|
||||
* 'src' => <storage path>,
|
||||
* 'dst' => <storage path>
|
||||
* 'dst' => <storage path>,
|
||||
* 'disposition' => <Content-Disposition header value>
|
||||
* )
|
||||
* @endcode
|
||||
* e) Delete a file within storage
|
||||
|
|
@ -445,6 +456,10 @@ abstract class FileBackend {
|
|||
* @par Boolean flags for operations (operation-specific):
|
||||
* - ignoreMissingSource : The operation will simply succeed and do
|
||||
* nothing if the source file does not exist.
|
||||
* - disposition : When supplied, the backend will add a Content-Disposition
|
||||
* header when GETs/HEADs of the destination file are made.
|
||||
* Backends that don't support file metadata will ignore this.
|
||||
* See http://tools.ietf.org/html/rfc6266 (since 1.20).
|
||||
*
|
||||
* $opts is an associative of boolean flags, including:
|
||||
* - bypassReadOnly : Allow writes in read-only mode (since 1.20)
|
||||
|
|
@ -1089,6 +1104,20 @@ abstract class FileBackend {
|
|||
return ( self::normalizeContainerPath( $path ) !== null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Content-Disposition header value per RFC 6266
|
||||
*
|
||||
* @param $type string One of (attachment, inline)
|
||||
* @param $filename string Suggested file name (should not contain slashes)
|
||||
* @return string
|
||||
* @since 1.20
|
||||
*/
|
||||
final public static function makeContentDisposition( $type, $filename ) {
|
||||
$type = strtolower( $type );
|
||||
$type = in_array( $type, array( 'inline', 'attachment' ) ) ? $type : 'inline';
|
||||
return "$type; filename*=UTF-8''" . rawurlencode( basename( $filename ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and normalize a relative storage path.
|
||||
* Null is returned if the path involves directory traversal.
|
||||
|
|
|
|||
|
|
@ -160,11 +160,14 @@ class FileBackendMultiWrite extends FileBackend {
|
|||
// Actually attempt the operation batch on the master backend...
|
||||
$masterStatus = $mbe->doOperations( $realOps, $opts );
|
||||
$status->merge( $masterStatus );
|
||||
// Propagate the operations to the clone backends...
|
||||
foreach ( $this->backends as $index => $backend ) {
|
||||
if ( $index !== $this->masterIndex ) { // not done already
|
||||
$realOps = $this->substOpBatchPaths( $ops, $backend );
|
||||
$status->merge( $backend->doOperations( $realOps, $opts ) );
|
||||
// Propagate the operations to the clone backends if there were no fatal errors.
|
||||
// If $ops only had one operation, this might avoid backend inconsistencies.
|
||||
if ( !count( $masterStatus->getErrorsArray() ) ) {
|
||||
foreach ( $this->backends as $index => $backend ) {
|
||||
if ( $index !== $this->masterIndex ) { // not done already
|
||||
$realOps = $this->substOpBatchPaths( $ops, $backend );
|
||||
$status->merge( $backend->doOperations( $realOps, $opts ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make 'success', 'successCount', and 'failCount' fields reflect
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* - content : the raw file contents
|
||||
* - dst : destination storage path
|
||||
* - overwrite : overwrite any file that exists at the destination
|
||||
* - disposition : Content-Disposition header value for the destination
|
||||
* - async : Status will be returned immediately if supported.
|
||||
* If the status is OK, then its value field will be
|
||||
* set to a FileBackendStoreOpHandle object.
|
||||
|
|
@ -105,7 +106,9 @@ abstract class FileBackendStore extends FileBackend {
|
|||
} else {
|
||||
$status = $this->doCreateInternal( $params );
|
||||
$this->clearCache( array( $params['dst'] ) );
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
}
|
||||
}
|
||||
wfProfileOut( __METHOD__ . '-' . $this->name );
|
||||
wfProfileOut( __METHOD__ );
|
||||
|
|
@ -125,6 +128,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* - src : source path on disk
|
||||
* - dst : destination storage path
|
||||
* - overwrite : overwrite any file that exists at the destination
|
||||
* - disposition : Content-Disposition header value for the destination
|
||||
* - async : Status will be returned immediately if supported.
|
||||
* If the status is OK, then its value field will be
|
||||
* set to a FileBackendStoreOpHandle object.
|
||||
|
|
@ -141,7 +145,9 @@ abstract class FileBackendStore extends FileBackend {
|
|||
} else {
|
||||
$status = $this->doStoreInternal( $params );
|
||||
$this->clearCache( array( $params['dst'] ) );
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
}
|
||||
}
|
||||
wfProfileOut( __METHOD__ . '-' . $this->name );
|
||||
wfProfileOut( __METHOD__ );
|
||||
|
|
@ -161,6 +167,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* - src : source storage path
|
||||
* - dst : destination storage path
|
||||
* - overwrite : overwrite any file that exists at the destination
|
||||
* - disposition : Content-Disposition header value for the destination
|
||||
* - async : Status will be returned immediately if supported.
|
||||
* If the status is OK, then its value field will be
|
||||
* set to a FileBackendStoreOpHandle object.
|
||||
|
|
@ -173,7 +180,9 @@ abstract class FileBackendStore extends FileBackend {
|
|||
wfProfileIn( __METHOD__ . '-' . $this->name );
|
||||
$status = $this->doCopyInternal( $params );
|
||||
$this->clearCache( array( $params['dst'] ) );
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
}
|
||||
wfProfileOut( __METHOD__ . '-' . $this->name );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $status;
|
||||
|
|
@ -222,6 +231,7 @@ abstract class FileBackendStore extends FileBackend {
|
|||
* - src : source storage path
|
||||
* - dst : destination storage path
|
||||
* - overwrite : overwrite any file that exists at the destination
|
||||
* - disposition : Content-Disposition header value for the destination
|
||||
* - async : Status will be returned immediately if supported.
|
||||
* If the status is OK, then its value field will be
|
||||
* set to a FileBackendStoreOpHandle object.
|
||||
|
|
@ -235,7 +245,9 @@ abstract class FileBackendStore extends FileBackend {
|
|||
$status = $this->doMoveInternal( $params );
|
||||
$this->clearCache( array( $params['src'], $params['dst'] ) );
|
||||
$this->deleteFileCache( $params['src'] ); // persistent cache
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->deleteFileCache( $params['dst'] ); // persistent cache
|
||||
}
|
||||
wfProfileOut( __METHOD__ . '-' . $this->name );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $status;
|
||||
|
|
@ -1460,7 +1472,9 @@ abstract class FileBackendStore extends FileBackend {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the cached stat info for a file path
|
||||
* Set the cached stat info for a file path.
|
||||
* Negatives (404s) are not cached. By not caching negatives, we can skip cache
|
||||
* salting for the case when a file is created at a path were there was none before.
|
||||
*
|
||||
* @param $path string Storage path
|
||||
* @param $val mixed Information to cache
|
||||
|
|
|
|||
|
|
@ -431,18 +431,15 @@ abstract class FileOp {
|
|||
|
||||
/**
|
||||
* Store a file into the backend from a file on the file system.
|
||||
* Parameters similar to FileBackendStore::storeInternal(), which include:
|
||||
* - src : source path on file system
|
||||
* - dst : destination storage path
|
||||
* - overwrite : do nothing and pass if an identical file exists at destination
|
||||
* - overwriteSame : override any existing file at destination
|
||||
* Parameters for this operation are outlined in FileBackend::doOperations().
|
||||
*/
|
||||
class StoreFileOp extends FileOp {
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function allowedParams() {
|
||||
return array( array( 'src', 'dst' ), array( 'overwrite', 'overwriteSame' ) );
|
||||
return array( array( 'src', 'dst' ),
|
||||
array( 'overwrite', 'overwriteSame', 'disposition' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -508,15 +505,12 @@ class StoreFileOp extends FileOp {
|
|||
|
||||
/**
|
||||
* Create a file in the backend with the given content.
|
||||
* Parameters similar to FileBackendStore::createInternal(), which include:
|
||||
* - content : the raw file contents
|
||||
* - dst : destination storage path
|
||||
* - overwrite : do nothing and pass if an identical file exists at destination
|
||||
* - overwriteSame : override any existing file at destination
|
||||
* Parameters for this operation are outlined in FileBackend::doOperations().
|
||||
*/
|
||||
class CreateFileOp extends FileOp {
|
||||
protected function allowedParams() {
|
||||
return array( array( 'content', 'dst' ), array( 'overwrite', 'overwriteSame' ) );
|
||||
return array( array( 'content', 'dst' ),
|
||||
array( 'overwrite', 'overwriteSame', 'disposition' ) );
|
||||
}
|
||||
|
||||
protected function doPrecheck( array &$predicates ) {
|
||||
|
|
@ -571,18 +565,15 @@ class CreateFileOp extends FileOp {
|
|||
|
||||
/**
|
||||
* Copy a file from one storage path to another in the backend.
|
||||
* Parameters similar to FileBackendStore::copyInternal(), which include:
|
||||
* - src : source storage path
|
||||
* - dst : destination storage path
|
||||
* - overwrite : do nothing and pass if an identical file exists at destination
|
||||
* - overwriteSame : override any existing file at destination
|
||||
* Parameters for this operation are outlined in FileBackend::doOperations().
|
||||
*/
|
||||
class CopyFileOp extends FileOp {
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function allowedParams() {
|
||||
return array( array( 'src', 'dst' ), array( 'overwrite', 'overwriteSame' ) );
|
||||
return array( array( 'src', 'dst' ),
|
||||
array( 'overwrite', 'overwriteSame', 'disposition' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -642,18 +633,15 @@ class CopyFileOp extends FileOp {
|
|||
|
||||
/**
|
||||
* Move a file from one storage path to another in the backend.
|
||||
* Parameters similar to FileBackendStore::moveInternal(), which include:
|
||||
* - src : source storage path
|
||||
* - dst : destination storage path
|
||||
* - overwrite : do nothing and pass if an identical file exists at destination
|
||||
* - overwriteSame : override any existing file at destination
|
||||
* Parameters for this operation are outlined in FileBackend::doOperations().
|
||||
*/
|
||||
class MoveFileOp extends FileOp {
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function allowedParams() {
|
||||
return array( array( 'src', 'dst' ), array( 'overwrite', 'overwriteSame' ) );
|
||||
return array( array( 'src', 'dst' ),
|
||||
array( 'overwrite', 'overwriteSame', 'disposition' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -719,9 +707,7 @@ class MoveFileOp extends FileOp {
|
|||
|
||||
/**
|
||||
* Delete a file at the given storage path from the backend.
|
||||
* Parameters similar to FileBackendStore::deleteInternal(), which include:
|
||||
* - src : source storage path
|
||||
* - ignoreMissingSource : don't return an error if the file does not exist
|
||||
* Parameters for this operation are outlined in FileBackend::doOperations().
|
||||
*/
|
||||
class DeleteFileOp extends FileOp {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -210,13 +210,21 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
if ( !strlen( $obj->content_type ) ) { // special case
|
||||
$obj->content_type = 'unknown/unknown';
|
||||
}
|
||||
// Set the Content-Disposition header if requested
|
||||
if ( isset( $params['disposition'] ) ) {
|
||||
$obj->headers['Content-Disposition'] = $params['disposition'];
|
||||
}
|
||||
if ( !empty( $params['async'] ) ) { // deferred
|
||||
$handle = $obj->write_async( $params['content'] );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Create', $handle );
|
||||
$status->value->affectedObjects[] = $obj;
|
||||
$op = $obj->write_async( $params['content'] );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Create', $op );
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$status->value->affectedObjects[] = $obj;
|
||||
}
|
||||
} else { // actually write the object in Swift
|
||||
$obj->write( $params['content'] );
|
||||
$this->purgeCDNCache( array( $obj ) );
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->purgeCDNCache( array( $obj ) );
|
||||
}
|
||||
}
|
||||
} catch ( CDNNotEnabledException $e ) {
|
||||
// CDN not enabled; nothing to see here
|
||||
|
|
@ -292,6 +300,10 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
if ( !strlen( $obj->content_type ) ) { // special case
|
||||
$obj->content_type = 'unknown/unknown';
|
||||
}
|
||||
// Set the Content-Disposition header if requested
|
||||
if ( isset( $params['disposition'] ) ) {
|
||||
$obj->headers['Content-Disposition'] = $params['disposition'];
|
||||
}
|
||||
if ( !empty( $params['async'] ) ) { // deferred
|
||||
wfSuppressWarnings();
|
||||
$fp = fopen( $params['src'], 'rb' );
|
||||
|
|
@ -299,14 +311,18 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
if ( !$fp ) {
|
||||
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
|
||||
} else {
|
||||
$handle = $obj->write_async( $fp, filesize( $params['src'] ), true );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Store', $handle );
|
||||
$op = $obj->write_async( $fp, filesize( $params['src'] ), true );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Store', $op );
|
||||
$status->value->resourcesToClose[] = $fp;
|
||||
$status->value->affectedObjects[] = $obj;
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$status->value->affectedObjects[] = $obj;
|
||||
}
|
||||
}
|
||||
} else { // actually write the object in Swift
|
||||
$obj->load_from_filename( $params['src'], true ); // calls $obj->write()
|
||||
$this->purgeCDNCache( array( $obj ) );
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->purgeCDNCache( array( $obj ) );
|
||||
}
|
||||
}
|
||||
} catch ( CDNNotEnabledException $e ) {
|
||||
// CDN not enabled; nothing to see here
|
||||
|
|
@ -374,13 +390,21 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
// (b) Actually copy the file to the destination
|
||||
try {
|
||||
$dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
|
||||
$hdrs = array(); // source file headers to override with new values
|
||||
if ( isset( $params['disposition'] ) ) {
|
||||
$hdrs['Content-Disposition'] = $params['disposition'];
|
||||
}
|
||||
if ( !empty( $params['async'] ) ) { // deferred
|
||||
$handle = $sContObj->copy_object_to_async( $srcRel, $dContObj, $dstRel );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Copy', $handle );
|
||||
$status->value->affectedObjects[] = $dstObj;
|
||||
$op = $sContObj->copy_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Copy', $op );
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$status->value->affectedObjects[] = $dstObj;
|
||||
}
|
||||
} else { // actually write the object in Swift
|
||||
$sContObj->copy_object_to( $srcRel, $dContObj, $dstRel );
|
||||
$this->purgeCDNCache( array( $dstObj ) );
|
||||
$sContObj->copy_object_to( $srcRel, $dContObj, $dstRel, null, $hdrs );
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->purgeCDNCache( array( $dstObj ) );
|
||||
}
|
||||
}
|
||||
} catch ( CDNNotEnabledException $e ) {
|
||||
// CDN not enabled; nothing to see here
|
||||
|
|
@ -445,14 +469,23 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
try {
|
||||
$srcObj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD
|
||||
$dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
|
||||
$hdrs = array(); // source file headers to override with new values
|
||||
if ( isset( $params['disposition'] ) ) {
|
||||
$hdrs['Content-Disposition'] = $params['disposition'];
|
||||
}
|
||||
if ( !empty( $params['async'] ) ) { // deferred
|
||||
$handle = $sContObj->move_object_to_async( $srcRel, $dContObj, $dstRel );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Move', $handle );
|
||||
$op = $sContObj->move_object_to_async( $srcRel, $dContObj, $dstRel, null, $hdrs );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Move', $op );
|
||||
$status->value->affectedObjects[] = $srcObj;
|
||||
$status->value->affectedObjects[] = $dstObj;
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$status->value->affectedObjects[] = $dstObj;
|
||||
}
|
||||
} else { // actually write the object in Swift
|
||||
$sContObj->move_object_to( $srcRel, $dContObj, $dstRel );
|
||||
$this->purgeCDNCache( array( $srcObj, $dstObj ) );
|
||||
$sContObj->move_object_to( $srcRel, $dContObj, $dstRel, null, $hdrs );
|
||||
$this->purgeCDNCache( array( $srcObj ) );
|
||||
if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
|
||||
$this->purgeCDNCache( array( $dstObj ) );
|
||||
}
|
||||
}
|
||||
} catch ( CDNNotEnabledException $e ) {
|
||||
// CDN not enabled; nothing to see here
|
||||
|
|
@ -493,8 +526,8 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
$sContObj = $this->getContainer( $srcCont );
|
||||
$srcObj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD
|
||||
if ( !empty( $params['async'] ) ) { // deferred
|
||||
$handle = $sContObj->delete_object_async( $srcRel );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Delete', $handle );
|
||||
$op = $sContObj->delete_object_async( $srcRel );
|
||||
$status->value = new SwiftFileOpHandle( $this, $params, 'Delete', $op );
|
||||
$status->value->affectedObjects[] = $srcObj;
|
||||
} else { // actually write the object in Swift
|
||||
$sContObj->delete_object( $srcRel );
|
||||
|
|
@ -989,11 +1022,8 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
return null;
|
||||
}
|
||||
|
||||
# Check the recursion guard to avoid loops when filling metadata
|
||||
if ( empty( $params['nostat'] ) && !$this->fileExists( $params ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Blindly create a tmp file and stream to it, catching any exception if the file does
|
||||
// not exist. Also, doing a stat here will cause infinite loops when filling metadata.
|
||||
$tmpFile = null;
|
||||
try {
|
||||
$sContObj = $this->getContainer( $srcCont );
|
||||
|
|
@ -1001,7 +1031,7 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
// Get source file extension
|
||||
$ext = FileBackend::extensionFromPath( $srcRel );
|
||||
// Create a new temporary file...
|
||||
$tmpFile = TempFSFile::factory( wfBaseName( $srcRel ) . '_', $ext );
|
||||
$tmpFile = TempFSFile::factory( 'localcopy_', $ext );
|
||||
if ( $tmpFile ) {
|
||||
$handle = fopen( $tmpFile->getPath(), 'wb' );
|
||||
if ( $handle ) {
|
||||
|
|
@ -1013,6 +1043,8 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
}
|
||||
} catch ( NoSuchContainerException $e ) {
|
||||
$tmpFile = null;
|
||||
} catch ( NoSuchObjectException $e ) {
|
||||
$tmpFile = null;
|
||||
} catch ( CloudFilesException $e ) { // some other exception?
|
||||
$tmpFile = null;
|
||||
$this->handleException( $e, null, __METHOD__, $params );
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class TempFSFile extends FSFile {
|
|||
*/
|
||||
public static function factory( $prefix, $extension = '' ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
$base = wfTempDir() . '/' . $prefix . dechex( mt_rand( 0, 99999999 ) );
|
||||
$base = wfTempDir() . '/' . $prefix . wfRandomString( 12 );
|
||||
$ext = ( $extension != '' ) ? ".{$extension}" : "";
|
||||
for ( $attempt = 1; true; $attempt++ ) {
|
||||
$path = "{$base}-{$attempt}{$ext}";
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ class FileRepo {
|
|||
var $pathDisclosureProtection = 'simple'; // 'paranoid'
|
||||
var $descriptionCacheExpiry, $url, $thumbUrl;
|
||||
var $hashLevels, $deletedHashLevels;
|
||||
protected $abbrvThreshold;
|
||||
|
||||
/**
|
||||
* Factory functions for creating new files
|
||||
|
|
@ -113,6 +114,9 @@ class FileRepo {
|
|||
? $info['deletedHashLevels']
|
||||
: $this->hashLevels;
|
||||
$this->transformVia404 = !empty( $info['transformVia404'] );
|
||||
$this->abbrvThreshold = isset( $info['abbrvThreshold'] )
|
||||
? $info['abbrvThreshold']
|
||||
: 255;
|
||||
$this->isPrivate = !empty( $info['isPrivate'] );
|
||||
// Give defaults for the basic zones...
|
||||
$this->zones = isset( $info['zones'] ) ? $info['zones'] : array();
|
||||
|
|
@ -839,10 +843,11 @@ class FileRepo {
|
|||
*
|
||||
* @param $src string File system path
|
||||
* @param $dst string Virtual URL or storage path
|
||||
* @param $disposition string|null Content-Disposition if given and supported
|
||||
* @return FileRepoStatus
|
||||
*/
|
||||
final public function quickImport( $src, $dst ) {
|
||||
return $this->quickImportBatch( array( array( $src, $dst ) ) );
|
||||
final public function quickImport( $src, $dst, $disposition = null ) {
|
||||
return $this->quickImportBatch( array( array( $src, $dst, $disposition ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -878,7 +883,9 @@ class FileRepo {
|
|||
* This function can be used to write to otherwise read-only foreign repos.
|
||||
* This is intended for copying generated thumbnails into the repo.
|
||||
*
|
||||
* @param $pairs Array List of tuples (file system path, virtual URL or storage path)
|
||||
* When "dispositions" are given they are used as Content-Disposition if supported.
|
||||
*
|
||||
* @param $pairs Array List of tuples (file system path, virtual URL/storage path, disposition)
|
||||
* @return FileRepoStatus
|
||||
*/
|
||||
public function quickImportBatch( array $pairs ) {
|
||||
|
|
@ -888,9 +895,10 @@ class FileRepo {
|
|||
list ( $src, $dst ) = $pair;
|
||||
$dst = $this->resolveToStoragePath( $dst );
|
||||
$operations[] = array(
|
||||
'op' => 'store',
|
||||
'src' => $src,
|
||||
'dst' => $dst
|
||||
'op' => 'store',
|
||||
'src' => $src,
|
||||
'dst' => $dst,
|
||||
'disposition' => isset( $pair[2] ) ? $pair[2] : null
|
||||
);
|
||||
$status->merge( $this->initDirectory( dirname( $dst ) ) );
|
||||
}
|
||||
|
|
@ -935,19 +943,38 @@ class FileRepo {
|
|||
public function storeTemp( $originalName, $srcPath ) {
|
||||
$this->assertWritableRepo(); // fail out if read-only
|
||||
|
||||
$date = gmdate( "YmdHis" );
|
||||
$hashPath = $this->getHashPath( $originalName );
|
||||
$dstRel = "{$hashPath}{$date}!{$originalName}";
|
||||
$dstUrlRel = $hashPath . $date . '!' . rawurlencode( $originalName );
|
||||
$date = gmdate( "YmdHis" );
|
||||
$hashPath = $this->getHashPath( $originalName );
|
||||
$dstRel = "{$hashPath}{$date}!{$originalName}";
|
||||
$dstUrlRel = $hashPath . $date . '!' . rawurlencode( $originalName );
|
||||
$virtualUrl = $this->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel;
|
||||
|
||||
$result = $this->store( $srcPath, 'temp', $dstRel, self::SKIP_LOCKING );
|
||||
$result->value = $this->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel;
|
||||
$result = $this->quickImport( $srcPath, $virtualUrl );
|
||||
$result->value = $virtualUrl;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate a list of files into a target file location.
|
||||
* Remove a temporary file or mark it for garbage collection
|
||||
*
|
||||
* @param $virtualUrl String: the virtual URL returned by FileRepo::storeTemp()
|
||||
* @return Boolean: true on success, false on failure
|
||||
*/
|
||||
public function freeTemp( $virtualUrl ) {
|
||||
$this->assertWritableRepo(); // fail out if read-only
|
||||
|
||||
$temp = $this->getVirtualUrl( 'temp' );
|
||||
if ( substr( $virtualUrl, 0, strlen( $temp ) ) != $temp ) {
|
||||
wfDebug( __METHOD__.": Invalid temp virtual URL\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->quickPurge( $virtualUrl )->isOK();
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate a list of temporary files into a target file location.
|
||||
*
|
||||
* @param $srcPaths Array Ordered list of source virtual URLs/storage paths
|
||||
* @param $dstPath String Target file system path
|
||||
|
|
@ -961,14 +988,10 @@ class FileRepo {
|
|||
$status = $this->newGood();
|
||||
|
||||
$sources = array();
|
||||
$deleteOperations = array(); // post-concatenate ops
|
||||
foreach ( $srcPaths as $srcPath ) {
|
||||
// Resolve source to a storage path if virtual
|
||||
$source = $this->resolveToStoragePath( $srcPath );
|
||||
$sources[] = $source; // chunk to merge
|
||||
if ( $flags & self::DELETE_SOURCE ) {
|
||||
$deleteOperations[] = array( 'op' => 'delete', 'src' => $source );
|
||||
}
|
||||
}
|
||||
|
||||
// Concatenate the chunks into one FS file
|
||||
|
|
@ -979,36 +1002,16 @@ class FileRepo {
|
|||
}
|
||||
|
||||
// Delete the sources if required
|
||||
if ( $deleteOperations ) {
|
||||
$opts = array( 'force' => true );
|
||||
$status->merge( $this->backend->doOperations( $deleteOperations, $opts ) );
|
||||
if ( $flags & self::DELETE_SOURCE ) {
|
||||
$status->merge( $this->quickPurgeBatch( $srcPaths ) );
|
||||
}
|
||||
|
||||
// Make sure status is OK, despite any $deleteOperations fatals
|
||||
// Make sure status is OK, despite any quickPurgeBatch() fatals
|
||||
$status->setResult( true );
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a temporary file or mark it for garbage collection
|
||||
*
|
||||
* @param $virtualUrl String: the virtual URL returned by FileRepo::storeTemp()
|
||||
* @return Boolean: true on success, false on failure
|
||||
*/
|
||||
public function freeTemp( $virtualUrl ) {
|
||||
$this->assertWritableRepo(); // fail out if read-only
|
||||
|
||||
$temp = "mwrepo://{$this->name}/temp";
|
||||
if ( substr( $virtualUrl, 0, strlen( $temp ) ) != $temp ) {
|
||||
wfDebug( __METHOD__.": Invalid temp virtual URL\n" );
|
||||
return false;
|
||||
}
|
||||
$path = $this->resolveVirtualUrl( $virtualUrl );
|
||||
|
||||
return $this->cleanupBatch( array( $path ), self::SKIP_LOCKING )->isOK();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy or move a file either from a storage path, virtual URL,
|
||||
* or FS path, into this repository at the specified destination location.
|
||||
|
|
@ -1554,6 +1557,21 @@ class FileRepo {
|
|||
return wfMessageFallback( 'shared-repo-name-' . $this->name, 'shared-repo' )->text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the portion of the file that contains the origin file name.
|
||||
* If that name is too long, then the name "thumbnail.<ext>" will be given.
|
||||
*
|
||||
* @param $name string
|
||||
* @return string
|
||||
*/
|
||||
public function nameForThumb( $name ) {
|
||||
if ( strlen( $name ) > $this->abbrvThreshold ) {
|
||||
$ext = FileBackend::extensionFromPath( $name );
|
||||
$name = ( $ext == '' ) ? 'thumbnail' : "thumbnail.$ext";
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this the local file repository.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -767,7 +767,8 @@ abstract class File {
|
|||
* @return string
|
||||
*/
|
||||
function thumbName( $params ) {
|
||||
return $this->generateThumbName( $this->getName(), $params );
|
||||
$name = $this->repo ? $this->repo->nameForThumb( $this->getName() ) : $this->getName();
|
||||
return $this->generateThumbName( $name, $params );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -942,7 +943,8 @@ abstract class File {
|
|||
}
|
||||
} elseif ( $this->repo && $thumb->hasFile() && !$thumb->fileIsSource() ) {
|
||||
// Copy the thumbnail from the file system into storage...
|
||||
$status = $this->repo->quickImport( $tmpThumbPath, $thumbPath );
|
||||
$disposition = $this->getThumbDisposition( $thumbName );
|
||||
$status = $this->repo->quickImport( $tmpThumbPath, $thumbPath, $disposition );
|
||||
if ( $status->isOK() ) {
|
||||
$thumb->setStoragePath( $thumbPath );
|
||||
} else {
|
||||
|
|
@ -966,6 +968,19 @@ abstract class File {
|
|||
return is_object( $thumb ) ? $thumb : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $thumbName string Thumbnail name
|
||||
* @return string Content-Disposition header value
|
||||
*/
|
||||
function getThumbDisposition( $thumbName ) {
|
||||
$fileName = $this->name; // file name to suggest
|
||||
$thumbExt = FileBackend::extensionFromPath( $thumbName );
|
||||
if ( $thumbExt != '' && $thumbExt !== $this->getExtension() ) {
|
||||
$fileName .= ".$thumbExt";
|
||||
}
|
||||
return FileBackend::makeContentDisposition( 'inline', $fileName );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook into transform() to allow migration of thumbnail files
|
||||
* STUB
|
||||
|
|
@ -998,7 +1013,8 @@ abstract class File {
|
|||
$path = '/common/images/icons/' . $icon;
|
||||
$filepath = $wgStyleDirectory . $path;
|
||||
if ( file_exists( $filepath ) ) { // always FS
|
||||
return new ThumbnailImage( $this, $wgStylePath . $path, 120, 120 );
|
||||
$params = array( 'width' => 120, 'height' => 120 );
|
||||
return new ThumbnailImage( $this, $wgStylePath . $path, false, $params );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1151,7 +1151,7 @@ class LocalFile extends File {
|
|||
# Add the log entry
|
||||
$log = new LogPage( 'upload' );
|
||||
$action = $reupload ? 'overwrite' : 'upload';
|
||||
$log->addEntry( $action, $descTitle, $comment, array(), $user );
|
||||
$logId = $log->addEntry( $action, $descTitle, $comment, array(), $user );
|
||||
|
||||
wfProfileIn( __METHOD__ . '-edit' );
|
||||
if ( $descTitle->exists() ) {
|
||||
|
|
@ -1169,6 +1169,8 @@ class LocalFile extends File {
|
|||
wfRunHooks( 'NewRevisionFromEditComplete', array( $wikiPage, $nullRevision, $latest, $user ) );
|
||||
$wikiPage->updateRevisionOn( $dbw, $nullRevision );
|
||||
}
|
||||
$dbw->update( 'logging', array( 'log_page' => $descTitle->getArticleID() ), array( 'log_id' => $logId ), __METHOD__ );
|
||||
|
||||
# Invalidate the cache for the description page
|
||||
$descTitle->invalidateCache();
|
||||
$descTitle->purgeSquid();
|
||||
|
|
@ -1177,7 +1179,11 @@ class LocalFile extends File {
|
|||
# There's already a log entry, so don't make a second RC entry
|
||||
# Squid and file cache for the description page are purged by doEditContent.
|
||||
$content = ContentHandler::makeContent( $pageText, $descTitle );
|
||||
$wikiPage->doEditContent( $content, $comment, EDIT_NEW | EDIT_SUPPRESS_RC, false, $user );
|
||||
$status = $wikiPage->doEditContent( $content, $comment, EDIT_NEW | EDIT_SUPPRESS_RC, false, $user );
|
||||
|
||||
if ( isset( $status->value['revision'] ) ) {
|
||||
$dbw->update( 'logging', array( 'log_page' => $status->value['revision']->getPage() ), array( 'log_id' => $logId ), __METHOD__ );
|
||||
}
|
||||
}
|
||||
wfProfileOut( __METHOD__ . '-edit' );
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class DoubleRedirectJob extends Job {
|
|||
return false;
|
||||
}
|
||||
|
||||
$targetRev = Revision::newFromTitle( $this->title );
|
||||
$targetRev = Revision::newFromTitle( $this->title, false, Revision::READ_LATEST );
|
||||
if ( !$targetRev ) {
|
||||
wfDebug( __METHOD__.": target redirect already deleted, ignoring\n" );
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -167,8 +167,11 @@ class BitmapHandler extends ImageHandler {
|
|||
|
||||
if ( $flags & self::TRANSFORM_LATER ) {
|
||||
wfDebug( __METHOD__ . ": Transforming later per flags.\n" );
|
||||
return new ThumbnailImage( $image, $dstUrl, $scalerParams['clientWidth'],
|
||||
$scalerParams['clientHeight'], false );
|
||||
$params = array(
|
||||
'width' => $scalerParams['clientWidth'],
|
||||
'height' => $scalerParams['clientHeight']
|
||||
);
|
||||
return new ThumbnailImage( $image, $dstUrl, false, $params );
|
||||
}
|
||||
|
||||
# Try to make a target path for the thumbnail
|
||||
|
|
@ -220,8 +223,11 @@ class BitmapHandler extends ImageHandler {
|
|||
} elseif ( $mto ) {
|
||||
return $mto;
|
||||
} else {
|
||||
return new ThumbnailImage( $image, $dstUrl, $scalerParams['clientWidth'],
|
||||
$scalerParams['clientHeight'], $dstPath );
|
||||
$params = array(
|
||||
'width' => $scalerParams['clientWidth'],
|
||||
'height' => $scalerParams['clientHeight']
|
||||
);
|
||||
return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,14 +264,17 @@ class BitmapHandler extends ImageHandler {
|
|||
* client side
|
||||
*
|
||||
* @param $image File File associated with this thumbnail
|
||||
* @param $params array Array with scaler params
|
||||
* @param $scalerParams array Array with scaler params
|
||||
* @return ThumbnailImage
|
||||
*
|
||||
* @todo fixme: no rotation support
|
||||
*/
|
||||
protected function getClientScalingThumbnailImage( $image, $params ) {
|
||||
return new ThumbnailImage( $image, $image->getURL(),
|
||||
$params['clientWidth'], $params['clientHeight'], null );
|
||||
protected function getClientScalingThumbnailImage( $image, $scalerParams ) {
|
||||
$params = array(
|
||||
'width' => $scalerParams['clientWidth'],
|
||||
'height' => $scalerParams['clientHeight']
|
||||
);
|
||||
return new ThumbnailImage( $image, $image->getURL(), null, $params );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ class BitmapHandler_ClientOnly extends BitmapHandler {
|
|||
if ( !$this->normaliseParams( $image, $params ) ) {
|
||||
return new TransformParameterError( $params );
|
||||
}
|
||||
return new ThumbnailImage( $image, $image->getURL(), $params['width'],
|
||||
$params['height'], $image->getLocalRefPath() );
|
||||
return new ThumbnailImage( $image, $image->getURL(), $image->getLocalRefPath(), $params );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,12 @@ class DjVuHandler extends ImageHandler {
|
|||
}
|
||||
|
||||
if ( $flags & self::TRANSFORM_LATER ) {
|
||||
return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page );
|
||||
$params = array(
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'page' => $page
|
||||
);
|
||||
return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
|
||||
}
|
||||
|
||||
if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
|
||||
|
|
@ -192,7 +197,12 @@ class DjVuHandler extends ImageHandler {
|
|||
wfHostname(), $retval, trim($err), $cmd ) );
|
||||
return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
|
||||
} else {
|
||||
return new ThumbnailImage( $image, $dstUrl, $width, $height, $dstPath, $page );
|
||||
$params = array(
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'page' => $page
|
||||
);
|
||||
return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class FormatMetadata {
|
|||
) {
|
||||
continue;
|
||||
}
|
||||
$tags[$tag] = intval( $h[0] / $h[1] )
|
||||
$tags[$tag] = str_pad( intval( $h[0] / $h[1] ), 2, '0', STR_PAD_LEFT )
|
||||
. ':' . str_pad( intval( $m[0] / $m[1] ), 2, '0', STR_PAD_LEFT )
|
||||
. ':' . str_pad( intval( $s[0] / $s[1] ), 2, '0', STR_PAD_LEFT );
|
||||
|
||||
|
|
|
|||
|
|
@ -189,11 +189,9 @@ abstract class ImageHandler extends MediaHandler {
|
|||
return false;
|
||||
}
|
||||
$url = $script . '&' . wfArrayToCGI( $this->getScriptParams( $params ) );
|
||||
$page = isset( $params['page'] ) ? $params['page'] : false;
|
||||
|
||||
if( $image->mustRender() || $params['width'] < $image->getWidth() ) {
|
||||
return new ThumbnailImage( $image,
|
||||
$url, $params['width'], $params['height'], false, $page );
|
||||
return new ThumbnailImage( $image, $url, false, $params );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -214,25 +214,46 @@ class ThumbnailImage extends MediaTransformOutput {
|
|||
* Get a thumbnail object from a file and parameters.
|
||||
* If $path is set to null, the output file is treated as a source copy.
|
||||
* If $path is set to false, no output file will be created.
|
||||
* $parameters should include, as a minimum, (file) 'width' and 'height'.
|
||||
* It may also include a 'page' parameter for multipage files.
|
||||
*
|
||||
* @param $file File object
|
||||
* @param $url String: URL path to the thumb
|
||||
* @param $width Integer: file's width
|
||||
* @param $height Integer: file's height
|
||||
* @param $path String|bool|null: filesystem path to the thumb
|
||||
* @param $page Integer: page number, for multipage files
|
||||
* @param $parameters Array: Associative array of parameters
|
||||
* @private
|
||||
*/
|
||||
function __construct( $file, $url, $width, $height, $path = false, $page = false ) {
|
||||
function __construct( $file, $url, $path = false, $parameters = array() ) {
|
||||
# Previous parameters:
|
||||
# $file, $url, $width, $height, $path = false, $page = false
|
||||
|
||||
if( is_array( $parameters ) ){
|
||||
$defaults = array(
|
||||
'page' => false
|
||||
);
|
||||
$actualParams = $parameters + $defaults;
|
||||
} else {
|
||||
# Using old format, should convert. Later a warning could be added here.
|
||||
$numArgs = func_num_args();
|
||||
$actualParams = array(
|
||||
'width' => $path,
|
||||
'height' => $parameters,
|
||||
'page' => ( $numArgs > 5 ) ? func_get_arg( 5 ) : false
|
||||
);
|
||||
$path = ( $numArgs > 4 ) ? func_get_arg( 4 ) : false;
|
||||
}
|
||||
|
||||
$this->file = $file;
|
||||
$this->url = $url;
|
||||
$this->path = $path;
|
||||
|
||||
# These should be integers when they get here.
|
||||
# If not, there's a bug somewhere. But let's at
|
||||
# least produce valid HTML code regardless.
|
||||
$this->width = round( $width );
|
||||
$this->height = round( $height );
|
||||
$this->path = $path;
|
||||
$this->page = $page;
|
||||
$this->width = round( $actualParams['width'] );
|
||||
$this->height = round( $actualParams['height'] );
|
||||
|
||||
$this->page = $actualParams['page'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class SvgHandler extends ImageHandler {
|
|||
$physicalHeight = $params['physicalHeight'];
|
||||
|
||||
if ( $flags & self::TRANSFORM_LATER ) {
|
||||
return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath );
|
||||
return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
|
||||
}
|
||||
|
||||
if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
|
||||
|
|
@ -128,7 +128,7 @@ class SvgHandler extends ImageHandler {
|
|||
$srcPath = $image->getLocalRefPath();
|
||||
$status = $this->rasterize( $srcPath, $dstPath, $physicalWidth, $physicalHeight );
|
||||
if( $status === true ) {
|
||||
return new ThumbnailImage( $image, $dstUrl, $clientWidth, $clientHeight, $dstPath );
|
||||
return new ThumbnailImage( $image, $dstUrl, $dstPath, $params );
|
||||
} else {
|
||||
return $status; // MediaTransformError
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
* @ingroup Cache
|
||||
*/
|
||||
class APCBagOStuff extends BagOStuff {
|
||||
|
||||
/**
|
||||
* @param $key string
|
||||
* @return mixed
|
||||
|
|
@ -36,7 +35,11 @@ class APCBagOStuff extends BagOStuff {
|
|||
$val = apc_fetch( $key );
|
||||
|
||||
if ( is_string( $val ) ) {
|
||||
$val = unserialize( $val );
|
||||
if ( $this->isInteger( $val ) ) {
|
||||
$val = intval( $val );
|
||||
} else {
|
||||
$val = unserialize( $val );
|
||||
}
|
||||
}
|
||||
|
||||
return $val;
|
||||
|
|
@ -49,7 +52,11 @@ class APCBagOStuff extends BagOStuff {
|
|||
* @return bool
|
||||
*/
|
||||
public function set( $key, $value, $exptime = 0 ) {
|
||||
apc_store( $key, serialize( $value ), $exptime );
|
||||
if ( !$this->isInteger( $value ) ) {
|
||||
$value = serialize( $value );
|
||||
}
|
||||
|
||||
apc_store( $key, $value, $exptime );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -65,6 +72,14 @@ class APCBagOStuff extends BagOStuff {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function incr( $key, $value = 1 ) {
|
||||
return apc_inc( $key, $value );
|
||||
}
|
||||
|
||||
public function decr( $key, $value = 1 ) {
|
||||
return apc_dec( $key, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Array
|
||||
*/
|
||||
|
|
@ -80,4 +95,3 @@ class APCBagOStuff extends BagOStuff {
|
|||
return $keys;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,10 +164,11 @@ abstract class BagOStuff {
|
|||
}
|
||||
|
||||
/**
|
||||
* Increase stored value of $key by $value while preserving its TTL
|
||||
* @param $key String: Key to increase
|
||||
* @param $value Integer: Value to add to $key (Default 1)
|
||||
* @return null if lock is not possible else $key value increased by $value
|
||||
* @return bool success
|
||||
* @return integer
|
||||
*/
|
||||
public function incr( $key, $value = 1 ) {
|
||||
if ( !$this->lock( $key ) ) {
|
||||
|
|
@ -186,9 +187,10 @@ abstract class BagOStuff {
|
|||
}
|
||||
|
||||
/**
|
||||
* Decrease stored value of $key by $value while preserving its TTL
|
||||
* @param $key String
|
||||
* @param $value Integer
|
||||
* @return bool success
|
||||
* @return integer
|
||||
*/
|
||||
public function decr( $key, $value = 1 ) {
|
||||
return $this->incr( $key, - $value );
|
||||
|
|
@ -235,4 +237,14 @@ abstract class BagOStuff {
|
|||
return $exptime;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a value is an integer
|
||||
*
|
||||
* @param $value mixed
|
||||
* @return bool
|
||||
*/
|
||||
protected function isInteger( $value ) {
|
||||
return ( is_int( $value ) || ctype_digit( $value ) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
$params['dir'] = wfTempDir();
|
||||
}
|
||||
|
||||
$this->mFile = $params['dir']."/mw-cache-" . wfWikiID();
|
||||
$this->mFile .= '.db';
|
||||
$this->mFile = $params['dir'] . '/mw-cache-' . wfWikiID() . '.db';
|
||||
wfDebug( __CLASS__ . ": using cache file {$this->mFile}\n" );
|
||||
$this->mHandler = $wgDBAhandler;
|
||||
}
|
||||
|
|
@ -58,7 +57,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function encode( $value, $expiry ) {
|
||||
protected function encode( $value, $expiry ) {
|
||||
# Convert to absolute time
|
||||
$expiry = $this->convertExpiry( $expiry );
|
||||
|
||||
|
|
@ -69,7 +68,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
* @param $blob string
|
||||
* @return array list containing value first and expiry second
|
||||
*/
|
||||
function decode( $blob ) {
|
||||
protected function decode( $blob ) {
|
||||
if ( !is_string( $blob ) ) {
|
||||
return array( null, 0 );
|
||||
} else {
|
||||
|
|
@ -83,7 +82,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
/**
|
||||
* @return resource
|
||||
*/
|
||||
function getReader() {
|
||||
protected function getReader() {
|
||||
if ( file_exists( $this->mFile ) ) {
|
||||
$handle = dba_open( $this->mFile, 'rl', $this->mHandler );
|
||||
} else {
|
||||
|
|
@ -100,7 +99,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
/**
|
||||
* @return resource
|
||||
*/
|
||||
function getWriter() {
|
||||
protected function getWriter() {
|
||||
$handle = dba_open( $this->mFile, 'cl', $this->mHandler );
|
||||
|
||||
if ( !$handle ) {
|
||||
|
|
@ -114,7 +113,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
* @param $key string
|
||||
* @return mixed|null|string
|
||||
*/
|
||||
function get( $key ) {
|
||||
public function get( $key ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
wfDebug( __METHOD__ . "($key)\n" );
|
||||
|
||||
|
|
@ -149,7 +148,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
* @param $exptime int
|
||||
* @return bool
|
||||
*/
|
||||
function set( $key, $value, $exptime = 0 ) {
|
||||
public function set( $key, $value, $exptime = 0 ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
wfDebug( __METHOD__ . "($key)\n" );
|
||||
|
||||
|
|
@ -173,7 +172,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
* @param $time int
|
||||
* @return bool
|
||||
*/
|
||||
function delete( $key, $time = 0 ) {
|
||||
public function delete( $key, $time = 0 ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
wfDebug( __METHOD__ . "($key)\n" );
|
||||
|
||||
|
|
@ -196,7 +195,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
* @param $exptime int
|
||||
* @return bool
|
||||
*/
|
||||
function add( $key, $value, $exptime = 0 ) {
|
||||
public function add( $key, $value, $exptime = 0 ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
$blob = $this->encode( $value, $exptime );
|
||||
|
|
@ -214,7 +213,7 @@ class DBABagOStuff extends BagOStuff {
|
|||
if ( !$ret ) {
|
||||
list( $value, $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
|
||||
|
||||
if ( $expiry < time() ) {
|
||||
if ( $expiry && $expiry < time() ) {
|
||||
# Yes expired, delete and try again
|
||||
dba_delete( $key, $handle );
|
||||
$ret = dba_insert( $key, $blob, $handle );
|
||||
|
|
@ -229,8 +228,43 @@ class DBABagOStuff extends BagOStuff {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return Array
|
||||
* @param $key string
|
||||
* @param $step integer
|
||||
* @return integer|bool
|
||||
*/
|
||||
public function incr( $key, $step = 1 ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
$handle = $this->getWriter();
|
||||
|
||||
if ( !$handle ) {
|
||||
wfProfileOut( __METHOD__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
list( $value, $expiry ) = $this->decode( dba_fetch( $key, $handle ) );
|
||||
if ( !is_null( $value ) ) {
|
||||
if ( $expiry && $expiry < time() ) {
|
||||
# Key is expired, delete it
|
||||
dba_delete( $key, $handle );
|
||||
wfDebug( __METHOD__ . ": $key expired\n" );
|
||||
$value = null;
|
||||
} else {
|
||||
$value += $step;
|
||||
$blob = $this->encode( $value, $expiry );
|
||||
|
||||
$ret = dba_replace( $key, $blob, $handle );
|
||||
$value = $ret ? $value : null;
|
||||
}
|
||||
}
|
||||
|
||||
dba_close( $handle );
|
||||
|
||||
wfProfileOut( __METHOD__ );
|
||||
|
||||
return is_null( $value ) ? false : (int)$value;
|
||||
}
|
||||
|
||||
function keys() {
|
||||
$reader = $this->getReader();
|
||||
$k1 = dba_firstkey( $reader );
|
||||
|
|
@ -250,4 +284,3 @@ class DBABagOStuff extends BagOStuff {
|
|||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
/*
|
||||
/**
|
||||
* Session storage in object cache.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -20,6 +20,13 @@
|
|||
* @file
|
||||
* @ingroup Cache
|
||||
*/
|
||||
|
||||
/**
|
||||
* Session storage in object cache.
|
||||
* Used if $wgSessionsInObjectCache is true.
|
||||
*
|
||||
* @ingroup Cache
|
||||
*/
|
||||
class ObjectCacheSessionHandler {
|
||||
/**
|
||||
* Install a session handler for the current web request
|
||||
|
|
@ -129,7 +136,7 @@ class ObjectCacheSessionHandler {
|
|||
}
|
||||
|
||||
/**
|
||||
* Shutdown function. See the comment inside ObjectCacheSessionHandler::install
|
||||
* Shutdown function. See the comment inside ObjectCacheSessionHandler::install
|
||||
* for rationale.
|
||||
*/
|
||||
static function handleShutdown() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* Object caching using Redis (http://redis.io/).
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
class RedisBagOStuff extends BagOStuff {
|
||||
protected $connectTimeout, $persistent, $password, $automaticFailover;
|
||||
|
|
@ -9,16 +30,16 @@ class RedisBagOStuff extends BagOStuff {
|
|||
protected $servers;
|
||||
|
||||
/**
|
||||
* A cache of Redis objects, representing connections to Redis servers.
|
||||
* A cache of Redis objects, representing connections to Redis servers.
|
||||
* The key is the server name.
|
||||
*/
|
||||
protected $conns = array();
|
||||
|
||||
/**
|
||||
* An array listing "dead" servers which have had a connection error in
|
||||
* the past. Servers are marked dead for a limited period of time, to
|
||||
* An array listing "dead" servers which have had a connection error in
|
||||
* the past. Servers are marked dead for a limited period of time, to
|
||||
* avoid excessive overhead from repeated connection timeouts. The key in
|
||||
* the array is the server name, the value is the UNIX timestamp at which
|
||||
* the array is the server name, the value is the UNIX timestamp at which
|
||||
* the server is resurrected.
|
||||
*/
|
||||
protected $deadServers = array();
|
||||
|
|
@ -26,9 +47,9 @@ class RedisBagOStuff extends BagOStuff {
|
|||
/**
|
||||
* Construct a RedisBagOStuff object. Parameters are:
|
||||
*
|
||||
* - servers: An array of server names. A server name may be a hostname,
|
||||
* - servers: An array of server names. A server name may be a hostname,
|
||||
* a hostname/port combination or the absolute path of a UNIX socket.
|
||||
* If a hostname is specified but no port, the standard port number
|
||||
* If a hostname is specified but no port, the standard port number
|
||||
* 6379 will be used. Required.
|
||||
*
|
||||
* - connectTimeout: The timeout for new connections, in seconds. Optional,
|
||||
|
|
@ -37,16 +58,16 @@ class RedisBagOStuff extends BagOStuff {
|
|||
* - persistent: Set this to true to allow connections to persist across
|
||||
* multiple web requests. False by default.
|
||||
*
|
||||
* - password: The authentication password, will be sent to Redis in
|
||||
* - password: The authentication password, will be sent to Redis in
|
||||
* clear text. Optional, if it is unspecified, no AUTH command will be
|
||||
* sent.
|
||||
*
|
||||
* - automaticFailover: If this is false, then each key will be mapped to
|
||||
* a single server, and if that server is down, any requests for that key
|
||||
* will fail. If this is true, a connection failure will cause the client
|
||||
* to immediately try the next server in the list (as determined by a
|
||||
* consistent hashing algorithm). True by default. This has the
|
||||
* potential to create consistency issues if a server is slow enough to
|
||||
* to immediately try the next server in the list (as determined by a
|
||||
* consistent hashing algorithm). True by default. This has the
|
||||
* potential to create consistency issues if a server is slow enough to
|
||||
* flap, for example if it is in swap death.
|
||||
*/
|
||||
function __construct( $params ) {
|
||||
|
|
@ -56,7 +77,7 @@ class RedisBagOStuff extends BagOStuff {
|
|||
}
|
||||
|
||||
$this->servers = $params['servers'];
|
||||
$this->connectTimeout = isset( $params['connectTimeout'] )
|
||||
$this->connectTimeout = isset( $params['connectTimeout'] )
|
||||
? $params['connectTimeout'] : 1;
|
||||
$this->persistent = !empty( $params['persistent'] );
|
||||
if ( isset( $params['password'] ) ) {
|
||||
|
|
@ -106,7 +127,7 @@ class RedisBagOStuff extends BagOStuff {
|
|||
$result = false;
|
||||
$this->handleException( $server, $e );
|
||||
}
|
||||
|
||||
|
||||
$this->logRequest( 'set', $key, $server, $result );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $result;
|
||||
|
|
@ -196,7 +217,7 @@ class RedisBagOStuff extends BagOStuff {
|
|||
}
|
||||
|
||||
/**
|
||||
* Non-atomic implementation of replace(). Could perhaps be done atomically
|
||||
* Non-atomic implementation of replace(). Could perhaps be done atomically
|
||||
* with WATCH or scripting, but this function is rarely used.
|
||||
*/
|
||||
public function replace( $key, $value, $expiry = 0 ) {
|
||||
|
|
@ -222,19 +243,19 @@ class RedisBagOStuff extends BagOStuff {
|
|||
$result = false;
|
||||
$this->handleException( $server, $e );
|
||||
}
|
||||
|
||||
|
||||
$this->logRequest( 'replace', $key, $server, $result );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-atomic implementation of incr().
|
||||
* Non-atomic implementation of incr().
|
||||
*
|
||||
* Probably all callers actually want incr() to atomically initialise
|
||||
* values to zero if they don't exist, as provided by the Redis INCR
|
||||
* command. But we are constrained by the memcached-like interface to
|
||||
* return null in that case. Once the key exists, further increments are
|
||||
* Probably all callers actually want incr() to atomically initialise
|
||||
* values to zero if they don't exist, as provided by the Redis INCR
|
||||
* command. But we are constrained by the memcached-like interface to
|
||||
* return null in that case. Once the key exists, further increments are
|
||||
* atomic.
|
||||
*/
|
||||
public function incr( $key, $value = 1 ) {
|
||||
|
|
@ -254,7 +275,7 @@ class RedisBagOStuff extends BagOStuff {
|
|||
$result = false;
|
||||
$this->handleException( $server, $e );
|
||||
}
|
||||
|
||||
|
||||
$this->logRequest( 'incr', $key, $server, $result );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $result;
|
||||
|
|
@ -317,7 +338,7 @@ class RedisBagOStuff extends BagOStuff {
|
|||
|
||||
if ( substr( $server, 0, 1 ) === '/' ) {
|
||||
// UNIX domain socket
|
||||
// These are required by the redis extension to start with a slash, but
|
||||
// These are required by the redis extension to start with a slash, but
|
||||
// we still need to set the port to a special value to make it work.
|
||||
$host = $server;
|
||||
$port = 0;
|
||||
|
|
@ -372,8 +393,8 @@ class RedisBagOStuff extends BagOStuff {
|
|||
|
||||
/**
|
||||
* The redis extension throws an exception in response to various read, write
|
||||
* and protocol errors. Sometimes it also closes the connection, sometimes
|
||||
* not. The safest response for us is to explicitly destroy the connection
|
||||
* and protocol errors. Sometimes it also closes the connection, sometimes
|
||||
* not. The safest response for us is to explicitly destroy the connection
|
||||
* object and let it be reopened during the next request.
|
||||
*/
|
||||
protected function handleException( $server, $e ) {
|
||||
|
|
@ -385,7 +406,7 @@ class RedisBagOStuff extends BagOStuff {
|
|||
* Send information about a single request to the debug log
|
||||
*/
|
||||
public function logRequest( $method, $key, $server, $result ) {
|
||||
$this->debug( "$method $key on $server: " .
|
||||
$this->debug( "$method $key on $server: " .
|
||||
( $result === false ? "failure" : "success" ) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,11 @@ class XCacheBagOStuff extends BagOStuff {
|
|||
$val = xcache_get( $key );
|
||||
|
||||
if ( is_string( $val ) ) {
|
||||
$val = unserialize( $val );
|
||||
if ( $this->isInteger( $val ) ) {
|
||||
$val = intval( $val );
|
||||
} else {
|
||||
$val = unserialize( $val );
|
||||
}
|
||||
}
|
||||
|
||||
return $val;
|
||||
|
|
@ -53,7 +57,11 @@ class XCacheBagOStuff extends BagOStuff {
|
|||
* @return bool
|
||||
*/
|
||||
public function set( $key, $value, $expire = 0 ) {
|
||||
xcache_set( $key, serialize( $value ), $expire );
|
||||
if ( !$this->isInteger( $value ) ) {
|
||||
$value = serialize( $value );
|
||||
}
|
||||
|
||||
xcache_set( $key, $value, $expire );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -68,5 +76,12 @@ class XCacheBagOStuff extends BagOStuff {
|
|||
xcache_unset( $key );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function incr( $key, $value = 1 ) {
|
||||
return xcache_inc( $key, $value );
|
||||
}
|
||||
|
||||
public function decr( $key, $value = 1 ) {
|
||||
return xcache_dec( $key, $value );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @todo document
|
||||
* Parser cache specific expiry check.
|
||||
*
|
||||
* 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
|
||||
|
|
@ -21,6 +20,12 @@
|
|||
* @file
|
||||
* @ingroup Parser
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parser cache specific expiry check.
|
||||
*
|
||||
* @ingroup Parser
|
||||
*/
|
||||
class CacheTime {
|
||||
|
||||
var $mVersion = Parser::VERSION, # Compatibility check
|
||||
|
|
@ -124,4 +129,4 @@ class CacheTime {
|
|||
version_compare( $this->mVersion, Parser::VERSION, "lt" );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ class Parser {
|
|||
public function __construct( $conf = array() ) {
|
||||
$this->mConf = $conf;
|
||||
$this->mUrlProtocols = wfUrlProtocols();
|
||||
$this->mExtLinkBracketedRegex = '/\[((' . $this->mUrlProtocols . ')'.
|
||||
$this->mExtLinkBracketedRegex = '/\[(((?i)' . $this->mUrlProtocols . ')'.
|
||||
self::EXT_LINK_URL_CLASS.'+)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/Su';
|
||||
if ( isset( $conf['preprocessorClass'] ) ) {
|
||||
$this->mPreprocessorClass = $conf['preprocessorClass'];
|
||||
|
|
@ -1187,7 +1187,7 @@ class Parser {
|
|||
'!(?: # Start cases
|
||||
(<a[ \t\r\n>].*?</a>) | # m[1]: Skip link text
|
||||
(<.*?>) | # m[2]: Skip stuff inside HTML elements' . "
|
||||
(\\b(?:$prots)$urlChar+) | # m[3]: Free external links" . '
|
||||
(\\b(?i:$prots)$urlChar+) | # m[3]: Free external links" . '
|
||||
(?:RFC|PMID)\s+([0-9]+) | # m[4]: RFC or PMID, capture number
|
||||
ISBN\s+(\b # m[5]: ISBN, capture number
|
||||
(?: 97[89] [\ \-]? )? # optional 13-digit ISBN prefix
|
||||
|
|
@ -1853,7 +1853,7 @@ class Parser {
|
|||
# Don't allow internal links to pages containing
|
||||
# PROTO: where PROTO is a valid URL protocol; these
|
||||
# should be external links.
|
||||
if ( preg_match( '/^(?:' . $this->mUrlProtocols . ')/', $m[1] ) ) {
|
||||
if ( preg_match( '/^(?i:' . $this->mUrlProtocols . ')/', $m[1] ) ) {
|
||||
$s .= $prefix . '[[' . $line ;
|
||||
wfProfileOut( __METHOD__."-misc" );
|
||||
continue;
|
||||
|
|
@ -2091,7 +2091,7 @@ class Parser {
|
|||
* @return String: less-or-more HTML with NOPARSE bits
|
||||
*/
|
||||
function armorLinks( $text ) {
|
||||
return preg_replace( '/\b(' . $this->mUrlProtocols . ')/',
|
||||
return preg_replace( '/\b((?i)' . $this->mUrlProtocols . ')/',
|
||||
"{$this->mUniqPrefix}NOPARSE$1", $text );
|
||||
}
|
||||
|
||||
|
|
@ -5103,8 +5103,8 @@ class Parser {
|
|||
$paramName = 'no-link';
|
||||
$value = true;
|
||||
$validated = true;
|
||||
} elseif ( preg_match( "/^$prots/", $value ) ) {
|
||||
if ( preg_match( "/^($prots)$chars+$/u", $value, $m ) ) {
|
||||
} elseif ( preg_match( "/^(?i)$prots/", $value ) ) {
|
||||
if ( preg_match( "/^((?i)$prots)$chars+$/u", $value, $m ) ) {
|
||||
$paramName = 'link-url';
|
||||
$this->mOutput->addExternalLink( $value );
|
||||
if ( $this->mOptions->getExternalLinkTarget() ) {
|
||||
|
|
@ -5630,7 +5630,7 @@ class Parser {
|
|||
# @todo FIXME: Not tolerant to blank link text
|
||||
# I.E. [http://www.mediawiki.org] will render as [1] or something depending
|
||||
# on how many empty links there are on the page - need to figure that out.
|
||||
$text = preg_replace( '/\[(?:' . $this->mUrlProtocols . ')([^ ]+?) ([^[]+)\]/', '$2', $text );
|
||||
$text = preg_replace( '/\[(?i:' . $this->mUrlProtocols . ')([^ ]+?) ([^[]+)\]/', '$2', $text );
|
||||
|
||||
# Parse wikitext quotes (italics & bold)
|
||||
$text = $this->doQuotes( $text );
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ class Parser_LinkHooks extends Parser {
|
|||
# Don't allow internal links to pages containing
|
||||
# PROTO: where PROTO is a valid URL protocol; these
|
||||
# should be external links.
|
||||
if( preg_match('/^\b(?:' . wfUrlProtocols() . ')/', $titleText) ) {
|
||||
if( preg_match('/^\b(?i:' . wfUrlProtocols() . ')/', $titleText) ) {
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $wt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class Preprocessor_HipHop implements Preprocessor {
|
|||
* @param $args array
|
||||
* @return PPCustomFrame_HipHop
|
||||
*/
|
||||
function newCustomFrame( array $args ) {
|
||||
function newCustomFrame( $args ) {
|
||||
return new PPCustomFrame_HipHop( $this, $args );
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ class Preprocessor_HipHop implements Preprocessor {
|
|||
* @throws MWException
|
||||
* @return PPNode_HipHop_Tree
|
||||
*/
|
||||
function preprocessToObj( string $text, int $flags = 0 ) {
|
||||
function preprocessToObj( $text, $flags = 0 ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
// Check cache.
|
||||
|
|
@ -1066,11 +1066,12 @@ class PPFrame_HipHop implements PPFrame {
|
|||
*
|
||||
* @param $args PPNode_HipHop_Array|array|bool
|
||||
* @param $title Title|bool
|
||||
* @param $indexOffset A number subtracted from the index attributes of the arguments
|
||||
*
|
||||
* @throws MWException
|
||||
* @return PPTemplateFrame_HipHop
|
||||
*/
|
||||
function newChild( $args = false, $title = false ) {
|
||||
function newChild( $args = false, $title = false, $indexOffset = 0 ) {
|
||||
$namedArgs = array();
|
||||
$numberedArgs = array();
|
||||
if ( $title === false ) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
|
|||
if ( !$title->isCssJsSubpage() && !$title->isCssOrJsPage() ) {
|
||||
return null;
|
||||
}
|
||||
$revision = Revision::newFromTitle( $title );
|
||||
$revision = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
|
||||
if ( !$revision ) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
|
|||
// We're dealing with a subclass that doesn't have a DB
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
$hash = $context->getHash();
|
||||
if ( isset( $this->titleMtimes[$hash] ) ) {
|
||||
return $this->titleMtimes[$hash];
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$form->setSubmitTextMsg( $msg );
|
||||
|
||||
# Don't need to do anything if the form has been posted
|
||||
if( !$this->getRequest()->wasPosted() && $this->preErrors ){
|
||||
if ( !$this->getRequest()->wasPosted() && $this->preErrors ) {
|
||||
$s = HTMLForm::formatErrors( $this->preErrors );
|
||||
if( $s ){
|
||||
if ( $s ) {
|
||||
$form->addHeaderText( Html::rawElement(
|
||||
'div',
|
||||
array( 'class' => 'error' ),
|
||||
|
|
@ -122,7 +122,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* Get the HTMLForm descriptor array for the block form
|
||||
* @return Array
|
||||
*/
|
||||
protected function getFormFields(){
|
||||
protected function getFormFields() {
|
||||
global $wgBlockAllowsUTEdit;
|
||||
|
||||
$user = $this->getUser();
|
||||
|
|
@ -158,14 +158,14 @@ class SpecialBlock extends FormSpecialPage {
|
|||
),
|
||||
);
|
||||
|
||||
if( self::canBlockEmail( $user ) ) {
|
||||
if ( self::canBlockEmail( $user ) ) {
|
||||
$a['DisableEmail'] = array(
|
||||
'type' => 'check',
|
||||
'label-message' => 'ipbemailban',
|
||||
);
|
||||
}
|
||||
|
||||
if( $wgBlockAllowsUTEdit ){
|
||||
if ( $wgBlockAllowsUTEdit ) {
|
||||
$a['DisableUTEdit'] = array(
|
||||
'type' => 'check',
|
||||
'label-message' => 'ipb-disableusertalk',
|
||||
|
|
@ -180,7 +180,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
);
|
||||
|
||||
# Allow some users to hide name from block log, blocklist and listusers
|
||||
if( $user->isAllowed( 'hideuser' ) ) {
|
||||
if ( $user->isAllowed( 'hideuser' ) ) {
|
||||
$a['HideUser'] = array(
|
||||
'type' => 'check',
|
||||
'label-message' => 'ipbhidename',
|
||||
|
|
@ -189,7 +189,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
}
|
||||
|
||||
# Watchlist their user page? (Only if user is logged in)
|
||||
if( $user->isLoggedIn() ) {
|
||||
if ( $user->isLoggedIn() ) {
|
||||
$a['Watch'] = array(
|
||||
'type' => 'check',
|
||||
'label-message' => 'ipbwatchuser',
|
||||
|
|
@ -228,7 +228,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* @return Bool whether fields were altered (that is, whether the target is
|
||||
* already blocked)
|
||||
*/
|
||||
protected function maybeAlterFormDefaults( &$fields ){
|
||||
protected function maybeAlterFormDefaults( &$fields ) {
|
||||
# This will be overwritten by request data
|
||||
$fields['Target']['default'] = (string)$this->target;
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
|
||||
$block = Block::newFromTarget( $this->target );
|
||||
|
||||
if( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
|
||||
if ( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
|
||||
&& ( $this->type != Block::TYPE_RANGE # The block isn't a rangeblock
|
||||
|| $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
|
||||
)
|
||||
|
|
@ -246,21 +246,27 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$fields['CreateAccount']['default'] = $block->prevents( 'createaccount' );
|
||||
$fields['AutoBlock']['default'] = $block->isAutoblocking();
|
||||
|
||||
if( isset( $fields['DisableEmail'] ) ){
|
||||
if ( isset( $fields['DisableEmail'] ) ) {
|
||||
$fields['DisableEmail']['default'] = $block->prevents( 'sendemail' );
|
||||
}
|
||||
|
||||
if( isset( $fields['HideUser'] ) ){
|
||||
if ( isset( $fields['HideUser'] ) ) {
|
||||
$fields['HideUser']['default'] = $block->mHideName;
|
||||
}
|
||||
|
||||
if( isset( $fields['DisableUTEdit'] ) ){
|
||||
if ( isset( $fields['DisableUTEdit'] ) ) {
|
||||
$fields['DisableUTEdit']['default'] = $block->prevents( 'editownusertalk' );
|
||||
}
|
||||
|
||||
$fields['Reason']['default'] = $block->mReason;
|
||||
// If the username was hidden (ipb_deleted == 1), don't show the reason
|
||||
// unless this user also has rights to hideuser: Bug 35839
|
||||
if ( !$block->mHideName || $this->getUser()->isAllowed( 'hideuser' ) ) {
|
||||
$fields['Reason']['default'] = $block->mReason;
|
||||
} else {
|
||||
$fields['Reason']['default'] = '';
|
||||
}
|
||||
|
||||
if( $this->getRequest()->wasPosted() ){
|
||||
if ( $this->getRequest()->wasPosted() ) {
|
||||
# Ok, so we got a POST submission asking us to reblock a user. So show the
|
||||
# confirm checkbox; the user will only see it if they haven't previously
|
||||
$fields['Confirm']['type'] = 'check';
|
||||
|
|
@ -271,7 +277,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$fields['Confirm']['default'] = 1;
|
||||
}
|
||||
|
||||
if( $block->mExpiry == 'infinity' ) {
|
||||
if ( $block->mExpiry == 'infinity' ) {
|
||||
$fields['Expiry']['default'] = 'infinite';
|
||||
} else {
|
||||
$fields['Expiry']['default'] = wfTimestamp( TS_RFC2822, $block->mExpiry );
|
||||
|
|
@ -282,14 +288,14 @@ class SpecialBlock extends FormSpecialPage {
|
|||
}
|
||||
|
||||
# We always need confirmation to do HideUser
|
||||
if( $this->requestedHideUser ){
|
||||
if ( $this->requestedHideUser ) {
|
||||
$fields['Confirm']['type'] = 'check';
|
||||
unset( $fields['Confirm']['default'] );
|
||||
$this->preErrors[] = 'ipb-confirmhideuser';
|
||||
}
|
||||
|
||||
# Or if the user is trying to block themselves
|
||||
if( (string)$this->target === $this->getUser()->getName() ){
|
||||
if ( (string)$this->target === $this->getUser()->getName() ) {
|
||||
$fields['Confirm']['type'] = 'check';
|
||||
unset( $fields['Confirm']['default'] );
|
||||
$this->preErrors[] = 'ipb-blockingself';
|
||||
|
|
@ -300,17 +306,17 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* Add header elements like block log entries, etc.
|
||||
* @return String
|
||||
*/
|
||||
protected function preText(){
|
||||
protected function preText() {
|
||||
$this->getOutput()->addModules( 'mediawiki.special.block' );
|
||||
|
||||
$text = $this->msg( 'blockiptext' )->parse();
|
||||
|
||||
$otherBlockMessages = array();
|
||||
if( $this->target !== null ) {
|
||||
if ( $this->target !== null ) {
|
||||
# Get other blocks, i.e. from GlobalBlocking or TorBlock extension
|
||||
wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockMessages, $this->target ) );
|
||||
|
||||
if( count( $otherBlockMessages ) ) {
|
||||
if ( count( $otherBlockMessages ) ) {
|
||||
$s = Html::rawElement(
|
||||
'h2',
|
||||
array(),
|
||||
|
|
@ -319,7 +325,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
|
||||
$list = '';
|
||||
|
||||
foreach( $otherBlockMessages as $link ) {
|
||||
foreach ( $otherBlockMessages as $link ) {
|
||||
$list .= Html::rawElement( 'li', array(), $link ) . "\n";
|
||||
}
|
||||
|
||||
|
|
@ -340,11 +346,11 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* Add footer elements to the form
|
||||
* @return string
|
||||
*/
|
||||
protected function postText(){
|
||||
protected function postText() {
|
||||
$links = array();
|
||||
|
||||
# Link to the user's contributions, if applicable
|
||||
if( $this->target instanceof User ){
|
||||
if ( $this->target instanceof User ) {
|
||||
$contribsPage = SpecialPage::getTitleFor( 'Contributions', $this->target->getName() );
|
||||
$links[] = Linker::link(
|
||||
$contribsPage,
|
||||
|
|
@ -353,7 +359,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
}
|
||||
|
||||
# Link to unblock the specified user, or to a blank unblock form
|
||||
if( $this->target instanceof User ) {
|
||||
if ( $this->target instanceof User ) {
|
||||
$message = $this->msg( 'ipb-unblock-addr', wfEscapeWikiText( $this->target->getName() ) )->parse();
|
||||
$list = SpecialPage::getTitleFor( 'Unblock', $this->target->getName() );
|
||||
} else {
|
||||
|
|
@ -387,7 +393,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
);
|
||||
|
||||
$userTitle = self::getTargetUserTitle( $this->target );
|
||||
if( $userTitle ){
|
||||
if ( $userTitle ) {
|
||||
# Get relevant extracts from the block and suppression logs, if possible
|
||||
$out = '';
|
||||
|
||||
|
|
@ -405,7 +411,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$text .= $out;
|
||||
|
||||
# Add suppression block entries if allowed
|
||||
if( $user->isAllowed( 'suppressionlog' ) ) {
|
||||
if ( $user->isAllowed( 'suppressionlog' ) ) {
|
||||
LogEventsList::showLogExtract(
|
||||
$out,
|
||||
'suppress',
|
||||
|
|
@ -433,7 +439,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* @return Title|null
|
||||
*/
|
||||
protected static function getTargetUserTitle( $target ) {
|
||||
if( $target instanceof User ) {
|
||||
if ( $target instanceof User ) {
|
||||
return $target->getUserPage();
|
||||
} elseif ( IP::isIPAddress( $target ) ) {
|
||||
return Title::makeTitleSafe( NS_USER, $target );
|
||||
|
|
@ -449,18 +455,18 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* @param $request WebRequest optionally try and get data from a request too
|
||||
* @return array( User|string|null, Block::TYPE_ constant|null )
|
||||
*/
|
||||
public static function getTargetAndType( $par, WebRequest $request = null ){
|
||||
public static function getTargetAndType( $par, WebRequest $request = null ) {
|
||||
$i = 0;
|
||||
$target = null;
|
||||
|
||||
while( true ){
|
||||
switch( $i++ ){
|
||||
while( true ) {
|
||||
switch( $i++ ) {
|
||||
case 0:
|
||||
# The HTMLForm will check wpTarget first and only if it doesn't get
|
||||
# a value use the default, which will be generated from the options
|
||||
# below; so this has to have a higher precedence here than $par, or
|
||||
# we could end up with different values in $this->target and the HTMLForm!
|
||||
if( $request instanceof WebRequest ){
|
||||
if ( $request instanceof WebRequest ) {
|
||||
$target = $request->getText( 'wpTarget', null );
|
||||
}
|
||||
break;
|
||||
|
|
@ -468,13 +474,13 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$target = $par;
|
||||
break;
|
||||
case 2:
|
||||
if( $request instanceof WebRequest ){
|
||||
if ( $request instanceof WebRequest ) {
|
||||
$target = $request->getText( 'ip', null );
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
# B/C @since 1.18
|
||||
if( $request instanceof WebRequest ){
|
||||
if ( $request instanceof WebRequest ) {
|
||||
$target = $request->getText( 'wpBlockAddress', null );
|
||||
}
|
||||
break;
|
||||
|
|
@ -484,7 +490,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
|
||||
list( $target, $type ) = Block::parseTarget( $target );
|
||||
|
||||
if( $type !== null ){
|
||||
if ( $type !== null ) {
|
||||
return array( $target, $type );
|
||||
}
|
||||
}
|
||||
|
|
@ -505,9 +511,9 @@ class SpecialBlock extends FormSpecialPage {
|
|||
|
||||
list( $target, $type ) = self::getTargetAndType( $value );
|
||||
|
||||
if( $type == Block::TYPE_USER ){
|
||||
if ( $type == Block::TYPE_USER ) {
|
||||
# TODO: why do we not have a User->exists() method?
|
||||
if( !$target->getId() ){
|
||||
if ( !$target->getId() ) {
|
||||
return $form->msg( 'nosuchusershort',
|
||||
wfEscapeWikiText( $target->getName() ) );
|
||||
}
|
||||
|
|
@ -517,31 +523,31 @@ class SpecialBlock extends FormSpecialPage {
|
|||
return $form->msg( 'badaccess', $status );
|
||||
}
|
||||
|
||||
} elseif( $type == Block::TYPE_RANGE ){
|
||||
} elseif ( $type == Block::TYPE_RANGE ) {
|
||||
list( $ip, $range ) = explode( '/', $target, 2 );
|
||||
|
||||
if( ( IP::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 )
|
||||
if ( ( IP::isIPv4( $ip ) && $wgBlockCIDRLimit['IPv4'] == 32 )
|
||||
|| ( IP::isIPv6( $ip ) && $wgBlockCIDRLimit['IPv6'] == 128 ) )
|
||||
{
|
||||
# Range block effectively disabled
|
||||
return $form->msg( 'range_block_disabled' );
|
||||
}
|
||||
|
||||
if( ( IP::isIPv4( $ip ) && $range > 32 )
|
||||
if ( ( IP::isIPv4( $ip ) && $range > 32 )
|
||||
|| ( IP::isIPv6( $ip ) && $range > 128 ) )
|
||||
{
|
||||
# Dodgy range
|
||||
return $form->msg( 'ip_range_invalid' );
|
||||
}
|
||||
|
||||
if( IP::isIPv4( $ip ) && $range < $wgBlockCIDRLimit['IPv4'] ) {
|
||||
if ( IP::isIPv4( $ip ) && $range < $wgBlockCIDRLimit['IPv4'] ) {
|
||||
return $form->msg( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv4'] );
|
||||
}
|
||||
|
||||
if( IP::isIPv6( $ip ) && $range < $wgBlockCIDRLimit['IPv6'] ) {
|
||||
if ( IP::isIPv6( $ip ) && $range < $wgBlockCIDRLimit['IPv6'] ) {
|
||||
return $form->msg( 'ip_range_toolarge', $wgBlockCIDRLimit['IPv6'] );
|
||||
}
|
||||
} elseif( $type == Block::TYPE_IP ){
|
||||
} elseif ( $type == Block::TYPE_IP ) {
|
||||
# All is well
|
||||
} else {
|
||||
return $form->msg( 'badipaddress' );
|
||||
|
|
@ -566,7 +572,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* @param $context IContextSource
|
||||
* @return Bool|String
|
||||
*/
|
||||
public static function processForm( array $data, IContextSource $context ){
|
||||
public static function processForm( array $data, IContextSource $context ) {
|
||||
global $wgBlockAllowsUTEdit;
|
||||
|
||||
$performer = $context->getUser();
|
||||
|
|
@ -579,7 +585,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$data['Confirm'] = !in_array( $data['Confirm'], array( '', '0', null, false ), true );
|
||||
|
||||
list( $target, $type ) = self::getTargetAndType( $data['Target'] );
|
||||
if( $type == Block::TYPE_USER ){
|
||||
if ( $type == Block::TYPE_USER ) {
|
||||
$user = $target;
|
||||
$target = $user->getName();
|
||||
$userId = $user->getId();
|
||||
|
|
@ -591,14 +597,14 @@ class SpecialBlock extends FormSpecialPage {
|
|||
# since both $data['PreviousTarget'] and $target are normalized
|
||||
# but $data['target'] gets overriden by (non-normalized) request variable
|
||||
# from previous request.
|
||||
if( $target === $performer->getName() &&
|
||||
if ( $target === $performer->getName() &&
|
||||
( $data['PreviousTarget'] !== $target || !$data['Confirm'] ) )
|
||||
{
|
||||
return array( 'ipb-blockingself' );
|
||||
}
|
||||
} elseif( $type == Block::TYPE_RANGE ){
|
||||
} elseif ( $type == Block::TYPE_RANGE ) {
|
||||
$userId = 0;
|
||||
} elseif( $type == Block::TYPE_IP ){
|
||||
} elseif ( $type == Block::TYPE_IP ) {
|
||||
$target = $target->getName();
|
||||
$userId = 0;
|
||||
} else {
|
||||
|
|
@ -606,24 +612,24 @@ class SpecialBlock extends FormSpecialPage {
|
|||
return array( 'badipaddress' );
|
||||
}
|
||||
|
||||
if( ( strlen( $data['Expiry'] ) == 0) || ( strlen( $data['Expiry'] ) > 50 )
|
||||
if ( ( strlen( $data['Expiry'] ) == 0) || ( strlen( $data['Expiry'] ) > 50 )
|
||||
|| !self::parseExpiryInput( $data['Expiry'] ) )
|
||||
{
|
||||
return array( 'ipb_expiry_invalid' );
|
||||
}
|
||||
|
||||
if( !isset( $data['DisableEmail'] ) ){
|
||||
if ( !isset( $data['DisableEmail'] ) ) {
|
||||
$data['DisableEmail'] = false;
|
||||
}
|
||||
|
||||
# If the user has done the form 'properly', they won't even have been given the
|
||||
# option to suppress-block unless they have the 'hideuser' permission
|
||||
if( !isset( $data['HideUser'] ) ){
|
||||
if ( !isset( $data['HideUser'] ) ) {
|
||||
$data['HideUser'] = false;
|
||||
}
|
||||
|
||||
if( $data['HideUser'] ) {
|
||||
if( !$performer->isAllowed('hideuser') ){
|
||||
if ( $data['HideUser'] ) {
|
||||
if ( !$performer->isAllowed('hideuser') ) {
|
||||
# this codepath is unreachable except by a malicious user spoofing forms,
|
||||
# or by race conditions (user has oversight and sysop, loads block form,
|
||||
# and is de-oversighted before submission); so need to fail completely
|
||||
|
|
@ -632,16 +638,16 @@ class SpecialBlock extends FormSpecialPage {
|
|||
}
|
||||
|
||||
# Recheck params here...
|
||||
if( $type != Block::TYPE_USER ) {
|
||||
if ( $type != Block::TYPE_USER ) {
|
||||
$data['HideUser'] = false; # IP users should not be hidden
|
||||
} elseif( !in_array( $data['Expiry'], array( 'infinite', 'infinity', 'indefinite' ) ) ) {
|
||||
} elseif ( !in_array( $data['Expiry'], array( 'infinite', 'infinity', 'indefinite' ) ) ) {
|
||||
# Bad expiry.
|
||||
return array( 'ipb_expiry_temp' );
|
||||
} elseif( $user->getEditCount() > self::HIDEUSER_CONTRIBLIMIT ) {
|
||||
} elseif ( $user->getEditCount() > self::HIDEUSER_CONTRIBLIMIT ) {
|
||||
# Typically, the user should have a handful of edits.
|
||||
# Disallow hiding users with many edits for performance.
|
||||
return array( 'ipb_hide_invalid' );
|
||||
} elseif( !$data['Confirm'] ){
|
||||
} elseif ( !$data['Confirm'] ) {
|
||||
return array( 'ipb-confirmhideuser' );
|
||||
}
|
||||
}
|
||||
|
|
@ -659,15 +665,15 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$block->isAutoblocking( $data['AutoBlock'] );
|
||||
$block->mHideName = $data['HideUser'];
|
||||
|
||||
if( !wfRunHooks( 'BlockIp', array( &$block, &$performer ) ) ) {
|
||||
if ( !wfRunHooks( 'BlockIp', array( &$block, &$performer ) ) ) {
|
||||
return array( 'hookaborted' );
|
||||
}
|
||||
|
||||
# Try to insert block. Is there a conflicting block?
|
||||
$status = $block->insert();
|
||||
if( !$status ) {
|
||||
if ( !$status ) {
|
||||
# Show form unless the user is already aware of this...
|
||||
if( !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
|
||||
if ( !$data['Confirm'] || ( array_key_exists( 'PreviousTarget', $data )
|
||||
&& $data['PreviousTarget'] !== $target ) )
|
||||
{
|
||||
return array( array( 'ipb_already_blocked', $block->getTarget() ) );
|
||||
|
|
@ -677,13 +683,13 @@ class SpecialBlock extends FormSpecialPage {
|
|||
# be sure the user is blocked by now it should work for our purposes
|
||||
$currentBlock = Block::newFromTarget( $target );
|
||||
|
||||
if( $block->equals( $currentBlock ) ) {
|
||||
if ( $block->equals( $currentBlock ) ) {
|
||||
return array( array( 'ipb_already_blocked', $block->getTarget() ) );
|
||||
}
|
||||
|
||||
# If the name was hidden and the blocking user cannot hide
|
||||
# names, then don't allow any block changes...
|
||||
if( $currentBlock->mHideName && !$performer->isAllowed( 'hideuser' ) ) {
|
||||
if ( $currentBlock->mHideName && !$performer->isAllowed( 'hideuser' ) ) {
|
||||
return array( 'cant-see-hidden-user' );
|
||||
}
|
||||
|
||||
|
|
@ -692,12 +698,12 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$logaction = 'reblock';
|
||||
|
||||
# Unset _deleted fields if requested
|
||||
if( $currentBlock->mHideName && !$data['HideUser'] ) {
|
||||
if ( $currentBlock->mHideName && !$data['HideUser'] ) {
|
||||
RevisionDeleteUser::unsuppressUserName( $target, $userId );
|
||||
}
|
||||
|
||||
# If hiding/unhiding a name, this should go in the private logs
|
||||
if( (bool)$currentBlock->mHideName ){
|
||||
if ( (bool)$currentBlock->mHideName ) {
|
||||
$data['HideUser'] = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -708,12 +714,12 @@ class SpecialBlock extends FormSpecialPage {
|
|||
wfRunHooks( 'BlockIpComplete', array( $block, $performer ) );
|
||||
|
||||
# Set *_deleted fields if requested
|
||||
if( $data['HideUser'] ) {
|
||||
if ( $data['HideUser'] ) {
|
||||
RevisionDeleteUser::suppressUserName( $target, $userId );
|
||||
}
|
||||
|
||||
# Can't watch a rangeblock
|
||||
if( $type != Block::TYPE_RANGE && $data['Watch'] ) {
|
||||
if ( $type != Block::TYPE_RANGE && $data['Watch'] ) {
|
||||
$performer->addWatch( Title::makeTitle( NS_USER, $target ) );
|
||||
}
|
||||
|
||||
|
|
@ -751,18 +757,18 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* the wiki's content language
|
||||
* @return Array
|
||||
*/
|
||||
public static function getSuggestedDurations( $lang = null ){
|
||||
public static function getSuggestedDurations( $lang = null ) {
|
||||
$a = array();
|
||||
$msg = $lang === null
|
||||
? wfMessage( 'ipboptions' )->inContentLanguage()->text()
|
||||
: wfMessage( 'ipboptions' )->inLanguage( $lang )->text();
|
||||
|
||||
if( $msg == '-' ){
|
||||
if ( $msg == '-' ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach( explode( ',', $msg ) as $option ) {
|
||||
if( strpos( $option, ':' ) === false ){
|
||||
foreach ( explode( ',', $msg ) as $option ) {
|
||||
if ( strpos( $option, ':' ) === false ) {
|
||||
$option = "$option:$option";
|
||||
}
|
||||
|
||||
|
|
@ -781,7 +787,7 @@ class SpecialBlock extends FormSpecialPage {
|
|||
*/
|
||||
public static function parseExpiryInput( $expiry ) {
|
||||
static $infinity;
|
||||
if( $infinity == null ){
|
||||
if ( $infinity == null ) {
|
||||
$infinity = wfGetDB( DB_SLAVE )->getInfinity();
|
||||
}
|
||||
|
||||
|
|
@ -826,8 +832,8 @@ class SpecialBlock extends FormSpecialPage {
|
|||
$user = User::newFromName( $user );
|
||||
}
|
||||
|
||||
if( $performer->isBlocked() ){
|
||||
if( $user instanceof User && $user->getId() == $performer->getId() ) {
|
||||
if ( $performer->isBlocked() ) {
|
||||
if ( $user instanceof User && $user->getId() == $performer->getId() ) {
|
||||
# User is trying to unblock themselves
|
||||
if ( $performer->isAllowed( 'unblockself' ) ) {
|
||||
return true;
|
||||
|
|
@ -851,40 +857,41 @@ class SpecialBlock extends FormSpecialPage {
|
|||
* reader for this block, to provide more information in the logs
|
||||
* @param $data Array from HTMLForm data
|
||||
* @param $type Block::TYPE_ constant (USER, RANGE, or IP)
|
||||
* @return array
|
||||
* @return string
|
||||
*/
|
||||
protected static function blockLogFlags( array $data, $type ) {
|
||||
global $wgBlockAllowsUTEdit;
|
||||
$flags = array();
|
||||
|
||||
# when blocking a user the option 'anononly' is not available/has no effect -> do not write this into log
|
||||
if( !$data['HardBlock'] && $type != Block::TYPE_USER ){
|
||||
# when blocking a user the option 'anononly' is not available/has no effect
|
||||
# -> do not write this into log
|
||||
if ( !$data['HardBlock'] && $type != Block::TYPE_USER ) {
|
||||
// For grepping: message block-log-flags-anononly
|
||||
$flags[] = 'anononly';
|
||||
}
|
||||
|
||||
if( $data['CreateAccount'] ){
|
||||
if ( $data['CreateAccount'] ) {
|
||||
// For grepping: message block-log-flags-nocreate
|
||||
$flags[] = 'nocreate';
|
||||
}
|
||||
|
||||
# Same as anononly, this is not displayed when blocking an IP address
|
||||
if( !$data['AutoBlock'] && $type == Block::TYPE_USER ){
|
||||
if ( !$data['AutoBlock'] && $type == Block::TYPE_USER ) {
|
||||
// For grepping: message block-log-flags-noautoblock
|
||||
$flags[] = 'noautoblock';
|
||||
}
|
||||
|
||||
if( $data['DisableEmail'] ){
|
||||
if ( $data['DisableEmail'] ) {
|
||||
// For grepping: message block-log-flags-noemail
|
||||
$flags[] = 'noemail';
|
||||
}
|
||||
|
||||
if( $wgBlockAllowsUTEdit && $data['DisableUTEdit'] ){
|
||||
if ( $wgBlockAllowsUTEdit && $data['DisableUTEdit'] ) {
|
||||
// For grepping: message block-log-flags-nousertalk
|
||||
$flags[] = 'nousertalk';
|
||||
}
|
||||
|
||||
if( $data['HideUser'] ){
|
||||
if ( $data['HideUser'] ) {
|
||||
// For grepping: message block-log-flags-hiddenname
|
||||
$flags[] = 'hiddenname';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -702,21 +702,18 @@ class SpecialUpload extends SpecialPage {
|
|||
* @return string
|
||||
*/
|
||||
public static function getDupeWarning( $dupes ) {
|
||||
global $wgOut;
|
||||
if( $dupes ) {
|
||||
$msg = '<gallery>';
|
||||
foreach( $dupes as $file ) {
|
||||
$title = $file->getTitle();
|
||||
$msg .= $title->getPrefixedText() .
|
||||
'|' . $title->getText() . "\n";
|
||||
}
|
||||
$msg .= '</gallery>';
|
||||
return '<li>' .
|
||||
wfMessage( 'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
|
||||
$wgOut->parse( $msg ) . "</li>\n";
|
||||
} else {
|
||||
if ( !$dupes ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$gallery = new ImageGallery;
|
||||
$gallery->setShowBytes( false );
|
||||
foreach( $dupes as $file ) {
|
||||
$gallery->add( $file->getTitle() );
|
||||
}
|
||||
return '<li>' .
|
||||
wfMessage( 'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
|
||||
$gallery->toHtml() . "</li>\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ def unichr3( *args ):
|
|||
|
||||
# DEFINE
|
||||
UNIHAN_VER = '5.2.0'
|
||||
SF_MIRROR = 'cdnetworks-kr-2'
|
||||
SF_MIRROR = 'dfn'
|
||||
SCIM_TABLES_VER = '0.5.10'
|
||||
SCIM_PINYIN_VER = '0.5.91'
|
||||
LIBTABE_VER = '0.2.3'
|
||||
|
|
@ -370,7 +370,7 @@ $zh2Hant = array(\n'''
|
|||
+ PHPArray( toCN ) \
|
||||
+ '\n);\n\n$zh2SG = array(\n' \
|
||||
+ PHPArray( toSG ) \
|
||||
+ '\n);'
|
||||
+ '\n);\n'
|
||||
|
||||
f = open( os.path.join( '..', 'ZhConversion.php' ), 'wb', encoding = 'utf8' )
|
||||
print ('Writing ZhConversion.php ... ')
|
||||
|
|
|
|||
|
|
@ -2240,3 +2240,61 @@
|
|||
分布于 分佈於
|
||||
分布於 分佈於
|
||||
想象 想像
|
||||
無線電視 無綫電視
|
||||
无线电视 無綫電視
|
||||
無線收費 無綫收費
|
||||
无线收费 無綫收費
|
||||
無線節目 無綫節目
|
||||
无线节目 無綫節目
|
||||
無線劇集 無綫劇集
|
||||
无线剧集 無綫劇集
|
||||
東鐵線 東鐵綫
|
||||
东铁线 東鐵綫
|
||||
觀塘線 觀塘綫
|
||||
观塘线 觀塘綫
|
||||
荃灣線 荃灣綫
|
||||
荃湾线 荃灣綫
|
||||
港島線 港島綫
|
||||
港岛线 港島綫
|
||||
東涌線 東涌綫
|
||||
东涌线 東涌綫
|
||||
將軍澳線 將軍澳綫
|
||||
将军澳线 將軍澳綫
|
||||
西鐵線 西鐵綫
|
||||
西铁线 西鐵綫
|
||||
馬鞍山線 馬鞍山綫
|
||||
马鞍山线 馬鞍山綫
|
||||
迪士尼線 迪士尼綫
|
||||
迪士尼线 迪士尼綫
|
||||
沙田至中環線 沙田至中環綫
|
||||
沙田至中环线 沙田至中環綫
|
||||
沙中線 沙中綫
|
||||
沙中线 沙中綫
|
||||
北環線 北環綫
|
||||
北环线 北環綫
|
||||
機場快線 機場快綫
|
||||
机场快线 機場快綫
|
||||
505線 505綫
|
||||
505线 505綫
|
||||
507線 507綫
|
||||
507线 507綫
|
||||
610線 610綫
|
||||
610线 610綫
|
||||
614線 614綫
|
||||
614线 614綫
|
||||
614P線 614P綫
|
||||
614P线 614P綫
|
||||
615線 615綫
|
||||
615线 615綫
|
||||
615P線 615P綫
|
||||
615P线 615P綫
|
||||
705線 705綫
|
||||
705线 705綫
|
||||
706線 706綫
|
||||
706线 706綫
|
||||
751線 751綫
|
||||
751线 751綫
|
||||
751P線 751P綫
|
||||
751P线 751P綫
|
||||
761P線 761P綫
|
||||
761P线 761P綫
|
||||
|
|
|
|||
|
|
@ -408,3 +408,4 @@
|
|||
想象 想像
|
||||
锎 鉲
|
||||
信道 信道
|
||||
綫 線
|
||||
|
|
|
|||
|
|
@ -443,20 +443,6 @@ class LanguageKk extends LanguageKk_cyrl {
|
|||
$wgHooks['ArticleSaveComplete'][] = $this->mConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work around for right-to-left direction support in kk-arab and kk-cn
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function isRTL() {
|
||||
$variant = $this->getPreferredVariant();
|
||||
if ( $variant == 'kk-arab' || $variant == 'kk-cn' ) {
|
||||
return true;
|
||||
} else {
|
||||
return parent::isRTL();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It fixes issue with ucfirst for transforming 'i' to 'İ'
|
||||
*
|
||||
|
|
|
|||
|
|
@ -6,30 +6,30 @@
|
|||
<pluralRule count="one">n is 1</pluralRule>
|
||||
<pluralRule count="two">n is 2</pluralRule>
|
||||
</pluralRules>
|
||||
<pluralRules locales="dsb">
|
||||
<pluralRule count="one">n mod 100 is 1</pluralRule>
|
||||
<pluralRule count="two">n mod 100 is 2</pluralRule>
|
||||
<pluralRule count="few">n mod 100 in 3..4</pluralRule>
|
||||
</pluralRules>
|
||||
<pluralRules locales="cu">
|
||||
<pluralRule count="one">n mod 10 is 1</pluralRule>
|
||||
<pluralRule count="two">n mod 10 is 2</pluralRule>
|
||||
<pluralRule count="few">n mod 10 in 3..4</pluralRule>
|
||||
</pluralRules>
|
||||
<!-- Plural form transformations
|
||||
Based on this discussion: http://translatewiki.net/wiki/Thread:Support/New_plural_rules_for_Scots_Gaelic_(gd)
|
||||
$forms[0] - 1
|
||||
$forms[1] - 2
|
||||
$forms[2] - 11
|
||||
$forms[3] - 12
|
||||
$forms[4] - 3-10, 13-19
|
||||
$forms[5] - 0, 20, rest -->
|
||||
<pluralRules locales="gd">
|
||||
<pluralRule count="one">n is 1</pluralRule>
|
||||
<pluralRule count="two">n is 2</pluralRule>
|
||||
<pluralRule count="elevan">n is 11</pluralRule>
|
||||
<pluralRule count="twelve">n is 12</pluralRule>
|
||||
<pluralRule count="few">n in 3..10 or n in 13..19</pluralRule>
|
||||
</pluralRules>
|
||||
</plurals>
|
||||
<pluralRules locales="dsb">
|
||||
<pluralRule count="one">n mod 100 is 1</pluralRule>
|
||||
<pluralRule count="two">n mod 100 is 2</pluralRule>
|
||||
<pluralRule count="few">n mod 100 in 3..4</pluralRule>
|
||||
</pluralRules>
|
||||
<pluralRules locales="cu">
|
||||
<pluralRule count="one">n mod 10 is 1</pluralRule>
|
||||
<pluralRule count="two">n mod 10 is 2</pluralRule>
|
||||
<pluralRule count="few">n mod 10 in 3..4</pluralRule>
|
||||
</pluralRules>
|
||||
<!-- Plural form transformations
|
||||
Based on this discussion: http://translatewiki.net/wiki/Thread:Support/New_plural_rules_for_Scots_Gaelic_(gd)
|
||||
$forms[0] - 1
|
||||
$forms[1] - 2
|
||||
$forms[2] - 11
|
||||
$forms[3] - 12
|
||||
$forms[4] - 3-10, 13-19
|
||||
$forms[5] - 0, 20, rest -->
|
||||
<pluralRules locales="gd">
|
||||
<pluralRule count="one">n is 1</pluralRule>
|
||||
<pluralRule count="two">n is 2</pluralRule>
|
||||
<pluralRule count="elevan">n is 11</pluralRule>
|
||||
<pluralRule count="twelve">n is 12</pluralRule>
|
||||
<pluralRule count="few">n in 3..10 or n in 13..19</pluralRule>
|
||||
</pluralRules>
|
||||
</supplementalData>
|
||||
|
|
|
|||
|
|
@ -825,6 +825,7 @@ $1',
|
|||
'newsectionsummary' => '/* $1 */ ܡܢܬܐ ܚܕܬܐ',
|
||||
'rc-enhanced-expand' => 'ܚܘܝ ܐܪ̈ܝܟܬܐ (ܒܥܐ ܠܟ JavaScript)',
|
||||
'rc-enhanced-hide' => 'ܛܫܝ ܐܪ̈ܝܟܬܐ',
|
||||
'rc-old-title' => 'ܐܬܒܪܝ ܫܪܫܐܝܬ ܐܝܟ "$1"',
|
||||
|
||||
# Recent changes linked
|
||||
'recentchangeslinked' => 'ܫܘܚܠܦ̈ܐ ܕ̈ܡܝܐ',
|
||||
|
|
@ -1135,6 +1136,7 @@ $1',
|
|||
'mywatchlist' => 'ܪ̈ܗܝܬܝ',
|
||||
'watchlistfor2' => 'ܕ $1 $2',
|
||||
'nowatchlist' => 'ܠܝܬ ܠܟ ܡܕܡ ܒܪ̈ܗܝܬܐ ܕܝܠܟ',
|
||||
'watchlistanontext' => '$1 ܠܚܙܝܐ ܐܘ ܫܚܠܦܬܐ ܕܦܐܬܬ̈ܐ ܒܪ̈ܗܝܬܟ.',
|
||||
'watchnologin' => 'ܠܝܬܝܟ ܥܠܝܠܐ',
|
||||
'watchnologintext' => 'ܐܠܨܐ ܕܬܗܘܐ [[Special:UserLogin|ܥܠܝܠܐ]] ܠܫܚܠܦܬܐ ܕܪ̈ܗܝܬܟ.',
|
||||
'addwatch' => 'ܐܘܣܦ ܥܠ ܪ̈ܗܝܬܝ',
|
||||
|
|
|
|||
|
|
@ -706,6 +706,7 @@ $2',
|
|||
'createaccount' => 'افتح حساب',
|
||||
'gotaccount' => "عندك حساب؟ '''$1'''.",
|
||||
'gotaccountlink' => 'دخول',
|
||||
'userlogin-resetlink' => 'نسيت تفاصيل الدخول؟',
|
||||
'createaccountmail' => 'بـ الايميل',
|
||||
'createaccountreason' => 'السبب:',
|
||||
'badretype' => 'كلمتين السر اللى كتبتهم مش زى بعضهم',
|
||||
|
|
@ -903,8 +904,8 @@ $2',
|
|||
افتكر أن ملفات ال.css و ال.js بتستخدم حروف صغيرة فى العنوان ، مثلا {{ns:user}}:Foo/vector.css و مش {{ns:user}}:Foo/Vector.css.",
|
||||
'updated' => '(متحدثة)',
|
||||
'note' => "'''ملحوظه:'''",
|
||||
'previewnote' => "''' دى بروفه للصفحه بس،
|
||||
ولسه ما تسييفتش!'''",
|
||||
'previewnote' => "'''دى بروفه للصفحه بس.'''
|
||||
ولسه ما تسييفتش! ،",
|
||||
'previewconflict' => 'البروفة دى بتبينلك فوق إزاى ح يكون شكل النص لو انت دوست على حفظ',
|
||||
'session_fail_preview' => "'''ما قدرناش نحفظ التعديلات اللى قمت بيها نتيجة لضياع بيانات الجلسه.
|
||||
الرجاء المحاولة مرة تانيه.
|
||||
|
|
@ -1172,7 +1173,7 @@ $1",
|
|||
'mergelogpagetext' => 'فى تحت لستة بأحدث عمليات الدمج لتاريخ صفحة فى التانية.',
|
||||
|
||||
# Diffs
|
||||
'history-title' => 'تاريخ تعديل "$1"',
|
||||
'history-title' => ' «$1»: تاريخ التعديل',
|
||||
'difference-multipage' => '(الفرق بين الصفحتين)',
|
||||
'lineno' => 'سطر $1:',
|
||||
'compareselectedversions' => 'قارن بين النسختين المختارتين',
|
||||
|
|
@ -1351,8 +1352,8 @@ $1",
|
|||
'email' => 'الإيميل',
|
||||
'prefs-help-realname' => 'الاسم الحقيقى اختيارى.
|
||||
لو إخترت تكتبه, حيستعمل بس علشان شغلك يتنسب لإسمك.',
|
||||
'prefs-help-email' => 'الإيميل اختيارى, بس لازم علشان لو نسيت الپاسوورد.
|
||||
ممكن بردو تختار انك تخلّى اليوزرات تبعتلك إيميل من صفحة اليوزر او المناقشه بتاعتك من غير ما تبقى شخصيتك معروفه.',
|
||||
'prefs-help-email' => 'عنوان اللإيميل اختيارى ، بس لازم علشان لو نسيت الپاسوورد..',
|
||||
'prefs-help-email-others' => 'ممكن بردو تختار انك تخلّى اليوزرات تبعتلك إيميل من صفحة اليوزر او المناقشه بتاعتك من غير ما تبقى شخصيتك معروفه.',
|
||||
'prefs-help-email-required' => 'عنوان الإيميل مطلوب.',
|
||||
'prefs-info' => 'معلومات اساسيه',
|
||||
'prefs-i18n' => 'التدويل',
|
||||
|
|
@ -2077,6 +2078,7 @@ PICT # misc.
|
|||
# Watchlist
|
||||
'watchlist' => 'لستة الصفحات اللى باراقبها',
|
||||
'mywatchlist' => 'لستة الصفح اللى باراقبها',
|
||||
'watchlistfor2' => 'لليوزر $1 ($2)',
|
||||
'nowatchlist' => 'مافيش حاجة فى لستة مراقبتك.',
|
||||
'watchlistanontext' => 'لو سمحت $1 لعرض أو تعديل الصفحات فى لستة مراقبتك.',
|
||||
'watchnologin' => 'مش متسجل',
|
||||
|
|
@ -2338,6 +2340,7 @@ $1',
|
|||
'sp-contributions-newbies-title' => 'مساهمات اليوزر للحسابات الجديدة',
|
||||
'sp-contributions-blocklog' => 'سجل المنع',
|
||||
'sp-contributions-deleted' => 'تعديلات اليوزر الممسوحه',
|
||||
'sp-contributions-uploads' => 'مرفوعات',
|
||||
'sp-contributions-logs' => 'السجلات',
|
||||
'sp-contributions-talk' => 'مناقشه',
|
||||
'sp-contributions-userrights' => 'ادارة حقوق اليوزر',
|
||||
|
|
@ -2345,6 +2348,7 @@ $1',
|
|||
آخر عمليه منع في السجل موجوده تحت كمرجع:',
|
||||
'sp-contributions-search' => 'دور على مساهمات',
|
||||
'sp-contributions-username' => 'عنوان أيبى أو اسم يوزر:',
|
||||
'sp-contributions-toponly' => 'اظهر اختير تعديل بس',
|
||||
'sp-contributions-submit' => 'تدوير',
|
||||
|
||||
# What links here
|
||||
|
|
@ -2738,6 +2742,7 @@ $1',
|
|||
'tooltip-upload' => 'ابتدى التحميل',
|
||||
'tooltip-rollback' => "\"'''ترجيع'''\" بيرجع بدوسه واحده التعديل (التعديلات) فى الصفحه دى لاخر واحد عدل الصفحه.",
|
||||
'tooltip-undo' => '"رجوع" بترجع التعديل دا وبتفتح استمارة التعديل فى شكل البروفة. بتسمح بإضافة سبب فى الملخص.',
|
||||
'tooltip-summary' => 'اكتب ملخص قصير',
|
||||
|
||||
# Stylesheets
|
||||
'common.css' => '/* الأنماط المتراصة CSS المعروضة هنا ستؤثر على كل الواجهات */',
|
||||
|
|
@ -2875,7 +2880,8 @@ $1',
|
|||
إذا كان الملف اتعدل عن حالته الأصلية، فبعض التفاصيل مش ها تعبر عن الملف المعدل.',
|
||||
'metadata-expand' => 'عرض التفاصيل الاضافيه',
|
||||
'metadata-collapse' => 'تخبية التفاصيل الاضافيه',
|
||||
'metadata-fields' => 'حقول معطيات الميتا EXIF الموجوده فى الرساله دى هاتتعرض فى صفحة الصوره لما يكون جدول معطيات الميتا مضغوط. الحقول التانيه هاتكون مخفيه افتراضيا.
|
||||
'metadata-fields' => 'معطيات الميتا الموجوده فى الرساله دى هاتتعرض فى صفحة الصوره لما يكون جدول معطيات الميتا مضغوط.
|
||||
المعطيات التانيه هاتكون مخفيه .
|
||||
* make
|
||||
* model
|
||||
* datetimeoriginal
|
||||
|
|
|
|||
|
|
@ -558,9 +558,9 @@ $1',
|
|||
'dberrortext' => 'Възникна синтактична грешка при заявка към базата данни.
|
||||
Това може да означава грешка в софтуера.
|
||||
Последната заявка към базата данни беше:
|
||||
<blockquote><tt>$1</tt></blockquote>
|
||||
при функцията „<tt>$2</tt>“.
|
||||
MySQL върна грешка „<tt>$3: $4</tt>“.',
|
||||
<blockquote><code>$1</code></blockquote>
|
||||
при функцията „<code>$2</code>“.
|
||||
Базата от данни върна грешка „<samp>$3: $4</samp>“.',
|
||||
'dberrortextcl' => 'Възникна синтактична грешка при заявка към базата данни.
|
||||
Последната заявка към базата данни беше:
|
||||
„$1“
|
||||
|
|
@ -1054,7 +1054,7 @@ $2
|
|||
'rev-deleted-text-permission' => "Тази версия на страницата е била '''изтрита'''.
|
||||
Допълнителна информация може да се съдържа в [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Дневника на изтриванията].",
|
||||
'rev-deleted-text-unhide' => "Тази версия на страницата е била '''изтрита'''.
|
||||
Допълнителна информация може се съдържа в [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Дневника на изтриванията].
|
||||
Допълнителна информация може се съдържа в [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Дневника на изтриванията].
|
||||
Като администратор на сайта вие можете да [$1 прегледате тази редакция], ако желаете да продължите.",
|
||||
'rev-suppressed-text-unhide' => "Тази версия на страницата е била '''прикрита'''.
|
||||
Допълнителна информация може да се съдържа в [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Дневника на прикриванията].
|
||||
|
|
@ -1076,7 +1076,7 @@ $2
|
|||
ато администратор на сайта, вие можете да [$1 прегледате тази разликова препратка], ако желаете да продължите.",
|
||||
'rev-deleted-diff-view' => "Една от версиите на тази разлика е била '''изтрита'''.
|
||||
Можете да видите тази разлика; възможно е да има повече информация в [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} дневника на изтриванията].",
|
||||
'rev-suppressed-diff-view' => "Една от редакциите от тази разлика между версиите беше '''прикрита'''.
|
||||
'rev-suppressed-diff-view' => "Една от редакциите от тази разлика между версиите е била '''прикрита'''.
|
||||
Като администратор, можете да видите тази разлика; повече подробности има в [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} дневника за прикриванията].",
|
||||
'rev-delundel' => 'показване/скриване',
|
||||
'rev-showdeleted' => 'показване',
|
||||
|
|
@ -1146,7 +1146,7 @@ $1",
|
|||
# Suppression log
|
||||
'suppressionlog' => 'Дневник на прикриванията',
|
||||
'suppressionlogtext' => 'По-долу е посочен списък на изтривания и блокирания, свързан със съдържание, скрито от администраторите.
|
||||
За текущите блокирания и забрани, вижте [[Special:BlockList|списъка с блокираните IP адреси]].',
|
||||
За текущите блокирания и забрани, вижте [[Special:BlockList|списъка с блокиранията]].',
|
||||
|
||||
# History merging
|
||||
'mergehistory' => 'Сливане на редакционни истории',
|
||||
|
|
@ -1947,6 +1947,7 @@ $1',
|
|||
'wantedpages' => 'Желани страници',
|
||||
'wantedpages-badtitle' => 'Невалидно заглавие в резултатното множество: $1',
|
||||
'wantedfiles' => 'Желани файлове',
|
||||
'wantedfiletext-nocat' => 'Следните файлове се използват, но не съществуват. Възможно е да са включени файлове от външни хранилища, въпреки че съществуват. Всички такива случаи на възможна фалшива тревога ще бъдат показвани <del>зачеркнати</del>.',
|
||||
'wantedtemplates' => 'Желани шаблони',
|
||||
'mostlinked' => 'Най-препращани страници',
|
||||
'mostlinkedcategories' => 'Най-препращани категории',
|
||||
|
|
@ -2852,6 +2853,7 @@ $1',
|
|||
'spambot_username' => 'Спамочистач',
|
||||
'spam_reverting' => 'Връщане на последната версия, несъдържаща препратки към $1',
|
||||
'spam_blanking' => 'Всички версии, съдържащи препратки към $1, изчистване',
|
||||
'spam_deleting' => 'Всички версии съдържат препратки към $1, изтриване',
|
||||
|
||||
# Info page
|
||||
'pageinfo-title' => 'Информация за "$1"',
|
||||
|
|
@ -2859,12 +2861,13 @@ $1',
|
|||
'pageinfo-header-edits' => 'Редакции',
|
||||
'pageinfo-views' => 'Брой прегледи',
|
||||
'pageinfo-watchers' => 'Брой наблюдабащи',
|
||||
'pageinfo-redirects-name' => 'Пренасочвания към тази страница',
|
||||
'pageinfo-subpages-name' => 'Подстраници на тази страница',
|
||||
'pageinfo-lastuser' => 'Последeн редактор',
|
||||
'pageinfo-lasttime' => 'Дата на последнoто редактиране',
|
||||
'pageinfo-edits' => 'Общ брой редакции',
|
||||
'pageinfo-authors' => 'Брой на отделни автори',
|
||||
'pageinfo-magic-words' => 'Вълшебни думички ($1)',
|
||||
'pageinfo-magic-words' => '{{PLURAL:$1|Вълшебна думичка|Вълшебни думички}} ($1)',
|
||||
|
||||
# Skin names
|
||||
'skinname-standard' => 'Класика',
|
||||
|
|
|
|||
|
|
@ -442,6 +442,10 @@ $1',
|
|||
'youhavenewmessages' => "$1 zo ganeoc'h ($2).",
|
||||
'newmessageslink' => 'Kemennoù nevez',
|
||||
'newmessagesdifflink' => "Diforc'hioù e-keñver ar stumm kent",
|
||||
'youhavenewmessagesfromusers' => '$1 ho peus eus {{PLURAL:$3|un implijer all|$3 implijer}} ($2).',
|
||||
'youhavenewmessagesmanyusers' => ' $1 ho peus implijerien a-leizh ($2).',
|
||||
'newmessageslinkplural' => "{{PLURAL:$1ur c'hemennad nevez|kemennadoù nevez}}",
|
||||
'newmessagesdifflinkplural' => '{{PLURAL:$1|kemennad diwezhañ|kemennadoù diwezhañ}}',
|
||||
'youhavenewmessagesmulti' => "Kemennoù nevez zo ganeoc'h war $1",
|
||||
'editsection' => 'kemmañ',
|
||||
'editold' => 'kemmañ',
|
||||
|
|
@ -495,9 +499,9 @@ Ur roll eus ar pajennoù dibar reizh a c'hallit kavour war [[Special:SpecialPage
|
|||
'databaseerror' => 'Fazi bank roadennoù',
|
||||
'dberrortext' => 'C\'hoarvezet ez eus ur fazi ereadur eus ar reked er bank roadennoù, ar pezh a c\'hall talvezout ez eus un draen er meziant.
|
||||
Setu ar goulenn bet pledet gantañ da ziwezhañ :
|
||||
<blockquote><tt>$1</tt></blockquote>
|
||||
adal an arc\'hwel "<tt>$2</tt>".
|
||||
Adkaset eo bet ar fazi "<tt>$3: $4</tt>" gant ar bank roadennoù.',
|
||||
<blockquote><code>$1</code></blockquote>
|
||||
adal an arc\'hwel "<code>$2</code>".
|
||||
Adkaset eo bet ar fazi "<samp>$3: $4</samp>" gant ar bank roadennoù.',
|
||||
'dberrortextcl' => 'Ur fazi ereadur zo en ur reked savet ouzh ar bank roadennoù.
|
||||
Setu ar goulenn bet pledet gantañ da ziwezhañ :
|
||||
"$1"
|
||||
|
|
@ -591,6 +595,7 @@ Na zisoñjit ket resisaat ho [[Special:Preferences|penndibaboù evit {{SITENAME}
|
|||
'remembermypassword' => "Derc'hel soñj eus ma ger-tremen war an urzhiataer-mañ (evit $1 devezh{{PLURAL:$1||}} d'ar muiañ)",
|
||||
'securelogin-stick-https' => 'Chom kevreet da HTTPS goude bezañ bet kevreet',
|
||||
'yourdomainname' => 'Ho tomani',
|
||||
'password-change-forbidden' => "Ne c'hallit ket kemmañ ar gerioù-tremen er wiki-mañ.",
|
||||
'externaldberror' => "Pe ez eus bet ur fazi gwiriekaat diavaez er bank titouroù pe n'oc'h ket aotreet da nevesaat ho kont diavaez.",
|
||||
'login' => 'Kevreañ',
|
||||
'nav-login-createaccount' => 'Krouiñ ur gont pe kevreañ',
|
||||
|
|
@ -832,15 +837,17 @@ Gallout a rit [[Special:Search/{{PAGENAME}}|klask an titl anezhi]] e pajennoù a
|
|||
'noarticletext-nopermission' => 'N\'eus, evit ar mare, tamm testenn ebet war ar bajenn-mañ.
|
||||
Gallout a rit [[Special:Search/{{PAGENAME}}|klask titl ar bajenn-mañ]] war pajennoù all,
|
||||
pe <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} klask er marilhoù kar]</span>.',
|
||||
'missing-revision' => "C'hoarvezout a ra peurliesañ pa vez heuliet ul liamm istorel dispredet war-zu ur bajenn zo bet dilamet.
|
||||
Gallout a reot kavout muioc'h a vunudoù e [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} renabl an dilamadurioù].",
|
||||
'userpage-userdoesnotexist' => 'N\'eo ket enrollet ar gont "<nowiki>$1</nowiki>". Merkit ma fell deoc\'h krouiñ/kemmañ ar bajenn-mañ.',
|
||||
'userpage-userdoesnotexist-view' => 'N\'eo ket enrollet ar gont implijer "$1".',
|
||||
'blocked-notice-logextract' => "Stanket eo an implijer-mañ evit poent.
|
||||
Dindan emañ merket moned diwezhañ marilh ar stankadennoù, d'ho kelaouiñ :",
|
||||
'clearyourcache' => "Notenn :''' Goude bezañ enrollet ho pajenn e rankot freskaat krubuilh ho merdeer a-benn gwelet ar c'hemmoù.
|
||||
* '''Firefox / Safari: ''' Derc'hel da bouezañ war ''Pennlizherenn'' en ur glikañ war ''Adkargañ'', pe pouezañ war ''Ctrl-F5'' pe ''Ctrl-R'' (''⌘-R'' war ur Mac);
|
||||
* '''Google Chrome:''' Pouezañ war ''Ctrl-Pennlizh-R'' (''⌘-Shift-R'' war ur Mac)
|
||||
* '''Firefox / Safari:''' Derc'hel da bouezañ war ''Pennlizherenn'' en ur glikañ war ''Adkargañ'', pe pouezañ war ''Ctrl-F5'' pe ''Ctrl-R'' (''⌘-R'' war ur Mac);
|
||||
* ''''Google Chrome:''' Pouezañ war ''Ctrl-Pennlizh-R'' (''⌘-Shift-R'' war ur Mac)
|
||||
* '''Internet Explorer:''' Derc'hel da bouezañ war ''Ctrl'' en ur glikañ war ''Freskaat,'' pe pouezañ war ''Ctrl-F5''
|
||||
* '''Konqueror: '''Klikañ war ''Adkargañ'' pe pouezañ war ''F5;''
|
||||
* ''''Konqueror: '''Klikañ war ''Adkargañ'' pe pouezañ war ''F5;''
|
||||
* '''Opera:''' Riñsañ ar grubuilh e ''Ostilhoù → Penndibaboù''",
|
||||
'usercssyoucanpreview' => "'''Tun :''' Grit gant ar bouton \"{{int:showpreview}}\" evit testiñ ho follenn CSS nevez a-raok enrollañ anezhi.",
|
||||
'userjsyoucanpreview' => "'''Tun :''' Grit gant ar bouton \"{{int:showpreview}}\" evit testiñ ho follenn JS nevez a-raok enrollañ anezhi.",
|
||||
|
|
@ -952,6 +959,7 @@ A-gostez eo bet lezet an arventenn-se.',
|
|||
'expansion-depth-exceeded-warning' => "Pajenn a ya dreist d'an donder astenn",
|
||||
'parser-unstrip-loop-warning' => "Detektet ez eus bet ul lagadenn n'haller ket divontañ",
|
||||
'parser-unstrip-recursion-limit' => "Aet dreist d'ar vevenn rekurziñ n'haller ket divontañ : $1",
|
||||
'converter-manual-rule-error' => 'Fazi dinodet er reolenn cheñch yezh dre zorn',
|
||||
|
||||
# "Undo" feature
|
||||
'undo-success' => "Gallout a reer disteurel ar c'hemmoù-mañ. Gwiriit, mar plij, gant ar geñveriadenn a-is evit bezañ sur eo an dra-se a fell deoc'h ober; goude-se enrollit ar c'hemmoù a-is a-benn echuiñ disteurel ar c'hemmoù.",
|
||||
|
|
@ -1136,6 +1144,8 @@ Gwiriit ne vo ket torret red istor ar bajenn gant ar c'hemm-mañ.",
|
|||
'editundo' => 'dizober',
|
||||
'diff-multi' => "({{PLURAL:$1|Ur reizhadenn da c'hortoz|$1 reizhadenn da c'hortoz}} gant {{PLURAL:$2|un implijer|$2 implijer}} kuzhet.)",
|
||||
'diff-multi-manyusers' => "({{PLURAL:$1|Ur reizhadenn da c'hortoz|$1 reizhadenn da c'hortoz}} gant muioc'h eget $2 {{PLURAL:$2|implijer|implijer}} kuzhet.)",
|
||||
'difference-missing-revision' => "C'hoarvezout a ra peurliesañ pa vez heuliet ul liamm disheñvel dispredet war-zu ur bajenn zo bet dilamet.
|
||||
Gallout a reot kavout munudoù e [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} renabl an dilamadurioù].",
|
||||
|
||||
# Search results
|
||||
'searchresults' => "Disoc'hoù enklask",
|
||||
|
|
@ -1402,6 +1412,7 @@ Ma skrivit anezhañ e vo implijet evit lakaat war wel ar pezh a vo bet degaset g
|
|||
'right-writeapi' => 'Ober gant an API evit kemmañ ar wiki',
|
||||
'right-delete' => 'Diverkañ pajennoù',
|
||||
'right-bigdelete' => 'Diverkañ pajennoù dezho un hir a istor',
|
||||
'right-deletelogentry' => 'Dilemel hag assevel monedoù dibar eus ar renabl',
|
||||
'right-deleterevision' => 'Diverkañ ha diziverkañ stummoù zo eus ur pajenn',
|
||||
'right-deletedhistory' => 'Gwelet anvioù an istorioù diverket hep diskouez an destenn stag outo',
|
||||
'right-deletedtext' => "Gwelet ar skrid diverket hag an diforc'hioù etre ar stummoù diverket",
|
||||
|
|
@ -1831,6 +1842,7 @@ Marteze a-walc'h e fell deoc'h kemmañ an deskrivadur anezhi war ar [$2 bajenn d
|
|||
'uploadnewversion-linktext' => 'Kargañ ur stumm nevez eus ar restr-mañ',
|
||||
'shared-repo-from' => 'eus $1',
|
||||
'shared-repo' => 'ur sanailh rannet',
|
||||
'upload-disallowed-here' => "Siwazh, ne c'hallit ket erlec'hiañ ar skeudenn-mañ",
|
||||
|
||||
# File reversion
|
||||
'filerevert' => 'Disteuler $1',
|
||||
|
|
@ -1938,6 +1950,7 @@ Diskoulmet eo bet an enmontoù <del>barrennet</del>.',
|
|||
'nbytes' => '$1 {{PLURAL:$1|eizhbit|eizhbit}}',
|
||||
'ncategories' => '
|
||||
$1 {{PLURAL:$1|rummad|rummad}}',
|
||||
'ninterwikis' => ' {{PLURAL:$1|interwiki|interwikis}}',
|
||||
'nlinks' => '$1 {{PLURAL:$1|liamm|liamm}}',
|
||||
'nmembers' => '$1 {{PLURAL:$1|elfenn|elfenn}}',
|
||||
'nrevisions' => '$1 {{PLURAL:$1|stumm|stumm}}',
|
||||
|
|
@ -2114,6 +2127,8 @@ Gallout a ra bezañ [[{{MediaWiki:Listgrouprights-helppage}}|titouroù ouzhpenn]
|
|||
ha bezañ merket ur chomlec'h postel reizh en ho [[Special:Preferences|penndibaboù]]
|
||||
evit gallout kas ur postel d'un implijer all.",
|
||||
'emailuser' => "Kas ur postel d'an implijer-mañ",
|
||||
'emailuser-title-target' => "Kas ur postel d'an {{PLURAL:$1|an implijer-mañ|an implijerez-mañ}}",
|
||||
'emailuser-title-notarget' => "Kas ur postel d'un implijer",
|
||||
'emailpage' => 'Postel implijer',
|
||||
'emailpagetext' => "Gallout a rit ober gant ar furmskrid a-is a-benn kas ur postel d'an implijer-mañ.
|
||||
E maezienn \"Kaser\" ho postel e vo merket ar chomlec'h postel resisaet ganeoc'h-c'hwi en ho [[Special:Preferences|Penndibaboù]], d'ar resever da c'hallout respont deoc'h war-eeun ma kar.",
|
||||
|
|
@ -2158,7 +2173,7 @@ a-benn gellout kemmañ ho roll evezhiañ.",
|
|||
'addedwatchtext' => 'Ouzh ho [[Special:Watchlist|rollad evezhiañ]] eo bet ouzhpennet ar bajenn "[[:$1]]".
|
||||
Kemmoù da zont ar bajenn-mañ ha re ar bajenn gaozeal stag outi a vo rollet amañ hag e teuio ar bajenn <b>e tev</b> er [[Special:RecentChanges|roll kemmoù diwezhañ]] evit bezañ gwelet aesoc\'h ganeoc\'h.
|
||||
|
||||
Evit tennañ ar bajenn-mañ a-ziwar ho rollad evezhiañ. klikit war "Paouez da evezhiañ" er framm merdeiñ.',
|
||||
Evit tennañ ar bajenn-mañ a-ziwar ho rollad evezhiañ, klikit war "Paouez da evezhiañ" er framm merdeiñ.',
|
||||
'removewatch' => 'Lemel a-ziwar ar roll evezhiañ',
|
||||
'removedwatchtext' => 'Lamet eo bet ar bajenn "[[:$1]]" a-ziwar ho [[Special:Watchlist|roll evezhiañ]].',
|
||||
'watch' => 'Evezhiañ',
|
||||
|
|
@ -2773,6 +2788,7 @@ Enrollit ar bajenn war hoc'h urzhiataer ha kargit anezhi amañ.",
|
|||
'import-error-interwiki' => 'Ne vez ket enporzhiet ar bajenn "$1" rak miret eo an anv evit liammoù diavaez (etrewiki).',
|
||||
'import-error-special' => 'Ne vez ket enporzhiet ar bajenn "$1" rak stag eo ouzh un esaouenn anv dibar na aotre ket pajennoù.',
|
||||
'import-error-invalid' => 'Ne vez ket enporzhiet ar bajenn "$1" rak direizh eo hec\'h anv.',
|
||||
'import-options-wrong' => '{{PLURAL:$2|Dibab fall|Dibaboù fall}}: <nowiki>$1</nowiki>',
|
||||
|
||||
# Import log
|
||||
'importlogpage' => 'Log an enporzhiadennoù',
|
||||
|
|
@ -2921,11 +2937,34 @@ Sur a-walc'h abalamour d'ul liamm enni a gas d'ul lec'hienn ziavaez berzet.",
|
|||
|
||||
# Info page
|
||||
'pageinfo-title' => 'Titouroù evit "$1"',
|
||||
'pageinfo-header-basic' => 'Titouroù diazez',
|
||||
'pageinfo-header-edits' => 'Kemmoù',
|
||||
'pageinfo-header-restrictions' => 'Gwarez ar bajenn',
|
||||
'pageinfo-header-properties' => 'Perzhioù ar bajenn',
|
||||
'pageinfo-display-title' => 'Titl diskwelet',
|
||||
'pageinfo-default-sort' => "Alc'hwez rummañ dre ziouer",
|
||||
'pageinfo-length' => 'Ment ar bajenn (en oktedoù)',
|
||||
'pageinfo-article-id' => 'Niverenn ar bajenn',
|
||||
'pageinfo-robot-policy' => 'Statud al lusker klask',
|
||||
'pageinfo-robot-index' => "A c'haller menegeriñ",
|
||||
'pageinfo-robot-noindex' => "Ne c'haller ket menegeriñ",
|
||||
'pageinfo-views' => 'Niver a weladennoù',
|
||||
'pageinfo-watchers' => 'Niver a dud o heuliañ',
|
||||
'pageinfo-redirects-name' => 'Adkas war-zu ar bajenn-mañ',
|
||||
'pageinfo-subpages-name' => 'Ispajennoù eus ar bajenn-mañ',
|
||||
'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|kasadur|kasadurioù}}; $3 {{PLURAL:$3|nann kasaduri|nann kasadurioù}})',
|
||||
'pageinfo-firstuser' => 'Krouer ar bajenn',
|
||||
'pageinfo-firsttime' => 'Deiziad krouiñ ar bajenn',
|
||||
'pageinfo-lastuser' => 'Kontroller diwezhañ',
|
||||
'pageinfo-lasttime' => "Deiziad ar c'hemm diwezhañ",
|
||||
'pageinfo-edits' => 'Niver a gemmoù',
|
||||
'pageinfo-authors' => 'Niver a aozerien disheñvel',
|
||||
'pageinfo-recent-edits' => 'Niver a gemmoù nevez (er $1 diwezhañ)',
|
||||
'pageinfo-recent-authors' => "Niver a aozerien nevez a-ziforc'h",
|
||||
'pageinfo-restriction' => 'Gwareziñ ar bajenn (<code>{{lcfirst:$1}}</code>)',
|
||||
'pageinfo-magic-words' => '{{PLURAL:$1|Ger hud |Gerioù hud}} ($1)',
|
||||
'pageinfo-hidden-categories' => '{{PLURAL:$1|Rumm kuzh|Rummoù kuzh}} ($1)',
|
||||
'pageinfo-templates' => "{{PLURAL:$1|Patrom endalc'het|Patromoù endalc'het}} ($1)",
|
||||
|
||||
# Skin names
|
||||
'skinname-standard' => 'Standard',
|
||||
|
|
@ -2980,6 +3019,7 @@ Ma vez erounezet ganeoc'h e c'hallje tagañ ho reizhiad.",
|
|||
'file-info-size-pages' => '$1 × $2 piksel, ment ar restr : $3, seurt MIME : $4, $5 {{PLURAL:$5|pajenn|pajenn}}',
|
||||
'file-nohires' => "N'haller ket gwellaat ar pizhder.",
|
||||
'svg-long-desc' => 'restr SVG file, pizhder $1 × $2 piksel, ment ar restr : $3',
|
||||
'svg-long-desc-animated' => 'Restr SVG bev, ment $1 × $2 piksel, ment ar restr: $3',
|
||||
'show-big-image' => 'Pizhder leun',
|
||||
'show-big-image-preview' => 'Ment ar rakweled-mañ : $1.',
|
||||
'show-big-image-other' => '{{PLURAL:$2|pizhder all|pizhderioù all}} : $1.',
|
||||
|
|
@ -2989,6 +3029,8 @@ Ma vez erounezet ganeoc'h e c'hallje tagañ ho reizhiad.",
|
|||
'file-info-png-looped' => "e kelc'h",
|
||||
'file-info-png-repeat' => 'lennet $1 {{PLURAL:$1|wezh|gwezh}}',
|
||||
'file-info-png-frames' => '$1 {{PLURAL:$1|skeudenn|skeudenn}}',
|
||||
'file-no-thumb-animation' => 'Evezhiadenn: En abeg da vevennoù teknikel ne vo ket bevaet skeudennoùigoù ar restr-mañ',
|
||||
'file-no-thumb-animation-gif' => 'Evezhiadenn: En abeg da vevennoù teknikel ne vo ket bevaet ar skeudennoù GIF uhel o diarunusted evel homañ.',
|
||||
|
||||
# Special:NewFiles
|
||||
'newimages' => 'Roll ar restroù nevez',
|
||||
|
|
@ -3809,7 +3851,7 @@ A-hend-all e c'hallit ober gant ar furmskrid eeunaet dindan. Ouzhpennet e vo hoc
|
|||
'api-error-file-too-large' => "Ar restr hoc'h eus roet a oa re vras.",
|
||||
'api-error-filename-tooshort' => 'Re verr eo anv ar restr.',
|
||||
'api-error-filetype-banned' => 'Difennet eo ar seurt restroù',
|
||||
'api-error-filetype-banned-type' => "'''N'eo ket $1 {{PLURAL:$4|ur seurt restr aotreet|seurtoù restroù aotreet}}. $2 eo {{PLURAL:$3|ar seurt restroù|ar seurtoù restroù}} degemeret.",
|
||||
'api-error-filetype-banned-type' => "N'eo ket $1{{PLURAL:$4|ur seurt restr aotreet | seurtoù restroù aotreet}}. $2 zo {{PLURAL:$3|ar seurt restroù|ar seurtoù restroù}} degemeret.?",
|
||||
'api-error-filetype-missing' => "Un astenn a vank d'ar restr.",
|
||||
'api-error-hookaborted' => "Ar c'hemm hoc'h eus klasket degas zo bet harzet gant ur c'hrog astenn.",
|
||||
'api-error-http' => "Fazi diabarzh : dibosupl kevreañ d'ar servijer.",
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ $1',
|
|||
'disclaimerpage' => 'Project:Uslovi korištenja, pravne napomene i odricanje odgovornosti',
|
||||
'edithelp' => 'Pomoć pri uređivanju stranice',
|
||||
'edithelppage' => 'Help:Uređivanje',
|
||||
'helppage' => 'Pomoć:Sadržaj',
|
||||
'helppage' => 'Help:Sadržaj',
|
||||
'mainpage' => 'Početna strana',
|
||||
'mainpage-description' => 'Početna strana',
|
||||
'policy-url' => 'Project:Pravila',
|
||||
|
|
@ -666,6 +666,7 @@ $2',
|
|||
'ns-specialprotected' => 'Specijalne stranice se ne mogu uređivati.',
|
||||
'titleprotected' => 'Naslov stranice je zaštićen od postavljanja od strane korisnika [[User:$1|$1]].
|
||||
Iz razloga "\'\'$2\'\'".',
|
||||
'exception-nologin' => 'Niste prijavljeni',
|
||||
|
||||
# Virus scanner
|
||||
'virus-badscanner' => "Loša konfiguracija: nepoznati anti-virus program: ''$1''",
|
||||
|
|
@ -3022,6 +3023,8 @@ Ovo je vjerovatno izazvao vezom ka vanjskoj nepoželjnoj stranici.',
|
|||
# Info page
|
||||
'pageinfo-title' => 'Informacije za "$1"',
|
||||
'pageinfo-header-edits' => 'Izmjene',
|
||||
'pageinfo-header-restrictions' => 'Zaštita stranice',
|
||||
'pageinfo-article-id' => 'ID stranice',
|
||||
'pageinfo-views' => 'Broj pogleda',
|
||||
'pageinfo-watchers' => 'Broj onih koji pregledaju',
|
||||
'pageinfo-edits' => 'Broj izmjena',
|
||||
|
|
|
|||
|
|
@ -174,8 +174,8 @@ $messages = array(
|
|||
'tog-enotifminoredits' => 'بۆ گۆڕانکارییە بچووکەکانی پەڕەکان و پەڕگەکانیش ئیمەیلم بۆ بنێرە',
|
||||
'tog-enotifrevealaddr' => 'ئەدرەسی ئیمەیلەکەم لە ئیمەیلە ئاگاداریدەرەکان دا نیشان بدە',
|
||||
'tog-shownumberswatching' => 'ژمارەی بەکارھێنەرە چاودێڕەکان نیشان بدە',
|
||||
'tog-oldsig' => 'واژۆی ئێستا:',
|
||||
'tog-fancysig' => 'وەک ویکیدەق لەگەڵ واژۆ مامەڵەبکە (بێ بەستەرێکی خۆکار)',
|
||||
'tog-oldsig' => 'واژووی ئێستا:',
|
||||
'tog-fancysig' => 'وەکوو ویکیدەق واژووەکە لەبەر چاو بگرە (بێ بەستەرێکی خۆگەڕ)',
|
||||
'tog-externaleditor' => 'دەستکاریکەری دەرەکی بەکاربێنە لە حاڵەتی دیفاڵتدا (تەنھا بۆ شارەزایان، ڕێکخستنی تایبەتی پێویستە لە سەر کۆمپیوتەرەکەت [//www.mediawiki.org/wiki/Manual:External_editors زانیاریی زۆرتر.])',
|
||||
'tog-externaldiff' => 'لە پرۆگرامێکی دەرەکی بۆ بینینی جیاوازیەکان کەڵک وەرگرە لە دیفاڵتدا (تەنها بۆ شارەزایان، ڕێکخستنی تایبەتی پێویستە لە سەر کۆمپیوتەرەکەت. [//www.mediawiki.org/wiki/Manual:External_editors زانیاریی زۆرتر.])',
|
||||
'tog-showjumplinks' => 'ڕێگە بدە بۆ بەستەرەکانی «{{int:jumpto}}»',
|
||||
|
|
@ -274,6 +274,7 @@ $messages = array(
|
|||
'index-category' => 'پەڕە پێرستەکراوەکان',
|
||||
'noindex-category' => 'پەڕە پێرستنەکراوەکان',
|
||||
'broken-file-category' => 'ئەو پەڕانەی بەستەری پەڕگەکانیان شکاوە',
|
||||
'categoryviewer-pagedlinks' => '($1) ($2)',
|
||||
|
||||
'about' => 'سەبارەت',
|
||||
'article' => 'بابەت',
|
||||
|
|
@ -405,11 +406,17 @@ $1',
|
|||
تەماشای [[Special:Version|پەڕەی وەشان]] بکە.',
|
||||
|
||||
'ok' => 'باشه',
|
||||
'pagetitle' => '$1 - {{SITENAME}}',
|
||||
'pagetitle-view-mainpage' => '{{SITENAME}}',
|
||||
'backlinksubtitle' => '→ $1',
|
||||
'retrievedfrom' => 'وەرگیراو لە «$1»',
|
||||
'youhavenewmessages' => '$1ت ھەیە ($2).',
|
||||
'newmessageslink' => 'پەیامی نوێ',
|
||||
'newmessagesdifflink' => 'دوا گۆڕانکارییەکان',
|
||||
'newmessagesdifflink' => 'دوایین گۆڕانکاری',
|
||||
'youhavenewmessagesfromusers' => '$1ت لە {{PLURAL:$3|بەکارھێنەرێکی تر| $3 بەکارھێنەر}} ھەیە ( $2 ).',
|
||||
'youhavenewmessagesmanyusers' => '$1ت لە ژمارەیەک بەکارھێنەر ھەیە ( $2 ).',
|
||||
'newmessageslinkplural' => '{{PLURAL:$1|پەیامێکی نوێ|پەیامی نوێ}}',
|
||||
'newmessagesdifflinkplural' => 'دوایین {{PLURAL:$1|گۆڕانکاری|گۆڕانکارییەکان}}',
|
||||
'youhavenewmessagesmulti' => 'لە $1 دا پەیامی نوێت ھەیە',
|
||||
'editsection' => 'دەستکاری',
|
||||
'editold' => 'دەستکاری',
|
||||
|
|
@ -432,6 +439,7 @@ $1',
|
|||
'site-atom-feed' => 'فیدی Atom بۆ $1',
|
||||
'page-rss-feed' => 'فیدی RSS بۆ «$1»',
|
||||
'page-atom-feed' => 'فیدی Atom بۆ «$1»',
|
||||
'feed-atom' => 'ئەتۆم',
|
||||
'red-link-title' => '$1 (پەڕە بوونی نییە)',
|
||||
|
||||
# Short words for each namespace, by default used in the namespace tab in monobook
|
||||
|
|
@ -1243,12 +1251,12 @@ $1",
|
|||
'yourrealname' => 'ناوی ڕاستی:',
|
||||
'yourlanguage' => 'زمان',
|
||||
'yourvariant' => 'شێوەزاری زمانی ناوەرۆک:',
|
||||
'yournick' => 'نازناو',
|
||||
'yournick' => 'واژووی نوێ:',
|
||||
'prefs-help-signature' => 'بۆچوونەکان لە لاپەڕەکانی وتووێژدا دەبێ بە "<nowiki>~~~~</nowiki>" دیاری بکرێن، کە دواتر خۆکار دەگۆڕێ بە واژۆکەت و مۆری کاتی.',
|
||||
'badsig' => 'ئیمزاكه ههڵهیه، تهماشای كۆدی HTML بكه',
|
||||
'badsiglength' => 'واژۆکەت زۆر درێژە.
|
||||
واژۆ نابێ لە $1 {{PLURAL:$1|نووسە|نووسە}} درێژتر بێت.',
|
||||
'yourgender' => 'ڕەگەز:',
|
||||
'yourgender' => 'زایەند:',
|
||||
'gender-unknown' => 'ئاشکرا نەکراو',
|
||||
'gender-male' => 'پیاو',
|
||||
'gender-female' => 'ژن',
|
||||
|
|
@ -1276,7 +1284,7 @@ $1",
|
|||
'prefs-diffs' => 'جیاوازییەکان',
|
||||
|
||||
# User rights
|
||||
'userrights' => 'بەڕێوەبردنی مافەکانی بەکارهێنەران',
|
||||
'userrights' => 'بەڕێوەبردنی مافەکانی بەکارھێنەر',
|
||||
'userrights-lookup-user' => 'بەڕێوەبردنی گرووپەکانی بەکارهێنەران',
|
||||
'userrights-user-editname' => 'ناوی بەکارهێنەرێک بنووسە:',
|
||||
'editusergroup' => 'گرووپەکانی بەکارهێنەر بگۆڕە',
|
||||
|
|
@ -1439,7 +1447,7 @@ $1",
|
|||
'rcshowhideanons' => 'بەکارھێنەرە نەناسراوەکان $1',
|
||||
'rcshowhidepatr' => 'گۆرانکارییە کۆنترۆڵکراوەکان $1',
|
||||
'rcshowhidemine' => 'دەستکارییەکانی من $1',
|
||||
'rclinks' => 'دوایین $1 گۆڕانکاریی $2 ڕۆژی ڕابردوو نیشانبدە<br />$3',
|
||||
'rclinks' => 'دوایین $1 گۆڕانکاریی $2 ڕۆژی ڕابردوو نیشان بدە<br />$3',
|
||||
'diff' => 'جیاوازی',
|
||||
'hist' => 'مێژوو',
|
||||
'hide' => 'بشارەوە',
|
||||
|
|
@ -1804,8 +1812,9 @@ $1',
|
|||
'mostimages' => 'ئەو پەڕگانە زۆرترین بەستەریان پێدراوە',
|
||||
'mostrevisions' => 'ئەو پەڕانە زۆرترین پیاچوونەوەیان ھەیە',
|
||||
'prefixindex' => 'گشت پەڕەکان بە پێشگرەوە',
|
||||
'prefixindex-namespace' => 'هەموو پەڕەکان بەپێشگری (بۆشایی ناوی $1)',
|
||||
'shortpages' => 'پەڕە کورتەکان',
|
||||
'longpages' => 'پەڕە دڕێژەکان',
|
||||
'longpages' => 'پەڕە درێژەکان',
|
||||
'deadendpages' => 'پەڕە بنبەستەکان',
|
||||
'deadendpagestext' => 'ئەم پەڕانەی خوارەوە پەیوەندییان لەگەڵ پەڕەکانی تری {{SITENAME}} نییە.',
|
||||
'protectedpages' => 'پەڕە پارێزراوەکان',
|
||||
|
|
@ -1948,6 +1957,7 @@ $1',
|
|||
'emailpagetext' => 'دەتوانی لەم فۆرمەی خوارەوە کەڵک وەربگریت بۆ ناردنی پەیامێکی ئیمەیل بۆ ئەم بەکارھێنەرە.
|
||||
ئەو ئەدرەسی ئیمەیلە لە [[Special:Preferences|ھەڵبژاردەکانی بەکارھێنەریتدا]] نووسیوتە، بۆ ئەدرەسی «لەلایەن» (From) لە ئیمەیلدا نیشان دەدرێت، کە وایە بەکارھێنەری وەرگر دەتوانێ ڕاستەوخۆ وەڵامت بداتەوە.',
|
||||
'defemailsubject' => 'ئیمەیڵی {{SITENAME}} لە بەکارھێنەر «$1»ەوە',
|
||||
'usermaildisabled' => 'ئیمەیڵی بەکارهێنەر لەکاردانیە',
|
||||
'noemailtitle' => 'هیچ ناونیشانێکی ئیمەیل نییە',
|
||||
'noemailtext' => 'ئەم بەکارهێنەرە ناونێشانێکی بڕوا پێکراوی ئیمەیلی دانەناوە.',
|
||||
'nowikiemailtitle' => 'ڕێگە بۆ ئیمەیل نەدراوە',
|
||||
|
|
@ -1972,7 +1982,7 @@ $1',
|
|||
'usermessage-editor' => 'پەیامنێری سیستەم',
|
||||
|
||||
# Watchlist
|
||||
'watchlist' => 'لیستی چاودێرییەکانم',
|
||||
'watchlist' => 'پێرستی چاودێرییەکانم',
|
||||
'mywatchlist' => 'پێرستی چاودێرییەکانم',
|
||||
'watchlistfor2' => 'بۆ $1 $2',
|
||||
'nowatchlist' => 'لە لیستی چاودێڕییەکانتدا ھیچ نیە.',
|
||||
|
|
@ -1982,6 +1992,7 @@ $1',
|
|||
'addwatch' => 'بیخە سەر لیستی چاودێری',
|
||||
'addedwatchtext' => 'پەڕەی «[[:$1]]» خرایە سەر [[Special:Watchlist|لیستی چاودێرییەکەت]].
|
||||
گۆڕانکارییەکانی داھاتووی ئەم پەڕە و پەڕەی وتووێژەکەی، لەوێدا ڕیزدەکرێ و پەڕەکە لە [[Special:RecentChanges|لیستی دوایین گۆڕانکارییەکاندا]] ئەستوورکراو دەردەکەوێت بۆ ئەوەی ئاسانتر دەستکەوێت.',
|
||||
'removewatch' => 'لەلیستی چاودێری لایبە',
|
||||
'removedwatchtext' => 'پەڕەی «[[:$1]]» لە [[Special:Watchlist|لیستی چاودێریەکەت]] لابرا.',
|
||||
'watch' => 'چاودێری بکە',
|
||||
'watchthispage' => 'چاودێریی ئەم پەڕە بکە',
|
||||
|
|
@ -2048,7 +2059,7 @@ $UNWATCHURL
|
|||
'deletepage' => 'پەڕە بسڕەوە',
|
||||
'confirm' => 'پشتدار بکەرەوە',
|
||||
'excontent' => 'ناوەرۆک ئەمە بوو: «$1»',
|
||||
'excontentauthor' => 'ناوەرۆک ئەمە بوو: «$1» (و تەنھا بەشداربوو «[[Special:Contributions/$2|$2]]» بوو)',
|
||||
'excontentauthor' => 'ناوەرۆک ئەمە بوو: «$1» (و تەنیا بەشداربوو «[[Special:Contributions/$2|$2]]» بوو)',
|
||||
'exbeforeblank' => 'ناوەرۆک بەر لە بەتاڵ کردنەوە ئەمە بوو: «$1»',
|
||||
'exblank' => 'پەڕە خاڵی بوو',
|
||||
'delete-confirm' => 'سڕینەوەی «$1»',
|
||||
|
|
@ -2470,7 +2481,7 @@ $1',
|
|||
'imagetypemismatch' => 'پاشگری ئەو پەڕگە نوێیە هاوتای جۆری پەڕگەکە نیە.',
|
||||
'imageinvalidfilename' => 'ناوی پەڕگەی ئامانج گونجاو نیە',
|
||||
'fix-double-redirects' => 'نوێکەردنەوەی هەموو ڕەوانکەرەکان وا ئاماژە بە سەردێڕە سەرەکیەکە دەکەن',
|
||||
'move-leave-redirect' => 'لە پاشەوە ڕەوانکەرێک بە جێ بھێڵە',
|
||||
'move-leave-redirect' => 'لە پاشەوە ڕەوانەکەرێک بھێڵەوە',
|
||||
'protectedpagemovewarning' => "'''ھۆشیار بە: ئەم پەڕە پارێزراوە بۆ ئەوی تەنیا ئەو بەکارھێنەرانە کە مافەکانی بەڕێوەبەرایەتییان ھەیە بتوانن بیگوازنەوە.'''
|
||||
دوایین لۆگ بۆ ژێدەر لە خوارەوەدا ھاتووە:",
|
||||
'semiprotectedpagemovewarning' => "'''ئاگاداری:''' ئەم پەڕە پارێزراوە بۆ ئەوی تەنھا بەکارھێنەرە تۆمارکراوەکان بتوانن بیگوازنەوە.
|
||||
|
|
@ -2641,6 +2652,7 @@ $1',
|
|||
'tooltip-upload' => 'دەستپێکردنی بارکردن',
|
||||
'tooltip-rollback' => "''گەڕاندنەوە'' بە یەک کلیک گۆڕانکاری (گۆڕانکارییەکانی) ئەم پەڕە ئەباتەوە بۆ ھی دواین بەشدار",
|
||||
'tooltip-undo' => '«پووچکردنەوە» ئەم گۆڕانکارییە دەگەڕێنێتەوە و فۆرمی دەستکاریکردنەکە لە حاڵەتی پێشبینیندا دەکاتەوە. بەم شێوە دەکرێ ھۆکارێک لە پوختەدا بنووسرێت.',
|
||||
'tooltip-preferences-save' => 'هەڵبژاردنەکانت بپارێزە',
|
||||
'tooltip-summary' => 'پوختەیەکی کورتی تێبخە',
|
||||
|
||||
# Metadata
|
||||
|
|
@ -2670,6 +2682,8 @@ $1',
|
|||
'pageinfo-title' => 'زانیاری بۆ «$1»',
|
||||
'pageinfo-header-basic' => 'زانیاریی سەرەتایی',
|
||||
'pageinfo-header-edits' => 'دەستکاریەکان',
|
||||
'pageinfo-display-title' => 'ناونیشان نیشانبدە',
|
||||
'pageinfo-article-id' => 'زنجیرەی پەڕە',
|
||||
'pageinfo-views' => 'ژمارەی بینینەکان',
|
||||
'pageinfo-watchers' => 'ژمارەی چاودێران',
|
||||
'pageinfo-firstuser' => 'دروستکەری پەڕە',
|
||||
|
|
@ -2741,6 +2755,10 @@ $1',
|
|||
|
||||
# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
|
||||
'video-dims' => '$1، $2 لە $3',
|
||||
'seconds-abbrev' => '$1چ',
|
||||
'minutes-abbrev' => '$1خ',
|
||||
'hours-abbrev' => '$1ک',
|
||||
'days-abbrev' => '$1ڕ',
|
||||
'seconds' => '{{PLURAL:$1|$1 چرکە|$1 چرکە}}',
|
||||
'minutes' => '{{PLURAL:$1|$1 خولەک|$1 خولەک}}',
|
||||
'hours' => '{{PLURAL:$1|$1 کاتژمێر|$1 کاتژمێر}}',
|
||||
|
|
@ -2791,6 +2809,7 @@ $1',
|
|||
'exif-pixelxdimension' => 'بەرزی وێنە',
|
||||
'exif-usercomment' => 'بۆچوونەکانی بەکارهێنەر',
|
||||
'exif-relatedsoundfile' => 'فایلی دهنگی لێکچوو',
|
||||
'exif-exposuretime-format' => '$1 چرکە ($2)',
|
||||
'exif-lightsource' => 'سەرچاوەی ڕووناکی',
|
||||
'exif-flash' => 'فلاش',
|
||||
'exif-filesource' => 'سەرچاوەی پەڕگە',
|
||||
|
|
@ -2807,8 +2826,16 @@ $1',
|
|||
'exif-objectname' => 'سەردێری کورت',
|
||||
'exif-headline' => 'سەردێر',
|
||||
'exif-source' => 'سەرچاوە',
|
||||
'exif-contact' => 'زانیاری پەیوەندیکردن',
|
||||
'exif-writer' => 'نووسەر',
|
||||
'exif-languagecode' => 'زمان',
|
||||
'exif-iimversion' => 'وەشانی IIM',
|
||||
'exif-iimcategory' => 'پۆل',
|
||||
'exif-copyrighted' => 'ڕەوشی مافی لەبەرگرتنەوە',
|
||||
|
||||
# Make & model, can be wikified in order to link to the camera and model name
|
||||
'exif-subjectnewscode-value' => '$2 ($1)',
|
||||
|
||||
# EXIF attributes
|
||||
'exif-compression-1' => 'نەپەستێنراو',
|
||||
|
||||
|
|
@ -2924,12 +2951,13 @@ $1',
|
|||
|
||||
'exif-dc-date' => 'ڕۆژ(ەکان)',
|
||||
'exif-dc-publisher' => 'بڵاوکار',
|
||||
'exif-dc-relation' => 'پەڕگەی پەیوەندیدار',
|
||||
'exif-dc-relation' => 'میدیای پەیوەندیدار',
|
||||
'exif-dc-rights' => 'مافەکان',
|
||||
'exif-dc-source' => 'سەرچاوەی پەڕگە',
|
||||
'exif-dc-type' => 'جۆری پەڕگە',
|
||||
'exif-dc-source' => 'سەرچاوەی میدیا',
|
||||
'exif-dc-type' => 'جۆری میدیا',
|
||||
|
||||
'exif-iimcategory-hth' => 'تەندروستی',
|
||||
'exif-iimcategory-pol' => 'سیاسەت',
|
||||
'exif-iimcategory-sci' => 'زانست و تەکنۆلۆژیا',
|
||||
'exif-iimcategory-soi' => 'بابەتە کۆمەڵایەتییەکان',
|
||||
'exif-iimcategory-spo' => 'وەرزشەکان',
|
||||
|
|
@ -3058,6 +3086,7 @@ $5
|
|||
'size-megabytes' => '$1 مێگابایت',
|
||||
'size-gigabytes' => '$1 گیگابایت',
|
||||
'size-terabytes' => '$1 تێرابایت',
|
||||
'size-petabytes' => '$1 پێبیبایت',
|
||||
|
||||
# Live preview
|
||||
'livepreview-loading' => 'باركردن...',
|
||||
|
|
@ -3123,7 +3152,8 @@ $5
|
|||
'hijri-calendar-m12' => 'زولحەججە',
|
||||
|
||||
# Signatures
|
||||
'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|وتووێژ]])',
|
||||
'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|لێدوان]])',
|
||||
'timezone-utc' => 'UTC',
|
||||
|
||||
# Core parser functions
|
||||
'unknown_extension_tag' => 'تاگی درێژکراوەی نەناسراو "$1"',
|
||||
|
|
@ -3244,8 +3274,9 @@ $5
|
|||
# New logging system
|
||||
'logentry-delete-delete' => '$1 پەڕەی $3ی سڕییەوە',
|
||||
'logentry-delete-restore' => '$1 پەڕەی $3ی ھێنایەوە',
|
||||
'logentry-delete-revision' => '$1 دەرکەوتنی {{PLURAL:$5|پێداچوونەوەیکی|$5 پێداچوونەوەی}} پەڕەی $3 گۆڕیی: $4',
|
||||
'logentry-delete-revision' => '$1 دەرکەوتنی {{PLURAL:$5|پێداچوونەوەیەکی|$5 پێداچوونەوەی}} پەڕەی $3 گۆڕیی: $4',
|
||||
'revdelete-content-hid' => 'شاردنەوەی ناوەرۆک',
|
||||
'revdelete-uname-hid' => 'ناوی بەکارهێنەری شاراوە',
|
||||
'revdelete-restricted' => 'ئەو سنووری بەرگریانەی خستراوەتە سەر بەڕێوبەران',
|
||||
'revdelete-unrestricted' => 'ئەو سنووری بەرگریانەی لابردراوە لە سەر بەڕێوبەران',
|
||||
'logentry-move-move' => '$1 پەڕەی $3ی گواستەوە بۆ $4',
|
||||
|
|
@ -3262,6 +3293,7 @@ $5
|
|||
'feedback-subject' => 'بابەت:',
|
||||
'feedback-message' => 'پەیام:',
|
||||
'feedback-cancel' => 'ھەڵیوەشێنەوە',
|
||||
'feedback-submit' => 'تێبینییەکان بنێرە',
|
||||
'feedback-close' => 'ئەنجام درا',
|
||||
|
||||
# API errors
|
||||
|
|
|
|||
|
|
@ -1678,7 +1678,7 @@ Gweler https://www.mediawiki.org/wiki/Manual:Image_Authorization.",
|
|||
'img-auth-nofile' => 'Nid oes ffeil a\'r enw "$1" ar gael.',
|
||||
'img-auth-isdir' => 'Rydych yn ceisio cyrchu cyfeiriadur o\'r enw "$1".
|
||||
Dim ond ffeiliau y cewch eu cyrchu.',
|
||||
'img-auth-streaming' => 'Wrthi\'n llifo "$1".',
|
||||
'img-auth-streaming' => 'Wrthi\'n ffrydio "$1".',
|
||||
'img-auth-public' => "Gwaith img_auth.php yw allbynnu ffeiliau o wici preifat.
|
||||
Mae'r wici hwn wedi ei osod yn wici gyhoeddus.
|
||||
Er mwyn sicrhau'r diogelwch gorau posib, analluogwyd img_auth.php.",
|
||||
|
|
@ -1765,6 +1765,7 @@ Mae modd golygu'r disgrifiad ohoni ar ei [$2 thudalen disgrifio] fan honno.",
|
|||
'shared-repo-from' => 'oddi ar $1',
|
||||
'shared-repo' => 'storfa cyfrannol',
|
||||
'shared-repo-name-wikimediacommons' => 'Comin Wikimedia',
|
||||
'upload-disallowed-here' => "Yn anffodus ni allwch drosysgrifo'r ddelwedd hon.",
|
||||
|
||||
# File reversion
|
||||
'filerevert' => 'Gwrthdroi $1',
|
||||
|
|
@ -1871,6 +1872,7 @@ Gosodwyd <del>llinell</del> drwy'r eitemau sydd eisoes wedi eu datrys.",
|
|||
# Miscellaneous special pages
|
||||
'nbytes' => '$1 {{PLURAL:$1|beit|beit|feit|beit|beit|beit}}',
|
||||
'ncategories' => '$1 {{PLURAL:$1|categori|categori|gategori|chategori|chategori|categori}}',
|
||||
'ninterwikis' => '$1 {{PLURAL:$1|cyswllt|cyswllt|gyswllt|chyswllt|chyswllt|cyswllt}}',
|
||||
'nlinks' => '$1 {{PLURAL:$1|cyswllt|cyswllt|gyswllt|chyswllt|chyswllt|cyswllt}}',
|
||||
'nmembers' => '$1 {{PLURAL:$1|aelod|aelod|aelod|aelod|aelod|aelod}}',
|
||||
'nrevisions' => '$1 {{PLURAL:$1|diwygiad|diwygiad|ddiwygiad|diwygiad|diwygiad|diwygiad}}',
|
||||
|
|
@ -1899,6 +1901,7 @@ Gosodwyd <del>llinell</del> drwy'r eitemau sydd eisoes wedi eu datrys.",
|
|||
'mostlinkedtemplates' => 'Nodiadau yn nhrefn nifer y cysylltiadau iddynt',
|
||||
'mostcategories' => 'Erthyglau yn nhrefn nifer eu categorïau',
|
||||
'mostimages' => 'Ffeiliau yn nhrefn nifer y cysylltiadau iddynt',
|
||||
'mostinterwikis' => "Tudalennau a'r nifer mwyaf o gysylltau rhyngwici",
|
||||
'mostrevisions' => 'Tudalennau yn nhrefn nifer y newidiadau iddynt',
|
||||
'prefixindex' => 'Pob tudalen yn ôl parth',
|
||||
'prefixindex-namespace' => 'Pob tudalen â rhagddodiad penodol (y parth $1)',
|
||||
|
|
@ -2046,6 +2049,7 @@ Protocoliau sy\'n cael eu cynnal: <code>$1</code> (peidiwch ag ychwanegu\'r rhai
|
|||
a bod cyfeiriad e-bost dilys yn eich [[Special:Preferences|dewisiadau]]
|
||||
er mwyn medru anfon e-bost at ddefnyddwyr eraill.',
|
||||
'emailuser' => 'Anfon e-bost at y defnyddiwr hwn',
|
||||
'emailuser-title-target' => "Ebostio'r {{GENDER:$1|defnyddiwr hwn}}",
|
||||
'emailuser-title-notarget' => 'Anfon e-bost at ddefnyddiwr',
|
||||
'emailpage' => 'Anfon e-bost at ddefnyddiwr',
|
||||
'emailpagetext' => "Os yw'r cyfeiriad e-bost sydd yn newisiadau'r defnyddiwr hwn yn un dilys, gellir anfon neges ato o'i ysgrifennu ar y ffurflen isod.
|
||||
|
|
@ -2846,16 +2850,23 @@ Achos hyn yn fwy na thebyg yw presenoldeb cysylltiad i wefan ar y rhestr wahardd
|
|||
'pageinfo-header-edits' => 'Hanes golygu',
|
||||
'pageinfo-header-restrictions' => 'Diogelwch y dudalen',
|
||||
'pageinfo-header-properties' => "Priodweddau'r dudalen",
|
||||
'pageinfo-display-title' => 'Teitl y dudalen',
|
||||
'pageinfo-default-sort' => 'Allwedd trefnu diofyn',
|
||||
'pageinfo-length' => 'Hyd y dudalen (beitiau)',
|
||||
'pageinfo-article-id' => 'ID y dudalen',
|
||||
'pageinfo-robot-policy' => 'Statws i beiriannau chwilio',
|
||||
'pageinfo-views' => 'Nifer yr ymweliadau',
|
||||
'pageinfo-watchers' => 'Nifer gwylwyr y dudalen',
|
||||
'pageinfo-redirects-name' => "Nifer yr ailgyfeiriadau i'r dudalen hon",
|
||||
'pageinfo-subpages-name' => "Nifer yr is-dudalennau i'r dudalen hon",
|
||||
'pageinfo-firstuser' => 'Y defnyddiwr a ddechreuodd y dudalen',
|
||||
'pageinfo-firsttime' => "Dyddiad dechrau'r dudalen",
|
||||
'pageinfo-lastuser' => 'Y golygydd diweddaraf',
|
||||
'pageinfo-lasttime' => 'Dyddiad y golygiad diweddaraf',
|
||||
'pageinfo-edits' => 'Cyfanswm y golygiadau',
|
||||
'pageinfo-authors' => 'Cyfanswm yr awduron gwahanol',
|
||||
'pageinfo-magic-words' => '{{PLURAL:$1|Gair|Gair|Geiriau}} hud ($1)',
|
||||
'pageinfo-hidden-categories' => '{{PLURAL:$1|Categori|Categori|Categorïau}} cudd ($1)',
|
||||
|
||||
# Skin names
|
||||
'skinname-standard' => 'Safonol',
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ $messages = array(
|
|||
'redirectedfrom' => '(Omdirigeret fra $1)',
|
||||
'redirectpagesub' => 'Omdirigering',
|
||||
'lastmodifiedat' => 'Denne side blev senest ændret $1 kl. $2.',
|
||||
'viewcount' => 'Siden er vist i {{PLURAL:$1|en gang|$1 gange}}.',
|
||||
'viewcount' => 'Siden er vist {{PLURAL:$1|en gang|$1 gange}}.',
|
||||
'protectedpage' => 'Beskyttet side',
|
||||
'jumpto' => 'Skift til:',
|
||||
'jumptonavigation' => 'Navigation',
|
||||
|
|
@ -858,7 +858,6 @@ Loggen over den seneste blokering ses nedenfor:',
|
|||
* '''Firefox / Safari:''' Hold ''shifttasten'' nede og klik på ''reload'', eller tryk enten ''Ctrl-F5'' eller ''Ctrl-Shift-r'' (''⌘-R'' på en Mac).
|
||||
* '''Google Chrome:''' Tryk ''Ctrl-Shift-R'' (''⌘-Shift-R'' på en Mac).
|
||||
* '''Internet Explorer:''' Hold ''controltasten'' nede og klik på ''refresh'' eller tryk på ''Ctrl-F5''.
|
||||
* '''Konqueror:''' Klik på ''reload'' eller tryk på ''F5''.
|
||||
* '''Opera:''' Tøm cachen i ''Tools → Preferences''.",
|
||||
'usercssyoucanpreview' => "'''Tip:''' Brug \"{{int:showpreview}}\"-knappen for at teste dit nye CSS inden du gemmer.",
|
||||
'userjsyoucanpreview' => "'''Tip:''' Brug \"{{int:showpreview}}\"-knappen for at teste dit nye JavaScript inden du gemmer.",
|
||||
|
|
@ -1836,6 +1835,7 @@ Måske vil du redigere beskrivelsen på dens [$2 filbeskrivelsesside] der.',
|
|||
'uploadnewversion-linktext' => 'Læg en ny version af denne fil op',
|
||||
'shared-repo-from' => 'fra $1',
|
||||
'shared-repo' => 'et delt filarkiv',
|
||||
'upload-disallowed-here' => 'Desværre kan du ikke overskrive dette billede.',
|
||||
|
||||
# File reversion
|
||||
'filerevert' => 'Gendan $1',
|
||||
|
|
@ -1944,6 +1944,7 @@ Hver linje indeholder henvisninger til den første og den anden omdirigering, s
|
|||
# Miscellaneous special pages
|
||||
'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
|
||||
'ncategories' => '$1 {{PLURAL:$1|kategori|kategorier}}',
|
||||
'ninterwikis' => '$1 {{PLURAL:$1|interwikilink|interwikilinks}}',
|
||||
'nlinks' => '{{PLURAL:$1|1 henvisning|$1 henvisninger}}',
|
||||
'nmembers' => '$1 {{PLURAL:$1|medlem|medlemmer}}',
|
||||
'nrevisions' => '{{PLURAL:$1|1 ændring|$1 ændringer}}',
|
||||
|
|
@ -1972,6 +1973,7 @@ Hver linje indeholder henvisninger til den første og den anden omdirigering, s
|
|||
'mostlinkedtemplates' => 'Hyppigst brugte skabeloner',
|
||||
'mostcategories' => 'Mest brugte sider',
|
||||
'mostimages' => 'Mest brugte filer',
|
||||
'mostinterwikis' => 'Sider med flest interwikilinks',
|
||||
'mostrevisions' => 'Sider med de fleste ændringer',
|
||||
'prefixindex' => 'Alle sider med præfiks',
|
||||
'prefixindex-namespace' => 'Alle sider med præfiks (navnerummet $1)',
|
||||
|
|
@ -2118,6 +2120,8 @@ Der findes muligvis [[{{MediaWiki:Listgrouprights-helppage}}|yderligere informat
|
|||
'mailnologin' => 'Du er ikke logget på',
|
||||
'mailnologintext' => 'Du skal være [[Special:UserLogin|logget på]] og have en gyldig e-mailadresse sat i dine [[Special:Preferences|indstillinger]] for at sende e-mail til andre brugere.',
|
||||
'emailuser' => 'E-mail til denne bruger',
|
||||
'emailuser-title-target' => 'Send email til denne {{GENDER:$1|bruger}}',
|
||||
'emailuser-title-notarget' => 'Send email til en bruger',
|
||||
'emailpage' => 'E-mail bruger',
|
||||
'emailpagetext' => 'Du kan bruge formularen nedenfor til at sende en e-mail til denne bruger.
|
||||
Den e-mail-adresse du har angivet i [[Special:Preferences|dine indstillinger]] vil dukke op i "fra"-feltet på e-mailen, så modtageren kan svare dig.',
|
||||
|
|
@ -2767,6 +2771,7 @@ Alle Transwiki import-aktioner protokolleres i [[Special:Log/import|import-logge
|
|||
'import-error-interwiki' => 'Siden "$1" importeres ikke, da dens navn er reserveret for eksterne henvisninger (interwiki).',
|
||||
'import-error-special' => 'Siden "$1" importeres ikke, da den tilhører et særligt navnerum, der ikke tillader sider.',
|
||||
'import-error-invalid' => 'Siden "$1" importeres ikke, da dens navn er ugyldigt.',
|
||||
'import-options-wrong' => '{{PLURAL:$2|Ugyldig indstilling|Ugyldige indstillinger}}: <nowiki>$1</nowiki>',
|
||||
'import-rootpage-invalid' => 'Den rodside der er angivet har en ugyldig titel.',
|
||||
'import-rootpage-nosubpage' => 'Navnerummet "$1" tillader ikke undersider af rodsiderne.',
|
||||
|
||||
|
|
@ -2895,11 +2900,29 @@ Dette skyldes sandsynligvis en henvisning til et sortlistet eksternt websted.',
|
|||
|
||||
# Info page
|
||||
'pageinfo-title' => 'Information om "$1"',
|
||||
'pageinfo-header-edits' => 'Redigeringer',
|
||||
'pageinfo-header-basic' => 'Grundlæggende oplysninger',
|
||||
'pageinfo-header-edits' => 'Redigeringshistorik',
|
||||
'pageinfo-header-restrictions' => 'Sidebeskyttelse',
|
||||
'pageinfo-header-properties' => 'Sideegenskaber',
|
||||
'pageinfo-default-sort' => 'Standardsorteringsnøgle',
|
||||
'pageinfo-length' => 'Sidelængde (i bytes)',
|
||||
'pageinfo-article-id' => 'Side-ID',
|
||||
'pageinfo-robot-policy' => 'Søgemaskinestatus',
|
||||
'pageinfo-robot-index' => 'Indekserbar',
|
||||
'pageinfo-robot-noindex' => 'Ikke indekserbar',
|
||||
'pageinfo-views' => 'Antal visninger',
|
||||
'pageinfo-watchers' => 'Antal brugere, der overvåger siden',
|
||||
'pageinfo-edits' => 'Antal redigeringer',
|
||||
'pageinfo-authors' => 'Antal forskellige forfattere',
|
||||
'pageinfo-redirects-name' => 'Omdirigeringer til denne side',
|
||||
'pageinfo-subpages-name' => 'Undersider til denne side',
|
||||
'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|omdirigering|omdirigeringer}}; $3 {{PLURAL:$3|der ikke er en omdirigering|der ikke er omdirigeringer}})',
|
||||
'pageinfo-firsttime' => 'Dato for oprettelsen af siden',
|
||||
'pageinfo-lasttime' => 'Dato for seneste redigering',
|
||||
'pageinfo-edits' => 'Samlet antal redigeringer',
|
||||
'pageinfo-authors' => 'Det samlede antal forskellige forfattere',
|
||||
'pageinfo-restriction' => 'Sidebeskyttelse (<code>{{lcfirst:$1}}</code>)',
|
||||
'pageinfo-magic-words' => '{{PLURAL:$1|Magisk|Magiske}} ord ($1)',
|
||||
'pageinfo-hidden-categories' => '{{PLURAL:$1|Skjult kategori|Skjulte kategorier}} ($1)',
|
||||
'pageinfo-templates' => '{{PLURAL:$1|Transkluderet skabelon|Transkluderede skabeloner}} ($1)',
|
||||
|
||||
# Skin names
|
||||
'skinname-standard' => 'Klassik',
|
||||
|
|
@ -2953,6 +2976,7 @@ Du kan beskadige dit system hvis du udfører den.",
|
|||
'file-info-size-pages' => '$1 × $2 punkter, filstørrelse: $3, MIME-type: $4, $5 {{PLURAL:$5|side|sider}}',
|
||||
'file-nohires' => 'Ingen højere opløsning fundet.',
|
||||
'svg-long-desc' => 'SVG fil, basisstørrelse $1 × $2 punkters, størrelse: $3',
|
||||
'svg-long-desc-animated' => 'Animeret SVG-fil, basisstørrelse $1 × $2 punkter, filstørrelse: $3',
|
||||
'show-big-image' => 'Version i større opløsning',
|
||||
'show-big-image-preview' => 'Størrelse af denne forhåndsvisning: $1.',
|
||||
'show-big-image-other' => '{{PLURAL:$2|Anden opløsning|Andre opløsninger}}: $1.',
|
||||
|
|
@ -2962,6 +2986,8 @@ Du kan beskadige dit system hvis du udfører den.",
|
|||
'file-info-png-looped' => 'gentaget',
|
||||
'file-info-png-repeat' => 'afspillede $1 {{PLURAL:$1|gang|gange}}',
|
||||
'file-info-png-frames' => '$1 {{PLURAL:$1|billede|billeder}}',
|
||||
'file-no-thumb-animation' => "'''Bemærk: På grund af tekniske begrænsninger vil miniaturebilleder af denne fil ikke blive animeret.'''",
|
||||
'file-no-thumb-animation-gif' => "'''Bemærk: På grund af tekniske begrænsninger vil miniaturebilleder af GIF-filer, der som denne er i høj opløsning, ikke blive animeret.'''",
|
||||
|
||||
# Special:NewFiles
|
||||
'newimages' => 'Galleri med de nyeste billeder',
|
||||
|
|
|
|||
|
|
@ -2062,8 +2062,8 @@ Eine [[Special:WhatLinksHere/$2|vollständige Liste]] ist verfügbar.',
|
|||
Vielleicht möchtest du die Beschreibung auf der dortigen [$2 Dateibeschreibungsseite] bearbeiten.',
|
||||
'sharedupload-desc-create' => 'Diese Datei stammt aus $1 und kann von anderen Projekten verwendet werden.
|
||||
Vielleicht möchtest du die Beschreibung auf der dortigen [$2 Dateibeschreibungsseite] bearbeiten.',
|
||||
'filepage-nofile' => 'Es ist keine Datei dieses namens vorhanden.',
|
||||
'filepage-nofile-link' => 'Es ist keine Datei dieses namens vorhanden. Du kannst jedoch [$1 diese Datei hochladen].',
|
||||
'filepage-nofile' => 'Es ist keine Datei dieses Namens vorhanden.',
|
||||
'filepage-nofile-link' => 'Es ist keine Datei dieses Namens vorhanden. Du kannst jedoch [$1 diese Datei hochladen].',
|
||||
'uploadnewversion-linktext' => 'Eine neue Version dieser Datei hochladen',
|
||||
'shared-repo-from' => 'aus $1',
|
||||
'shared-repo' => 'einem gemeinsam genutzten Medienarchiv',
|
||||
|
|
@ -2714,7 +2714,7 @@ Bitte gib den Grund für die Sperre an.',
|
|||
'ipb-change-block' => 'Sperre mit diesen Sperrparametern erneuern',
|
||||
'ipb-confirm' => 'Sperrung bestätigen',
|
||||
'badipaddress' => 'Die IP-Adresse hat ein falsches Format.',
|
||||
'blockipsuccesssub' => 'Sperre erfolgreich',
|
||||
'blockipsuccesssub' => 'Die Sperrung war erfolgreich.',
|
||||
'blockipsuccesstext' => 'Der Benutzer / die IP-Adresse [[Special:Contributions/$1|$1]] wurde gesperrt.<br />
|
||||
Zur Aufhebung der Sperre siehe die [[Special:BlockList|Liste aller aktiven Sperren]].',
|
||||
'ipb-blockingself' => 'Du bist gerade dabei, dich selbst zu sperren! Möchtest du das wirklich tun?',
|
||||
|
|
@ -2782,7 +2782,7 @@ Siehe die [[Special:BlockList|Liste der gesperrten IP-Adressen und Benutzernamen
|
|||
'ipb_expiry_invalid' => 'Die eingegebene Dauer ist ungültig.',
|
||||
'ipb_expiry_temp' => 'Benutzernamens-Sperren mit der Verstecken-Option müssen permanent sein.',
|
||||
'ipb_hide_invalid' => 'Dieses Konto kann nicht unterdrückt werden, da es zu viele Bearbeitungen aufweist.',
|
||||
'ipb_already_blocked' => '„$1“ wurde bereits gesperrt.',
|
||||
'ipb_already_blocked' => '„$1“ ist bereits gesperrt',
|
||||
'ipb-needreblock' => '„$1“ ist bereits gesperrt. Möchtest du die Sperrparameter ändern?',
|
||||
'ipb-otherblocks-header' => 'Andere {{PLURAL:$1|Sperre|Sperren}}',
|
||||
'unblock-hideuser' => 'Dieser Benutzer kann nicht entsperrt werden, da dessen Benutzername versteckt wurde.',
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ $messages = array(
|
|||
'dec' => 'Kan',
|
||||
|
||||
# Categories related messages
|
||||
'pagecategories' => '{{PLURAL:$1|Kategori|Kategoriy}}',
|
||||
'pagecategories' => '{{PLURAL:$1|Kategoriye|Kategoriy}}',
|
||||
'category_header' => 'Pelê ke kategoriya "$1" derê',
|
||||
'subcategories' => 'Kategoriyê bınêni',
|
||||
'category-media-header' => 'Medyawa ke kategoriya "$1" dera',
|
||||
|
|
@ -508,7 +508,7 @@ $messages = array(
|
|||
'talkpage' => 'Ena pele sero werêne',
|
||||
'talkpagelinktext' => 'Mesac',
|
||||
'specialpage' => 'Pela xısusiye',
|
||||
'personaltools' => 'Hacetê şexsi',
|
||||
'personaltools' => 'Haletê şexsi',
|
||||
'postcomment' => 'Qısımo newe',
|
||||
'articlepage' => 'Pela zerreki bıvêne',
|
||||
'talk' => 'Werênayış',
|
||||
|
|
@ -1332,9 +1332,9 @@ Detayê besternayışi [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}
|
|||
'mwsuggest-disable' => 'Tewsiyay AJAXi bıgê',
|
||||
'searcheverything-enable' => 'cayê nameyê hemi de bigêre',
|
||||
'searchrelated' => 'eleqayî',
|
||||
'searchall' => 'têdıne',
|
||||
'searchall' => 'pêro',
|
||||
'showingresults' => "Heta {{PLURAL:$1|'''1''' netice|'''$1''' neticeyan}} ke pê #'''$2''' başli beno ey bimocne .",
|
||||
'showingresultsnum' => "Heta binê {{PLURAL:$3|'''1''' netice|'''$3''' neticeyan}} ke pê #'''$2''' başli beno ey bimocne .",
|
||||
'showingresultsnum' => "'''$2''' netican ra nata {{PLURAL:$3|'''1''' netice|'''$3''' neticeyê}} cêrde liste biyê.",
|
||||
'showingresultsheader' => "{{PLURAL:$5|Neticeyê '''$1''' of '''$3'''|Neticeyanê '''$1 - $2''' of '''$3'''}} qe '''$4'''",
|
||||
'nonefound' => "'''Teme''': Teyna tay namecayan cıgeyro beno.
|
||||
Pe verbendi ''all:'', vaceyê xo bıvurni ki contenti hemi cıgeyro (pelanê mınaqeşe, templatenan, ucb.) ya zi cıgeyro ser namecay ki tı wazeni.",
|
||||
|
|
@ -1942,7 +1942,7 @@ keyepel nıka zaf meşğulo yew dema herayi de newe ra tesel bıkerê.',
|
|||
'listfiles_name' => 'Name',
|
||||
'listfiles_user' => 'Karber',
|
||||
'listfiles_size' => 'Gırdiye',
|
||||
'listfiles_description' => 'Şınasiyen',
|
||||
'listfiles_description' => 'Sılasnayış',
|
||||
'listfiles_count' => 'Versiyoni',
|
||||
|
||||
# File description page
|
||||
|
|
@ -2050,7 +2050,7 @@ listeya ke ha ver a têna na {{PLURAL:$1|dosyaya ewwili|dosyaya $1 ewwili}} mocn
|
|||
'statistics-header-users' => 'Îstatistiksê karberî',
|
||||
'statistics-header-hooks' => 'Îstatistiksê binî',
|
||||
'statistics-articles' => 'Pelanê tedesteyî',
|
||||
'statistics-pages' => 'Peli',
|
||||
'statistics-pages' => 'Peley',
|
||||
'statistics-pages-desc' => 'Pelanê hemî ke wîkî de estê, pelanê mineqeşeyî, redireksiyon ucb... dehil o.',
|
||||
'statistics-files' => 'Dosyayê bar biye',
|
||||
'statistics-edits' => 'Amarê vurnayîşî ke wextê {{SITENAME}} ronayîşî ra',
|
||||
|
|
@ -2211,7 +2211,7 @@ hem zi bıewnê [[Special:WantedCategories|kategori yê ke waziyeni]].',
|
|||
# Special:DeletedContributions
|
||||
'deletedcontributions' => 'İştiraqê karberan de besternayına',
|
||||
'deletedcontributions-title' => 'Îştirakê karberî wederna',
|
||||
'sp-deletedcontributions-contribs' => 'iştıraqi',
|
||||
'sp-deletedcontributions-contribs' => 'pêşteni',
|
||||
|
||||
# Special:LinkSearch
|
||||
'linksearch' => 'Gıreyê teberi cı geyrê',
|
||||
|
|
@ -2269,7 +2269,7 @@ qey heqê şexsi de [[{{MediaWiki:Listgrouprights-helppage}}|hema malumato ziyed
|
|||
'emailuser' => 'Ena karberi rê mesac bırse',
|
||||
'emailuser-title-target' => 'Na E-postaya {{GENDER:$1|karberi}}ya',
|
||||
'emailuser-title-notarget' => 'E-postaya karberi',
|
||||
'emailpage' => 'karberi re e-mail bışaw',
|
||||
'emailpage' => 'karberi re e-posta bırışê',
|
||||
'emailpagetext' => 'no/na karberi re e-posta erşawıtışi de şıma pê forma cêrıni eşkeni kar bıkerî.
|
||||
[[Special:Preferences|tercihanê şıma ye karberi]] de adresa e-posta ya ke şıma dayo, na adres qısmê adresa e-postayi de "From (kam ra)" asena, no sebebi ra gırewtox/e eşkeno/a direk cewab bıdo şıma.',
|
||||
'usermailererror' => 'xizmetê e-postayi xeta da:',
|
||||
|
|
@ -2341,7 +2341,7 @@ Ena deme ra, ma qe vurnayışan ser ena pele tı haberdar keni. Hem zi çı dem
|
|||
'enotif_reset' => 'Pela pêro ziyaret kerde deye mor ke',
|
||||
'enotif_newpagetext' => 'Ena yew pela newî ya.',
|
||||
'enotif_impersonal_salutation' => '{{SITENAME}} karber',
|
||||
'changed' => 'vurniya',
|
||||
'changed' => 'vurneya',
|
||||
'created' => 'viraziya',
|
||||
'enotif_subject' => 'pelê {{SITENAME}}i $PAGETITLE, hetê/perrê $PAGEEDITOR $CHANGEDORCREATED',
|
||||
'enotif_lastvisited' => 'ziyareta şıma ye peyini ra nata heme vuryayiş ê ke biyê bıewnê $1i re..',
|
||||
|
|
@ -2558,9 +2558,9 @@ $1',
|
|||
'blanknamespace' => '(Ser)',
|
||||
|
||||
# Contributions
|
||||
'contributions' => 'İştirakê karberi',
|
||||
'contributions' => 'İştiraqê karberi',
|
||||
'contributions-title' => '$1 de iştırakê karberi',
|
||||
'mycontris' => 'İştıraqi',
|
||||
'mycontris' => 'Pêşteni',
|
||||
'contribsub2' => 'Qandê $1 ($2)',
|
||||
'nocontribs' => 'Ena kriteriya de vurnayîş çini yo.',
|
||||
'uctop' => '(ser)',
|
||||
|
|
@ -2683,7 +2683,7 @@ Cıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:',
|
|||
'blocklink' => 'kılit ke',
|
||||
'unblocklink' => 'ake',
|
||||
'change-blocklink' => 'kılit-kerdışi bıvurne',
|
||||
'contribslink' => 'iştıraqi',
|
||||
'contribslink' => 'pêşteni',
|
||||
'emaillink' => 'e-poste bırışe',
|
||||
'autoblocker' => 'Şıma otomatikmen kılit biy, çıke adresa şımawa \'\'IP\'\'y terefê "[[User:$1|$1]]" gureniyena.
|
||||
Sebebê kılit-biyayışê $1\'i: "$2"o',
|
||||
|
|
@ -2938,7 +2938,7 @@ dosyaya emaneti vindbiyo',
|
|||
'xml-error-string' => '$1 çizgi de $2 col $3 (bit $4): $5',
|
||||
'import-upload' => 'Dosyayê XML bar bike',
|
||||
'import-token-mismatch' => "vindibiyayişê ma'lumatê hesabi. kerem kerê newe ra tesel/cereb bıkerê.",
|
||||
'import-invalid-interwiki' => 'Eya wîkî ra nieşkenî împort bike.',
|
||||
'import-invalid-interwiki' => 'Ena wiki ra azere kerdış nêbeno.',
|
||||
'import-error-edit' => 'Pela " $1 " qandê vurnayışi aya nêgêrêna çıkı cı rê icazet nêdeyayo.',
|
||||
'import-error-create' => 'Pela " $1 " qandê vıraştışi aya nêabêna çıkı cı rê icazet nêdeyayo.',
|
||||
'import-error-interwiki' => 'Pela " $1 " qandê name dayışi aya nêgêrêna çıkı namey cı (interwiki) sero cırê ca abıryayo.',
|
||||
|
|
@ -3664,7 +3664,7 @@ $8',
|
|||
'exif-ycbcrpositioning-1' => 'Wertekerdış',
|
||||
'exif-ycbcrpositioning-2' => 'Wayırê-site',
|
||||
|
||||
'exif-dc-contributor' => 'İştırakdari',
|
||||
'exif-dc-contributor' => 'Pêşteni',
|
||||
'exif-dc-coverage' => 'Heruna yana wextin grotışa medya',
|
||||
'exif-dc-date' => 'Tarix(i)',
|
||||
'exif-dc-publisher' => 'Hesrekar',
|
||||
|
|
@ -3708,9 +3708,9 @@ $8',
|
|||
|
||||
# 'all' in various places, this might be different for inflected languages
|
||||
'watchlistall2' => 'pêro',
|
||||
'namespacesall' => 'têde',
|
||||
'namespacesall' => 'pêro',
|
||||
'monthsall' => 'pêro',
|
||||
'limitall' => 'hemi',
|
||||
'limitall' => 'pêro',
|
||||
|
||||
# E-mail address confirmation
|
||||
'confirmemail' => 'Adresê e-posta tesdiq ker',
|
||||
|
|
@ -3823,7 +3823,7 @@ Ma rica keno tesdiq bike ke ti raştî wazeno eno pel bivirazo.",
|
|||
# Table pager
|
||||
'ascending_abbrev' => 'berz',
|
||||
'descending_abbrev' => 'nızm',
|
||||
'table_pager_next' => 'Pela badê cû',
|
||||
'table_pager_next' => 'Pela peyên',
|
||||
'table_pager_prev' => 'Pela verêne',
|
||||
'table_pager_first' => 'Pela jûyıne',
|
||||
'table_pager_last' => 'Pela peyêne',
|
||||
|
|
@ -4031,10 +4031,10 @@ Resımi be tam asayış mocniyayê, tipê dosyaê bini be programê cıyo elaqed
|
|||
'specialpages-group-users' => 'Karber u heqqî',
|
||||
'specialpages-group-highuse' => 'Peleyê ke vêşi karênê',
|
||||
'specialpages-group-pages' => 'listeyanê pelan',
|
||||
'specialpages-group-pagetools' => 'Hacetê pelan',
|
||||
'specialpages-group-pagetools' => 'Haletê pelan',
|
||||
'specialpages-group-wiki' => 'Malumatê wiki u haceti',
|
||||
'specialpages-group-redirects' => 'Pela xasîyê ke heteneyayê',
|
||||
'specialpages-group-spam' => 'hacetê spami',
|
||||
'specialpages-group-spam' => 'haletê spami',
|
||||
|
||||
# Special:BlankPage
|
||||
'blankpage' => 'Pela venge',
|
||||
|
|
|
|||
|
|
@ -616,6 +616,10 @@ $1',
|
|||
'youhavenewmessages' => 'Έχετε $1 ($2).',
|
||||
'newmessageslink' => 'νέα μηνύματα',
|
||||
'newmessagesdifflink' => 'τελευταία αλλαγή',
|
||||
'youhavenewmessagesfromusers' => 'Έχετε $1 από {{PLURAL:$3|ένα άλλο χρήστη|$3 χρήστες}} ($2).',
|
||||
'youhavenewmessagesmanyusers' => 'Έχετε $1 από πολλούς χρήστες ($2).',
|
||||
'newmessageslinkplural' => '{{PLURAL:$1|ένα νέο μήνυμα|νέα μηνύματα}}',
|
||||
'newmessagesdifflinkplural' => '{{PLURAL:$1|τελευταία αλλαγή|τελευταίες αλλαγές}}',
|
||||
'youhavenewmessagesmulti' => 'Έχετε νέα μηνύματα στο $1',
|
||||
'editsection' => 'επεξεργασία',
|
||||
'editold' => 'επεξεργασία',
|
||||
|
|
@ -736,6 +740,8 @@ $2',
|
|||
'filereadonlyerror' => 'Δεν είναι δυνατή η τροποποίηση του αρχείου " $1 " επειδή το αποθετήριο αρχείων " $2 " είναι σε κατάσταση λειτουργίας μόνο για ανάγνωση.
|
||||
|
||||
Ο διαχειριστής που το κλείδωσε προσφέρει αυτή την αιτιολόγηση: " $3 ".',
|
||||
'exception-nologin' => 'Δεν έχετε συνδεθεί.',
|
||||
'exception-nologin-text' => 'Αυτή η σελίδα ή η ενέργεια απαιτεί να είστε {{GENDER:|συνδεμένος|συνδεμένη}} στο wiki.',
|
||||
|
||||
# Virus scanner
|
||||
'virus-badscanner' => "Λάθος ρύθμιση: άγνωστος ανιχνευτής ιών: ''$1''",
|
||||
|
|
@ -2239,6 +2245,8 @@ $1',
|
|||
μια έγκυρη ηλεκτρονική διεύθυνση στις [[Special:Preferences|Προτιμήσεις]]
|
||||
για να στείλετε e-mail σε άλλους χρήστες.',
|
||||
'emailuser' => 'Στείλτε μήνυμα σε αυτό τον χρήστη',
|
||||
'emailuser-title-target' => 'Αποστολή e-mail {{GENDER:$1|στο|στη}} χρήστη',
|
||||
'emailuser-title-notarget' => 'Αποστολή e-mail σε χρήστη',
|
||||
'emailpage' => 'Αποστολή μηνύματος ηλεκτρονικού ταχυδρομείο στο χρήστη',
|
||||
'emailpagetext' => 'Συπληρώνοντας την παρακάτω φόρμα θα στείλετε ένα μήνυμα εφόσον έχετε δηλώσει μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου στις [[Special:Preferences|προτιμήσεις χρήστη]]. Αυτή θα εμφανιστεί ως διεύθυνση αποστολέα του μηνύματος, ούτως ώστε ο παραλήπτης να μπορέσει να σας απαντήσει.',
|
||||
'usermailererror' => 'Σφάλμα ηλεκτρονικού ταχυδρομείου:',
|
||||
|
|
@ -2386,6 +2394,8 @@ $UNWATCHURL
|
|||
'rollback' => 'Επαναφορά επεξεργασιών',
|
||||
'rollback_short' => 'Επαναφορά',
|
||||
'rollbacklink' => 'Επαναφορά στην προηγούμενη',
|
||||
'rollbacklinkcount' => 'Επαναφορά $1 {{PLURAL:$1|επεξεργασίας|επεξεργασιών}}',
|
||||
'rollbacklinkcount-morethan' => 'επαναφορά περισσότερων από $1 {{PLURAL:$1|επεξεργασία|επεξεργασίες}}',
|
||||
'rollbackfailed' => 'Η επαναφορά απέτυχε.',
|
||||
'cantrollback' => 'Δεν είναι δυνατή η αναίρεση αυτής της αλλαγής, πρόκειται για την αρχική ενέργεια δημιουργίας της σελίδας.',
|
||||
'alreadyrolled' => 'Αδύνατον να αναιρεθεί η τελευταία αλλαγή της σελίδας [[:$1]] από το χρήστη ([[User:$2|$2]] ([[User talk:$2|Συζήτηση]]){{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), διότι κάποιος έχει ήδη αναιρέσει την αλλαγή ή έχει αλλάξει εκ νέου τη σελίδα.
|
||||
|
|
@ -3044,7 +3054,14 @@ $1',
|
|||
|
||||
# Info page
|
||||
'pageinfo-title' => 'Πληροφορίες για "$1"',
|
||||
'pageinfo-header-edits' => 'Επεξεργασίες',
|
||||
'pageinfo-header-basic' => 'Βασικές πληροφορίες',
|
||||
'pageinfo-header-edits' => 'Ιστορικό επεξεργασίας',
|
||||
'pageinfo-header-restrictions' => 'Προστασία σελίδας',
|
||||
'pageinfo-header-properties' => 'Ιδιότητες σελίδας',
|
||||
'pageinfo-display-title' => 'Εμφάνιση τίτλου',
|
||||
'pageinfo-default-sort' => 'Προεπιλεγμένο κλειδί ταξινόμησης',
|
||||
'pageinfo-length' => 'Μήκος σελίδας (σε bytes)',
|
||||
'pageinfo-article-id' => 'Αναγνωριστικό σελίδας',
|
||||
'pageinfo-views' => 'Αριθμός προβολών',
|
||||
'pageinfo-watchers' => 'Αριθμός παρατηρητών',
|
||||
'pageinfo-edits' => 'Αριθμός επεξεργασιών',
|
||||
|
|
|
|||
|
|
@ -3737,6 +3737,7 @@ This is probably caused by a link to a blacklisted external site.',
|
|||
'spam_deleting' => 'All revisions contained links to $1, deleting',
|
||||
|
||||
# Info page
|
||||
'pageinfo-header' => '-', # do not translate or duplicate this message to other languages
|
||||
'pageinfo-title' => 'Information for "$1"',
|
||||
'pageinfo-header-basic' => 'Basic information',
|
||||
'pageinfo-header-edits' => 'Edit history',
|
||||
|
|
@ -3767,6 +3768,7 @@ This is probably caused by a link to a blacklisted external site.',
|
|||
'pageinfo-magic-words' => 'Magic {{PLURAL:$1|word|words}} ($1)',
|
||||
'pageinfo-hidden-categories' => 'Hidden {{PLURAL:$1|category|categories}} ($1)',
|
||||
'pageinfo-templates' => 'Transcluded {{PLURAL:$1|template|templates}} ($1)',
|
||||
'pageinfo-footer' => '-', # do not translate or duplicate this message to other languages
|
||||
|
||||
# Skin names
|
||||
'skinname-standard' => 'Classic', # only translate this message to other languages if you have to change it
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ $messages = array(
|
|||
'tog-externaldiff' => 'Utilizar diff externo por defecto (sólo para expertos, pues necesitas ajustes especiales en tu ordenador; [//www.mediawiki.org/wiki/Manual:External_editors más información])',
|
||||
'tog-showjumplinks' => 'Habilitar enlaces de accesibilidad «saltar a»',
|
||||
'tog-uselivepreview' => 'Usar live preview (JavaScript) (Experimental)',
|
||||
'tog-forceeditsummary' => 'Alertar al grabar sin resumen de edición.',
|
||||
'tog-forceeditsummary' => 'Avisar cuando grabe la página sin introducir un resumen de edición',
|
||||
'tog-watchlisthideown' => 'Ocultar mis ediciones en la lista de seguimiento',
|
||||
'tog-watchlisthidebots' => 'Ocultar ediciones de bots en la lista de seguimiento',
|
||||
'tog-watchlisthideminor' => 'Ocultar ediciones menores en la lista de seguimiento',
|
||||
|
|
@ -572,7 +572,7 @@ $messages = array(
|
|||
'categorypage' => 'Ver página de categoría',
|
||||
'viewtalkpage' => 'Ver discusión',
|
||||
'otherlanguages' => 'Otros idiomas',
|
||||
'redirectedfrom' => '(Redirigido desde $1)',
|
||||
'redirectedfrom' => '(Redirigido desde «$1»)',
|
||||
'redirectpagesub' => 'Página redirigida',
|
||||
'lastmodifiedat' => 'Esta página fue modificada por última vez el $1, a las $2.',
|
||||
'viewcount' => 'Esta página ha sido visitada {{PLURAL:$1|una vez|$1 veces}}.',
|
||||
|
|
@ -610,7 +610,7 @@ $1',
|
|||
'privacypage' => 'Project:Política de protección de datos',
|
||||
|
||||
'badaccess' => 'Error de permisos',
|
||||
'badaccess-group0' => 'No tienes autorización para ejecutar la acción que ha solicitado.',
|
||||
'badaccess-group0' => 'No estás autorizado a ejecutar la acción solicitada.',
|
||||
'badaccess-groups' => 'La acción que has solicitado está restringida a los usuarios {{PLURAL:$2|del grupo|de uno de estos $2 grupos}}: $1.',
|
||||
|
||||
'versionrequired' => 'La versión $1 de MediaWiki es necesaria para utilizar esta página',
|
||||
|
|
@ -1025,8 +1025,10 @@ o [{{fullurl:{{FULLPAGENAME}}|action=edit}} editar esta página]</span>.',
|
|||
'noarticletext-nopermission' => 'Actualmente no hay texto en esta página.
|
||||
Puedes [[Special:Search/{{PAGENAME}}|buscar este título de página]] en otras páginas,
|
||||
o <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar en los registros relacionados]</span>.',
|
||||
'missing-revision' => 'La revisión # $1 de la página denominada "{{PAGENAME}}" no existe.
|
||||
!¡ N!Esto es generalmente causado al seguir un enlace de historia obsoleto a una página que se ha borrado.!¡ N!Los detalles pueden encontrarse en el [{{fullurl: {{#Special:Log}} / delete|page = {{FULLPAGENAMEE}}}} registro de borrado].',
|
||||
'missing-revision' => 'La revisión #$1 de la página «{{PAGENAME}}» no existe.
|
||||
|
||||
Esto suele deberse a seguir un enlace obsoleto hacia el historial de una página que ya ha sido borrada.
|
||||
Los detalles pueden encontrarse en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrado].',
|
||||
'userpage-userdoesnotexist' => 'La cuenta de usuario «<nowiki>$1</nowiki>» no está registrada. Por favor comprueba si quieres crear o editar esta página.',
|
||||
'userpage-userdoesnotexist-view' => 'La cuenta de usuario «$1» no está registrada.',
|
||||
'blocked-notice-logextract' => 'Este usuario está actualmente bloqueado.
|
||||
|
|
@ -1340,8 +1342,10 @@ Nota que usar los enlaces de navegación borrará las selecciones de esta column
|
|||
'editundo' => 'deshacer',
|
||||
'diff-multi' => '(No se {{PLURAL:$1|muestra una edición intermedia realizada|muestran $1 ediciones intermedias realizadas}} por {{PLURAL:$2|un usuario|$2 usuarios}})',
|
||||
'diff-multi-manyusers' => '(No se {{PLURAL:$1|muestra una edición intermedia|muestran $1 ediciones intermedias}} de {{PLURAL:$2|un usuario|$2 usuarios}})',
|
||||
'difference-missing-revision' => '{{PLURAL:$2|Un revisión| $2 revisiones}} de esta diferencia ( $1 ) no {{PLURAL:$2| ha siado encontrada|han sido encontradas}}.
|
||||
!¡ N!Esto es generalmente causado por seguir un enlace de diffs obsoletas a una página que ha sido borrada.!¡ N!Los detalles pueden encontrarse en el [{{fullurl:{{#Special:log}} / delete|page = {{FULLPAGENAMEE}}}} registro de borrado].',
|
||||
'difference-missing-revision' => 'No {{PLURAL:$2|se ha encontrado|se han encontrado}} {{PLURAL:$2|una revisión|$2 revisiones}} de esta diferencia ($1).
|
||||
|
||||
Esto suele deberse a seguir un enlace obsoleto hacia una página que ya ha sido borrada.
|
||||
Los detalles pueden encontrarse en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrado].',
|
||||
|
||||
# Search results
|
||||
'searchresults' => 'Resultados de la búsqueda',
|
||||
|
|
|
|||
|
|
@ -290,16 +290,16 @@ $dateFormats = array(
|
|||
|
||||
$messages = array(
|
||||
# User preference toggles
|
||||
'tog-underline' => 'Lingid alla kriipsutada',
|
||||
'tog-underline' => 'Linkide allakriipsutus:',
|
||||
'tog-justify' => 'Lõikude rööpjoondus',
|
||||
'tog-hideminor' => 'Peida pisiparandused viimastes muudatustes',
|
||||
'tog-hidepatrolled' => 'Peida viimaste muudatuste loetelus jälgimisloendis esitatavad muudatused',
|
||||
'tog-hidepatrolled' => 'Peida kontrollitud redaktsioonid viimastes muudatustes',
|
||||
'tog-newpageshidepatrolled' => 'Peida uute lehtede loendis kontrollitud leheküljed',
|
||||
'tog-extendwatchlist' => 'Laienda jälgimisloendit, et näha kõiki muudatusi, mitte vaid kõige värskemaid',
|
||||
'tog-usenewrc' => 'Rühmita viimased muudatused ja muudatused jälgimisloendis lehekülje järgi (vaja JavaScripti)',
|
||||
'tog-numberheadings' => 'Pealkirjade automaatnummerdus',
|
||||
'tog-showtoolbar' => 'Redigeerimise tööriistariba näitamine',
|
||||
'tog-editondblclick' => 'Artiklite redigeerimine topeltklõpsu peale (JavaScript)',
|
||||
'tog-showtoolbar' => 'Näita redigeerimise tööriistariba (vaja JavaScripti)',
|
||||
'tog-editondblclick' => 'Redigeeri lehekülgi topeltklõpsu peale (vaja JavaScripti)',
|
||||
'tog-editsection' => 'Näita alaosade redigeerimise linke',
|
||||
'tog-editsectiononrightclick' => 'Alusta alaosa redigeerimist paremklõpsuga alaosa pealkirjal (vaja JavaScripti)',
|
||||
'tog-showtoc' => 'Näita sisukorda (lehtedel, millel on rohkem kui 3 pealkirja)',
|
||||
|
|
@ -494,14 +494,14 @@ $messages = array(
|
|||
'talk' => 'Arutelu',
|
||||
'views' => 'vaatamisi',
|
||||
'toolbox' => 'Tööriistad',
|
||||
'userpage' => 'Kasutajalehekülg',
|
||||
'userpage' => 'Vaata kasutajalehekülge',
|
||||
'projectpage' => 'Vaata projektilehekülge',
|
||||
'imagepage' => 'Vaata faililehekülge',
|
||||
'mediawikipage' => 'Vaata sõnumi lehekülge',
|
||||
'templatepage' => 'Mallilehekülg',
|
||||
'templatepage' => 'Vaata malli lehekülge',
|
||||
'viewhelppage' => 'Vaata abilehekülge',
|
||||
'categorypage' => 'Kategoorialehekülg',
|
||||
'viewtalkpage' => 'Arutelulehekülg',
|
||||
'categorypage' => 'Vaata kategooria lehekülge',
|
||||
'viewtalkpage' => 'Vaata arutelulehekülge',
|
||||
'otherlanguages' => 'Teistes keeltes',
|
||||
'redirectedfrom' => '(Ümber suunatud leheküljelt $1)',
|
||||
'redirectpagesub' => 'Ümbersuunamisleht',
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ $messages = array(
|
|||
'viewhelppage' => 'نمایش صفحهٔ راهنما',
|
||||
'categorypage' => 'نمایش صفحهٔ رده',
|
||||
'viewtalkpage' => 'نمایش صفحهٔ بحث',
|
||||
'otherlanguages' => 'زبانهای دیگر',
|
||||
'otherlanguages' => 'به زبانهای دیگر',
|
||||
'redirectedfrom' => '(تغییرمسیر از $1)',
|
||||
'redirectpagesub' => 'صفحهٔ تغییرمسیر',
|
||||
'lastmodifiedat' => 'این صفحه آخرینبار در $1 ساعت $2 تغییر یافتهاست.',
|
||||
|
|
@ -697,6 +697,10 @@ $1',
|
|||
'youhavenewmessages' => '$1 دارید ($2).',
|
||||
'newmessageslink' => 'پیامهای جدید',
|
||||
'newmessagesdifflink' => 'آخرین تغییر',
|
||||
'youhavenewmessagesfromusers' => 'شما $1 از {{PLURAL:$3| کاربر دیگر| $3 کاربر}} دارید ( $2 ).',
|
||||
'youhavenewmessagesmanyusers' => 'شما $1 از تعدادی کاربر دارید ( $2 ).',
|
||||
'newmessageslinkplural' => '{{PLURAL:$1|پیام جدید |پیام جدید}}',
|
||||
'newmessagesdifflinkplural' => '{{formatnum:$1}} {{PLURAL:$1|تغییر|تغییرات}} اخیر',
|
||||
'youhavenewmessagesmulti' => 'پیامهای جدیدی در $1 دارید.',
|
||||
'editsection' => 'ویرایش',
|
||||
'editold' => 'ویرایش',
|
||||
|
|
@ -753,10 +757,10 @@ $1',
|
|||
'dberrortext' => 'اشکال نحوی در درخواست فرستاده شده به پایگاه داده رخ داد.
|
||||
دلیل این مشکل میتواند ایرادی در نرمافزار باشد.
|
||||
آخرین درخواست که برای پایگاه داده فرستاد شد این بود:
|
||||
<blockquote style="direction:ltr;"><tt>$1</tt></blockquote>
|
||||
این درخواست از درون عملگر «<span class="ltr"><tt>$2</tt></span>» فرستاده شد.
|
||||
<blockquote style="direction:ltr;"><code>$1</code></blockquote>
|
||||
این درخواست از درون عملگر «<span class="ltr"><code>$2</code></span>» فرستاده شد.
|
||||
پایگاه داده این خطا را بازگرداند:
|
||||
<div class="ltr"><tt>$3: $4</tt></div>',
|
||||
<div class="ltr"><samp>$3: $4</samp></div>',
|
||||
'dberrortextcl' => 'اشکال نحوی در درخواست فرستاده شده به پایگاه داده رخ داد.
|
||||
آخرین درخواستی که برای پایگاه داده فرستاد شد این بود:
|
||||
<div class="ltr">$1</div>
|
||||
|
|
@ -1109,16 +1113,19 @@ $2
|
|||
'noarticletext-nopermission' => 'این صفحه هماکنون متنی ندارد.
|
||||
شما میتوانید در دیگر صفحهها [[Special:Search/{{PAGENAME}}|این عنوان را جستجو کنید]]،
|
||||
یا <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} سیاهههای مرتبط را بگردید]</span>.',
|
||||
'missing-revision' => 'ویرایش #$1 از صفحهٔ "{{PAGENAME}}" موجود نیست.
|
||||
|
||||
معمولاً در اثر پیوند به تاریخچهٔ بهروز نشدهٔ صفحهٔ حذف شده است.
|
||||
میتوانید جزئیات بیشتر را در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] بیابید.',
|
||||
'userpage-userdoesnotexist' => 'حساب کاربر «<nowiki>$1</nowiki>» ثبت نشدهاست.
|
||||
لطفاً مطمئن شوید که میخواهید این صفحه را ایجاد یا ویرایش کنید.',
|
||||
'userpage-userdoesnotexist-view' => 'حساب کاربری «$1» ثبت نشدهاست.',
|
||||
'blocked-notice-logextract' => 'دسترسی این کاربر در حال حاضر بسته است.
|
||||
آخرین مورد سیاهه قطع دسترسی در زیر آمدهاست:',
|
||||
'clearyourcache' => "'''نکته:''' پس از ذخیرهکردن ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
|
||||
'clearyourcache' => "''نکته:''' پس از ذخیرهکردن ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
|
||||
*'''فایرفاکس / سافاری:''' کلید ''Shift'' را نگه دارید و روی دکمهٔ ''Reload'' کلیک کنید، یا کلیدهای ''Ctrl-F5'' یا ''Ctrl-R'' را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ''⌘-R'')
|
||||
*'''گوگل کروم:'''کلیدهای ''Ctrl+Shift+R'' را با هم فشار دهید. (در رایانههای اپل مکینتاش کلیدهای ''⌘-Shift-R'')
|
||||
*'''اینترنت اکسپلورر:''' کلید ''Ctrl'' را نگهدارید و روی دکمهٔ ''Refresh'' کلیک کنید، یا کلیدهای ''Ctrl-F5'' را با هم فشار دهید
|
||||
*'''کانکوئرر:''' روی دکمهٔ ''Reload'' کلیک کنید و یا کلید ''F5'' را فشار دهید
|
||||
*'''اپرا:''' حافظهٔ نهانی مرورگر را از طریق منوی ''Tools → Preferences'' پاک کنید",
|
||||
'usercssyoucanpreview' => "'''نکته:''' پیش از ذخیهکردن فایل CSS یا JS خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
|
||||
'userjsyoucanpreview' => "'''نکته:''' پیش از ذخیرهکردن فایل CSS یا JS خود، با دکمهٔ '''{{int:showpreview}}''' آن را آزمایش کنید.",
|
||||
|
|
@ -1242,6 +1249,7 @@ $2
|
|||
'expansion-depth-exceeded-warning' => 'صفحه حداکثر عمق بسط دادن تجاوز کرد',
|
||||
'parser-unstrip-loop-warning' => 'حلقه در دستور unstrip پیدا شد',
|
||||
'parser-unstrip-recursion-limit' => 'از حداکثر ارجاع در دستور unstrip تجاوز شد ($1)',
|
||||
'converter-manual-rule-error' => 'خطا در ساختار کتابچهٔ مبدل زبان',
|
||||
|
||||
# "Undo" feature
|
||||
'undo-success' => 'این ویرایش را میتوان خنثی کرد.
|
||||
|
|
@ -1428,6 +1436,10 @@ $1",
|
|||
'editundo' => 'خنثیسازی',
|
||||
'diff-multi' => '({{PLURAL:$1|یک|$1}} ویرایش میانی توسط {{PLURAL:$2|یک|$2}} کاربر نشان داده نشدهاست)',
|
||||
'diff-multi-manyusers' => '({{PLURAL:$1|یک|$1}} ویرایش میانی توسط بیش از {{PLURAL:$2|یک|$2}} کاربر نشان داده نشدهاست)',
|
||||
'difference-missing-revision' => '{{PLURAL:$2|یک ویرایش|$2 ویرایش}} از تفاوت نسخهها ($1) {{PLURAL:$2|یافت|یافت}} نشد.
|
||||
|
||||
معمولاً در اثر پیوند به تاریخچهٔ بهروز نشدهٔ صفحهٔ حذف شده است.
|
||||
میتوانید جزئیات بیشتر را در [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سیاههٔ حذف] بیابید.',
|
||||
|
||||
# Search results
|
||||
'searchresults' => 'نتایج جستجو',
|
||||
|
|
@ -2132,6 +2144,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
|
|||
'shared-repo-from' => 'از $1',
|
||||
'shared-repo' => 'یک مخزن مشترک',
|
||||
'shared-repo-name-wikimediacommons' => 'ویکیانبار',
|
||||
'upload-disallowed-here' => 'متاسفانه شما نمی توانید این نگاره را بازنویس کنید.',
|
||||
|
||||
# File reversion
|
||||
'filerevert' => 'واگردانی $1',
|
||||
|
|
@ -2213,8 +2226,8 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
|
|||
|
||||
'disambiguations' => 'صفحههای دارای پیوند به صفحههای ابهامزدایی',
|
||||
'disambiguationspage' => 'Template:ابهامزدایی',
|
||||
'disambiguations-text' => "صفحههای زیر پیوندی به یک '''صفحهٔ ابهامزدایی''' هستند.
|
||||
این صفحهها باید در عوض به موضوعات مرتبط پیوند داده شوند.<br />
|
||||
'disambiguations-text' => "صفحههای زیر حاوی حداقل یک پیوند به یک '''صفحهٔ ابهامزدایی''' هستند.
|
||||
این صفحهها شاید در عوض به موضوعات مرتبط پیوند داده شوند.<br />
|
||||
یک صفحه هنگامی صفحهٔ ابهامزدایی در نظر گرفته میشود که در آن از الگویی که به [[MediaWiki:Disambiguationspage]] پیوند دارد استفاده شده باشد.",
|
||||
|
||||
'doubleredirects' => 'تغییرمسیرهای دوتایی',
|
||||
|
|
@ -2240,6 +2253,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
|
|||
# Miscellaneous special pages
|
||||
'nbytes' => '$1 {{PLURAL:$1|بایت|بایت}}',
|
||||
'ncategories' => '$1 {{PLURAL:$1|رده|رده}}',
|
||||
'ninterwikis' => '$1 {{PLURAL:$1|میانویکی|میانویکی}}',
|
||||
'nlinks' => '$1 {{PLURAL:$1|پیوند|پیوند}}',
|
||||
'nmembers' => '$1 {{PLURAL:$1|عضو|عضو}}',
|
||||
'nrevisions' => '$1 {{PLURAL:$1|نسخه|نسخه}}',
|
||||
|
|
@ -2268,6 +2282,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
|
|||
'mostlinkedtemplates' => 'الگوهایی که بیشتر از همه به آنها پیوند داده شدهاست',
|
||||
'mostcategories' => 'صفحههای دارای بیشترین رده',
|
||||
'mostimages' => 'پروندههایی که بیشتر از همه به آنها پیوند داده شدهاست',
|
||||
'mostinterwikis' => 'صفحههای دارای بیشترین میانویکی',
|
||||
'mostrevisions' => 'صفحههای دارای بیشترین نسخه',
|
||||
'prefixindex' => 'تمام صفحهها با پیشوند',
|
||||
'prefixindex-namespace' => 'همهٔ صفحههای دارای پیشوند (فضاینام $1)',
|
||||
|
|
@ -2414,6 +2429,8 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
|
|||
'mailnologin' => 'نشانیای از فرستنده موجود نیست',
|
||||
'mailnologintext' => 'برای فرستادن رایانامه به کاربران دیگر باید [[Special:UserLogin|به سامانه وارد شوید]] و نشانی رایانامهٔ معتبری در [[Special:Preferences|ترجیحات]] خود داشته باشید.',
|
||||
'emailuser' => 'فرستادن نامه به این کاربر',
|
||||
'emailuser-title-target' => 'ایمیل این {{GENDER:$1| کاربر}}',
|
||||
'emailuser-title-notarget' => 'رایانامه به کاربر',
|
||||
'emailpage' => 'رایانامه به کاربر',
|
||||
'emailpagetext' => 'شما میتوانید از فرم زیر برای ارسال یک رایانامه به این کاربر استفاده کنید.
|
||||
نشانی رایانامهای که در [[Special:Preferences|ترجیحات کاربریتان]] وارد کردهاید در نشانی فرستنده (From) نامه خواهد آمد، تا گیرنده بتواند پاسخ دهد.',
|
||||
|
|
@ -3066,6 +3083,7 @@ $1',
|
|||
'import-interwiki-templates' => 'تمام الگوها را شامل شود',
|
||||
'import-interwiki-submit' => 'درونریزی شود',
|
||||
'import-interwiki-namespace' => 'فضای نام مقصد:',
|
||||
'import-interwiki-rootpage' => 'مقصد صفحه ٔ مبنا (اختیاری):',
|
||||
'import-upload-filename' => 'نام پرونده:',
|
||||
'import-comment' => 'توضیح:',
|
||||
'importtext' => 'لطفاً پرونده را از ویکی منبع با کمک [[Special:Export|ابزار برونبری]] دریافت کنید.
|
||||
|
|
@ -3100,6 +3118,9 @@ $1',
|
|||
'import-error-interwiki' => 'صفحه «$1» وارد نشد. چون نام آن برای پیوند خارجی (interwiki) رزرو شدهاست.',
|
||||
'import-error-special' => 'صفحه «$1» درونریزی نشد، چرا که متعلق به فضای نام غیرمجاز است.',
|
||||
'import-error-invalid' => 'صفحه "$1" به دلیل نامعتبر بودن نامش وارد نمیشود.',
|
||||
'import-options-wrong' => '{{PLURAL:$2|جزئیات|جزئیات}} اشتباه: <nowiki>$1</nowiki>',
|
||||
'import-rootpage-invalid' => 'با توجه به ریشه صفحه عنوان نامعتبر است.',
|
||||
'import-rootpage-nosubpage' => 'فضای نام "$1" صفحهٔ مبنا اجازهٔ زیرصفحه نمیدهد.',
|
||||
|
||||
# Import log
|
||||
'importlogpage' => 'سیاههٔ درونریزیها',
|
||||
|
|
@ -3221,11 +3242,34 @@ $1',
|
|||
|
||||
# Info page
|
||||
'pageinfo-title' => 'اطلاعات در مورد «$1»',
|
||||
'pageinfo-header-edits' => 'ویرایش',
|
||||
'pageinfo-header-basic' => 'اطلاعات اولیه',
|
||||
'pageinfo-header-edits' => 'ویرایش تاریخچه',
|
||||
'pageinfo-header-restrictions' => 'حفاظت از صفحه',
|
||||
'pageinfo-header-properties' => 'ويژگيهای صفحه',
|
||||
'pageinfo-display-title' => 'نمایش عنوان',
|
||||
'pageinfo-default-sort' => 'کلید مرتبسازی پیشفرض',
|
||||
'pageinfo-length' => 'حجم صفحه (بایت)',
|
||||
'pageinfo-article-id' => 'شناسهٔ صفحه',
|
||||
'pageinfo-robot-policy' => 'وضعیت موتور جستجو',
|
||||
'pageinfo-robot-index' => 'فهرستپذیر',
|
||||
'pageinfo-robot-noindex' => 'عدم فهرستپذیری',
|
||||
'pageinfo-views' => 'شمار بازدیدها',
|
||||
'pageinfo-watchers' => 'شمار پیگیریکنندگان',
|
||||
'pageinfo-edits' => 'شمار ویرایشها',
|
||||
'pageinfo-authors' => 'شمار نویسندگان یکتا',
|
||||
'pageinfo-watchers' => 'شمار پیگیریکنندگان صفحه',
|
||||
'pageinfo-redirects-name' => 'تغییرمسیرها به این صفحه',
|
||||
'pageinfo-subpages-name' => 'زیرصفحههای این صفحه',
|
||||
'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|تغییرمسیر|تغییرمسیر}}; $3 {{PLURAL:$3|غیرتغییرمسیر|غیرتغییرمسیر}})',
|
||||
'pageinfo-firstuser' => 'بهوجود آورندهٔ صفحه',
|
||||
'pageinfo-firsttime' => 'زمان ایجاد صفحه',
|
||||
'pageinfo-lastuser' => 'آخرین ویرایشگر',
|
||||
'pageinfo-lasttime' => 'تاریخ آخرین ویرایش',
|
||||
'pageinfo-edits' => 'شمار کلی ویرایشها',
|
||||
'pageinfo-authors' => 'تعداد کلی نویسندگان یکتا',
|
||||
'pageinfo-recent-edits' => 'شماره ویرایشهای اخیر (در $1 گذشته)',
|
||||
'pageinfo-recent-authors' => 'تعداد نویسندگان یکتای اخیر',
|
||||
'pageinfo-restriction' => 'محافظت صفحه ( <code>{{lcfirst:$1}}</code> )',
|
||||
'pageinfo-magic-words' => '{{PLURAL:$1|حرف|حروف}} جادویی ($1)',
|
||||
'pageinfo-hidden-categories' => '{{PLURAL:$1| ردهٔ|ردهٔ}} پنهان ( $1 )',
|
||||
'pageinfo-templates' => '{{PLURAL:$1|الگو|الگو}} استفادهشده ($1)',
|
||||
|
||||
# Skin names
|
||||
'skinname-standard' => 'کلاسیک',
|
||||
|
|
@ -3281,6 +3325,7 @@ $1',
|
|||
'file-info-size-pages' => '<span style="direction:ltr">$1 × $2</span> نقطه، حجم پرونده: $3، نوع MIME پرونده: $4، $5 صفحه',
|
||||
'file-nohires' => 'تفکیکپذیری بالاتری در دسترس نیست.',
|
||||
'svg-long-desc' => 'پروندهٔ اسویجی، با ابعاد <span dir="ltr">$1 × $2</span> پیکسل، اندازهٔ پرونده: $3',
|
||||
'svg-long-desc-animated' => 'پروندهٔ اسویجی متحرک، با ابعاد <span dir="ltr">$1 × $2</span> پیکسل، اندازهٔ پرونده: $3',
|
||||
'show-big-image' => 'تصویر با تفکیکپذیری بالاتر',
|
||||
'show-big-image-preview' => 'اندازهٔ این پیشنمایش: $1.',
|
||||
'show-big-image-other' => '{{PLURAL:$2|کیفیت|کیفیتهای}} دیگر: $1.',
|
||||
|
|
@ -3290,6 +3335,8 @@ $1',
|
|||
'file-info-png-looped' => 'چرخشدار',
|
||||
'file-info-png-repeat' => '$1 {{PLURAL:$1|بار|بار}} پخش شد',
|
||||
'file-info-png-frames' => '$1 {{PLURAL:$1|قاب|قاب}}',
|
||||
'file-no-thumb-animation' => "'''توجه: به علت مسائل فنی پیشنمایش پرونده به صورت متحرک نمایش داده نمیشود.'''",
|
||||
'file-no-thumb-animation-gif' => "'''توجه:به علت مسائل فنی پیشنمایش پروندههای GIF مانند این پرونده، به صورت متحرک نمایش داده نمیشود.'''",
|
||||
|
||||
# Special:NewFiles
|
||||
'newimages' => 'نگارخانهٔ پروندههای جدید',
|
||||
|
|
@ -3318,7 +3365,7 @@ $1',
|
|||
پیوندهایی بعدی در همان سطر استثنا در نظر گرفته میشوند.',
|
||||
|
||||
# Metadata
|
||||
'metadata' => 'متاداده',
|
||||
'metadata' => 'فراداده',
|
||||
'metadata-help' => 'این پرونده حاوی اطلاعات اضافهایاست که احتمالاً دوربین دیجیتال یا پویشگری که در ایجاد یا دیجیتالیکردن آن به کار رفته آن را افزودهاست. اگر پرونده از وضعیت ابتداییاش تغییر داده شده باشد آنگاه ممکن است شرح و تفصیلات موجود اطلاعات تصویر را تماماً بازتاب ندهد.',
|
||||
'metadata-expand' => 'نمایش جزئیات تفصیلی',
|
||||
'metadata-collapse' => 'نهفتن جزئیات تفصیلی',
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ $messages = array(
|
|||
'tagline' => '{{SITENAME}}',
|
||||
'help' => 'Ohje',
|
||||
'search' => 'Haku',
|
||||
'searchbutton' => 'Etsi',
|
||||
'searchbutton' => 'Hae',
|
||||
'go' => 'Siirry',
|
||||
'searcharticle' => 'Siirry',
|
||||
'history' => 'Historia',
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ $messages = array(
|
|||
'faqpage' => 'Project:Quèstions sovent posâyes',
|
||||
|
||||
# Vector skin
|
||||
'vector-action-addsection' => 'Apondre un sujèt',
|
||||
'vector-action-addsection' => 'Apondre na chousa',
|
||||
'vector-action-delete' => 'Suprimar',
|
||||
'vector-action-move' => 'Renomar',
|
||||
'vector-action-protect' => 'Protègiér',
|
||||
|
|
@ -643,7 +643,7 @@ La bâsa de donâs at retornâ la fôta « $3 : $4 ».',
|
|||
'laggedslavemode' => "'''Atencion :''' cela pâge pôt pas contegnir tôs los dèrriérs changements fêts.",
|
||||
'readonly' => 'Bâsa de donâs vèrrolyêye',
|
||||
'enterlockreason' => 'Balyéd la rêson du vèrroly et pués n’èstimacion de la sina durâ',
|
||||
'readonlytext' => 'Ora la bâsa de donâs est vèrrolyêye por les entrâs novèles et los ôtros changements, probâblament por pèrmetre la sina mantegnence, dês cen tot tornerat en ôrdre.
|
||||
'readonlytext' => 'Ora la bâsa de donâs est vèrrolyêye por les entrâs novèles et los ôtros changements, de sûr por pèrmetre la sina mantegnence, dês cen tot tornerat en ôrdre.
|
||||
|
||||
L’administrator que l’at vèrrolyê at balyê cet’èxplicacion : $1',
|
||||
'missing-article' => 'La bâsa de donâs at pas trovâ lo tèxto d’una pâge qu’el arêt diu trovar, avouéc lo titro « $1 » $2.
|
||||
|
|
@ -772,14 +772,14 @@ Volyéd tornar èprovar.',
|
|||
'password-login-forbidden' => 'L’usâjo de cél nom d’utilisator et de cél contresegno est étâ dèfendu.',
|
||||
'mailmypassword' => 'Recêvre un contresegno novél per mèssageria èlèctronica',
|
||||
'passwordremindertitle' => 'Contresegno temporèro novél por {{SITENAME}}',
|
||||
'passwordremindertext' => 'Quârqu’un (probâblament vos, avouéc l’adrèce IP $1) at demandâ un contresegno
|
||||
'passwordremindertext' => 'Quârqu’un (probâblament vos, dês l’adrèce IP $1) at demandâ un contresegno
|
||||
novél por {{SITENAME}} ($4). Un contresegno temporèro est étâ fêt por
|
||||
l’utilisator « $2 » et est « $3 ». S’o ére voutra entencion, vos vos devréd
|
||||
branchiér et pués chouèsir un contresegno novél.
|
||||
Voutron contresegno temporèro èxpirerat dens $5 jorn{{PLURAL:$5||s}}.
|
||||
Voutron contresegno temporèro èxpirerat dens {{PLURAL:$5|yon jorn|$5 jorns}}.
|
||||
|
||||
Se cela demanda vint pas de vos ou ben se vos vos rapelâd ora
|
||||
de voutron contresegno et que vos souhètâd pas més nen changiér, vos
|
||||
Se cela demanda vint pas de vos ou ben que vos vos éte rapelâ
|
||||
de voutron contresegno et que vos souhètâd pas més lo changiér, vos
|
||||
pouede ignorar ceti mèssâjo et continuar a empleyér voutron viely contresegno.',
|
||||
'noemail' => 'Niona adrèce èlèctronica est étâye encartâye por l’utilisator « $1 ».',
|
||||
'noemailcreate' => 'Vos dête balyér n’adrèce èlèctronica valida',
|
||||
|
|
@ -845,44 +845,44 @@ Pôt-étre vos éd ja changiê voutron contresegno avouéc reusséta ou ben dema
|
|||
'passwordreset-text' => 'Rempléd ceti formulèro por recêvre un mèssâjo de sovegnence des dètalys de voutron compto.',
|
||||
'passwordreset-legend' => 'Tornar inicialisar lo contresegno',
|
||||
'passwordreset-disabled' => 'La remisa a zérô des contresegnos est étâye dèsactivâye sur ceti vouiqui.',
|
||||
'passwordreset-pretext' => '{{PLURAL:$1||Buchiéd yon des bocons de balyês ce-desot}}',
|
||||
'passwordreset-username' => 'Nom d’usanciér :',
|
||||
'passwordreset-pretext' => '{{PLURAL:$1||Buchiéd yona de les piéces de donâs ce-desot}}',
|
||||
'passwordreset-username' => 'Nom d’utilisator :',
|
||||
'passwordreset-domain' => 'Domêno :',
|
||||
'passwordreset-capture' => 'Vêre lo mèssâjo que rèsulte ?',
|
||||
'passwordreset-capture-help' => 'Se vos pouentâd cela câsa, lo mèssâjo (avouéc lo contresegno temporèro) vos serat montrâ en mémo temps que serat mandâ a l’usanciér.',
|
||||
'passwordreset-capture-help' => 'Se vos pouentâd cela câsa, lo mèssâjo (avouéc lo contresegno temporèro) vos serat fêt vêre quand serat mandâ a l’utilisator.',
|
||||
'passwordreset-email' => 'Adrèce èlèctronica :',
|
||||
'passwordreset-emailtitle' => 'Dètalys du compto dessus {{SITENAME}}',
|
||||
'passwordreset-emailtext-ip' => 'Quârqu’un (probâblament vos, avouéc l’adrèce IP $1) at demandâ un rapèl des dètalys
|
||||
de voutron compto por {{SITENAME}} ($4). {{PLURAL:$3|Ceti compto usanciér est associyê|Cetos comptos usanciérs sont associyês}}
|
||||
a cela adrèce èlèctronica :
|
||||
'passwordreset-emailtext-ip' => 'Quârqu’un (probâblament vos, dês l’adrèce IP $1) at demandâ na sovegnence des dètalys
|
||||
de voutron compto por {{SITENAME}} ($4). {{PLURAL:$3|Ceti compto utilisator est associyê|Cetos comptos utilisators sont associyês}}
|
||||
a cel’adrèce èlèctronica :
|
||||
|
||||
$2
|
||||
|
||||
{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens $5 jorn{{PLURAL:$5||s}}.
|
||||
Ora, vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos,
|
||||
ou ben se vos vos rapelâd ora de voutron contresegno originâl et que vos souhètâd pas més nen changiér,
|
||||
vos pouede ignorar ceti mèssâjo et continuar a utilisar voutron viely contresegno.',
|
||||
'passwordreset-emailtext-user' => 'L’usanciér $1 dessus {{SITENAME}} at demandâ un rapèl des dètalys
|
||||
de voutron compto por {{SITENAME}} ($4). {{PLURAL:$3|Ceti compto usanciér est associyê|Cetos comptos usanciérs sont associyês}}
|
||||
a cela adrèce èlèctronica :
|
||||
{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|yon jorn|$5 jorns}}.
|
||||
Ora vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos
|
||||
ou ben que vos vos éte rapelâ de voutron contresegno originâl et que vos souhètâd pas més lo changiér,
|
||||
vos pouede ignorar ceti mèssâjo et continuar a empleyér voutron viely contresegno.',
|
||||
'passwordreset-emailtext-user' => 'L’utilisator $1 dessus {{SITENAME}} at demandâ na sovegnence des dètalys
|
||||
de voutron compto por {{SITENAME}} ($4). {{PLURAL:$3|Ceti compto utilisator est associyê|Cetos comptos utilisators sont associyês}}
|
||||
a cel’adrèce èlèctronica :
|
||||
|
||||
$2
|
||||
|
||||
{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens $5 jorn{{PLURAL:$5||s}}.
|
||||
Ora, vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos,
|
||||
ou ben se vos vos rapelâd ora de voutron contresegno originâl et que vos souhètâd pas més nen changiér,
|
||||
vos pouede ignorar ceti mèssâjo et continuar a utilisar voutron viely contresegno.',
|
||||
'passwordreset-emailelement' => 'Nom d’usanciér : $1
|
||||
{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|yon jorn|$5 jorns}}.
|
||||
Ora vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos
|
||||
ou ben que vos vos éte rapelâ de voutron contresegno originâl et que vos souhètâd pas més lo changiér,
|
||||
vos pouede ignorar ceti mèssâjo et continuar a empleyér voutron viely contresegno.',
|
||||
'passwordreset-emailelement' => 'Nom d’utilisator : $1
|
||||
Contresegno temporèro : $2',
|
||||
'passwordreset-emailsent' => 'Un mèssâjo de rapèl at étâ mandâ.',
|
||||
'passwordreset-emailsent-capture' => 'Un mèssâjo de rapèl at étâ mandâ, qu’est montrâ ce-desot.',
|
||||
'passwordreset-emailerror-capture' => 'Un mèssâjo de rapèl at étâ fêt, qu’est montrâ ce-desot, mas l’èxpèdicion a l’usanciér at pas reussia : $1',
|
||||
'passwordreset-emailsent' => 'Un mèssâjo de sovegnence est étâ mandâ.',
|
||||
'passwordreset-emailsent-capture' => 'Un mèssâjo de sovegnence est étâ mandâ, qu’est fêt vêre ce-desot.',
|
||||
'passwordreset-emailerror-capture' => 'Un mèssâjo de sovegnence est étâ fêt, qu’est fêt vêre ce-desot, mas l’èxpèdicion a l’utilisator at pas reussi : $1',
|
||||
|
||||
# Special:ChangeEmail
|
||||
'changeemail' => 'Changiér l’adrèce èlèctronica',
|
||||
'changeemail-header' => 'Changiér l’adrèce èlèctronica',
|
||||
'changeemail-text' => 'Rempléd ceti formulèro por changiér voutra adrèce èlèctronica. Vos devréd buchiér voutron contresegno por confirmar cél changement.',
|
||||
'changeemail-no-info' => 'Vos dête étre branchiê por avêr accès a cela pâge.',
|
||||
'changeemail-header' => 'Changiér l’adrèce èlèctronica du compto',
|
||||
'changeemail-text' => 'Rempléd ceti formulèro por changiér voutron adrèce èlèctronica. Vos devréd buchiér voutron contresegno por confirmar cél changement.',
|
||||
'changeemail-no-info' => 'Vos dête étre branchiê por arrevar tot drêt a cela pâge.',
|
||||
'changeemail-oldemail' => 'Adrèce èlèctronica d’ora :',
|
||||
'changeemail-newemail' => 'Novèla adrèce èlèctronica :',
|
||||
'changeemail-none' => '(niona)',
|
||||
|
|
@ -890,28 +890,28 @@ Contresegno temporèro : $2',
|
|||
'changeemail-cancel' => 'Anular',
|
||||
|
||||
# Edit page toolbar
|
||||
'bold_sample' => 'Tèxto en grâs',
|
||||
'bold_tip' => 'Tèxto en grâs',
|
||||
'italic_sample' => 'Tèxto en étalico',
|
||||
'italic_tip' => 'Tèxto en étalico',
|
||||
'bold_sample' => 'Tèxto grâs',
|
||||
'bold_tip' => 'Tèxto grâs',
|
||||
'italic_sample' => 'Tèxto étalico',
|
||||
'italic_tip' => 'Tèxto étalico',
|
||||
'link_sample' => 'Titro du lim',
|
||||
'link_tip' => 'Lim de dedens',
|
||||
'extlink_sample' => 'http://www.example.com titro du lim',
|
||||
'extlink_tip' => 'Lim de defôr (oubliâd pas lo prèfixo http://)',
|
||||
'headline_sample' => 'Tèxto de sot-titro',
|
||||
'headline_sample' => 'Tèxto du titro',
|
||||
'headline_tip' => 'Sot-titro nivél 2',
|
||||
'nowiki_sample' => 'Buchiéd lo tèxto pas formatâ ique',
|
||||
'nowiki_tip' => 'Ignorar lo formatâjo vouiqui',
|
||||
'image_sample' => 'Ègzemplo.jpg',
|
||||
'image_tip' => 'Fichiér entrebetâ',
|
||||
'image_tip' => 'Fichiér apondu',
|
||||
'media_sample' => 'Ègzemplo.ogg',
|
||||
'media_tip' => 'Lim de vers un fichiér',
|
||||
'sig_tip' => 'Voutra signatura avouéc la dâta',
|
||||
'sig_tip' => 'Voutra signatura avouéc la dâta et hora',
|
||||
'hr_tip' => 'Legne plana (pas nen abusar)',
|
||||
|
||||
# Edit pages
|
||||
'summary' => 'Rèsumâ :',
|
||||
'subject' => 'Sujèt / titro :',
|
||||
'subject' => 'Chousa / titro :',
|
||||
'minoredit' => 'Petiôt changement',
|
||||
'watchthis' => 'Siuvre ceta pâge',
|
||||
'savearticle' => 'Sôvar la pâge',
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue