r76108 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r76107‎ | r76108 | r76109 >
Date:16:14, 5 November 2010
Author:travis
Status:deferred
Tags:
Comment:
rewrite make it compatible with 1.16
Modified paths:
  • /trunk/extensions/MultiUpload/MultiUpload.body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/MultiUpload/MultiUpload.body.php
@@ -1,445 +1,498 @@
22 <?php
 3+/**
 4+ * @file
 5+ * @ingroup SpecialPage
 6+ * @ingroup Upload
 7+ *
 8+ * Form for handling multiple uploads and special page.
 9+ *
 10+ */
311
4 -class MultipleUpload extends SpecialPage {
 12+class MultipleUpload extends SpecialUpload {
513 /**
6 - * Constructor
 14+ * Constructor : initialise object
 15+ * Get data POSTed through the form and assign them to the object
 16+ * @param WebRequest $request Data posted.
717 */
8 - public function __construct() {
9 - parent::__construct( 'MultipleUpload'/*class*/, 'upload'/*restriction*/ );
 18+
 19+ public $mDesiredDestNames;
 20+ public $mUploads;
 21+ public $mUploadHasBeenShown;
 22+ public $mSessionKeys;
 23+
 24+ // status messagse for multiple files
 25+ public $mWarnings;
 26+ public $mSuccesses;
 27+ public $mErrors;
 28+
 29+ public function __construct( $request = null ) {
 30+ global $wgRequest;
 31+
 32+ parent::SpecialPage( 'MultipleUpload', 'upload' );
 33+
 34+ $this->loadRequest( is_null( $request ) ? $wgRequest : $request );
 35+ $this->mUploadHasBeenShown = false;
 36+ $this->mSessionKeys = array();
 37+ $this->mWarnings = array();
 38+ $this->mSuccesses = array();
 39+ $this->mErrors = array();
1040 }
1141
1242 /**
13 - * Show the special page
 43+ * Initialize instance variables from request and create an Upload handler
1444 *
15 - * @param $par Mixed: parameter passed to the page or null
 45+ * @param WebRequest $request The request to extract variables from
1646 */
17 - public function execute( $par ) {
18 - global $wgRequest, $wgOut, $wgUser;
19 - $this->setHeaders();
 47+ protected function loadRequest( $request ) {
 48+ global $wgUser, $wgMaxUploadFiles;
2049
21 - # Check permissions
22 - if( !$wgUser->isAllowed( 'upload' ) ) {
23 - $wgOut->permissionRequired( 'upload' );
24 - return;
 50+ // let's make the parent happy
 51+ $_FILES['wpUploadFile'] = $_FILES['wpUploadFile0'];
 52+ // Guess the desired name from the filename if not provided
 53+ $this->mDesiredDestNames = array();
 54+ $this->mUploads = array();
 55+
 56+ // deal with session keys, if we have some pick the first one, for now
 57+ $vals = $request->getValues();
 58+ $fromsession = false;
 59+ foreach ($vals as $k=>$v) {
 60+ if (preg_match("@^wpSessionKey@", $k)) {
 61+ $request->setVal('wpSessionKey', $v);
 62+ $fromsession = true;
 63+ $filenum = preg_replace("@wpSessionKey@", "", $k);
 64+ $request->setVal('wpDestFile', $request->getVal('wpDestFile' . $filenum));
 65+ $up = UploadBase::createFromRequest( $request );
 66+ $this->mUploads[] = $up;
 67+ $this->mDesiredDestNames[] = $request->getVal('wpDestFile' . $filenum);
 68+ }
2569 }
 70+
 71+ parent::loadRequest($request);
2672
27 - # Show a message if the database is in read-only mode
28 - if ( wfReadOnly() ) {
29 - $wgOut->readOnlyPage();
30 - return;
 73+ $this->mUploadClicked = $request->wasPosted()
 74+ && ( $request->getCheck( 'wpUpload' )
 75+ || $request->getCheck( 'wpUploadIgnoreWarning' ) );
 76+
 77+ if (!$fromsession) {
 78+ for ($i = 0; $i < $wgMaxUploadFiles; $i++) {
 79+ $this->mDesiredDestNames[$i] = $request->getText( 'wpDestFile'. $i);
 80+ if( !$this->mDesiredDestNames[$i] && $request->getFileName( 'wpUploadFile' . $i) !== null )
 81+ $this->mDesiredDestNames[$i] = $request->getFileName( 'wpUploadFile' . $i);
 82+ $request->setVal('wpUploadFile', $_FILES['wpUploadFile' . $i]);
 83+ $request->setVal('wpDestFile', $request->getVal('wpDestFile' . $i));
 84+ move_uploaded_file('wpUploadFile' . $i, 'wpUploadFile');
 85+ $_FILES['wpUploadFile'] = $_FILES['wpUploadFile' . $i];
 86+ $up = UploadBase::createFromRequest( $request );
 87+ $this->mUploads[$i] = $up;
 88+ }
3189 }
 90+ //
 91+ $this->mDesiredDestName = $this->mDesiredDestNames[0];
 92+ $this->mUpload= $this->mUploads[0];
 93+ }
3294
33 - # If user is blocked, s/he doesn't need to access this page
34 - if ( $wgUser->isBlocked() ) {
35 - $wgOut->blockedPage();
 95+ function showUploadForm($form) {
 96+ if ($this->mUploadHasBeenShown)
3697 return;
 98+ parent::showUploadForm($form);
 99+ $this->mUploadHasBeenShown = true;
 100+ }
 101+ /**
 102+ * Get an UploadForm instance with title and text properly set.
 103+ *
 104+ * @param string $message HTML string to add to the form
 105+ * @param string $sessionKey Session key in case this is a stashed upload
 106+ * @return UploadForm
 107+ */
 108+ protected function getUploadForm( $message = '', $sessionKeys = array(), $hideIgnoreWarning = false ) {
 109+ global $wgOut, $wgMaxUploadFiles;
 110+
 111+ # Initialize form
 112+ $options = array(
 113+ 'watch' => $this->getWatchCheck(),
 114+ 'forreupload' => $this->mForReUpload,
 115+ 'hideignorewarning' => $hideIgnoreWarning,
 116+ 'destwarningack' => (bool)$this->mDestWarningAck,
 117+ 'texttop' => $this->uploadFormTextTop,
 118+ 'textaftersummary' => $this->uploadFormTextAfterSummary,
 119+ );
 120+ foreach ($this->mSessionKeys as $f=>$key)
 121+ $options['sessionkey'. $f] = $key;
 122+ for ($i = 0; $i < $wgMaxUploadFiles; $i++)
 123+ $options['destfile' . $i] = $this->mDesiredDestNames[$i];
 124+ $form = new MultiUploadForm($options);
 125+ $form->setTitle( $this->getTitle() );
 126+
 127+ # Check the token, but only if necessary
 128+ if( !$this->mTokenOk && !$this->mCancelUpload
 129+ && ( $this->mUploads[0] && $this->mUploadClicked ) ) {
 130+ $form->addPreText( wfMsgExt( 'session_fail_preview', 'parseinline' ) );
37131 }
38132
39 - $form = new MultipleUploadForm( $wgRequest );
40 - $form->execute();
 133+ # Add text to form
 134+ $form->addPreText( '<div id="uploadtext">' .
 135+ wfMsgExt( 'uploadtext', 'parse', array( $this->mDesiredDestName ) ) .
 136+ '</div>' );
 137+ # Add upload error message
 138+ $form->addPreText( $message );
 139+
 140+ # Add footer to form
 141+ $uploadFooter = wfMsgNoTrans( 'uploadfooter' );
 142+ if ( $uploadFooter != '-' && !wfEmptyMsg( 'uploadfooter', $uploadFooter ) ) {
 143+ $form->addPostText( '<div id="mw-upload-footer-message">'
 144+ . $wgOut->parse( $uploadFooter ) . "</div>\n" );
 145+ }
 146+
 147+ return $form;
41148
42 - $form->cleanupTempFile();
43149 }
44 -}
45150
46 -/**
47 - * Main class
48 - * @ingroup SpecialPage
49 - */
50 -class MultipleUploadForm extends UploadForm {
51 -
52 - // extra goodies
53 - // access private
54 - var $mUploadTempNameArray, $mUploadSizeArray, $mOnameArray, $mUploadError, $mDestFileArray, $mFilePropsArray;
55 - var $mUploadDescriptionArray;
56 - var $mShowUploadForm, $mHasWarning, $mFileIndex;
57 - var $mWarnings = 0;
58 - var $mSessionKey = null;
59 -
60151 /**
61 - * Constructor : initialise object
62 - * Get data POSTed through the form and assign them to the object
63 - * @param $request Data posted.
 152+ * Shows the "view X deleted revivions link""
64153 */
65 - function __construct( &$request ) {
 154+ protected function showViewDeletedLinks() {
66155 global $wgMaxUploadFiles;
67 - // call the parent constructor
68 - parent::UploadForm($request);
 156+ for ($i = 0; $i < $wgMaxUploadFiles; $i++)
 157+ $this->showViewDeletedLinksInner($this->mDesiredDestNames[$i]);
 158+ }
69159
70 - // initialize
71 - $this->mUploadTempNameArray = $this->mUploadSizeArray = $this->mOnameArray = $this->mUploadError = $this->mDestFileArray = $this->mUploadDescriptionArray = array();
72 - $this->mmFilePropsArray = array();
73 - $this->mShowUploadForm = true;
74 - $this->mFileIndex = 0;
 160+ protected function showViewDeletedLinksInner($name) {
 161+ global $wgOut, $wgUser;
75162
76 - for( $x = 0; $x < $wgMaxUploadFiles; $x++ ) $this->mDestFileArray[$x] = $request->getText( "wpDestFile_$x" );
 163+ $title = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
 164+ // Show a subtitle link to deleted revisions (to sysops et al only)
 165+ if( $title instanceof Title ) {
 166+ $count = $title->isDeleted();
 167+ if ( $count > 0 && $wgUser->isAllowed( 'deletedhistory' ) ) {
 168+ $link = wfMsgExt(
 169+ $wgUser->isAllowed( 'delete' ) ? 'thisisdeleted' : 'viewdeleted',
 170+ array( 'parse', 'replaceafter' ),
 171+ $wgUser->getSkin()->linkKnown(
 172+ SpecialPage::getTitleFor( 'Undelete', $title->getPrefixedText() ),
 173+ wfMsgExt( 'restorelink', array( 'parsemag', 'escape' ), $count )
 174+ )
 175+ );
 176+ $wgOut->addHTML( "<div id=\"contentSub2\">{$link}</div>" );
 177+ }
 178+ }
77179
78 - if( !$request->wasPosted() ) {
79 - # GET requests just give the main form; no data except wpDestfile.
80 - return;
 180+ // Show the relevant lines from deletion log (for still deleted files only)
 181+ if( $title instanceof Title && $title->isDeletedQuick() && !$title->exists() ) {
 182+ $this->showDeletionLog( $wgOut, $title->getPrefixedText() );
81183 }
 184+ }
82185
83 - for( $x = 0; $x < $wgMaxUploadFiles; $x++ ) {
84 - $this->mDestFile[$x] = $request->getText( "wpDestFile_$x" );
85 - $this->mUploadDescriptionArray[$x] = $request->getText( "wpUploadDescription_$x" );
 186+ /**
 187+ * Stashes the upload, shows the main form, but adds an "continue anyway button".
 188+ * Also checks whether there are actually warnings to display.
 189+ *
 190+ * @param array $warnings
 191+ * @return boolean true if warnings were displayed, false if there are no
 192+ * warnings and the should continue processing like there was no warning
 193+ */
 194+ protected function showUploadWarning( $warnings ) {
 195+ global $wgUser;
 196+
 197+ # If there are no warnings, or warnings we can ignore, return early.
 198+ # mDestWarningAck is set when some javascript has shown the warning
 199+ # to the user. mForReUpload is set when the user clicks the "upload a
 200+ # new version" link.
 201+ if ( !$warnings || ( count( $warnings ) == 1 &&
 202+ isset( $warnings['exists'] ) &&
 203+ ( $this->mDestWarningAck || $this->mForReUpload ) ) )
 204+ {
 205+ return false;
86206 }
87 - $this->mSessionKey = $request->getInt( 'wpSessionKey' );
88207
89 - if( !empty( $this->mSessionKey ) ) {
90 - for( $x = 0; $x < $wgMaxUploadFiles; $x++ ) {
91 - if( !isset( $_SESSION["wsUploadData_$x"][$this->mSessionKey] ) ) continue;
92 - $data = $_SESSION["wsUploadData_$x"][$this->mSessionKey];
93 - $this->mUploadTempNameArray[$x] = $data['mTempPath'];
94 - $this->mUploadSizeArray[$x] = $data['mFileSize'];
95 - $this->mOnameArray[$x] = $data['mSrcName'];
96 - $this->mFileProps[$x] = $data['mFileProps'];
97 - $this->mCurlError = 0 /*UPLOAD_ERR_OK*/;
98 - $this->mStashed = true;
99 - $this->mRemoveTempFile = false;
100 - }
101 - } else {
102 - /**
103 - *Check for a newly uploaded file.
104 - */
105 - for( $x = 0; $x < $wgMaxUploadFiles; $x++ ) {
106 - $this->mUploadTempNameArray[$x] = $request->getFileTempName( "wpUploadFile_$x" );
107 - $this->mUploadSizeArray [$x] = $request->getFileSize( "wpUploadFile_$x" );
108 - $this->mOnameArray[$x] = $request->getFileName( "wpUploadFile_$x" );
109 - $this->mUploadErrorArray[$x] = $request->getUploadError( "wpUploadFile_$x" );
110 - $this->mUploadDescriptionArray[$x] = $request->getVal( "wpUploadDescription_$x" );
111 - }
 208+
 209+ $sessionKey = $this->mUpload->stashSession();
 210+
 211+ $sk = $wgUser->getSkin();
 212+
 213+ $warningHtml = '<h2>' . wfMsgHtml( 'uploadwarning' ) . "</h2>\n"
 214+ . '<ul class="warning">';
 215+ foreach( $warnings as $warning => $args ) {
 216+ $msg = '';
 217+ if( $warning == 'exists' ) {
 218+ $msg = "\t<li>" . self::getExistsWarning( $args ) . "</li>\n";
 219+ } elseif( $warning == 'duplicate' ) {
 220+ $msg = self::getDupeWarning( $args, $this->mLocalFile->getTitle() );
 221+ } elseif( $warning == 'duplicate-archive' ) {
 222+ $msg = "\t<li>" . wfMsgExt( 'file-deleted-duplicate', 'parseinline',
 223+ array( Title::makeTitle( NS_FILE, $args )->getPrefixedText() ) )
 224+ . "</li>\n";
 225+ } else {
 226+ if ( $args === true )
 227+ $args = array();
 228+ elseif ( !is_array( $args ) )
 229+ $args = array( $args );
 230+ $msg = "\t<li>" . wfMsgExt( $warning, 'parseinline', $args ) . "</li>\n";
 231+ }
 232+ $warningHtml .= $msg;
112233 }
 234+ $warningHtml .= "</ul>\n";
 235+ $warningHtml .= wfMsgExt( 'uploadwarning-text', 'parse' );
113236
 237+ // store it in an array to show later
 238+ $this->mWarnings[] = $warningHtml;
 239+ $this->mSessionKeys[$this->mUpload->getLocalFile()->getName()] = $sessionKey;
 240+
 241+ # Indicate that we showed a form
 242+ return true;
114243 }
115244
 245+ /**
 246+ * Show the upload form with error message, but do not stash the file.
 247+ *
 248+ * @param string $message
 249+ */
 250+ protected function showUploadError( $message ) {
 251+ $this->mErrors[] = '<ul><li>' . $this->mLocalFile->getTitle()->getFullText() . ':' . $message . "</li></ul>\n";
 252+ }
 253+
 254+
116255 /**
117 - * Really do the upload
 256+ * Do the upload.
118257 * Checks are made in SpecialUpload::execute()
119 - * @access private
120258 */
121 - function processUpload() {
122 - global $wgMaxUploadFiles, $wgOut, $wgRequest;
 259+ protected function processUpload() {
 260+ global $wgMaxUploadFiles, $wgOut;
123261
124 - $images = 0;
125 - $wgOut->addHTML( '<table>' );
126 - $this->mShowUploadForm = false;
127 -
128 - $titleObj = SpecialPage::getTitleFor( 'MultipleUpload' );
129 - $wgOut->addHTML(
130 - Xml::openElement( 'form', array( 'method' => 'post', 'action' => $titleObj->getLocalURL( 'action=submit' ),
131 - 'enctype' => 'multipart/form-data', 'id' => 'uploadwarning' ) ) . "\n"
132 - );
133 -
134 - $this->mLicense = $wgRequest->getText( 'wpLicense' );
135 -
136 - for( $x = 0; $x < $wgMaxUploadFiles; $x++ ) {
137 - $this->mFileIndex = $x;
138 - if( !isset( $this->mUploadTempNameArray[$x] ) || $this->mUploadTempNameArray[$x] == null ) {
139 - continue;
 262+ for ($i = 0; $i < $wgMaxUploadFiles; $i++) {
 263+ if (isset($this->mUploads[$i])) {
 264+ $this->mUpload = $this->mUploads[$i];
 265+ $this->mUploadSuccessful = false; // reset
 266+ parent::processUpload();
 267+ if ( $this->mUploadSuccessful) {
 268+ $this->mSuccesses[] = "<ul><li><a href='" . $this->mLocalFile->getTitle()->getFullURL() . "' target='new'>{$this->mLocalFile->getTitle()->getFullText()}: " . wfMsg('multiupload-fileuploaded') . "</a></li></ul>";
 269+ }
140270 }
 271+ }
 272+ // clear out the redirects
 273+ $wgOut->redirect('');
141274
142 - $images++;
143 - $this->mTempPath = $this->mUploadTempNameArray[$x];
144 - $this->mFileSize = $this->mUploadSizeArray[$x];
145 - $this->mSrcName = $this->mOnameArray[$x]; // for mw > 1.9
146 - $this->mRemoveTempFile = true;
147 - $this->mIgnoreWarning = $wgRequest->getCheck( 'wpIgnoreWarning' );
 275+ // tell the good news first
 276+ if (sizeof($this->mSuccesses) > 0) {
 277+ $wgOut->addHTML('<h2>' . wfMsgHtml( 'successfulupload' ) . "</h2>\n");
 278+ $wgOut->addHTML(implode($this->mSuccesses));
 279+ }
148280
149 - $this->mUploadError = $this->mUploadErrorArray[$x];
150 - $this->mDesiredDestName = $this->mDestFileArray[$x];
151 - $this->mComment = $this->mUploadDescriptionArray[$x];
152 - $this->mFileProps = $this->mFileProps[$x];
153 -
154 - $wgOut->addHTML( '<tr><td>' );
155 - parent::processUpload();
156 - $wgOut->addHTML( '</td></tr>' );
 281+ // the bad news
 282+ if (sizeof($this->mErrors) > 0) {
 283+ $wgOut->addHTML('<h2>' . wfMsgHtml( 'uploadwarning' ) . "</h2>\n");
 284+ $wgOut->addHTML(implode($this->mErrors));
157285 }
158286
159 - $wgOut->addHTML( '</table>' );
160 - // Display a form again with a warning if we gave no files, instead of a blank screen
161 - if( 0 == $images ) {
162 - $this->mShowUploadForm = true;
163 - $this->mUploadSaveName = wfMsg( 'multiupload-blank' );
164 - $this->mainUploadForm( wfMsg( 'multiupload-no-files' ) );
165 - } else {
166 - $this->mShowUploadForm = false;
167 - $wgOut->redirect( '' ); // clear the redirect, we want to show a nice page of images
168 - $this->mShowUploadForm = true;
169 - if( $this->mHasWarning ) {
170 - $this->showWarningOptions();
171 - }
 287+ // the hopefully recoverable news
 288+ if (sizeof($this->mWarnings) > 0 || sizeof($this->mErrors) > 0 ) {
 289+ $wgOut->addHTML("<br/><br/><hr/>"); // visually separate the form from the errors/successes
 290+ $form = $this->getUploadForm( implode($this->mWarnings), $this->mSessionKeys, /* $hideIgnoreWarning */ true );
 291+ $form->setSubmitText( wfMsg( 'upload-tryagain' ) );
 292+ $form->addButton( 'wpUploadIgnoreWarning', wfMsg( 'ignorewarning' ) );
 293+ $form->addButton( 'wpCancelUpload', wfMsg( 'reuploaddesc' ) );
 294+ $this->showUploadForm( $form );
172295 }
173 - $wgOut->addHTML( Xml::closeElement( 'form' ) . "\n" );
174296 }
175297
176 - /**
177 - * Show some text and linkage on successful upload.
178 - * @access private
179 - */
180 - function showSuccess() {
181 - global $wgUser, $wgOut;
182 - $t = $this->mLocalFile->getTitle();
183 - $wgOut->addHTML( '<h2>' . wfMsg( 'multiupload-fileuploaded' ) . '</h2>' );
184 - $wgOut->addHTML( $wgUser->getSkin()->makeThumbLink2( $t, $this->mLocalFile, array( 'caption' => $t->getText() ) ) );
185 - }
186298
187299 /**
188 - * @param string $error as HTML
 300+ * Remove a temporarily kept file stashed by saveTempUploadedFile().
189301 * @access private
 302+ * @return success
190303 */
191 - function uploadError( $error ) {
192 - global $wgOut;
193 - $wgOut->addHTML( "<b>{$this->mUploadSaveName}</b>\n" );
194 - $wgOut->addHTML( "<span class='error'>{$error}</span>\n" );
 304+ protected function unsaveUploadedFile() {
 305+ global $wgMaxUploadFiles;
 306+ $ret = true;
 307+ for ($i = 0; $i < $wgMaxUploadFiles; $i++) {
 308+ if (isset($this->mUploads[$i])) {
 309+ $this->mUpload = $this->mUploads[$i];
 310+ // return false if even one of them failed
 311+ $ret = $ret && parent::unsaveUploadedFile();
 312+ }
 313+ }
 314+ return $ret;
195315 }
196316
197 - function showWarningOptions() {
198 - global $wgOut, $wgMaxUploadFiles, $wgUseCopyrightUpload;
 317+ /**
 318+ * Construct a warning and a gallery from an array of duplicate files.
 319+ * Override because the original doesn't say which file is a dupe
 320+ */
 321+ public static function getDupeWarning( $dupes, $dupetitle = null ) {
 322+ $result = parent::getDupeWarning($dupes);
 323+ return preg_replace("@<li>@", "<li>{$dupetitle->getText()}", $result);
 324+ }
199325
200 - $save = wfMsgHtml( 'multipleupload-saveallfiles' );
201 - $reupload = wfMsgHtml( 'reupload' );
202 - $iw = wfMsgWikiHtml( 'multipleupload-ignoreallwarnings' );
203 - $reup = wfMsgWikiHtml( 'reuploaddesc' );
 326+}
204327
205 - if ( $wgUseCopyrightUpload ) {
206 - $copyright = '
207 - <input type="hidden" name="wpUploadCopyStatus" value="' . htmlspecialchars( $this->mUploadCopyStatus ) . '" />
208 - <input type="hidden" name="wpUploadSource" value="' . htmlspecialchars( $this->mUploadSource ) . '" />';
209 - } else {
210 - $copyright = '';
211 - }
 328+/**
 329+ * Sub class of HTMLForm that provides the form section of SpecialUpload
 330+ */
 331+class MultiUploadForm extends UploadForm {
212332
213 - $wgOut->addHTML( '<input type="hidden" name="wpIgnoreWarning" value="1" />
214 - <input type="hidden" name="wpSessionKey" value="' . htmlspecialchars( $this->mSessionKey ) . '" />
215 - <input type="hidden" name="wpLicense" value="' . htmlspecialchars( $this->mLicense ) . '" />');
 333+ protected $mDestFiles;
 334+ protected $mSessionKeys;
216335
217 - for( $x = 0; $x < $wgMaxUploadFiles; $x++ ) {
218 - $wgOut->addHTML("<input type='hidden' name='wpDestFile_$x' value=\"" . htmlspecialchars( $this->mDestFileArray[$x] ) . "\" />");
 336+ public function __construct( $options = array() ) {
 337+
 338+// basically we want to map filenames to session keys here somehow
 339+ global $wgMaxUploadFiles;
 340+ $this->mDestFiles = array();
 341+ for($i = 0; $i < $wgMaxUploadFiles; $i++) {
 342+ $this->mDestFiles[$i] = $options['destfile'. $i];
 343+ }
 344+ $this->mSessionKeys = array();
 345+ foreach ($options as $k=>$v) {
 346+ if (preg_match("@^sessionkey@", $k))
 347+ $this->mSessionKeys[$k] = $v;
219348 }
 349+ parent::__construct( $options) ;
 350+ }
220351
221 - $wgOut->addHTML("<input type='hidden' name='wpWatchthis' value=\"" . htmlspecialchars( intval( $this->mWatchthis ) ) . "\" />
222 - {$copyright}
223 - <table border='0'>
224 - <tr>
225 - <tr>
226 - <td align='right'>
227 - <input tabindex='2' type='submit' name='wpUpload' value='$save' />
228 - </td>
229 - <td align='left'>$iw</td>
230 - </tr>
231 - <tr>
232 - <td align='right'>
233 - <input tabindex='2' type='submit' name='wpReUpload' value='{$reupload}' />
234 - </td>
235 - <td align='left'>$reup</td>
236 - </tr>
237 - </tr>
238 - </table></form>\n" );
239352
 353+ protected function getDescriptionSection() {
 354+ // get the usual one and clear out the DestFile
 355+ $descriptor = parent::getDescriptionSection();
 356+ unset($descriptor['DestFile']);
 357+ return $descriptor;
240358 }
241 -
242359 /**
243 - * Displays the main upload form, optionally with a highlighted
244 - * error message up at the top.
245 - *
246 - * @param string $msg as HTML
247 - * @access private
 360+ * Get the descriptor of the fieldset that contains the file source
 361+ * selection. The section is 'source'
 362+ *
 363+ * @return array Descriptor array
248364 */
249 - function mainUploadForm( $msg = '' ) {
250 - global $wgOut, $wgUser, $wgScriptPath, $wgUseCopyrightUpload, $wgMaxUploadFiles;
 365+ protected function getSourceSection() {
 366+ global $wgLang, $wgUser, $wgRequest, $wgMaxUploadFiles;
251367
252 - if( $msg == '' && !$this->mShowUploadForm ) return;
253 - $cols = intval( $wgUser->getOption( 'cols' ) );
254 - $ew = $wgUser->getOption( 'editwidth' );
255 - if ( $ew ) $ew = " style=\"width:100%\"";
256 - else $ew = '';
257 -
258 - if ( '' != $msg ) {
259 - $wgOut->addHTML( "<b>{$this->mUploadSaveName}</b>\n<br />" );
260 - $sub = wfMsgHtml( 'multipleupload-addresswarnings' );
261 - $wgOut->addHTML( "<b>{$sub}</b><br /><span class='error'>{$msg}</span>\n" );
 368+ if ( sizeof($this->mSessionKeys) > 0) {
 369+ $data = array(
 370+ 'wpSourceType' => array(
 371+ 'type' => 'hidden',
 372+ 'default' => 'Stash',
 373+ ),
 374+ );
 375+ $index = 0;
 376+ foreach ($this->mDestFiles as $k=>$v) {
 377+ if ($v == "") continue;
 378+ $data['wpDestFile' . $index] = array(
 379+ 'type' => 'hidden',
 380+ 'default' => $v,
 381+ );
 382+ $data['wpSessionKey' . $index] = array(
 383+ 'type' => 'hidden',
 384+ 'default' => $this->mSessionKeys['sessionkey' . $v],
 385+ );
 386+ $index++;
 387+ }
 388+ return $data;
262389 }
263 - $wgOut->addHTML( '<div id="uploadtext">' );
264 - $wgOut->addWikiMsg('multipleupload-text', $wgMaxUploadFiles);
265 - $wgOut->addHTML( '</div>' );
266 - $sk = $wgUser->getSkin();
267390
268 - $sourcefilename = wfMsgHtml( 'sourcefilename' );
269 - $destfilename = wfMsgHtml( 'destfilename' );
270 - $summary = wfMsg( 'fileuploadsummary' );
271 - $licenses = new Licenses();
272 - $license = wfMsgHtml( 'license' );
273 - $nolicense = wfMsgHtml( 'nolicense' );
274 - $licenseshtml = $licenses->getHtml();
275 - $ulb = wfMsgHtml( 'uploadbtn' );
 391+ $canUploadByUrl = UploadFromUrl::isEnabled() && $wgUser->isAllowed( 'upload_by_url' );
 392+ $radio = $canUploadByUrl;
 393+ $selectedSourceType = strtolower( $wgRequest->getText( 'wpSourceType', 'File' ) );
276394
277 - $titleObj = SpecialPage::getTitleFor( 'MultipleUpload' );
278 - $action = $titleObj->escapeLocalURL();
279 -
280 - $watchChecked = $wgUser->getOption( 'watchdefault' )
281 - ? 'checked="checked"'
282 - : '';
283 -
284 - $wgOut->addScriptFile( $wgScriptPath . '/extensions/MultiUpload/multiupload.js' );
285 - $wgOut->addHTML( "
286 - <form id='upload' method='post' enctype='multipart/form-data' action=\"$action\">
287 - <table border='0' width='90%'>
288 - <tr>
289 - <td align='left'><label for='wpUploadFile'><b>{$sourcefilename}</b></label></td>
290 - <td align='left'><label for='wpDestFile'><b>{$destfilename}</b></label></td>
291 - <td align='left' valign='middle'><b>{$summary}</b></td>
292 - </tr>");
293 - for( $i = 0; $i < $wgMaxUploadFiles; $i++ ) {
294 - $encDestFile = htmlspecialchars( $this->mDestFileArray[$i] );
295 - $wgOut->addHTML("
296 - <tr>
297 - <td align='left'>
298 - <input tabindex='1' type='file' name='wpUploadFile_$i' id='wpUploadFile_$i' " . ( $this->mDestName ? "" : "onchange='fillDestFilenameMulti($i)' " ) . "size='25' />
299 - </td>
300 - <td align='left'>
301 - <input tabindex='2' type='text' name='wpDestFile_$i' id='wpDestFile_$i' size='25' value=\"$encDestFile\" />
302 - </td>
303 - <td align='left'>
304 - <input tabindex='3' name='wpUploadDescription_$i' id='wpUploadDescription' value=\"". htmlspecialchars( $this->mComment ) . "\" size=25>
305 - </td>
306 - </tr>
307 - <tr>" );
308 - }
309 -
310 - if ( $licenseshtml != '' ) {
311 - global $wgAjaxLicensePreview;
312 - $wgOut->addScriptFile( 'upload.js' );
313 - // This is one nasty hack...but necessary to make upload.js not bitch if the user actually touches the "Licensing" dropdown menu instead of just admiring it from a distance.
314 - $wgOut->addInlineScript( 'var wgAjaxLicensePreview = "'.$wgAjaxLicensePreview.'";' );
315 - $wgOut->addHTML( "
316 - <td align='left' colspan='3'>
317 - <label for='wpLicense'>$license</label>
318 - <select name='wpLicense' id='wpLicense' tabindex='4' style='font-size: xx-small;'
319 - onchange='licenseSelectorCheck()'>
320 - <option value=''>$nolicense</option>
321 - $licenseshtml
322 - </select>
323 - </td>
324 - </tr>
325 - <tr>");
326 - // So that the license previews will show up on the page
327 - $wgOut->addHTML( '
328 - <td id="mw-license-preview" colspan="3"></td>
329 - </tr>
330 - <tr>' );
 395+ $descriptor = array();
 396+ if ( $this->mTextTop ) {
 397+ $descriptor['UploadFormTextTop'] = array(
 398+ 'type' => 'info',
 399+ 'section' => 'source',
 400+ 'default' => $this->mTextTop,
 401+ 'raw' => true,
 402+ );
331403 }
332 -
333 - if ( $wgUseCopyrightUpload ) {
334 - global $wgRequest;
335 - $filestatus = wfMsgHtml( 'filestatus' );
336 - $copystatus = htmlspecialchars( $this->mUploadCopyStatus );
337 - $filesource = wfMsgHtml( 'filesource' );
338 - $uploadsource = htmlspecialchars( $this->mUploadSource );
339 -
340 - $wgOut->addHTML( "
341 - <td align='right' nowrap='nowrap'><label for='wpUploadCopyStatus'>$filestatus</label></td>
342 - <td><input tabindex='5' type='text' name='wpUploadCopyStatus' id='wpUploadCopyStatus' value=\"$copystatus\" size='40' /></td>
343 - </tr>
344 - <tr>
345 - <td align='right'><label for='wpUploadCopyStatus'>$filesource</label></td>
346 - <td><input tabindex='6' type='text' name='wpUploadSource' id='wpUploadCopyStatus' value=\"$uploadsource\" size='40' /></td>
347 - </tr>
348 - <tr>" );
349 - // For license selector
350 - $wgOut->addHTML( Xml::hidden( 'wpLicense', $wgRequest->getText( 'wpLicense' ) ) . "\n" );
 404+
 405+ for ($i = 0; $i < $wgMaxUploadFiles; $i++) {
 406+ $descriptor['UploadFile' . $i] = array(
 407+ 'class' => 'UploadSourceField',
 408+ 'section' => 'source',
 409+ 'type' => 'file',
 410+ 'id' => 'wpUploadFile' . $i,
 411+ 'label-message' => 'sourcefilename',
 412+ 'upload-type' => 'File',
 413+ 'radio' => &$radio,
 414+ 'checked' => $selectedSourceType == 'file',
 415+ );
 416+ $descriptor['DestFile' . $i] = array(
 417+ 'type' => 'text',
 418+ 'section' => 'source',
 419+ 'id' => 'wpDestFile' . $i,
 420+ 'label-message' => 'destfilename',
 421+ 'size' => 60,
 422+ 'default' => $this->mDestFiles[$i],
 423+ # FIXME: hack to work around poor handling of the 'default' option in HTMLForm
 424+ 'nodata' => strval( $this->mDestFile ) !== '',
 425+ );
 426+
 427+ if ( $canUploadByUrl ) {
 428+ global $wgMaxUploadSize;
 429+ $descriptor['UploadFileURL'] = array(
 430+ 'class' => 'UploadSourceField',
 431+ 'section' => 'source',
 432+ 'id' => 'wpUploadFileURL',
 433+ 'label-message' => 'sourceurl',
 434+ 'upload-type' => 'url',
 435+ 'radio' => &$radio,
 436+ 'help' => wfMsgExt( 'upload-maxfilesize',
 437+ array( 'parseinline', 'escapenoentities' ),
 438+ $wgLang->formatSize( $wgMaxUploadSize )
 439+ ) . ' ' . wfMsgHtml( 'upload_source_url' ),
 440+ 'checked' => $selectedSourceType == 'url',
 441+ );
 442+ }
351443 }
 444+ wfRunHooks( 'UploadFormSourceDescriptors', array( &$descriptor, &$radio, $selectedSourceType ) );
352445
353 - $wgOut->addHTML( "
354 - <td>
355 - <input tabindex='7' type='checkbox' name='wpWatchthis' id='wpWatchthis' $watchChecked value='true' />
356 - <label for='wpWatchthis'>" . wfMsgHtml( 'watchthis' ) . "</label>
357 - <input tabindex='8' type='checkbox' name='wpIgnoreWarning' id='wpIgnoreWarning' value='true' />
358 - <label for='wpIgnoreWarning'>" . wfMsgHtml( 'ignorewarnings' ) . "</label>
359 - </td>
360 - </tr>
361 - <tr>
 446+ $descriptor['Extensions'] = array(
 447+ 'type' => 'info',
 448+ 'section' => 'source',
 449+ 'default' => $this->getExtensionsMessage(),
 450+ 'raw' => true,
 451+ 'help' => wfMsgExt( 'upload-maxfilesize',
 452+ array( 'parseinline', 'escapenoentities' ),
 453+ $wgLang->formatSize(
 454+ wfShorthandToInteger( ini_get( 'upload_max_filesize' ) )
 455+ )
 456+ ) . ' ' . wfMsgHtml( 'upload_source_file' ),
 457+ );
 458+ return $descriptor;
 459+ }
362460
363 - </tr>
364 - <tr>
365 - <td align='left'><input tabindex='9' type='submit' name='wpUpload' value=\"{$ulb}\" /></td>
366 - </tr>
367461
368 - </table>
369 - </form>" );
370 - }
371 -
372462 /**
373 - * Override uploadWarning so we can put multiple warnings on the same page
374 - * @param $warning String: warning as HTML
375 - * @access private
 463+ * Add upload JS to $wgOut
 464+ *
 465+ * @param bool $autofill Whether or not to autofill the destination
 466+ * filename text box
376467 */
377 - function uploadWarning( $warning ) {
378 - global $wgOut, $wgUseCopyrightUpload;
 468+ protected function addUploadJS( ) {
 469+ global $wgScriptPath, $wgMaxUploadFiles, $wgFileExtensions;
379470
380 - $this->mHasWarning = true;
381 - $this->mSessionKey = $this->stashSession();
382 - if( !$this->mSessionKey ) {
383 - # Couldn't save file; an error has been displayed so let's go.
384 - return;
385 - }
 471+ global $wgUseAjax, $wgAjaxUploadDestCheck, $wgAjaxLicensePreview, $wgEnableAPI;
 472+ global $wgOut;
386473
387 - $wgOut->addHTML( '<h2>' . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" );
388 - $wgOut->addHTML( '<ul class="warning">' . $warning . "</ul>\n" );
 474+ $useAjaxDestCheck = $wgUseAjax && $wgAjaxUploadDestCheck;
 475+ $useAjaxLicensePreview = $wgUseAjax && $wgAjaxLicensePreview && $wgEnableAPI;
389476
390 - $titleObj = SpecialPage::getTitleFor( 'Upload' );
391 -
392 - if ( $wgUseCopyrightUpload ) {
393 - $copyright = Xml::hidden( 'wpUploadCopyStatus', $this->mCopyrightStatus ) . "\n" .
394 - Xml::hidden( 'wpUploadSource', $this->mCopyrightSource ) . "\n";
395 - } else {
396 - $copyright = '';
397 - }
398 -
399 - $wgOut->addHTML(
400 - Xml::hidden( 'wpIgnoreWarning', '1' ) . "\n" .
401 - Xml::hidden( 'wpUploadDescription_' . $this->mFileIndex, $this->mComment ) . "\n" .
402 - Xml::hidden( 'wpLicense', $this->mLicense ) . "\n" .
403 - Xml::hidden( 'wpDestFile_' . $this->mFileIndex, $this->mDesiredDestName ) . "\n" .
404 - Xml::hidden( 'wpWatchthis', $this->mWatchthis ) . "\n" .
405 - "{$copyright}<br />" .
406 - Xml::check( 'wpUpload_' . $this->mSessionKey, array( 'name' => 'wpUpload', 'id' => 'wpUpload', 'checked' => 'checked' ) ) . ' ' .
407 - Xml::label( wfMsg( 'ignorewarning' ), 'wpUpload_' . $this->mSessionKey ) . '<br />' .
408 - Xml::check( 'wpReUpload_' . $this->mSessionKey ) .
409 - Xml::label( wfMsg( 'reuploaddesc' ), 'wpUpload_' . $this->mSessionKey )
 477+ $scriptVars = array(
 478+ 'wgAjaxUploadDestCheck' => $useAjaxDestCheck,
 479+ 'wgAjaxLicensePreview' => $useAjaxLicensePreview,
 480+ 'wgUploadAutoFill' => !$this->mForReUpload &&
 481+ // If we received mDestFile from the request, don't autofill
 482+ // the wpDestFile textbox
 483+ $this->mDestFile === '',
 484+ 'wgUploadSourceIds' => $this->mSourceIds,
410485 );
411 - }
412486
413 - function stashSession() {
414 - $stash = $this->saveTempUploadedFile( $this->mDestName, $this->mTempPath );
 487+ $wgOut->addScript( Skin::makeVariablesScript( $scriptVars ) );
 488+
 489+ // For <charinsert> support
 490+ $wgOut->addScriptFile( 'edit.js' );
415491
416 - if( !$stash ) {
417 - # Couldn't save the file.
418 - return false;
419 - }
420 -
421 - if( $this->mSessionKey == null ) {
422 - $this->mSessionKey = mt_rand( 0, 0x7fffffff );
423 - }
424 - $_SESSION['wsUploadData_' . $this->mFileIndex][$this->mSessionKey] = array(
425 - 'mTempPath' => $stash,
426 - 'mFileSize' => $this->mFileSize,
427 - 'mSrcName' => $this->mSrcName,
428 - 'mFileProps' => $this->mFileProps,
429 - 'version' => self::SESSION_VERSION,
430 - );
431 - return $this->mSessionKey;
 492+ // changed
 493+ $wgOut->addScriptFile( "$wgScriptPath/extensions/MultiUpload/multiupload.js" );
 494+ $newscriptVars = array('wgMaxUploadFiles' => $wgMaxUploadFiles, 'wgFileExtensions' => $wgFileExtensions);
 495+ $wgOut->addScript( Skin::makeVariablesScript( $newscriptVars ) );
432496 }
433497
434 - /**
435 - * If we've modified the upload file we need to manually remove it
436 - * on exit to clean up.
437 - * @access private
438 - */
439 - function cleanupTempFile() {
440 - global $wgMaxUploadFiles;
441 - for( $x = 0; $x < $wgMaxUploadFiles; $x++ ) {
442 - $this->mTempPath = $this->mTempPathArray[$x];
443 - parent::cleanupTempFile();
444 - }
445 - }
446498 }
 499+

Follow-up revisions

RevisionCommit summaryAuthorDate
r76115MultiUpload: follow-up to r76108 and r76109 - coding style tweaks and bump ve...ashley16:42, 5 November 2010

Status & tagging log