'EditAction' => __DIR__ . '/includes/actions/EditAction.php',
'EditCLI' => __DIR__ . '/maintenance/edit.php',
'EditPage' => __DIR__ . '/includes/EditPage.php',
- 'EditWatchlistCheckboxSeriesField' => __DIR__ . '/includes/specials/SpecialEditWatchlist.php',
- 'EditWatchlistNormalHTMLForm' => __DIR__ . '/includes/specials/SpecialEditWatchlist.php',
+ 'EditWatchlistCheckboxSeriesField' => __DIR__ . '/includes/specials/formfields/EditWatchlistCheckboxSeriesField.php',
+ 'EditWatchlistNormalHTMLForm' => __DIR__ . '/includes/specials/forms/EditWatchlistNormalHTMLForm.php',
'EmailConfirmation' => __DIR__ . '/includes/specials/SpecialConfirmemail.php',
'EmailInvalidation' => __DIR__ . '/includes/specials/SpecialEmailInvalidate.php',
'EmailNotification' => __DIR__ . '/includes/mail/EmailNotification.php',
'ImageQueryPage' => __DIR__ . '/includes/specialpage/ImageQueryPage.php',
'ImportImages' => __DIR__ . '/maintenance/importImages.php',
'ImportLogFormatter' => __DIR__ . '/includes/logging/ImportLogFormatter.php',
- 'ImportReporter' => __DIR__ . '/includes/specials/SpecialImport.php',
+ 'ImportReporter' => __DIR__ . '/includes/specials/helpers/ImportReporter.php',
'ImportSiteScripts' => __DIR__ . '/maintenance/importSiteScripts.php',
'ImportSites' => __DIR__ . '/maintenance/importSites.php',
'ImportSource' => __DIR__ . '/includes/import/ImportSource.php',
'Languages' => __DIR__ . '/maintenance/language/languages.inc',
'LayeredParameterizedPassword' => __DIR__ . '/includes/password/LayeredParameterizedPassword.php',
'LegacyLogFormatter' => __DIR__ . '/includes/logging/LogFormatter.php',
- 'License' => __DIR__ . '/includes/Licenses.php',
- 'Licenses' => __DIR__ . '/includes/Licenses.php',
+ 'License' => __DIR__ . '/includes/specials/helpers/License.php',
+ 'Licenses' => __DIR__ . '/includes/specials/formfields/Licenses.php',
'LinkBatch' => __DIR__ . '/includes/cache/LinkBatch.php',
'LinkCache' => __DIR__ . '/includes/cache/LinkCache.php',
'LinkFilter' => __DIR__ . '/includes/LinkFilter.php',
'PostgresInstaller' => __DIR__ . '/includes/installer/PostgresInstaller.php',
'PostgresUpdater' => __DIR__ . '/includes/installer/PostgresUpdater.php',
'Preferences' => __DIR__ . '/includes/Preferences.php',
- 'PreferencesForm' => __DIR__ . '/includes/Preferences.php',
+ 'PreferencesForm' => __DIR__ . '/includes/specials/forms/PreferencesForm.php',
'PrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
'PreprocessDump' => __DIR__ . '/maintenance/preprocessDump.php',
'Preprocessor' => __DIR__ . '/includes/parser/Preprocessor.php',
'UploadChunkVerificationException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
'UploadChunkZeroLengthFileException' => __DIR__ . '/includes/upload/UploadFromChunks.php',
'UploadDumper' => __DIR__ . '/maintenance/dumpUploads.php',
- 'UploadForm' => __DIR__ . '/includes/specials/SpecialUpload.php',
+ 'UploadForm' => __DIR__ . '/includes/specials/forms/UploadForm.php',
'UploadFromChunks' => __DIR__ . '/includes/upload/UploadFromChunks.php',
'UploadFromFile' => __DIR__ . '/includes/upload/UploadFromFile.php',
'UploadFromStash' => __DIR__ . '/includes/upload/UploadFromStash.php',
'UploadFromUrl' => __DIR__ . '/includes/upload/UploadFromUrl.php',
'UploadLogFormatter' => __DIR__ . '/includes/logging/UploadLogFormatter.php',
'UploadSourceAdapter' => __DIR__ . '/includes/import/UploadSourceAdapter.php',
- 'UploadSourceField' => __DIR__ . '/includes/specials/SpecialUpload.php',
+ 'UploadSourceField' => __DIR__ . '/includes/specials/formfields/UploadSourceField.php',
'UploadStash' => __DIR__ . '/includes/upload/UploadStash.php',
'UploadStashBadPathException' => __DIR__ . '/includes/upload/UploadStash.php',
'UploadStashCleanup' => __DIR__ . '/maintenance/cleanupUploadStash.php',
+++ /dev/null
-<?php
-/**
- * License selector for use on Special:Upload.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup SpecialPage
- * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
- */
-
-/**
- * A License class for use on Special:Upload
- */
-class Licenses extends HTMLFormField {
- /** @var string */
- protected $msg;
-
- /** @var array */
- protected $licenses = [];
-
- /** @var string */
- protected $html;
- /**#@-*/
-
- /**
- * @param array $params
- */
- public function __construct( $params ) {
- parent::__construct( $params );
-
- $this->msg = empty( $params['licenses'] )
- ? wfMessage( 'licenses' )->inContentLanguage()->plain()
- : $params['licenses'];
- $this->selected = null;
-
- $this->makeLicenses();
- }
-
- /**
- * @private
- */
- protected function makeLicenses() {
- $levels = [];
- $lines = explode( "\n", $this->msg );
-
- foreach ( $lines as $line ) {
- if ( strpos( $line, '*' ) !== 0 ) {
- continue;
- } else {
- list( $level, $line ) = $this->trimStars( $line );
-
- if ( strpos( $line, '|' ) !== false ) {
- $obj = new License( $line );
- $this->stackItem( $this->licenses, $levels, $obj );
- } else {
- if ( $level < count( $levels ) ) {
- $levels = array_slice( $levels, 0, $level );
- }
- if ( $level == count( $levels ) ) {
- $levels[$level - 1] = $line;
- } elseif ( $level > count( $levels ) ) {
- $levels[] = $line;
- }
- }
- }
- }
- }
-
- /**
- * @param string $str
- * @return array
- */
- protected function trimStars( $str ) {
- $numStars = strspn( $str, '*' );
- return [ $numStars, ltrim( substr( $str, $numStars ), ' ' ) ];
- }
-
- /**
- * @param array &$list
- * @param array $path
- * @param mixed $item
- */
- protected function stackItem( &$list, $path, $item ) {
- $position =& $list;
- if ( $path ) {
- foreach ( $path as $key ) {
- $position =& $position[$key];
- }
- }
- $position[] = $item;
- }
-
- /**
- * @param array $tagset
- * @param int $depth
- */
- protected function makeHtml( $tagset, $depth = 0 ) {
- foreach ( $tagset as $key => $val ) {
- if ( is_array( $val ) ) {
- $this->html .= $this->outputOption(
- $key, '',
- [
- 'disabled' => 'disabled',
- 'style' => 'color: GrayText', // for MSIE
- ],
- $depth
- );
- $this->makeHtml( $val, $depth + 1 );
- } else {
- $this->html .= $this->outputOption(
- $val->text, $val->template,
- [ 'title' => '{{' . $val->template . '}}' ],
- $depth
- );
- }
- }
- }
-
- /**
- * @param string $message
- * @param string $value
- * @param null|array $attribs
- * @param int $depth
- * @return string
- */
- protected function outputOption( $message, $value, $attribs = null, $depth = 0 ) {
- $msgObj = $this->msg( $message );
- $text = $msgObj->exists() ? $msgObj->text() : $message;
- $attribs['value'] = $value;
- if ( $value === $this->selected ) {
- $attribs['selected'] = 'selected';
- }
-
- $val = str_repeat( /*   */ "\xc2\xa0", $depth * 2 ) . $text;
- return str_repeat( "\t", $depth ) . Xml::element( 'option', $attribs, $val ) . "\n";
- }
-
- /**#@-*/
-
- /**
- * Accessor for $this->licenses
- *
- * @return array
- */
- public function getLicenses() {
- return $this->licenses;
- }
-
- /**
- * Accessor for $this->html
- *
- * @param bool $value
- *
- * @return string
- */
- public function getInputHTML( $value ) {
- $this->selected = $value;
-
- $this->html = $this->outputOption( wfMessage( 'nolicense' )->text(), '',
- (bool)$this->selected ? null : [ 'selected' => 'selected' ] );
- $this->makeHtml( $this->getLicenses() );
-
- $attribs = [
- 'name' => $this->mName,
- 'id' => $this->mID
- ];
- if ( !empty( $this->mParams['disabled'] ) ) {
- $attibs['disabled'] = 'disabled';
- }
-
- return Html::rawElement( 'select', $attribs, $this->html );
- }
-}
-
-/**
- * A License class for use on Special:Upload (represents a single type of license).
- */
-class License {
- /** @var string */
- public $template;
-
- /** @var string */
- public $text;
-
- /**
- * @param string $str License name??
- */
- function __construct( $str ) {
- list( $text, $template ) = explode( '|', strrev( $str ), 2 );
-
- $this->template = strrev( $template );
- $this->text = strrev( $text );
- }
-}
<?php
/**
- * Form to edit user preferences.
- *
* 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
return $timeZoneList;
}
}
-
-/** Some tweaks to allow js prefs to work */
-class PreferencesForm extends HTMLForm {
- // Override default value from HTMLForm
- protected $mSubSectionBeforeFields = false;
-
- private $modifiedUser;
-
- /**
- * @param User $user
- */
- public function setModifiedUser( $user ) {
- $this->modifiedUser = $user;
- }
-
- /**
- * @return User
- */
- public function getModifiedUser() {
- if ( $this->modifiedUser === null ) {
- return $this->getUser();
- } else {
- return $this->modifiedUser;
- }
- }
-
- /**
- * Get extra parameters for the query string when redirecting after
- * successful save.
- *
- * @return array
- */
- public function getExtraSuccessRedirectParameters() {
- return [];
- }
-
- /**
- * @param string $html
- * @return string
- */
- function wrapForm( $html ) {
- $html = Xml::tags( 'div', [ 'id' => 'preferences' ], $html );
-
- return parent::wrapForm( $html );
- }
-
- /**
- * @return string
- */
- function getButtons() {
- $attrs = [ 'id' => 'mw-prefs-restoreprefs' ];
-
- if ( !$this->getModifiedUser()->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) {
- return '';
- }
-
- $html = parent::getButtons();
-
- if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) {
- $t = $this->getTitle()->getSubpage( 'reset' );
-
- $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
- $html .= "\n" . $linkRenderer->makeLink( $t, $this->msg( 'restoreprefs' )->text(),
- Html::buttonAttributes( $attrs, [ 'mw-ui-quiet' ] ) );
-
- $html = Xml::tags( 'div', [ 'class' => 'mw-prefs-buttons' ], $html );
- }
-
- return $html;
- }
-
- /**
- * Separate multi-option preferences into multiple preferences, since we
- * have to store them separately
- * @param array $data
- * @return array
- */
- function filterDataForSubmit( $data ) {
- foreach ( $this->mFlatFields as $fieldname => $field ) {
- if ( $field instanceof HTMLNestedFilterable ) {
- $info = $field->mParams;
- $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $fieldname;
- foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
- $data["$prefix$key"] = $value;
- }
- unset( $data[$fieldname] );
- }
- }
-
- return $data;
- }
-
- /**
- * Get the whole body of the form.
- * @return string
- */
- function getBody() {
- return $this->displaySection( $this->mFieldTree, '', 'mw-prefsection-' );
- }
-
- /**
- * Get the "<legend>" for a given section key. Normally this is the
- * prefs-$key message but we'll allow extensions to override it.
- * @param string $key
- * @return string
- */
- function getLegend( $key ) {
- $legend = parent::getLegend( $key );
- Hooks::run( 'PreferencesGetLegend', [ $this, $key, &$legend ] );
- return $legend;
- }
-
- /**
- * Get the keys of each top level preference section.
- * @return array of section keys
- */
- function getPreferenceSections() {
- return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
- }
-}
);
}
}
-
-/**
- * Extend HTMLForm purely so we can have a more sane way of getting the section headers
- */
-class EditWatchlistNormalHTMLForm extends HTMLForm {
- public function getLegend( $namespace ) {
- $namespace = substr( $namespace, 2 );
-
- return $namespace == NS_MAIN
- ? $this->msg( 'blanknamespace' )->escaped()
- : htmlspecialchars( $this->getContext()->getLanguage()->getFormattedNsText( $namespace ) );
- }
-
- public function getBody() {
- return $this->displaySection( $this->mFieldTree, '', 'editwatchlist-' );
- }
-}
-
-class EditWatchlistCheckboxSeriesField extends HTMLMultiSelectField {
- /**
- * HTMLMultiSelectField throws validation errors if we get input data
- * that doesn't match the data set in the form setup. This causes
- * problems if something gets removed from the watchlist while the
- * form is open (T34126), but we know that invalid items will
- * be harmless so we can override it here.
- *
- * @param string $value The value the field was submitted with
- * @param array $alldata The data collected from the form
- * @return bool|string Bool true on success, or String error to display.
- */
- function validate( $value, $alldata ) {
- // Need to call into grandparent to be a good citizen. :)
- return HTMLFormField::validate( $value, $alldata );
- }
-}
* @ingroup SpecialPage
*/
-use MediaWiki\MediaWikiServices;
-
/**
* MediaWiki page data importer
*
return 'pagetools';
}
}
-
-/**
- * Reporting callback
- * @ingroup SpecialPage
- */
-class ImportReporter extends ContextSource {
- private $reason = false;
- private $logTags = [];
- private $mOriginalLogCallback = null;
- private $mOriginalPageOutCallback = null;
- private $mLogItemCount = 0;
-
- /**
- * @param WikiImporter $importer
- * @param bool $upload
- * @param string $interwiki
- * @param string|bool $reason
- */
- function __construct( $importer, $upload, $interwiki, $reason = false ) {
- $this->mOriginalPageOutCallback =
- $importer->setPageOutCallback( [ $this, 'reportPage' ] );
- $this->mOriginalLogCallback =
- $importer->setLogItemCallback( [ $this, 'reportLogItem' ] );
- $importer->setNoticeCallback( [ $this, 'reportNotice' ] );
- $this->mPageCount = 0;
- $this->mIsUpload = $upload;
- $this->mInterwiki = $interwiki;
- $this->reason = $reason;
- }
-
- /**
- * Sets change tags to apply to the import log entry and null revision.
- *
- * @param array $tags
- * @since 1.29
- */
- public function setChangeTags( array $tags ) {
- $this->logTags = $tags;
- }
-
- function open() {
- $this->getOutput()->addHTML( "<ul>\n" );
- }
-
- function reportNotice( $msg, array $params ) {
- $this->getOutput()->addHTML(
- Html::element( 'li', [], $this->msg( $msg, $params )->text() )
- );
- }
-
- function reportLogItem( /* ... */ ) {
- $this->mLogItemCount++;
- if ( is_callable( $this->mOriginalLogCallback ) ) {
- call_user_func_array( $this->mOriginalLogCallback, func_get_args() );
- }
- }
-
- /**
- * @param Title $title
- * @param ForeignTitle $foreignTitle
- * @param int $revisionCount
- * @param int $successCount
- * @param array $pageInfo
- * @return void
- */
- public function reportPage( $title, $foreignTitle, $revisionCount,
- $successCount, $pageInfo ) {
- $args = func_get_args();
- call_user_func_array( $this->mOriginalPageOutCallback, $args );
-
- if ( $title === null ) {
- # Invalid or non-importable title; a notice is already displayed
- return;
- }
-
- $this->mPageCount++;
- $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
- if ( $successCount > 0 ) {
- // <bdi> prevents jumbling of the versions count
- // in RTL wikis in case the page title is LTR
- $this->getOutput()->addHTML(
- "<li>" . $linkRenderer->makeLink( $title ) . " " .
- "<bdi>" .
- $this->msg( 'import-revision-count' )->numParams( $successCount )->escaped() .
- "</bdi>" .
- "</li>\n"
- );
-
- $logParams = [ '4:number:count' => $successCount ];
- if ( $this->mIsUpload ) {
- $detail = $this->msg( 'import-logentry-upload-detail' )->numParams(
- $successCount )->inContentLanguage()->text();
- $action = 'upload';
- } else {
- $pageTitle = $foreignTitle->getFullText();
- $fullInterwikiPrefix = $this->mInterwiki;
- Hooks::run( 'ImportLogInterwikiLink', [ &$fullInterwikiPrefix, &$pageTitle ] );
-
- $interwikiTitleStr = $fullInterwikiPrefix . ':' . $pageTitle;
- $interwiki = '[[:' . $interwikiTitleStr . ']]';
- $detail = $this->msg( 'import-logentry-interwiki-detail' )->numParams(
- $successCount )->params( $interwiki )->inContentLanguage()->text();
- $action = 'interwiki';
- $logParams['5:title-link:interwiki'] = $interwikiTitleStr;
- }
- if ( $this->reason ) {
- $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text()
- . $this->reason;
- }
-
- $comment = $detail; // quick
- $dbw = wfGetDB( DB_MASTER );
- $latest = $title->getLatestRevID();
- $nullRevision = Revision::newNullRevision(
- $dbw,
- $title->getArticleID(),
- $comment,
- true,
- $this->getUser()
- );
-
- $nullRevId = null;
- if ( !is_null( $nullRevision ) ) {
- $nullRevId = $nullRevision->insertOn( $dbw );
- $page = WikiPage::factory( $title );
- # Update page record
- $page->updateRevisionOn( $dbw, $nullRevision );
- Hooks::run(
- 'NewRevisionFromEditComplete',
- [ $page, $nullRevision, $latest, $this->getUser() ]
- );
- }
-
- // Create the import log entry
- $logEntry = new ManualLogEntry( 'import', $action );
- $logEntry->setTarget( $title );
- $logEntry->setComment( $this->reason );
- $logEntry->setPerformer( $this->getUser() );
- $logEntry->setParameters( $logParams );
- $logid = $logEntry->insert();
- if ( count( $this->logTags ) ) {
- $logEntry->setTags( $this->logTags );
- }
- // Make sure the null revision will be tagged as well
- $logEntry->setAssociatedRevId( $nullRevId );
-
- $logEntry->publish( $logid );
-
- } else {
- $this->getOutput()->addHTML( "<li>" . $linkRenderer->makeKnownLink( $title ) . " " .
- $this->msg( 'import-nonewrevisions' )->escaped() . "</li>\n" );
- }
- }
-
- function close() {
- $out = $this->getOutput();
- if ( $this->mLogItemCount > 0 ) {
- $msg = $this->msg( 'imported-log-entries' )->numParams( $this->mLogItemCount )->parse();
- $out->addHTML( Xml::tags( 'li', null, $msg ) );
- } elseif ( $this->mPageCount == 0 && $this->mLogItemCount == 0 ) {
- $out->addHTML( "</ul>\n" );
-
- return Status::newFatal( 'importnopages' );
- }
- $out->addHTML( "</ul>\n" );
-
- return Status::newGood( $this->mPageCount );
- }
-}
* @ingroup Upload
*/
-use MediaWiki\Linker\LinkRenderer;
use MediaWiki\MediaWikiServices;
/**
return $bitmapHandler->autoRotateEnabled();
}
}
-
-/**
- * Sub class of HTMLForm that provides the form section of SpecialUpload
- */
-class UploadForm extends HTMLForm {
- protected $mWatch;
- protected $mForReUpload;
- protected $mSessionKey;
- protected $mHideIgnoreWarning;
- protected $mDestWarningAck;
- protected $mDestFile;
-
- protected $mComment;
- protected $mTextTop;
- protected $mTextAfterSummary;
-
- protected $mSourceIds;
-
- protected $mMaxFileSize = [];
-
- protected $mMaxUploadSize = [];
-
- public function __construct( array $options = [], IContextSource $context = null,
- LinkRenderer $linkRenderer = null
- ) {
- if ( $context instanceof IContextSource ) {
- $this->setContext( $context );
- }
-
- if ( !$linkRenderer ) {
- $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
- }
-
- $this->mWatch = !empty( $options['watch'] );
- $this->mForReUpload = !empty( $options['forreupload'] );
- $this->mSessionKey = isset( $options['sessionkey'] ) ? $options['sessionkey'] : '';
- $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
- $this->mDestWarningAck = !empty( $options['destwarningack'] );
- $this->mDestFile = isset( $options['destfile'] ) ? $options['destfile'] : '';
-
- $this->mComment = isset( $options['description'] ) ?
- $options['description'] : '';
-
- $this->mTextTop = isset( $options['texttop'] )
- ? $options['texttop'] : '';
-
- $this->mTextAfterSummary = isset( $options['textaftersummary'] )
- ? $options['textaftersummary'] : '';
-
- $sourceDescriptor = $this->getSourceSection();
- $descriptor = $sourceDescriptor
- + $this->getDescriptionSection()
- + $this->getOptionsSection();
-
- Hooks::run( 'UploadFormInitDescriptor', [ &$descriptor ] );
- parent::__construct( $descriptor, $context, 'upload' );
-
- # Add a link to edit MediaWiki:Licenses
- if ( $this->getUser()->isAllowed( 'editinterface' ) ) {
- $this->getOutput()->addModuleStyles( 'mediawiki.special.upload.styles' );
- $licensesLink = $linkRenderer->makeKnownLink(
- $this->msg( 'licenses' )->inContentLanguage()->getTitle(),
- $this->msg( 'licenses-edit' )->text(),
- [],
- [ 'action' => 'edit' ]
- );
- $editLicenses = '<p class="mw-upload-editlicenses">' . $licensesLink . '</p>';
- $this->addFooterText( $editLicenses, 'description' );
- }
-
- # Set some form properties
- $this->setSubmitText( $this->msg( 'uploadbtn' )->text() );
- $this->setSubmitName( 'wpUpload' );
- # Used message keys: 'accesskey-upload', 'tooltip-upload'
- $this->setSubmitTooltip( 'upload' );
- $this->setId( 'mw-upload-form' );
-
- # Build a list of IDs for javascript insertion
- $this->mSourceIds = [];
- foreach ( $sourceDescriptor as $field ) {
- if ( !empty( $field['id'] ) ) {
- $this->mSourceIds[] = $field['id'];
- }
- }
- }
-
- /**
- * Get the descriptor of the fieldset that contains the file source
- * selection. The section is 'source'
- *
- * @return array Descriptor array
- */
- protected function getSourceSection() {
- if ( $this->mSessionKey ) {
- return [
- 'SessionKey' => [
- 'type' => 'hidden',
- 'default' => $this->mSessionKey,
- ],
- 'SourceType' => [
- 'type' => 'hidden',
- 'default' => 'Stash',
- ],
- ];
- }
-
- $canUploadByUrl = UploadFromUrl::isEnabled()
- && ( UploadFromUrl::isAllowed( $this->getUser() ) === true )
- && $this->getConfig()->get( 'CopyUploadsFromSpecialUpload' );
- $radio = $canUploadByUrl;
- $selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
-
- $descriptor = [];
- if ( $this->mTextTop ) {
- $descriptor['UploadFormTextTop'] = [
- 'type' => 'info',
- 'section' => 'source',
- 'default' => $this->mTextTop,
- 'raw' => true,
- ];
- }
-
- $this->mMaxUploadSize['file'] = min(
- UploadBase::getMaxUploadSize( 'file' ),
- UploadBase::getMaxPhpUploadSize()
- );
-
- $help = $this->msg( 'upload-maxfilesize',
- $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['file'] )
- )->parse();
-
- // If the user can also upload by URL, there are 2 different file size limits.
- // This extra message helps stress which limit corresponds to what.
- if ( $canUploadByUrl ) {
- $help .= $this->msg( 'word-separator' )->escaped();
- $help .= $this->msg( 'upload_source_file' )->parse();
- }
-
- $descriptor['UploadFile'] = [
- 'class' => 'UploadSourceField',
- 'section' => 'source',
- 'type' => 'file',
- 'id' => 'wpUploadFile',
- 'radio-id' => 'wpSourceTypeFile',
- 'label-message' => 'sourcefilename',
- 'upload-type' => 'File',
- 'radio' => &$radio,
- 'help' => $help,
- 'checked' => $selectedSourceType == 'file',
- ];
-
- if ( $canUploadByUrl ) {
- $this->mMaxUploadSize['url'] = UploadBase::getMaxUploadSize( 'url' );
- $descriptor['UploadFileURL'] = [
- 'class' => 'UploadSourceField',
- 'section' => 'source',
- 'id' => 'wpUploadFileURL',
- 'radio-id' => 'wpSourceTypeurl',
- 'label-message' => 'sourceurl',
- 'upload-type' => 'url',
- 'radio' => &$radio,
- 'help' => $this->msg( 'upload-maxfilesize',
- $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['url'] )
- )->parse() .
- $this->msg( 'word-separator' )->escaped() .
- $this->msg( 'upload_source_url' )->parse(),
- 'checked' => $selectedSourceType == 'url',
- ];
- }
- Hooks::run( 'UploadFormSourceDescriptors', [ &$descriptor, &$radio, $selectedSourceType ] );
-
- $descriptor['Extensions'] = [
- 'type' => 'info',
- 'section' => 'source',
- 'default' => $this->getExtensionsMessage(),
- 'raw' => true,
- ];
-
- return $descriptor;
- }
-
- /**
- * Get the messages indicating which extensions are preferred and prohibitted.
- *
- * @return string HTML string containing the message
- */
- protected function getExtensionsMessage() {
- # Print a list of allowed file extensions, if so configured. We ignore
- # MIME type here, it's incomprehensible to most people and too long.
- $config = $this->getConfig();
-
- if ( $config->get( 'CheckFileExtensions' ) ) {
- $fileExtensions = array_unique( $config->get( 'FileExtensions' ) );
- if ( $config->get( 'StrictFileExtensions' ) ) {
- # Everything not permitted is banned
- $extensionsList =
- '<div id="mw-upload-permitted">' .
- $this->msg( 'upload-permitted' )
- ->params( $this->getLanguage()->commaList( $fileExtensions ) )
- ->numParams( count( $fileExtensions ) )
- ->parseAsBlock() .
- "</div>\n";
- } else {
- # We have to list both preferred and prohibited
- $fileBlacklist = array_unique( $config->get( 'FileBlacklist' ) );
- $extensionsList =
- '<div id="mw-upload-preferred">' .
- $this->msg( 'upload-preferred' )
- ->params( $this->getLanguage()->commaList( $fileExtensions ) )
- ->numParams( count( $fileExtensions ) )
- ->parseAsBlock() .
- "</div>\n" .
- '<div id="mw-upload-prohibited">' .
- $this->msg( 'upload-prohibited' )
- ->params( $this->getLanguage()->commaList( $fileBlacklist ) )
- ->numParams( count( $fileBlacklist ) )
- ->parseAsBlock() .
- "</div>\n";
- }
- } else {
- # Everything is permitted.
- $extensionsList = '';
- }
-
- return $extensionsList;
- }
-
- /**
- * Get the descriptor of the fieldset that contains the file description
- * input. The section is 'description'
- *
- * @return array Descriptor array
- */
- protected function getDescriptionSection() {
- $config = $this->getConfig();
- if ( $this->mSessionKey ) {
- $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash( $this->getUser() );
- try {
- $file = $stash->getFile( $this->mSessionKey );
- } catch ( Exception $e ) {
- $file = null;
- }
- if ( $file ) {
- global $wgContLang;
-
- $mto = $file->transform( [ 'width' => 120 ] );
- if ( $mto ) {
- $this->addHeaderText(
- '<div class="thumb t' . $wgContLang->alignEnd() . '">' .
- Html::element( 'img', [
- 'src' => $mto->getUrl(),
- 'class' => 'thumbimage',
- ] ) . '</div>', 'description' );
- }
- }
- }
-
- $descriptor = [
- 'DestFile' => [
- 'type' => 'text',
- 'section' => 'description',
- 'id' => 'wpDestFile',
- 'label-message' => 'destfilename',
- 'size' => 60,
- 'default' => $this->mDestFile,
- # @todo FIXME: Hack to work around poor handling of the 'default' option in HTMLForm
- 'nodata' => strval( $this->mDestFile ) !== '',
- ],
- 'UploadDescription' => [
- 'type' => 'textarea',
- 'section' => 'description',
- 'id' => 'wpUploadDescription',
- 'label-message' => $this->mForReUpload
- ? 'filereuploadsummary'
- : 'fileuploadsummary',
- 'default' => $this->mComment,
- 'cols' => 80,
- 'rows' => 8,
- ]
- ];
- if ( $this->mTextAfterSummary ) {
- $descriptor['UploadFormTextAfterSummary'] = [
- 'type' => 'info',
- 'section' => 'description',
- 'default' => $this->mTextAfterSummary,
- 'raw' => true,
- ];
- }
-
- $descriptor += [
- 'EditTools' => [
- 'type' => 'edittools',
- 'section' => 'description',
- 'message' => 'edittools-upload',
- ]
- ];
-
- if ( $this->mForReUpload ) {
- $descriptor['DestFile']['readonly'] = true;
- } else {
- $descriptor['License'] = [
- 'type' => 'select',
- 'class' => 'Licenses',
- 'section' => 'description',
- 'id' => 'wpLicense',
- 'label-message' => 'license',
- ];
- }
-
- if ( $config->get( 'UseCopyrightUpload' ) ) {
- $descriptor['UploadCopyStatus'] = [
- 'type' => 'text',
- 'section' => 'description',
- 'id' => 'wpUploadCopyStatus',
- 'label-message' => 'filestatus',
- ];
- $descriptor['UploadSource'] = [
- 'type' => 'text',
- 'section' => 'description',
- 'id' => 'wpUploadSource',
- 'label-message' => 'filesource',
- ];
- }
-
- return $descriptor;
- }
-
- /**
- * Get the descriptor of the fieldset that contains the upload options,
- * such as "watch this file". The section is 'options'
- *
- * @return array Descriptor array
- */
- protected function getOptionsSection() {
- $user = $this->getUser();
- if ( $user->isLoggedIn() ) {
- $descriptor = [
- 'Watchthis' => [
- 'type' => 'check',
- 'id' => 'wpWatchthis',
- 'label-message' => 'watchthisupload',
- 'section' => 'options',
- 'default' => $this->mWatch,
- ]
- ];
- }
- if ( !$this->mHideIgnoreWarning ) {
- $descriptor['IgnoreWarning'] = [
- 'type' => 'check',
- 'id' => 'wpIgnoreWarning',
- 'label-message' => 'ignorewarnings',
- 'section' => 'options',
- ];
- }
-
- $descriptor['DestFileWarningAck'] = [
- 'type' => 'hidden',
- 'id' => 'wpDestFileWarningAck',
- 'default' => $this->mDestWarningAck ? '1' : '',
- ];
-
- if ( $this->mForReUpload ) {
- $descriptor['ForReUpload'] = [
- 'type' => 'hidden',
- 'id' => 'wpForReUpload',
- 'default' => '1',
- ];
- }
-
- return $descriptor;
- }
-
- /**
- * Add the upload JS and show the form.
- */
- public function show() {
- $this->addUploadJS();
- parent::show();
- }
-
- /**
- * Add upload JS to the OutputPage
- */
- protected function addUploadJS() {
- $config = $this->getConfig();
-
- $useAjaxDestCheck = $config->get( 'UseAjax' ) && $config->get( 'AjaxUploadDestCheck' );
- $useAjaxLicensePreview = $config->get( 'UseAjax' ) &&
- $config->get( 'AjaxLicensePreview' ) && $config->get( 'EnableAPI' );
- $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize();
-
- $scriptVars = [
- 'wgAjaxUploadDestCheck' => $useAjaxDestCheck,
- 'wgAjaxLicensePreview' => $useAjaxLicensePreview,
- 'wgUploadAutoFill' => !$this->mForReUpload &&
- // If we received mDestFile from the request, don't autofill
- // the wpDestFile textbox
- $this->mDestFile === '',
- 'wgUploadSourceIds' => $this->mSourceIds,
- 'wgCheckFileExtensions' => $config->get( 'CheckFileExtensions' ),
- 'wgStrictFileExtensions' => $config->get( 'StrictFileExtensions' ),
- 'wgFileExtensions' => array_values( array_unique( $config->get( 'FileExtensions' ) ) ),
- 'wgCapitalizeUploads' => MWNamespace::isCapitalized( NS_FILE ),
- 'wgMaxUploadSize' => $this->mMaxUploadSize,
- 'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
- ];
-
- $out = $this->getOutput();
- $out->addJsConfigVars( $scriptVars );
-
- $out->addModules( [
- 'mediawiki.special.upload', // Extras for thumbnail and license preview.
- ] );
- }
-
- /**
- * Empty function; submission is handled elsewhere.
- *
- * @return bool False
- */
- function trySubmit() {
- return false;
- }
-}
-
-/**
- * A form field that contains a radio box in the label
- */
-class UploadSourceField extends HTMLTextField {
-
- /**
- * @param array $cellAttributes
- * @return string
- */
- function getLabelHtml( $cellAttributes = [] ) {
- $id = $this->mParams['id'];
- $label = Html::rawElement( 'label', [ 'for' => $id ], $this->mLabel );
-
- if ( !empty( $this->mParams['radio'] ) ) {
- if ( isset( $this->mParams['radio-id'] ) ) {
- $radioId = $this->mParams['radio-id'];
- } else {
- // Old way. For the benefit of extensions that do not define
- // the 'radio-id' key.
- $radioId = 'wpSourceType' . $this->mParams['upload-type'];
- }
-
- $attribs = [
- 'name' => 'wpSourceType',
- 'type' => 'radio',
- 'id' => $radioId,
- 'value' => $this->mParams['upload-type'],
- ];
-
- if ( !empty( $this->mParams['checked'] ) ) {
- $attribs['checked'] = 'checked';
- }
-
- $label .= Html::element( 'input', $attribs );
- }
-
- return Html::rawElement( 'td', [ 'class' => 'mw-label' ] + $cellAttributes, $label );
- }
-
- /**
- * @return int
- */
- function getSize() {
- return isset( $this->mParams['size'] )
- ? $this->mParams['size']
- : 60;
- }
-}
--- /dev/null
+<?php
+/**
+ * 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 EditWatchlistCheckboxSeriesField extends HTMLMultiSelectField {
+ /**
+ * HTMLMultiSelectField throws validation errors if we get input data
+ * that doesn't match the data set in the form setup. This causes
+ * problems if something gets removed from the watchlist while the
+ * form is open (T34126), but we know that invalid items will
+ * be harmless so we can override it here.
+ *
+ * @param string $value The value the field was submitted with
+ * @param array $alldata The data collected from the form
+ * @return bool|string Bool true on success, or String error to display.
+ */
+ function validate( $value, $alldata ) {
+ // Need to call into grandparent to be a good citizen. :)
+ return HTMLFormField::validate( $value, $alldata );
+ }
+}
--- /dev/null
+<?php
+/**
+ * License selector for use on Special:Upload.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * A License class for use on Special:Upload
+ */
+class Licenses extends HTMLFormField {
+ /** @var string */
+ protected $msg;
+
+ /** @var array */
+ protected $licenses = [];
+
+ /** @var string */
+ protected $html;
+ /**#@-*/
+
+ /**
+ * @param array $params
+ */
+ public function __construct( $params ) {
+ parent::__construct( $params );
+
+ $this->msg = empty( $params['licenses'] )
+ ? wfMessage( 'licenses' )->inContentLanguage()->plain()
+ : $params['licenses'];
+ $this->selected = null;
+
+ $this->makeLicenses();
+ }
+
+ /**
+ * @private
+ */
+ protected function makeLicenses() {
+ $levels = [];
+ $lines = explode( "\n", $this->msg );
+
+ foreach ( $lines as $line ) {
+ if ( strpos( $line, '*' ) !== 0 ) {
+ continue;
+ } else {
+ list( $level, $line ) = $this->trimStars( $line );
+
+ if ( strpos( $line, '|' ) !== false ) {
+ $obj = new License( $line );
+ $this->stackItem( $this->licenses, $levels, $obj );
+ } else {
+ if ( $level < count( $levels ) ) {
+ $levels = array_slice( $levels, 0, $level );
+ }
+ if ( $level == count( $levels ) ) {
+ $levels[$level - 1] = $line;
+ } elseif ( $level > count( $levels ) ) {
+ $levels[] = $line;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param string $str
+ * @return array
+ */
+ protected function trimStars( $str ) {
+ $numStars = strspn( $str, '*' );
+ return [ $numStars, ltrim( substr( $str, $numStars ), ' ' ) ];
+ }
+
+ /**
+ * @param array &$list
+ * @param array $path
+ * @param mixed $item
+ */
+ protected function stackItem( &$list, $path, $item ) {
+ $position =& $list;
+ if ( $path ) {
+ foreach ( $path as $key ) {
+ $position =& $position[$key];
+ }
+ }
+ $position[] = $item;
+ }
+
+ /**
+ * @param array $tagset
+ * @param int $depth
+ */
+ protected function makeHtml( $tagset, $depth = 0 ) {
+ foreach ( $tagset as $key => $val ) {
+ if ( is_array( $val ) ) {
+ $this->html .= $this->outputOption(
+ $key, '',
+ [
+ 'disabled' => 'disabled',
+ 'style' => 'color: GrayText', // for MSIE
+ ],
+ $depth
+ );
+ $this->makeHtml( $val, $depth + 1 );
+ } else {
+ $this->html .= $this->outputOption(
+ $val->text, $val->template,
+ [ 'title' => '{{' . $val->template . '}}' ],
+ $depth
+ );
+ }
+ }
+ }
+
+ /**
+ * @param string $message
+ * @param string $value
+ * @param null|array $attribs
+ * @param int $depth
+ * @return string
+ */
+ protected function outputOption( $message, $value, $attribs = null, $depth = 0 ) {
+ $msgObj = $this->msg( $message );
+ $text = $msgObj->exists() ? $msgObj->text() : $message;
+ $attribs['value'] = $value;
+ if ( $value === $this->selected ) {
+ $attribs['selected'] = 'selected';
+ }
+
+ $val = str_repeat( /*   */ "\xc2\xa0", $depth * 2 ) . $text;
+ return str_repeat( "\t", $depth ) . Xml::element( 'option', $attribs, $val ) . "\n";
+ }
+
+ /**#@-*/
+
+ /**
+ * Accessor for $this->licenses
+ *
+ * @return array
+ */
+ public function getLicenses() {
+ return $this->licenses;
+ }
+
+ /**
+ * Accessor for $this->html
+ *
+ * @param bool $value
+ *
+ * @return string
+ */
+ public function getInputHTML( $value ) {
+ $this->selected = $value;
+
+ $this->html = $this->outputOption( wfMessage( 'nolicense' )->text(), '',
+ (bool)$this->selected ? null : [ 'selected' => 'selected' ] );
+ $this->makeHtml( $this->getLicenses() );
+
+ $attribs = [
+ 'name' => $this->mName,
+ 'id' => $this->mID
+ ];
+ if ( !empty( $this->mParams['disabled'] ) ) {
+ $attibs['disabled'] = 'disabled';
+ }
+
+ return Html::rawElement( 'select', $attribs, $this->html );
+ }
+}
--- /dev/null
+<?php
+/**
+ * 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
+ */
+
+/**
+ * A form field that contains a radio box in the label
+ */
+class UploadSourceField extends HTMLTextField {
+
+ /**
+ * @param array $cellAttributes
+ * @return string
+ */
+ function getLabelHtml( $cellAttributes = [] ) {
+ $id = $this->mParams['id'];
+ $label = Html::rawElement( 'label', [ 'for' => $id ], $this->mLabel );
+
+ if ( !empty( $this->mParams['radio'] ) ) {
+ if ( isset( $this->mParams['radio-id'] ) ) {
+ $radioId = $this->mParams['radio-id'];
+ } else {
+ // Old way. For the benefit of extensions that do not define
+ // the 'radio-id' key.
+ $radioId = 'wpSourceType' . $this->mParams['upload-type'];
+ }
+
+ $attribs = [
+ 'name' => 'wpSourceType',
+ 'type' => 'radio',
+ 'id' => $radioId,
+ 'value' => $this->mParams['upload-type'],
+ ];
+
+ if ( !empty( $this->mParams['checked'] ) ) {
+ $attribs['checked'] = 'checked';
+ }
+
+ $label .= Html::element( 'input', $attribs );
+ }
+
+ return Html::rawElement( 'td', [ 'class' => 'mw-label' ] + $cellAttributes, $label );
+ }
+
+ /**
+ * @return int
+ */
+ function getSize() {
+ return isset( $this->mParams['size'] )
+ ? $this->mParams['size']
+ : 60;
+ }
+}
--- /dev/null
+<?php
+/**
+ * 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
+ */
+
+/**
+ * Extend HTMLForm purely so we can have a more sane way of getting the section headers
+ */
+class EditWatchlistNormalHTMLForm extends HTMLForm {
+ public function getLegend( $namespace ) {
+ $namespace = substr( $namespace, 2 );
+
+ return $namespace == NS_MAIN
+ ? $this->msg( 'blanknamespace' )->escaped()
+ : htmlspecialchars( $this->getContext()->getLanguage()->getFormattedNsText( $namespace ) );
+ }
+
+ public function getBody() {
+ return $this->displaySection( $this->mFieldTree, '', 'editwatchlist-' );
+ }
+}
--- /dev/null
+<?php
+/**
+ * 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
+ */
+
+use MediaWiki\MediaWikiServices;
+
+/**
+ * Form to edit user preferences.
+ */
+class PreferencesForm extends HTMLForm {
+ // Override default value from HTMLForm
+ protected $mSubSectionBeforeFields = false;
+
+ private $modifiedUser;
+
+ /**
+ * @param User $user
+ */
+ public function setModifiedUser( $user ) {
+ $this->modifiedUser = $user;
+ }
+
+ /**
+ * @return User
+ */
+ public function getModifiedUser() {
+ if ( $this->modifiedUser === null ) {
+ return $this->getUser();
+ } else {
+ return $this->modifiedUser;
+ }
+ }
+
+ /**
+ * Get extra parameters for the query string when redirecting after
+ * successful save.
+ *
+ * @return array
+ */
+ public function getExtraSuccessRedirectParameters() {
+ return [];
+ }
+
+ /**
+ * @param string $html
+ * @return string
+ */
+ function wrapForm( $html ) {
+ $html = Xml::tags( 'div', [ 'id' => 'preferences' ], $html );
+
+ return parent::wrapForm( $html );
+ }
+
+ /**
+ * @return string
+ */
+ function getButtons() {
+ $attrs = [ 'id' => 'mw-prefs-restoreprefs' ];
+
+ if ( !$this->getModifiedUser()->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) {
+ return '';
+ }
+
+ $html = parent::getButtons();
+
+ if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) {
+ $t = $this->getTitle()->getSubpage( 'reset' );
+
+ $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+ $html .= "\n" . $linkRenderer->makeLink( $t, $this->msg( 'restoreprefs' )->text(),
+ Html::buttonAttributes( $attrs, [ 'mw-ui-quiet' ] ) );
+
+ $html = Xml::tags( 'div', [ 'class' => 'mw-prefs-buttons' ], $html );
+ }
+
+ return $html;
+ }
+
+ /**
+ * Separate multi-option preferences into multiple preferences, since we
+ * have to store them separately
+ * @param array $data
+ * @return array
+ */
+ function filterDataForSubmit( $data ) {
+ foreach ( $this->mFlatFields as $fieldname => $field ) {
+ if ( $field instanceof HTMLNestedFilterable ) {
+ $info = $field->mParams;
+ $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $fieldname;
+ foreach ( $field->filterDataForSubmit( $data[$fieldname] ) as $key => $value ) {
+ $data["$prefix$key"] = $value;
+ }
+ unset( $data[$fieldname] );
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Get the whole body of the form.
+ * @return string
+ */
+ function getBody() {
+ return $this->displaySection( $this->mFieldTree, '', 'mw-prefsection-' );
+ }
+
+ /**
+ * Get the "<legend>" for a given section key. Normally this is the
+ * prefs-$key message but we'll allow extensions to override it.
+ * @param string $key
+ * @return string
+ */
+ function getLegend( $key ) {
+ $legend = parent::getLegend( $key );
+ Hooks::run( 'PreferencesGetLegend', [ $this, $key, &$legend ] );
+ return $legend;
+ }
+
+ /**
+ * Get the keys of each top level preference section.
+ * @return array of section keys
+ */
+ function getPreferenceSections() {
+ return array_keys( array_filter( $this->mFieldTree, 'is_array' ) );
+ }
+}
--- /dev/null
+<?php
+/**
+ * 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
+ */
+
+use MediaWiki\Linker\LinkRenderer;
+use MediaWiki\MediaWikiServices;
+
+/**
+ * Sub class of HTMLForm that provides the form section of SpecialUpload
+ */
+class UploadForm extends HTMLForm {
+ protected $mWatch;
+ protected $mForReUpload;
+ protected $mSessionKey;
+ protected $mHideIgnoreWarning;
+ protected $mDestWarningAck;
+ protected $mDestFile;
+
+ protected $mComment;
+ protected $mTextTop;
+ protected $mTextAfterSummary;
+
+ protected $mSourceIds;
+
+ protected $mMaxFileSize = [];
+
+ protected $mMaxUploadSize = [];
+
+ public function __construct( array $options = [], IContextSource $context = null,
+ LinkRenderer $linkRenderer = null
+ ) {
+ if ( $context instanceof IContextSource ) {
+ $this->setContext( $context );
+ }
+
+ if ( !$linkRenderer ) {
+ $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+ }
+
+ $this->mWatch = !empty( $options['watch'] );
+ $this->mForReUpload = !empty( $options['forreupload'] );
+ $this->mSessionKey = isset( $options['sessionkey'] ) ? $options['sessionkey'] : '';
+ $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
+ $this->mDestWarningAck = !empty( $options['destwarningack'] );
+ $this->mDestFile = isset( $options['destfile'] ) ? $options['destfile'] : '';
+
+ $this->mComment = isset( $options['description'] ) ?
+ $options['description'] : '';
+
+ $this->mTextTop = isset( $options['texttop'] )
+ ? $options['texttop'] : '';
+
+ $this->mTextAfterSummary = isset( $options['textaftersummary'] )
+ ? $options['textaftersummary'] : '';
+
+ $sourceDescriptor = $this->getSourceSection();
+ $descriptor = $sourceDescriptor
+ + $this->getDescriptionSection()
+ + $this->getOptionsSection();
+
+ Hooks::run( 'UploadFormInitDescriptor', [ &$descriptor ] );
+ parent::__construct( $descriptor, $context, 'upload' );
+
+ # Add a link to edit MediaWiki:Licenses
+ if ( $this->getUser()->isAllowed( 'editinterface' ) ) {
+ $this->getOutput()->addModuleStyles( 'mediawiki.special.upload.styles' );
+ $licensesLink = $linkRenderer->makeKnownLink(
+ $this->msg( 'licenses' )->inContentLanguage()->getTitle(),
+ $this->msg( 'licenses-edit' )->text(),
+ [],
+ [ 'action' => 'edit' ]
+ );
+ $editLicenses = '<p class="mw-upload-editlicenses">' . $licensesLink . '</p>';
+ $this->addFooterText( $editLicenses, 'description' );
+ }
+
+ # Set some form properties
+ $this->setSubmitText( $this->msg( 'uploadbtn' )->text() );
+ $this->setSubmitName( 'wpUpload' );
+ # Used message keys: 'accesskey-upload', 'tooltip-upload'
+ $this->setSubmitTooltip( 'upload' );
+ $this->setId( 'mw-upload-form' );
+
+ # Build a list of IDs for javascript insertion
+ $this->mSourceIds = [];
+ foreach ( $sourceDescriptor as $field ) {
+ if ( !empty( $field['id'] ) ) {
+ $this->mSourceIds[] = $field['id'];
+ }
+ }
+ }
+
+ /**
+ * Get the descriptor of the fieldset that contains the file source
+ * selection. The section is 'source'
+ *
+ * @return array Descriptor array
+ */
+ protected function getSourceSection() {
+ if ( $this->mSessionKey ) {
+ return [
+ 'SessionKey' => [
+ 'type' => 'hidden',
+ 'default' => $this->mSessionKey,
+ ],
+ 'SourceType' => [
+ 'type' => 'hidden',
+ 'default' => 'Stash',
+ ],
+ ];
+ }
+
+ $canUploadByUrl = UploadFromUrl::isEnabled()
+ && ( UploadFromUrl::isAllowed( $this->getUser() ) === true )
+ && $this->getConfig()->get( 'CopyUploadsFromSpecialUpload' );
+ $radio = $canUploadByUrl;
+ $selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
+
+ $descriptor = [];
+ if ( $this->mTextTop ) {
+ $descriptor['UploadFormTextTop'] = [
+ 'type' => 'info',
+ 'section' => 'source',
+ 'default' => $this->mTextTop,
+ 'raw' => true,
+ ];
+ }
+
+ $this->mMaxUploadSize['file'] = min(
+ UploadBase::getMaxUploadSize( 'file' ),
+ UploadBase::getMaxPhpUploadSize()
+ );
+
+ $help = $this->msg( 'upload-maxfilesize',
+ $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['file'] )
+ )->parse();
+
+ // If the user can also upload by URL, there are 2 different file size limits.
+ // This extra message helps stress which limit corresponds to what.
+ if ( $canUploadByUrl ) {
+ $help .= $this->msg( 'word-separator' )->escaped();
+ $help .= $this->msg( 'upload_source_file' )->parse();
+ }
+
+ $descriptor['UploadFile'] = [
+ 'class' => 'UploadSourceField',
+ 'section' => 'source',
+ 'type' => 'file',
+ 'id' => 'wpUploadFile',
+ 'radio-id' => 'wpSourceTypeFile',
+ 'label-message' => 'sourcefilename',
+ 'upload-type' => 'File',
+ 'radio' => &$radio,
+ 'help' => $help,
+ 'checked' => $selectedSourceType == 'file',
+ ];
+
+ if ( $canUploadByUrl ) {
+ $this->mMaxUploadSize['url'] = UploadBase::getMaxUploadSize( 'url' );
+ $descriptor['UploadFileURL'] = [
+ 'class' => 'UploadSourceField',
+ 'section' => 'source',
+ 'id' => 'wpUploadFileURL',
+ 'radio-id' => 'wpSourceTypeurl',
+ 'label-message' => 'sourceurl',
+ 'upload-type' => 'url',
+ 'radio' => &$radio,
+ 'help' => $this->msg( 'upload-maxfilesize',
+ $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['url'] )
+ )->parse() .
+ $this->msg( 'word-separator' )->escaped() .
+ $this->msg( 'upload_source_url' )->parse(),
+ 'checked' => $selectedSourceType == 'url',
+ ];
+ }
+ Hooks::run( 'UploadFormSourceDescriptors', [ &$descriptor, &$radio, $selectedSourceType ] );
+
+ $descriptor['Extensions'] = [
+ 'type' => 'info',
+ 'section' => 'source',
+ 'default' => $this->getExtensionsMessage(),
+ 'raw' => true,
+ ];
+
+ return $descriptor;
+ }
+
+ /**
+ * Get the messages indicating which extensions are preferred and prohibitted.
+ *
+ * @return string HTML string containing the message
+ */
+ protected function getExtensionsMessage() {
+ # Print a list of allowed file extensions, if so configured. We ignore
+ # MIME type here, it's incomprehensible to most people and too long.
+ $config = $this->getConfig();
+
+ if ( $config->get( 'CheckFileExtensions' ) ) {
+ $fileExtensions = array_unique( $config->get( 'FileExtensions' ) );
+ if ( $config->get( 'StrictFileExtensions' ) ) {
+ # Everything not permitted is banned
+ $extensionsList =
+ '<div id="mw-upload-permitted">' .
+ $this->msg( 'upload-permitted' )
+ ->params( $this->getLanguage()->commaList( $fileExtensions ) )
+ ->numParams( count( $fileExtensions ) )
+ ->parseAsBlock() .
+ "</div>\n";
+ } else {
+ # We have to list both preferred and prohibited
+ $fileBlacklist = array_unique( $config->get( 'FileBlacklist' ) );
+ $extensionsList =
+ '<div id="mw-upload-preferred">' .
+ $this->msg( 'upload-preferred' )
+ ->params( $this->getLanguage()->commaList( $fileExtensions ) )
+ ->numParams( count( $fileExtensions ) )
+ ->parseAsBlock() .
+ "</div>\n" .
+ '<div id="mw-upload-prohibited">' .
+ $this->msg( 'upload-prohibited' )
+ ->params( $this->getLanguage()->commaList( $fileBlacklist ) )
+ ->numParams( count( $fileBlacklist ) )
+ ->parseAsBlock() .
+ "</div>\n";
+ }
+ } else {
+ # Everything is permitted.
+ $extensionsList = '';
+ }
+
+ return $extensionsList;
+ }
+
+ /**
+ * Get the descriptor of the fieldset that contains the file description
+ * input. The section is 'description'
+ *
+ * @return array Descriptor array
+ */
+ protected function getDescriptionSection() {
+ $config = $this->getConfig();
+ if ( $this->mSessionKey ) {
+ $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash( $this->getUser() );
+ try {
+ $file = $stash->getFile( $this->mSessionKey );
+ } catch ( Exception $e ) {
+ $file = null;
+ }
+ if ( $file ) {
+ global $wgContLang;
+
+ $mto = $file->transform( [ 'width' => 120 ] );
+ if ( $mto ) {
+ $this->addHeaderText(
+ '<div class="thumb t' . $wgContLang->alignEnd() . '">' .
+ Html::element( 'img', [
+ 'src' => $mto->getUrl(),
+ 'class' => 'thumbimage',
+ ] ) . '</div>', 'description' );
+ }
+ }
+ }
+
+ $descriptor = [
+ 'DestFile' => [
+ 'type' => 'text',
+ 'section' => 'description',
+ 'id' => 'wpDestFile',
+ 'label-message' => 'destfilename',
+ 'size' => 60,
+ 'default' => $this->mDestFile,
+ # @todo FIXME: Hack to work around poor handling of the 'default' option in HTMLForm
+ 'nodata' => strval( $this->mDestFile ) !== '',
+ ],
+ 'UploadDescription' => [
+ 'type' => 'textarea',
+ 'section' => 'description',
+ 'id' => 'wpUploadDescription',
+ 'label-message' => $this->mForReUpload
+ ? 'filereuploadsummary'
+ : 'fileuploadsummary',
+ 'default' => $this->mComment,
+ 'cols' => 80,
+ 'rows' => 8,
+ ]
+ ];
+ if ( $this->mTextAfterSummary ) {
+ $descriptor['UploadFormTextAfterSummary'] = [
+ 'type' => 'info',
+ 'section' => 'description',
+ 'default' => $this->mTextAfterSummary,
+ 'raw' => true,
+ ];
+ }
+
+ $descriptor += [
+ 'EditTools' => [
+ 'type' => 'edittools',
+ 'section' => 'description',
+ 'message' => 'edittools-upload',
+ ]
+ ];
+
+ if ( $this->mForReUpload ) {
+ $descriptor['DestFile']['readonly'] = true;
+ } else {
+ $descriptor['License'] = [
+ 'type' => 'select',
+ 'class' => 'Licenses',
+ 'section' => 'description',
+ 'id' => 'wpLicense',
+ 'label-message' => 'license',
+ ];
+ }
+
+ if ( $config->get( 'UseCopyrightUpload' ) ) {
+ $descriptor['UploadCopyStatus'] = [
+ 'type' => 'text',
+ 'section' => 'description',
+ 'id' => 'wpUploadCopyStatus',
+ 'label-message' => 'filestatus',
+ ];
+ $descriptor['UploadSource'] = [
+ 'type' => 'text',
+ 'section' => 'description',
+ 'id' => 'wpUploadSource',
+ 'label-message' => 'filesource',
+ ];
+ }
+
+ return $descriptor;
+ }
+
+ /**
+ * Get the descriptor of the fieldset that contains the upload options,
+ * such as "watch this file". The section is 'options'
+ *
+ * @return array Descriptor array
+ */
+ protected function getOptionsSection() {
+ $user = $this->getUser();
+ if ( $user->isLoggedIn() ) {
+ $descriptor = [
+ 'Watchthis' => [
+ 'type' => 'check',
+ 'id' => 'wpWatchthis',
+ 'label-message' => 'watchthisupload',
+ 'section' => 'options',
+ 'default' => $this->mWatch,
+ ]
+ ];
+ }
+ if ( !$this->mHideIgnoreWarning ) {
+ $descriptor['IgnoreWarning'] = [
+ 'type' => 'check',
+ 'id' => 'wpIgnoreWarning',
+ 'label-message' => 'ignorewarnings',
+ 'section' => 'options',
+ ];
+ }
+
+ $descriptor['DestFileWarningAck'] = [
+ 'type' => 'hidden',
+ 'id' => 'wpDestFileWarningAck',
+ 'default' => $this->mDestWarningAck ? '1' : '',
+ ];
+
+ if ( $this->mForReUpload ) {
+ $descriptor['ForReUpload'] = [
+ 'type' => 'hidden',
+ 'id' => 'wpForReUpload',
+ 'default' => '1',
+ ];
+ }
+
+ return $descriptor;
+ }
+
+ /**
+ * Add the upload JS and show the form.
+ */
+ public function show() {
+ $this->addUploadJS();
+ parent::show();
+ }
+
+ /**
+ * Add upload JS to the OutputPage
+ */
+ protected function addUploadJS() {
+ $config = $this->getConfig();
+
+ $useAjaxDestCheck = $config->get( 'UseAjax' ) && $config->get( 'AjaxUploadDestCheck' );
+ $useAjaxLicensePreview = $config->get( 'UseAjax' ) &&
+ $config->get( 'AjaxLicensePreview' ) && $config->get( 'EnableAPI' );
+ $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize();
+
+ $scriptVars = [
+ 'wgAjaxUploadDestCheck' => $useAjaxDestCheck,
+ 'wgAjaxLicensePreview' => $useAjaxLicensePreview,
+ 'wgUploadAutoFill' => !$this->mForReUpload &&
+ // If we received mDestFile from the request, don't autofill
+ // the wpDestFile textbox
+ $this->mDestFile === '',
+ 'wgUploadSourceIds' => $this->mSourceIds,
+ 'wgCheckFileExtensions' => $config->get( 'CheckFileExtensions' ),
+ 'wgStrictFileExtensions' => $config->get( 'StrictFileExtensions' ),
+ 'wgFileExtensions' => array_values( array_unique( $config->get( 'FileExtensions' ) ) ),
+ 'wgCapitalizeUploads' => MWNamespace::isCapitalized( NS_FILE ),
+ 'wgMaxUploadSize' => $this->mMaxUploadSize,
+ 'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
+ ];
+
+ $out = $this->getOutput();
+ $out->addJsConfigVars( $scriptVars );
+
+ $out->addModules( [
+ 'mediawiki.special.upload', // Extras for thumbnail and license preview.
+ ] );
+ }
+
+ /**
+ * Empty function; submission is handled elsewhere.
+ *
+ * @return bool False
+ */
+ function trySubmit() {
+ return false;
+ }
+}
--- /dev/null
+<?php
+/**
+ * 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
+ */
+
+use MediaWiki\MediaWikiServices;
+
+/**
+ * Reporting callback
+ * @ingroup SpecialPage
+ */
+class ImportReporter extends ContextSource {
+ private $reason = false;
+ private $logTags = [];
+ private $mOriginalLogCallback = null;
+ private $mOriginalPageOutCallback = null;
+ private $mLogItemCount = 0;
+
+ /**
+ * @param WikiImporter $importer
+ * @param bool $upload
+ * @param string $interwiki
+ * @param string|bool $reason
+ */
+ function __construct( $importer, $upload, $interwiki, $reason = false ) {
+ $this->mOriginalPageOutCallback =
+ $importer->setPageOutCallback( [ $this, 'reportPage' ] );
+ $this->mOriginalLogCallback =
+ $importer->setLogItemCallback( [ $this, 'reportLogItem' ] );
+ $importer->setNoticeCallback( [ $this, 'reportNotice' ] );
+ $this->mPageCount = 0;
+ $this->mIsUpload = $upload;
+ $this->mInterwiki = $interwiki;
+ $this->reason = $reason;
+ }
+
+ /**
+ * Sets change tags to apply to the import log entry and null revision.
+ *
+ * @param array $tags
+ * @since 1.29
+ */
+ public function setChangeTags( array $tags ) {
+ $this->logTags = $tags;
+ }
+
+ function open() {
+ $this->getOutput()->addHTML( "<ul>\n" );
+ }
+
+ function reportNotice( $msg, array $params ) {
+ $this->getOutput()->addHTML(
+ Html::element( 'li', [], $this->msg( $msg, $params )->text() )
+ );
+ }
+
+ function reportLogItem( /* ... */ ) {
+ $this->mLogItemCount++;
+ if ( is_callable( $this->mOriginalLogCallback ) ) {
+ call_user_func_array( $this->mOriginalLogCallback, func_get_args() );
+ }
+ }
+
+ /**
+ * @param Title $title
+ * @param ForeignTitle $foreignTitle
+ * @param int $revisionCount
+ * @param int $successCount
+ * @param array $pageInfo
+ * @return void
+ */
+ public function reportPage( $title, $foreignTitle, $revisionCount,
+ $successCount, $pageInfo ) {
+ $args = func_get_args();
+ call_user_func_array( $this->mOriginalPageOutCallback, $args );
+
+ if ( $title === null ) {
+ # Invalid or non-importable title; a notice is already displayed
+ return;
+ }
+
+ $this->mPageCount++;
+ $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+ if ( $successCount > 0 ) {
+ // <bdi> prevents jumbling of the versions count
+ // in RTL wikis in case the page title is LTR
+ $this->getOutput()->addHTML(
+ "<li>" . $linkRenderer->makeLink( $title ) . " " .
+ "<bdi>" .
+ $this->msg( 'import-revision-count' )->numParams( $successCount )->escaped() .
+ "</bdi>" .
+ "</li>\n"
+ );
+
+ $logParams = [ '4:number:count' => $successCount ];
+ if ( $this->mIsUpload ) {
+ $detail = $this->msg( 'import-logentry-upload-detail' )->numParams(
+ $successCount )->inContentLanguage()->text();
+ $action = 'upload';
+ } else {
+ $pageTitle = $foreignTitle->getFullText();
+ $fullInterwikiPrefix = $this->mInterwiki;
+ Hooks::run( 'ImportLogInterwikiLink', [ &$fullInterwikiPrefix, &$pageTitle ] );
+
+ $interwikiTitleStr = $fullInterwikiPrefix . ':' . $pageTitle;
+ $interwiki = '[[:' . $interwikiTitleStr . ']]';
+ $detail = $this->msg( 'import-logentry-interwiki-detail' )->numParams(
+ $successCount )->params( $interwiki )->inContentLanguage()->text();
+ $action = 'interwiki';
+ $logParams['5:title-link:interwiki'] = $interwikiTitleStr;
+ }
+ if ( $this->reason ) {
+ $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text()
+ . $this->reason;
+ }
+
+ $comment = $detail; // quick
+ $dbw = wfGetDB( DB_MASTER );
+ $latest = $title->getLatestRevID();
+ $nullRevision = Revision::newNullRevision(
+ $dbw,
+ $title->getArticleID(),
+ $comment,
+ true,
+ $this->getUser()
+ );
+
+ $nullRevId = null;
+ if ( !is_null( $nullRevision ) ) {
+ $nullRevId = $nullRevision->insertOn( $dbw );
+ $page = WikiPage::factory( $title );
+ # Update page record
+ $page->updateRevisionOn( $dbw, $nullRevision );
+ Hooks::run(
+ 'NewRevisionFromEditComplete',
+ [ $page, $nullRevision, $latest, $this->getUser() ]
+ );
+ }
+
+ // Create the import log entry
+ $logEntry = new ManualLogEntry( 'import', $action );
+ $logEntry->setTarget( $title );
+ $logEntry->setComment( $this->reason );
+ $logEntry->setPerformer( $this->getUser() );
+ $logEntry->setParameters( $logParams );
+ $logid = $logEntry->insert();
+ if ( count( $this->logTags ) ) {
+ $logEntry->setTags( $this->logTags );
+ }
+ // Make sure the null revision will be tagged as well
+ $logEntry->setAssociatedRevId( $nullRevId );
+
+ $logEntry->publish( $logid );
+
+ } else {
+ $this->getOutput()->addHTML( "<li>" . $linkRenderer->makeKnownLink( $title ) . " " .
+ $this->msg( 'import-nonewrevisions' )->escaped() . "</li>\n" );
+ }
+ }
+
+ function close() {
+ $out = $this->getOutput();
+ if ( $this->mLogItemCount > 0 ) {
+ $msg = $this->msg( 'imported-log-entries' )->numParams( $this->mLogItemCount )->parse();
+ $out->addHTML( Xml::tags( 'li', null, $msg ) );
+ } elseif ( $this->mPageCount == 0 && $this->mLogItemCount == 0 ) {
+ $out->addHTML( "</ul>\n" );
+
+ return Status::newFatal( 'importnopages' );
+ }
+ $out->addHTML( "</ul>\n" );
+
+ return Status::newGood( $this->mPageCount );
+ }
+}
--- /dev/null
+<?php
+/**
+ * License selector for use on Special:Upload.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+
+/**
+ * A License class for use on Special:Upload (represents a single type of license).
+ */
+class License {
+ /** @var string */
+ public $template;
+
+ /** @var string */
+ public $text;
+
+ /**
+ * @param string $str License name??
+ */
+ function __construct( $str ) {
+ list( $text, $template ) = explode( '|', strrev( $str ), 2 );
+
+ $this->template = strrev( $template );
+ $this->text = strrev( $text );
+ }
+}