Wiki Upload Fix
How It Works
The idea behind this is that the fopen(), fclose(), fread() calls that MediaWiki uses don't have access to the /tmp/ directory where uploaded files are temporarily stored. The move_uploaded_file() function however does have access to move PHP uploaded files out of the /tmp. What we're doing here is taking the uploaded file from the /tmp directory, uploading it to a local location we can access, then substituting server's temporary $_FILES[file]['tmp_name'] variable with where we've put the new file. The wiki has access to this folder and therefore can do all the necessary checks.
The only thing we need to make sure gets done is cleanup of the files sitting in our tmp directory, thus we edit the files below to take care of that.
Code Changes
Make sure there is a "tmp" folder in the main folder of your Wiki directory. Give it the AFS permissions necessary to be writeable by the Engineering web servers.
Open includes/SpecialUpload.php and find:
$status = $this->mLocalFile->upload( $this->mTempPath, $this->mComment, $pageText, File::DELETE_SOURCE, $this->mFileProps ); if ( !$status->isGood() ) { $this->showError( $status->getWikiText() ); } else { if ( $this->mWatchthis ) { global $wgUser; $wgUser->addWatch( $this->mLocalFile->getTitle() ); } // Success, redirect to description page $wgOut->redirect( $this->mLocalFile->getTitle()->getFullURL() ); $img = null; // @todo: added to avoid passing a ref to null - should this be defined somewhere? wfRunHooks( 'UploadComplete', array( &$img ) ); }
Replace with:
$status = $this->mLocalFile->upload( $this->mTempPath, $this->mComment, $pageText, File::DELETE_SOURCE, $this->mFileProps ); echo $this->mTempPath; if ( !$status->isGood() ) { $this->showError( $status->getWikiText() ); } else { if ( $this->mWatchthis ) { global $wgUser; $wgUser->addWatch( $this->mLocalFile->getTitle() ); } // Success, redirect to description page $this->cleanupTempFile(); $wgOut->redirect( $this->mLocalFile->getTitle()->getFullURL() ); $img = null; // @todo: added to avoid passing a ref to null - should this be defined somewhere? wfRunHooks( 'UploadComplete', array( &$img ) ); }
Also in includes\SpecialUpload.php find:
function uploadError( $error ) { global $wgOut; $wgOut->addHTML( "<h2>" . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" ); $wgOut->addHTML( "<span class='error'>{$error}</span>\n" ); }
Replace with:
function uploadError( $error ) { global $wgOut; $this->mRemoveTempFile = file_exists( $this->mTempPath ); $this->cleanupTempFile(); $wgOut->addHTML( "<h2>" . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" ); $wgOut->addHTML( "<span class='error'>{$error}</span>\n" ); }
Open includes/WebRequest.php and find:
function getFileTempname( $key ) { if( !isset( $_FILES[$key] ) ) { return NULL; } return $_FILES[$key]['tmp_name']; }
Replace with:
function getFileTempname( $key ) { if( !isset( $_FILES[$key] ) ) { return NULL; } if (preg_match('#^/tmp/php#', $_FILES[$key]['tmp_name'])){ if (move_uploaded_file($_FILES[$key]['tmp_name'], $GLOBALS['IP'] . $_FILES[$key]['tmp_name'])){ $_FILES[$key]['tmp_name'] = $GLOBALS['IP'] . $_FILES[$key]['tmp_name']; } } return $_FILES[$key]['tmp_name']; }