<?php
/**
+ * Implements 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
* @ingroup Upload
- *
- * Form for handling uploads and special page.
*/
+/**
+ * Form for handling uploads and special page.
+ *
+ * @ingroup SpecialPage
+ * @ingroup Upload
+ */
class SpecialUpload extends SpecialPage {
/**
* Constructor : initialise object
}
/** Misc variables **/
- protected $mRequest; // The WebRequest or FauxRequest this form is supposed to handle
- protected $mSourceType;
- protected $mUpload;
- protected $mLocalFile;
- protected $mUploadClicked;
+ public $mRequest; // The WebRequest or FauxRequest this form is supposed to handle
+ public $mSourceType;
+ public $mUpload;
+ public $mLocalFile;
+ public $mUploadClicked;
/** User input variables from the "description" section **/
- public $mDesiredDestName; // The requested target file name
- protected $mComment;
- protected $mLicense;
+ public $mDesiredDestName; // The requested target file name
+ public $mComment;
+ public $mLicense;
/** User input variables from the root section **/
- protected $mIgnoreWarning;
- protected $mWatchThis;
- protected $mCopyrightStatus;
- protected $mCopyrightSource;
+ public $mIgnoreWarning;
+ public $mWatchThis;
+ public $mCopyrightStatus;
+ public $mCopyrightSource;
/** Hidden variables **/
- protected $mDestWarningAck;
- protected $mForReUpload; // The user followed an "overwrite this file" link
- protected $mCancelUpload; // The user clicked "Cancel and return to upload form" button
- protected $mTokenOk;
- protected $mUploadSuccessful = false; // Subclasses can use this to determine whether a file was uploaded
+ public $mDestWarningAck;
+ public $mForReUpload; // The user followed an "overwrite this file" link
+ public $mCancelUpload; // The user clicked "Cancel and return to upload form" button
+ public $mTokenOk;
+ public $mUploadSuccessful = false; // Subclasses can use this to determine whether a file was uploaded
/** Text injection points for hooks not using HTMLForm **/
public $uploadFormTextTop;
// Guess the desired name from the filename if not provided
$this->mDesiredDestName = $request->getText( 'wpDestFile' );
- if( !$this->mDesiredDestName ) {
- $this->mDesiredDestName = $request->getText( 'wpUploadFile' );
+ if( !$this->mDesiredDestName && $request->getFileName( 'wpUploadFile' ) !== null ) {
+ $this->mDesiredDestName = $request->getFileName( 'wpUploadFile' );
}
$this->mComment = $request->getText( 'wpUploadDescription' );
$this->mLicense = $request->getText( 'wpLicense' );
* Special page entry point
*/
public function execute( $par ) {
- global $wgUser, $wgOut, $wgRequest;
+ global $wgUser, $wgOut;
$this->setHeaders();
$this->outputHeader();
# Check permissions
global $wgGroupPermissions;
- if( !$wgUser->isAllowed( 'upload' ) ) {
+ $permissionRequired = UploadBase::isAllowed( $wgUser );
+ if( $permissionRequired !== true ) {
if( !$wgUser->isLoggedIn() && ( $wgGroupPermissions['user']['upload']
|| $wgGroupPermissions['autoconfirmed']['upload'] ) ) {
// Custom message if logged-in users without any special rights can upload
$wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
} else {
- $wgOut->permissionRequired( 'upload' );
+ $wgOut->permissionRequired( $permissionRequired );
}
return;
}
wfDebug( "Hook 'UploadForm:initial' broke output of the upload form" );
return;
}
+
$this->showUploadForm( $this->getUploadForm() );
}
'texttop' => $this->uploadFormTextTop,
'textaftersummary' => $this->uploadFormTextAfterSummary,
+ 'destfile' => $this->mDesiredDestName,
) );
$form->setTitle( $this->getTitle() );
$form->addPreText( wfMsgExt( 'session_fail_preview', 'parseinline' ) );
}
+ # Give a notice if the user is uploading a file that has been deleted or moved
+ # Note that this is independent from the message 'filewasdeleted' that requires JS
+ $desiredTitleObj = Title::newFromText( $this->mDesiredDestName, NS_FILE );
+ $delNotice = ''; // empty by default
+ if ( $desiredTitleObj instanceof Title && !$desiredTitleObj->exists() ) {
+ LogEventsList::showLogExtract( $delNotice, array( 'delete', 'move' ),
+ $desiredTitleObj->getPrefixedText(),
+ '', array( 'lim' => 10,
+ 'conds' => array( "log_action != 'revision'" ),
+ 'showIfEmpty' => false,
+ 'msgKey' => array( 'upload-recreate-warning' ) )
+ );
+ }
+ $form->addPreText( $delNotice );
+
# Add text to form
$form->addPreText( '<div id="uploadtext">' .
wfMsgExt( 'uploadtext', 'parse', array( $this->mDesiredDestName ) ) .
/**
* Show the upload form with error message, but do not stash the file.
*
- * @param $message String
+ * @param $message HTML string
*/
protected function showUploadError( $message ) {
$message = '<h2>' . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" .
protected function processUpload() {
global $wgUser, $wgOut;
- // Verify permissions
- $permErrors = $this->mUpload->verifyPermissions( $wgUser );
- if( $permErrors !== true ) {
- $wgOut->showPermissionsErrorPage( $permErrors );
- return;
- }
-
// Fetch the file if required
$status = $this->mUpload->fetchFile();
if( !$status->isOK() ) {
- $this->showUploadForm( $this->getUploadForm( $wgOut->parse( $status->getWikiText() ) ) );
+ $this->showUploadError( $wgOut->parse( $status->getWikiText() ) );
return;
}
// Deprecated backwards compatibility hook
if( !wfRunHooks( 'UploadForm:BeforeProcessing', array( &$this ) ) ) {
wfDebug( "Hook 'UploadForm:BeforeProcessing' broke processing the file.\n" );
- return array( 'status' => UploadBase::BEFORE_PROCESSING );
+ // Return without notifying the user of an error. This sucks, but
+ // this was the previous behaviour as well, and as this hook is
+ // deprecated we're not going to do anything about it.
+ return;
}
$this->processVerificationError( $details );
return;
}
+
+ // Verify permissions for this title
+ $permErrors = $this->mUpload->verifyPermissions( $wgUser );
+ if( $permErrors !== true ) {
+ $code = array_shift( $permErrors[0] );
+ $this->showRecoverableUploadError( wfMsgExt( $code,
+ 'parseinline', $permErrors[0] ) );
+ return;
+ }
$this->mLocalFile = $this->mUpload->getLocalFile();
$this->showRecoverableUploadError( wfMsgExt( 'illegalfilename',
'parseinline', $details['filtered'] ) );
break;
- case UploadBase::OVERWRITE_EXISTING_FILE:
- $this->showRecoverableUploadError( wfMsgExt( $details['overwrite'],
- 'parseinline' ) );
- break;
case UploadBase::FILETYPE_MISSING:
$this->showRecoverableUploadError( wfMsgExt( 'filetype-missing',
'parseinline' ) );
/** Statuses that require reuploading **/
case UploadBase::EMPTY_FILE:
- $this->showUploadForm( $this->getUploadForm( wfMsgHtml( 'emptyfile' ) ) );
+ $this->showUploadError( wfMsgHtml( 'emptyfile' ) );
+ break;
+ case UploadBase::FILE_TOO_LARGE:
+ $this->showUploadError( wfMsgHtml( 'largefileserver' ) );
break;
case UploadBase::FILETYPE_BADTYPE:
$finalExt = $details['finalExt'];
* @return String: empty string if there is no warning or an HTML fragment
*/
public static function getExistsWarning( $exists ) {
- global $wgUser, $wgContLang;
+ global $wgUser;
if ( !$exists ) {
return '';
// if there isn't an exact match...
$file = wfLocalFile( $filename );
}
- $s = ' ';
+ $s = ' ';
if ( $file ) {
$exists = UploadBase::getExistsWarning( $file );
$warning = self::getExistsWarning( $exists );
protected $mSessionKey;
protected $mHideIgnoreWarning;
protected $mDestWarningAck;
+ protected $mDestFile;
protected $mTextTop;
protected $mTextAfterSummary;
? $options['sessionkey'] : '';
$this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
$this->mDestWarningAck = !empty( $options['destwarningack'] );
+ $this->mDestFile = isset( $options['destfile'] ) ? $options['destfile'] : '';
+
+ $this->mTextTop = isset( $options['texttop'] )
+ ? $options['texttop'] : '';
- $this->mTextTop = $options['texttop'];
- $this->mTextAfterSummary = $options['textaftersummary'];
+ $this->mTextAfterSummary = isset( $options['textaftersummary'] )
+ ? $options['textaftersummary'] : '';
$sourceDescriptor = $this->getSourceSection();
$descriptor = $sourceDescriptor
# Set some form properties
$this->setSubmitText( wfMsg( 'uploadbtn' ) );
$this->setSubmitName( 'wpUpload' );
+ # Used message keys: 'accesskey-upload', 'tooltip-upload'
$this->setSubmitTooltip( 'upload' );
$this->setId( 'mw-upload-form' );
*/
protected function getSourceSection() {
global $wgLang, $wgUser, $wgRequest;
+ global $wgMaxUploadSize;
if ( $this->mSessionKey ) {
return array(
'help' => wfMsgExt( 'upload-maxfilesize',
array( 'parseinline', 'escapenoentities' ),
$wgLang->formatSize(
- wfShorthandToInteger( ini_get( 'upload_max_filesize' ) )
+ wfShorthandToInteger( min(
+ wfShorthandToInteger(
+ ini_get( 'upload_max_filesize' )
+ ), $wgMaxUploadSize
+ ) )
)
) . ' ' . wfMsgHtml( 'upload_source_file' ),
'checked' => $selectedSourceType == 'file',
);
if ( $canUploadByUrl ) {
- global $wgMaxUploadSize;
$descriptor['UploadFileURL'] = array(
'class' => 'UploadSourceField',
'section' => 'source',
global $wgLang, $wgCheckFileExtensions, $wgStrictFileExtensions,
$wgFileExtensions, $wgFileBlacklist;
- $allowedExtensions = '';
if( $wgCheckFileExtensions ) {
if( $wgStrictFileExtensions ) {
# Everything not permitted is banned
'id' => 'wpDestFile',
'label-message' => 'destfilename',
'size' => 60,
+ 'default' => $this->mDestFile,
+ # FIXME: hack to work around poor handling of the 'default' option in HTMLForm
+ 'nodata' => strval( $this->mDestFile ) !== '',
),
'UploadDescription' => array(
'type' => 'textarea',
'EditTools' => array(
'type' => 'edittools',
'section' => 'description',
- ),
- 'License' => array(
+ )
+ );
+
+ if ( $this->mForReUpload ) {
+ $descriptor['DestFile']['readonly'] = true;
+ } else {
+ $descriptor['License'] = array(
'type' => 'select',
'class' => 'Licenses',
'section' => 'description',
'id' => 'wpLicense',
'label-message' => 'license',
- ),
- );
- if ( $this->mForReUpload ) {
- $descriptor['DestFile']['readonly'] = true;
+ );
}
global $wgUseCopyrightUpload;
);
}
- $descriptor['DestFileWarningAck'] = array(
+ $descriptor['wpDestFileWarningAck'] = array(
'type' => 'hidden',
'id' => 'wpDestFileWarningAck',
'default' => $this->mDestWarningAck ? '1' : '',
);
if ( $this->mForReUpload ) {
- $descriptor['ForReUpload'] = array(
+ $descriptor['wpForReUpload'] = array(
'type' => 'hidden',
'id' => 'wpForReUpload',
'default' => '1',
* Add upload JS to $wgOut
*/
protected function addUploadJS() {
- global $wgUseAjax, $wgAjaxUploadDestCheck, $wgAjaxLicensePreview, $wgEnableAPI;
+ global $wgUseAjax, $wgAjaxUploadDestCheck, $wgAjaxLicensePreview, $wgEnableAPI, $wgStrictFileExtensions;
global $wgOut;
$useAjaxDestCheck = $wgUseAjax && $wgAjaxUploadDestCheck;
$scriptVars = array(
'wgAjaxUploadDestCheck' => $useAjaxDestCheck,
'wgAjaxLicensePreview' => $useAjaxLicensePreview,
- 'wgUploadAutoFill' => !$this->mForReUpload,
+ 'wgUploadAutoFill' => !$this->mForReUpload &&
+ // If we received mDestFile from the request, don't autofill
+ // the wpDestFile textbox
+ $this->mDestFile === '',
'wgUploadSourceIds' => $this->mSourceIds,
+ 'wgStrictFileExtensions' => $wgStrictFileExtensions,
+ 'wgCapitalizeUploads' => MWNamespace::isCapitalized( NS_FILE ),
);
$wgOut->addScript( Skin::makeVariablesScript( $scriptVars ) );
// For <charinsert> support
- $wgOut->addScriptFile( 'edit.js' );
- $wgOut->addScriptFile( 'upload.js' );
+ $wgOut->addModules( array( 'mediawiki.legacy.edit', 'mediawiki.legacy.upload' ) );
}
/**
* A form field that contains a radio box in the label
*/
class UploadSourceField extends HTMLTextField {
- function getLabelHtml() {
+ function getLabelHtml( $cellAttributes = array() ) {
$id = "wpSourceType{$this->mParams['upload-type']}";
$label = Html::rawElement( 'label', array( 'for' => $id ), $this->mLabel );
$label .= Html::element( 'input', $attribs );
}
- return Html::rawElement( 'td', array( 'class' => 'mw-label' ), $label );
+ return Html::rawElement( 'td', array( 'class' => 'mw-label' ) + $cellAttributes, $label );
}
function getSize() {