60 private const MAX_US_PROPS_SIZE = 65535;
96 $this->user = $user ?? RequestContext::getMain()->getUser();
112 public function getFile( $key, $noAuth =
false ) {
113 if ( !preg_match( self::KEY_FORMAT_REGEX, $key ) ) {
115 wfMessage(
'uploadstash-bad-path-bad-format', $key )
119 if ( !$noAuth && !$this->user->isRegistered() ) {
125 if ( !isset( $this->fileMetadata[$key] ) ) {
132 if ( !isset( $this->fileMetadata[$key] ) ) {
134 wfMessage(
'uploadstash-file-not-found', $key )
143 isset( $this->fileMetadata[$key][
'us_props'] ) && strlen( $this->fileMetadata[$key][
'us_props'] )
145 $this->fileProps[$key] = unserialize( $this->fileMetadata[$key][
'us_props'] );
147 wfDebug( __METHOD__ .
" fetched props for $key from file" );
148 $path = $this->fileMetadata[$key][
'us_path'];
149 $this->fileProps[$key] = $this->repo->getFileProps(
$path );
153 if ( !$this->files[$key]->exists() ) {
154 wfDebug( __METHOD__ .
" tried to get file at $key, but it doesn't exist" );
161 if ( !$noAuth && $this->fileMetadata[$key][
'us_user'] != $this->user->getId() ) {
163 wfMessage(
'uploadstash-wrong-owner', $key )
167 return $this->files[$key];
179 return $this->fileMetadata[$key];
191 return $this->fileProps[$key];
207 if ( !is_file(
$path ) ) {
208 wfDebug( __METHOD__ .
" tried to stash file at '$path', but it doesn't exist" );
214 $mwProps =
new MWFileProps( MediaWikiServices::getInstance()->getMimeAnalyzer() );
216 wfDebug( __METHOD__ .
" stashing file at '$path'" );
220 $extension = self::getExtensionForPath(
$path );
221 if ( !preg_match(
"/\\.\\Q$extension\\E$/",
$path ) ) {
222 $pathWithGoodExtension =
"$path.$extension";
224 $pathWithGoodExtension =
$path;
232 [ $usec, $sec ] = explode(
' ', microtime() );
233 $usec = substr( $usec, 2 );
234 $key = Wikimedia\base_convert( $sec . $usec, 10, 36 ) .
'.' .
235 Wikimedia\base_convert( (
string)mt_rand(), 10, 36 ) .
'.' .
236 $this->user->getId() .
'.' .
241 if ( !preg_match( self::KEY_FORMAT_REGEX, $key ) ) {
243 wfMessage(
'uploadstash-bad-path-bad-format', $key )
247 wfDebug( __METHOD__ .
" key for '$path': $key" );
250 $storeStatus = $this->repo->storeTemp( basename( $pathWithGoodExtension ),
$path );
252 if ( !$storeStatus->isOK() ) {
261 $error = $storeStatus->getErrorsArray();
262 $error = reset( $error );
263 if ( !count( $error ) ) {
264 $error = $storeStatus->getWarningsArray();
265 $error = reset( $error );
266 if ( !count( $error ) ) {
267 $error = [
'unknown',
'no error recorded' ];
272 $errorMsg = array_shift( $error );
275 $stashPath = $storeStatus->value;
278 if ( !$this->user->isRegistered() ) {
285 wfDebug( __METHOD__ .
" inserting $stashPath under $key" );
286 $dbw = $this->repo->getPrimaryDB();
288 $serializedFileProps = serialize(
$fileProps );
289 if ( strlen( $serializedFileProps ) > self::MAX_US_PROPS_SIZE ) {
294 $serializedFileProps = serialize(
$fileProps );
298 'us_user' => $this->user->getId(),
300 'us_orig_path' =>
$path,
301 'us_path' => $stashPath,
302 'us_props' => $dbw->encodeBlob( $serializedFileProps ),
310 'us_source_type' => $sourceType,
311 'us_timestamp' => $dbw->timestamp(),
312 'us_status' =>
'finished'
315 $dbw->newInsertQueryBuilder()
316 ->insertInto(
'uploadstash' )
318 ->caller( __METHOD__ )->execute();
322 $insertRow[
'us_id'] = $dbw->insertId();
324 $this->fileMetadata[$key] = $insertRow;
326 # create the UploadStashFile object for this file.
340 if ( !$this->user->isRegistered() ) {
346 wfDebug( __METHOD__ .
' clearing all rows for user ' . $this->user->getId() );
347 $dbw = $this->repo->getPrimaryDB();
348 $dbw->newDeleteQueryBuilder()
349 ->deleteFrom(
'uploadstash' )
350 ->where( [
'us_user' => $this->user->getId() ] )
351 ->caller( __METHOD__ )->execute();
355 $this->fileMetadata = [];
369 if ( !$this->user->isRegistered() ) {
375 $dbw = $this->repo->getPrimaryDB();
379 $row = $dbw->newSelectQueryBuilder()
380 ->select(
'us_user' )
381 ->from(
'uploadstash' )
382 ->where( [
'us_key' => $key ] )
383 ->caller( __METHOD__ )->fetchRow();
387 wfMessage(
'uploadstash-no-such-key', $key )
391 if ( $row->us_user != $this->user->getId() ) {
393 wfMessage(
'uploadstash-wrong-owner', $key )
407 wfDebug( __METHOD__ .
" clearing row $key" );
412 $dbw = $this->repo->getPrimaryDB();
414 $dbw->newDeleteQueryBuilder()
415 ->deleteFrom(
'uploadstash' )
416 ->where( [
'us_key' => $key ] )
417 ->caller( __METHOD__ )->execute();
422 $this->files[$key]->remove();
424 unset( $this->files[$key] );
425 unset( $this->fileMetadata[$key] );
437 if ( !$this->user->isRegistered() ) {
443 $res = $this->repo->getReplicaDB()->newSelectQueryBuilder()
445 ->from(
'uploadstash' )
446 ->where( [
'us_user' => $this->user->getId() ] )
447 ->caller( __METHOD__ )->fetchResultSet();
449 if ( !is_object( $res ) || $res->numRows() == 0 ) {
456 foreach ( $res as $row ) {
457 $keys[] = $row->us_key;
473 $prohibitedFileExtensions = MediaWikiServices::getInstance()
474 ->getMainConfig()->get( MainConfigNames::ProhibitedFileExtensions );
476 $n = strrpos(
$path,
'.' );
478 if ( $n !==
false ) {
479 $extension = $n ? substr(
$path, $n + 1 ) :
'';
482 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
483 $mimeType = $magic->guessMimeType(
$path );
484 $extension = $magic->getExtensionFromMimeTypeOrNull( $mimeType ) ??
'';
487 $extension = File::normalizeExtension( $extension );
488 if ( in_array( $extension, $prohibitedFileExtensions ) ) {
510 $dbr = $this->repo->getPrimaryDB();
512 $dbr = $this->repo->getReplicaDB();
515 $row = $dbr->newSelectQueryBuilder()
517 'us_user',
'us_key',
'us_orig_path',
'us_path',
'us_props',
518 'us_size',
'us_sha1',
'us_mime',
'us_media_type',
519 'us_image_width',
'us_image_height',
'us_image_bits',
520 'us_source_type',
'us_timestamp',
'us_status',
522 ->from(
'uploadstash' )
523 ->where( [
'us_key' => $key ] )
524 ->caller( __METHOD__ )->fetchRow();
526 if ( !is_object( $row ) ) {
531 $this->fileMetadata[$key] = (array)$row;
532 $this->fileMetadata[$key][
'us_props'] = $dbr->decodeBlob( $row->us_props );
546 if (
$file->getSize() === 0 ) {
551 $this->files[$key] =
$file;
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
getFile()
Get the file for this page, if one exists.
Base class for file repositories.
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
MimeMagic helper wrapper.
A class containing constants representing the names of configuration variables.
UploadStash is intended to accomplish a few things:
static getExtensionForPath( $path)
Find or guess extension – ensuring that our extension matches our MIME type.
removeFile( $key)
Remove a particular file from the stash.
fetchFileMetadata( $key, $readFromDB=DB_REPLICA)
Helper function: do the actual database query to fetch file metadata.
getFileProps( $key)
Getter for fileProps.
stashFile( $path, $sourceType=null)
Stash a file in a temp directory and record that we did this in the database, along with other metada...
clear()
Remove all files from the stash.
array $fileMetadata
cache of the file metadata that's stored in the database
array $fileProps
fileprops cache
listFiles()
List all files in the stash.
__construct(FileRepo $repo, UserIdentity $user=null)
Represents a temporary filestore, with metadata in the database.
getMetadata( $key)
Getter for file metadata.
removeFileNoAuth( $key)
Remove a file (see removeFile), but doesn't check ownership first.
initFile( $key)
Helper function: Initialize the UploadStashFile for a given file.
getFile( $key, $noAuth=false)
Get a file and its metadata from the stash.
LocalRepo $repo
repository that this uses to store temp files public because we sometimes need to get a LocalFile wit...
array $files
array of initialized repo objects
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.