summaryrefslogtreecommitdiff
path: root/www/wiki/includes/specials/forms/UploadForm.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/includes/specials/forms/UploadForm.php')
-rw-r--r--www/wiki/includes/specials/forms/UploadForm.php446
1 files changed, 446 insertions, 0 deletions
diff --git a/www/wiki/includes/specials/forms/UploadForm.php b/www/wiki/includes/specials/forms/UploadForm.php
new file mode 100644
index 00000000..eacdace1
--- /dev/null
+++ b/www/wiki/includes/specials/forms/UploadForm.php
@@ -0,0 +1,446 @@
+<?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::class,
+ '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::class,
+ '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::class,
+ '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;
+ }
+}