Tidy up the class
[mediawiki.git] / includes / upload / UploadFromUrl.php
blob763dae38d1ca6e769c51f094801d59c6bf373a93
1 <?php
2 /**
3 * @file
4 * @ingroup upload
6 * Implements uploading from a HTTP resource.
8 * @author Bryan Tong Minh
9 * @author Michael Dale
11 class UploadFromUrl extends UploadBase {
12 protected $mTempDownloadPath;
14 /**
15 * Checks if the user is allowed to use the upload-by-URL feature. If the
16 * user is allowed, pass on permissions checking to the parent.
18 public static function isAllowed( $user ) {
19 if( !$user->isAllowed( 'upload_by_url' ) )
20 return 'upload_by_url';
21 return parent::isAllowed( $user );
24 /**
25 * Checks if the upload from URL feature is enabled
27 public static function isEnabled() {
28 global $wgAllowCopyUploads;
29 return $wgAllowCopyUploads && parent::isEnabled();
32 /**
33 * Entry point for API upload
35 public function initialize( $name, $url, $na, $nb = false ) {
36 global $wgTmpDirectory;
38 $localFile = tempnam( $wgTmpDirectory, 'WEBUPLOAD' );
39 $this->initializePathInfo( $name, $localFile, 0, true );
41 $this->mUrl = trim( $url );
44 /**
45 * Entry point for SpecialUpload
46 * @param $request Object: WebRequest object
48 public function initializeFromRequest( &$request ) {
49 $desiredDestName = $request->getText( 'wpDestFile' );
50 if( !$desiredDestName )
51 $desiredDestName = $request->getText( 'wpUploadFileURL' );
52 return $this->initialize(
53 $desiredDestName,
54 $request->getVal( 'wpUploadFileURL' ),
55 false
59 /**
60 * @param $request Object: WebRequest object
62 public static function isValidRequest( $request ){
63 if( !$request->getVal( 'wpUploadFileURL' ) )
64 return false;
65 // check that is a valid url:
66 return self::isValidUrl( $request->getVal( 'wpUploadFileURL' ) );
69 public static function isValidUrl( $url ) {
70 // Only allow HTTP or FTP for now
71 return (bool)preg_match( '!^(http://|ftp://)!', $url );
74 /**
75 * Do the real fetching stuff
77 function fetchFile() {
78 if( !self::isValidUrl( $this->mUrl ) ) {
79 return Status::newFatal( 'upload-proto-error' );
81 $res = $this->curlCopy();
82 if( $res !== true ) {
83 return Status::newFatal( $res );
85 return Status::newGood();
88 /**
89 * Safe copy from URL
90 * Returns true if there was an error, false otherwise
92 private function curlCopy() {
93 global $wgOut;
95 # Open temporary file
96 $this->mCurlDestHandle = @fopen( $this->mTempPath, "wb" );
97 if( $this->mCurlDestHandle === false ) {
98 # Could not open temporary file to write in
99 return 'upload-file-error';
102 $ch = curl_init();
103 curl_setopt( $ch, CURLOPT_HTTP_VERSION, 1.0); # Probably not needed, but apparently can work around some bug
104 curl_setopt( $ch, CURLOPT_TIMEOUT, 10); # 10 seconds timeout
105 curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 512); # 0.5KB per second minimum transfer speed
106 curl_setopt( $ch, CURLOPT_URL, $this->mUrl);
107 curl_setopt( $ch, CURLOPT_WRITEFUNCTION, array( $this, 'uploadCurlCallback' ) );
108 curl_exec( $ch );
109 $error = curl_errno( $ch );
110 curl_close( $ch );
112 fclose( $this->mCurlDestHandle );
113 unset( $this->mCurlDestHandle );
115 if( $error )
116 return "upload-curl-error$errornum";
118 return true;
122 * Callback function for CURL-based web transfer
123 * Write data to file unless we've passed the length limit;
124 * if so, abort immediately.
125 * @access private
127 function uploadCurlCallback( $ch, $data ) {
128 global $wgMaxUploadSize;
129 $length = strlen( $data );
130 $this->mFileSize += $length;
131 if( $this->mFileSize > $wgMaxUploadSize ) {
132 return 0;
134 fwrite( $this->mCurlDestHandle, $data );
135 return $length;