Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4107008
ImportTranslationsSpecialPage.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
ImportTranslationsSpecialPage.php
View Options
<?php
declare
(
strict_types
=
1
);
namespace
MediaWiki\Extension\Translate\Synchronization
;
use
BagOStuff
;
use
FileBasedMessageGroup
;
use
MediaWiki\Extension\Translate\FileFormatSupport\GettextFormat
;
use
MediaWiki\Extension\Translate\FileFormatSupport\GettextParseException
;
use
MediaWiki\Extension\Translate\MessageGroupProcessing\MessageGroups
;
use
MediaWiki\Html\Html
;
use
MediaWiki\SpecialPage\SpecialPage
;
use
MessageGroupBase
;
use
Xml
;
/**
* Special page to import Gettext (.po) files exported using Translate extension.
* Does not support generic Gettext files.
*
* @author Niklas Laxström
* @author Siebrand Mazeland
* @license GPL-2.0-or-later
* @ingroup SpecialPage TranslateSpecialPage
*/
class
ImportTranslationsSpecialPage
extends
SpecialPage
{
private
BagOStuff
$cache
;
public
function
__construct
(
BagOStuff
$cache
)
{
parent
::
__construct
(
'ImportTranslations'
,
'translate-import'
);
$this
->
cache
=
$cache
;
}
public
function
doesWrites
()
{
return
true
;
}
protected
function
getGroupName
()
{
return
'translation'
;
}
/**
* Special page entry point.
* @param null|string $parameters
* @throws \PermissionsError
*/
public
function
execute
(
$parameters
)
{
$this
->
setHeaders
();
// Security and validity checks
if
(
!
$this
->
userCanExecute
(
$this
->
getUser
()
)
)
{
$this
->
displayRestrictionError
();
}
if
(
!
$this
->
getRequest
()->
wasPosted
()
)
{
$this
->
outputForm
();
return
;
}
$csrfTokenSet
=
$this
->
getContext
()->
getCsrfTokenSet
();
if
(
!
$csrfTokenSet
->
matchTokenField
(
'token'
)
)
{
$this
->
getOutput
()->
addWikiMsg
(
'session_fail_preview'
);
$this
->
outputForm
();
return
;
}
if
(
$this
->
getRequest
()->
getCheck
(
'process'
)
)
{
$data
=
$this
->
getCachedData
();
if
(
!
$data
)
{
$this
->
getOutput
()->
addWikiMsg
(
'session_fail_preview'
);
$this
->
outputForm
();
return
;
}
}
else
{
/**
* Proceed to loading and parsing if possible
* @todo: use a Status object instead?
*/
$file
=
null
;
$msg
=
$this
->
loadFile
(
$file
);
if
(
$this
->
checkError
(
$msg
)
)
{
return
;
}
$msg
=
$this
->
parseFile
(
$file
);
if
(
$this
->
checkError
(
$msg
)
)
{
return
;
}
$data
=
$msg
[
1
];
$this
->
setCachedData
(
$data
);
}
$messages
=
$data
[
'MESSAGES'
];
$groupId
=
$data
[
'EXTRA'
][
'METADATA'
][
'group'
];
$code
=
$data
[
'EXTRA'
][
'METADATA'
][
'code'
];
if
(
!
MessageGroups
::
exists
(
$groupId
)
)
{
$errorWrap
=
"<div class='error'>
\n
$1
\n
</div>"
;
$this
->
getOutput
()->
wrapWikiMsg
(
$errorWrap
,
'translate-import-err-stale-group'
);
return
;
}
$importer
=
new
MessageWebImporter
(
$this
->
getPageTitle
(),
$this
->
getUser
(),
$groupId
,
$code
);
$allDone
=
$importer
->
execute
(
$messages
);
$out
=
$this
->
getOutput
();
$pageTitle
=
$this
->
getPageTitle
();
if
(
$allDone
)
{
$this
->
deleteCachedData
();
$this
->
outputForm
();
}
$out
->
addBacklinkSubtitle
(
$pageTitle
);
}
/**
* Checks for error state from the return value of loadFile and parseFile
* functions. Prints the error and the form and returns true if there is an
* error. Returns false and does nothing if there is no error.
*/
private
function
checkError
(
array
$msg
):
bool
{
// Give grep a chance to find the usages:
// translate-import-err-dl-failed, translate-import-err-ul-failed,
// translate-import-err-invalid-title, translate-import-err-no-such-file,
// translate-import-err-stale-group, translate-import-err-no-headers,
if
(
$msg
[
0
]
!==
'ok'
)
{
$errorWrap
=
"<div class='error'>
\n
$1
\n
</div>"
;
$msg
[
0
]
=
'translate-import-err-'
.
$msg
[
0
];
$this
->
getOutput
()->
wrapWikiMsg
(
$errorWrap
,
$msg
);
$this
->
outputForm
();
return
true
;
}
return
false
;
}
/** Constructs and outputs file input form with supported methods. */
private
function
outputForm
():
void
{
$this
->
getOutput
()->
addModules
(
'ext.translate.special.importtranslations'
);
$this
->
getOutput
()->
addHelpLink
(
'Help:Extension:Translate/Off-line_translation'
);
/** Ugly but necessary form building ahead, ohoy */
$this
->
getOutput
()->
addHTML
(
Xml
::
openElement
(
'form'
,
[
'action'
=>
$this
->
getPageTitle
()->
getLocalURL
(),
'method'
=>
'post'
,
'enctype'
=>
'multipart/form-data'
,
'id'
=>
'mw-translate-import'
,
]
)
.
Html
::
hidden
(
'token'
,
$this
->
getContext
()->
getCsrfTokenSet
()->
getToken
()
)
.
Html
::
hidden
(
'title'
,
$this
->
getPageTitle
()->
getPrefixedText
()
)
.
Xml
::
inputLabel
(
$this
->
msg
(
'translate-import-from-local'
)->
text
(),
'upload-local'
,
// name
'mw-translate-up-local-input'
,
// id
50
,
// size
$this
->
getRequest
()->
getText
(
'upload-local'
),
[
'type'
=>
'file'
]
)
.
Html
::
submitButton
(
$this
->
msg
(
'translate-import-load'
)->
text
()
)
.
Xml
::
closeElement
(
'form'
)
);
}
/** Try to get the file data from any of the supported methods. */
private
function
loadFile
(
?
string
&
$filedata
):
array
{
$filename
=
$this
->
getRequest
()->
getFileTempname
(
'upload-local'
);
if
(
!
is_uploaded_file
(
$filename
)
)
{
return
[
'ul-failed'
];
}
$filedata
=
file_get_contents
(
$filename
);
return
[
'ok'
];
}
/** Try parsing file. */
private
function
parseFile
(
string
$data
):
array
{
/** Construct a dummy group for us...
* @todo Time to rethink the interface again?
* @var FileBasedMessageGroup $group
*/
$group
=
MessageGroupBase
::
factory
(
[
'FILES'
=>
[
'format'
=>
'Gettext'
,
'CtxtAsKey'
=>
true
,
],
'BASIC'
=>
[
'class'
=>
FileBasedMessageGroup
::
class
,
'namespace'
=>
-
1
,
]
]
);
'@phan-var FileBasedMessageGroup $group'
;
$ffs
=
new
GettextFormat
(
$group
);
try
{
$parseOutput
=
$ffs
->
readFromVariable
(
$data
);
}
catch
(
GettextParseException
$e
)
{
return
[
'no-headers'
];
}
// Special data added by GettextFormat
$metadata
=
$parseOutput
[
'EXTRA'
][
'METADATA'
];
// This should catch everything that is not a Gettext file exported from us
if
(
!
isset
(
$metadata
[
'code'
]
)
||
!
isset
(
$metadata
[
'group'
]
)
)
{
return
[
'no-headers'
];
}
return
[
'ok'
,
$parseOutput
];
}
private
function
setCachedData
(
$data
):
void
{
$key
=
$this
->
cache
->
makeKey
(
'translate'
,
'webimport'
,
$this
->
getUser
()->
getId
()
);
$this
->
cache
->
set
(
$key
,
$data
,
60
*
30
);
}
private
function
getCachedData
()
{
$key
=
$this
->
cache
->
makeKey
(
'translate'
,
'webimport'
,
$this
->
getUser
()->
getId
()
);
return
$this
->
cache
->
get
(
$key
);
}
private
function
deleteCachedData
():
bool
{
$key
=
$this
->
cache
->
makeKey
(
'translate'
,
'webimport'
,
$this
->
getUser
()->
getId
()
);
return
$this
->
cache
->
delete
(
$key
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Tue, Aug 18, 19:50 (2 w, 3 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
f6/eb/2de285fe22627a3f64e97424bf75
Default Alt Text
ImportTranslationsSpecialPage.php (6 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment