Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F2752930
SpecialImport.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
SpecialImport.php
View Options
<?php
/**
* Copyright © 2003,2005 Brooke Vibber <bvibber@wikimedia.org>
* https://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
namespace
MediaWiki\Specials
;
use
Exception
;
use
ImportReporter
;
use
ImportStreamSource
;
use
MediaWiki\Exception\PermissionsError
;
use
MediaWiki\Html\Html
;
use
MediaWiki\HTMLForm\HTMLForm
;
use
MediaWiki\MainConfigNames
;
use
MediaWiki\Permissions\PermissionStatus
;
use
MediaWiki\SpecialPage\SpecialPage
;
use
MediaWiki\Status\Status
;
use
UnexpectedValueException
;
use
WikiImporterFactory
;
use
Wikimedia\Rdbms\DBError
;
use
Wikimedia\RequestTimeout\TimeoutException
;
/**
* MediaWiki page data importer
*
* @ingroup SpecialPage
*/
class
SpecialImport
extends
SpecialPage
{
/** @var array */
private
$importSources
;
private
WikiImporterFactory
$wikiImporterFactory
;
public
function
__construct
(
WikiImporterFactory
$wikiImporterFactory
)
{
parent
::
__construct
(
'Import'
,
'import'
);
$this
->
wikiImporterFactory
=
$wikiImporterFactory
;
}
public
function
doesWrites
()
{
return
true
;
}
/**
* Execute
* @param string|null $par
*/
public
function
execute
(
$par
)
{
$this
->
useTransactionalTimeLimit
();
$this
->
setHeaders
();
$this
->
outputHeader
();
$this
->
importSources
=
$this
->
getConfig
()->
get
(
MainConfigNames
::
ImportSources
);
// Avoid phan error by checking the type
if
(
!
is_array
(
$this
->
importSources
)
)
{
throw
new
UnexpectedValueException
(
'$wgImportSources must be an array'
);
}
$this
->
getHookRunner
()->
onImportSources
(
$this
->
importSources
);
$authority
=
$this
->
getAuthority
();
$statusImport
=
PermissionStatus
::
newEmpty
();
$authority
->
isDefinitelyAllowed
(
'import'
,
$statusImport
);
$statusImportUpload
=
PermissionStatus
::
newEmpty
();
$authority
->
isDefinitelyAllowed
(
'importupload'
,
$statusImportUpload
);
// Only show an error here if the user can't import using either method.
// If they can use at least one of the methods, allow access, and checks elsewhere
// will ensure that we only show the form(s) they can use.
$out
=
$this
->
getOutput
();
if
(
!
$statusImport
->
isGood
()
&&
!
$statusImportUpload
->
isGood
()
)
{
// Show separate messages for each check. There isn't a good way to merge them into a single
// message if the checks failed for different reasons.
$out
->
prepareErrorPage
();
$out
->
setPageTitleMsg
(
$this
->
msg
(
'permissionserrors'
)
);
$out
->
addModuleStyles
(
'mediawiki.codex.messagebox.styles'
);
$out
->
addWikiTextAsInterface
(
Html
::
errorBox
(
$out
->
formatPermissionStatus
(
$statusImport
,
'import'
)
)
);
$out
->
addWikiTextAsInterface
(
Html
::
errorBox
(
$out
->
formatPermissionStatus
(
$statusImportUpload
,
'importupload'
)
)
);
return
;
}
$out
->
addModules
(
'mediawiki.misc-authed-ooui'
);
$out
->
addModuleStyles
(
'mediawiki.special.import.styles.ooui'
);
$this
->
checkReadOnly
();
$request
=
$this
->
getRequest
();
if
(
$request
->
wasPosted
()
&&
$request
->
getRawVal
(
'action'
)
==
'submit'
)
{
$this
->
doImport
();
}
$this
->
showForm
();
}
/**
* Do the actual import
*/
private
function
doImport
()
{
$isUpload
=
false
;
$request
=
$this
->
getRequest
();
$sourceName
=
$request
->
getVal
(
'source'
);
$assignKnownUsers
=
$request
->
getCheck
(
'assignKnownUsers'
);
$logcomment
=
$request
->
getText
(
'log-comment'
);
$pageLinkDepth
=
$this
->
getConfig
()->
get
(
MainConfigNames
::
ExportMaxLinkDepth
)
==
0
?
0
:
$request
->
getIntOrNull
(
'pagelink-depth'
);
$rootpage
=
''
;
$mapping
=
$request
->
getVal
(
'mapping'
);
$namespace
=
$this
->
getConfig
()->
get
(
MainConfigNames
::
ImportTargetNamespace
);
if
(
$mapping
===
'namespace'
)
{
$namespace
=
$request
->
getIntOrNull
(
'namespace'
);
}
elseif
(
$mapping
===
'subpage'
)
{
$rootpage
=
$request
->
getText
(
'rootpage'
);
}
$user
=
$this
->
getUser
();
$authority
=
$this
->
getAuthority
();
$status
=
PermissionStatus
::
newEmpty
();
$fullInterwikiPrefix
=
null
;
if
(
!
$user
->
matchEditToken
(
$request
->
getVal
(
'wpEditToken'
)
)
)
{
$source
=
Status
::
newFatal
(
'import-token-mismatch'
);
}
elseif
(
$sourceName
===
'upload'
)
{
$isUpload
=
true
;
$fullInterwikiPrefix
=
$request
->
getVal
(
'usernamePrefix'
);
if
(
$authority
->
authorizeAction
(
'importupload'
,
$status
)
)
{
$source
=
ImportStreamSource
::
newFromUpload
(
"xmlimport"
);
}
else
{
throw
new
PermissionsError
(
'importupload'
,
$status
);
}
}
elseif
(
$sourceName
===
'interwiki'
)
{
if
(
!
$authority
->
authorizeAction
(
'import'
,
$status
)
)
{
throw
new
PermissionsError
(
'import'
,
$status
);
}
$interwiki
=
$fullInterwikiPrefix
=
$request
->
getVal
(
'interwiki'
);
// does this interwiki have subprojects?
$hasSubprojects
=
array_key_exists
(
$interwiki
,
$this
->
importSources
);
if
(
!
$hasSubprojects
&&
!
in_array
(
$interwiki
,
$this
->
importSources
)
)
{
$source
=
Status
::
newFatal
(
"import-invalid-interwiki"
);
}
else
{
$subproject
=
null
;
if
(
$hasSubprojects
)
{
$subproject
=
$request
->
getVal
(
'subproject'
);
// Trim "project::" prefix added for JS
if
(
str_starts_with
(
$subproject
,
$interwiki
.
'::'
)
)
{
$subproject
=
substr
(
$subproject
,
strlen
(
$interwiki
.
'::'
)
);
}
$fullInterwikiPrefix
.=
':'
.
$subproject
;
}
if
(
$hasSubprojects
&&
!
in_array
(
$subproject
,
$this
->
importSources
[
$interwiki
]
)
)
{
$source
=
Status
::
newFatal
(
'import-invalid-interwiki'
);
}
else
{
$history
=
$request
->
getCheck
(
'interwikiHistory'
);
$frompage
=
$request
->
getText
(
'frompage'
);
$includeTemplates
=
$request
->
getCheck
(
'interwikiTemplates'
);
$source
=
ImportStreamSource
::
newFromInterwiki
(
// @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive
$fullInterwikiPrefix
,
$frompage
,
$history
,
$includeTemplates
,
$pageLinkDepth
);
}
}
}
else
{
$source
=
Status
::
newFatal
(
"importunknownsource"
);
}
if
(
(
string
)
$fullInterwikiPrefix
===
''
)
{
$source
->
fatal
(
'importnoprefix'
);
}
$out
=
$this
->
getOutput
();
if
(
!
$source
->
isGood
()
)
{
$out
->
wrapWikiMsg
(
Html
::
errorBox
(
'$1'
),
[
'importfailed'
,
$source
->
getWikiText
(
false
,
false
,
$this
->
getLanguage
()
),
count
(
$source
->
getMessages
()
)
]
);
}
else
{
$importer
=
$this
->
wikiImporterFactory
->
getWikiImporter
(
$source
->
value
,
$this
->
getAuthority
()
);
if
(
$namespace
!==
null
)
{
$importer
->
setTargetNamespace
(
$namespace
);
}
elseif
(
$rootpage
!==
null
)
{
$statusRootPage
=
$importer
->
setTargetRootPage
(
$rootpage
);
if
(
!
$statusRootPage
->
isGood
()
)
{
$out
->
wrapWikiMsg
(
Html
::
errorBox
(
'$1'
),
[
'import-options-wrong'
,
$statusRootPage
->
getWikiText
(
false
,
false
,
$this
->
getLanguage
()
),
count
(
$statusRootPage
->
getMessages
()
)
]
);
return
;
}
}
// @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive
$importer
->
setUsernamePrefix
(
$fullInterwikiPrefix
,
$assignKnownUsers
);
$out
->
addWikiMsg
(
"importstart"
);
$reporter
=
new
ImportReporter
(
$importer
,
$isUpload
,
// @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive
$fullInterwikiPrefix
,
$logcomment
,
$this
->
getContext
()
);
$exception
=
false
;
$reporter
->
open
();
try
{
$importer
->
doImport
();
}
catch
(
DBError
|
TimeoutException
$e
)
{
// Re-throw exceptions which are not safe to catch (T383933).
throw
$e
;
}
catch
(
Exception
$e
)
{
$exception
=
$e
;
}
finally
{
$result
=
$reporter
->
close
();
}
if
(
$exception
)
{
# No source or XML parse error
$out
->
wrapWikiMsg
(
Html
::
errorBox
(
'$1'
),
[
'importfailed'
,
wfEscapeWikiText
(
$exception
->
getMessage
()
),
1
]
);
}
elseif
(
!
$result
->
isGood
()
)
{
# Zero revisions
$out
->
wrapWikiMsg
(
Html
::
errorBox
(
'$1'
),
[
'importfailed'
,
$result
->
getWikiText
(
false
,
false
,
$this
->
getLanguage
()
),
count
(
$result
->
getMessages
()
)
]
);
}
else
{
# Success!
$out
->
addWikiMsg
(
'importsuccess'
);
}
$out
->
addHTML
(
'<hr />'
);
}
}
private
function
getMappingFormPart
(
string
$sourceName
):
array
{
$defaultNamespace
=
$this
->
getConfig
()->
get
(
MainConfigNames
::
ImportTargetNamespace
);
return
[
'mapping'
=>
[
'type'
=>
'radio'
,
'name'
=>
'mapping'
,
// IDs: mw-import-mapping-interwiki, mw-import-mapping-upload
'id'
=>
"mw-import-mapping-$sourceName"
,
'options-messages'
=>
[
'import-mapping-default'
=>
'default'
,
'import-mapping-namespace'
=>
'namespace'
,
'import-mapping-subpage'
=>
'subpage'
],
'default'
=>
$defaultNamespace
!==
null
?
'namespace'
:
'default'
],
'namespace'
=>
[
'type'
=>
'namespaceselect'
,
'name'
=>
'namespace'
,
// IDs: mw-import-namespace-interwiki, mw-import-namespace-upload
'id'
=>
"mw-import-namespace-$sourceName"
,
'default'
=>
$defaultNamespace
?:
''
,
'all'
=>
null
,
'disable-if'
=>
[
'!=='
,
'mapping'
,
'namespace'
],
],
'rootpage'
=>
[
'type'
=>
'text'
,
'name'
=>
'rootpage'
,
// Should be "mw-import-...", but we keep the inaccurate ID for compat
// IDs: mw-interwiki-rootpage-interwiki, mw-interwiki-rootpage-upload
'id'
=>
"mw-interwiki-rootpage-$sourceName"
,
'disable-if'
=>
[
'!=='
,
'mapping'
,
'subpage'
],
],
];
}
private
function
showForm
()
{
$action
=
$this
->
getPageTitle
()->
getLocalURL
(
[
'action'
=>
'submit'
]
);
$authority
=
$this
->
getAuthority
();
$out
=
$this
->
getOutput
();
$this
->
addHelpLink
(
'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Import'
,
true
);
$interwikiFormDescriptor
=
[];
$uploadFormDescriptor
=
[];
if
(
$authority
->
isDefinitelyAllowed
(
'importupload'
)
)
{
$mappingSelection
=
$this
->
getMappingFormPart
(
'upload'
);
$uploadFormDescriptor
+=
[
'intro'
=>
[
'type'
=>
'info'
,
'raw'
=>
true
,
'default'
=>
$this
->
msg
(
'importtext'
)->
parseAsBlock
()
],
'xmlimport'
=>
[
'type'
=>
'file'
,
'name'
=>
'xmlimport'
,
'accept'
=>
[
'application/xml'
,
'text/xml'
],
'label-message'
=>
'import-upload-filename'
,
'required'
=>
true
,
],
'usernamePrefix'
=>
[
'type'
=>
'text'
,
'name'
=>
'usernamePrefix'
,
'label-message'
=>
'import-upload-username-prefix'
,
'required'
=>
true
,
],
'assignKnownUsers'
=>
[
'type'
=>
'check'
,
'name'
=>
'assignKnownUsers'
,
'label-message'
=>
'import-assign-known-users'
],
'log-comment'
=>
[
'type'
=>
'text'
,
'name'
=>
'log-comment'
,
'label-message'
=>
'import-comment'
],
'source'
=>
[
'type'
=>
'hidden'
,
'name'
=>
'source'
,
'default'
=>
'upload'
,
'id'
=>
''
,
],
];
$uploadFormDescriptor
+=
$mappingSelection
;
$htmlForm
=
HTMLForm
::
factory
(
'ooui'
,
$uploadFormDescriptor
,
$this
->
getContext
()
);
$htmlForm
->
setAction
(
$action
);
$htmlForm
->
setId
(
'mw-import-upload-form'
);
$htmlForm
->
setWrapperLegendMsg
(
'import-upload'
);
$htmlForm
->
setSubmitTextMsg
(
'uploadbtn'
);
$htmlForm
->
prepareForm
()->
displayForm
(
false
);
}
elseif
(
!
$this
->
importSources
)
{
$out
->
addWikiMsg
(
'importnosources'
);
}
if
(
$authority
->
isDefinitelyAllowed
(
'import'
)
&&
$this
->
importSources
)
{
$projects
=
[];
$needSubprojectField
=
false
;
foreach
(
$this
->
importSources
as
$key
=>
$value
)
{
if
(
is_int
(
$key
)
)
{
$key
=
$value
;
}
elseif
(
$value
!==
$key
)
{
$needSubprojectField
=
true
;
}
$projects
[
$key
]
=
$key
;
}
$interwikiFormDescriptor
+=
[
'intro'
=>
[
'type'
=>
'info'
,
'raw'
=>
true
,
'default'
=>
$this
->
msg
(
'import-interwiki-text'
)->
parseAsBlock
()
],
'interwiki'
=>
[
'type'
=>
'select'
,
'name'
=>
'interwiki'
,
'label-message'
=>
'import-interwiki-sourcewiki'
,
'options'
=>
$projects
],
];
if
(
$needSubprojectField
)
{
$subprojects
=
[];
foreach
(
$this
->
importSources
as
$key
=>
$value
)
{
if
(
is_array
(
$value
)
)
{
foreach
(
$value
as
$subproject
)
{
$subprojects
[
$subproject
]
=
$key
.
'::'
.
$subproject
;
}
}
}
$interwikiFormDescriptor
+=
[
'subproject'
=>
[
'type'
=>
'select'
,
'name'
=>
'subproject'
,
'options'
=>
$subprojects
]
];
}
$interwikiFormDescriptor
+=
[
'frompage'
=>
[
'type'
=>
'text'
,
'name'
=>
'frompage'
,
'label-message'
=>
'import-interwiki-sourcepage'
],
'interwikiHistory'
=>
[
'type'
=>
'check'
,
'name'
=>
'interwikiHistory'
,
'label-message'
=>
'import-interwiki-history'
],
'interwikiTemplates'
=>
[
'type'
=>
'check'
,
'name'
=>
'interwikiTemplates'
,
'label-message'
=>
'import-interwiki-templates'
],
'assignKnownUsers'
=>
[
'type'
=>
'check'
,
'name'
=>
'assignKnownUsers'
,
'label-message'
=>
'import-assign-known-users'
],
];
if
(
$this
->
getConfig
()->
get
(
MainConfigNames
::
ExportMaxLinkDepth
)
>
0
)
{
$interwikiFormDescriptor
+=
[
'pagelink-depth'
=>
[
'type'
=>
'int'
,
'name'
=>
'pagelink-depth'
,
'label-message'
=>
'export-pagelinks'
,
'default'
=>
0
]
];
}
$interwikiFormDescriptor
+=
[
'log-comment'
=>
[
'type'
=>
'text'
,
'name'
=>
'log-comment'
,
'label-message'
=>
'import-comment'
],
'source'
=>
[
'type'
=>
'hidden'
,
'name'
=>
'source'
,
'default'
=>
'interwiki'
,
'id'
=>
''
,
],
];
$mappingSelection
=
$this
->
getMappingFormPart
(
'interwiki'
);
$interwikiFormDescriptor
+=
$mappingSelection
;
$htmlForm
=
HTMLForm
::
factory
(
'ooui'
,
$interwikiFormDescriptor
,
$this
->
getContext
()
);
$htmlForm
->
setAction
(
$action
);
$htmlForm
->
setId
(
'mw-import-interwiki-form'
);
$htmlForm
->
setWrapperLegendMsg
(
'importinterwiki'
);
$htmlForm
->
setSubmitTextMsg
(
'import-interwiki-submit'
);
$htmlForm
->
prepareForm
()->
displayForm
(
false
);
}
}
protected
function
getGroupName
()
{
return
'pagetools'
;
}
}
/** @deprecated class alias since 1.41 */
class_alias
(
SpecialImport
::
class
,
'SpecialImport'
);
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Fri, Jul 3, 20:34 (1 d, 7 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
9c/47/2994280d5593cc8d4fe8dff083b3
Default Alt Text
SpecialImport.php (14 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment