diff --git a/actions/apimediaupload.php b/actions/apimediaupload.php index 6f8781fab5..2d81af157e 100644 --- a/actions/apimediaupload.php +++ b/actions/apimediaupload.php @@ -26,9 +26,7 @@ * @link http://status.net/ */ -if (!defined('STATUSNET')) { - exit(1); -} +if (!defined('GNUSOCIAL')) { exit(1); } /** * Upload an image via the API. Returns a shortened URL for the image @@ -42,6 +40,8 @@ if (!defined('STATUSNET')) { */ class ApiMediaUploadAction extends ApiAuthAction { + protected $needPost = true; + /** * Handle the request * @@ -53,17 +53,9 @@ class ApiMediaUploadAction extends ApiAuthAction * * @return void */ - function handle($args) + protected function handle() { - parent::handle($args); - - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - $this->clientError( - // TRANS: Client error. POST is a HTTP command. It should not be translated. - _('This method requires a POST.'), - 400, $this->format - ); - } + parent::handle(); // Workaround for PHP returning empty $_POST and $_FILES when POST // length > post_max_size in php.ini @@ -80,31 +72,21 @@ class ApiMediaUploadAction extends ApiAuthAction $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); } - $upload = null; + // we could catch "NoUploadedMediaException" as "no media uploaded", but here we _always_ want an upload + $upload = MediaFile::fromUpload('media', $this->auth_user->getProfile()); - try { - $upload = MediaFile::fromUpload('media', $this->auth_user->getProfile()); - } catch (Exception $e) { - $this->clientError($e->getMessage(), $e->getCode()); - } - - if (isset($upload)) { - $this->showResponse($upload); - } else { - // TRANS: Client error displayed when uploading a media file has failed. - $this->clientError(_('Upload failed.')); - } + $this->showResponse($upload); } /** * Show a Twitpic-like response with the ID of the media file * and a (hopefully) shortened URL for it. * - * @param File $upload the uploaded file + * @param MediaFile $upload the uploaded file * * @return void */ - function showResponse($upload) + function showResponse(MediaFile $upload) { $this->initDocument(); $this->elementStart('rsp', array('stat' => 'ok')); diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php index d5fc7c9945..6b876c8f11 100644 --- a/actions/apistatusesupdate.php +++ b/actions/apistatusesupdate.php @@ -245,24 +245,19 @@ class ApiStatusesUpdateAction extends ApiAuthAction } $upload = null; - try { $upload = MediaFile::fromUpload('media', $this->scoped); - } catch (Exception $e) { - $this->clientError($e->getMessage(), $e->getCode()); - } - - if ($upload instanceof MediaFile) { $this->status .= ' ' . $upload->shortUrl(); - /* Do not call shortenlinks until the whole notice has been build */ + } catch (NoUploadedMediaException $e) { + // There was no uploaded media for us today. } /* Do call shortenlinks here & check notice length since notice is about to be saved & sent */ $status_shortened = $this->auth_user->shortenlinks($this->status); if (Notice::contentTooLong($status_shortened)) { - if (isset($upload)) { + if ($upload instanceof MediaFile) { $upload->delete(); } // TRANS: Client error displayed exceeding the maximum notice length. diff --git a/actions/newnotice.php b/actions/newnotice.php index ca770f38b6..d1e47fec5c 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -129,10 +129,10 @@ class NewnoticeAction extends FormAction $options['reply_to'] = $replyto; } - $upload = MediaFile::fromUpload('attach', $this->scoped); - - if (isset($upload)) { - + $upload = null; + try { + // throws exception on failure + $upload = MediaFile::fromUpload('attach', $this->scoped); if (Event::handle('StartSaveNewNoticeAppendAttachment', array($this, $upload, &$content_shortened, &$options))) { $content_shortened .= ' ' . $upload->shortUrl(); } @@ -147,8 +147,11 @@ class NewnoticeAction extends FormAction Notice::maxContent()), Notice::maxContent())); } + } catch (NoUploadedMediaException $e) { + // simply no attached media to the new notice } + if ($this->scoped->shareLocation()) { // use browser data if checked; otherwise profile data if ($this->arg('notice_data-geo')) { @@ -179,7 +182,7 @@ class NewnoticeAction extends FormAction $this->stored = Notice::saveNew($this->scoped->id, $content_shortened, 'web', $options); - if (isset($upload)) { + if ($upload instanceof MediaFile) { $upload->attachToNotice($this->stored); } diff --git a/lib/mediafile.php b/lib/mediafile.php index 92a069facf..4ac33ab7e1 100644 --- a/lib/mediafile.php +++ b/lib/mediafile.php @@ -147,14 +147,15 @@ class MediaFile } } - static function fromUpload($param = 'media', Profile $scoped) + static function fromUpload($param='media', Profile $scoped=null) { if (is_null($scoped)) { $scoped = Profile::current(); } - if (!isset($_FILES[$param]['error'])){ - return; + // The existence of the "error" element means PHP has processed it properly even if it was ok. + if (!isset($_FILES[$param]) || !isset($_FILES[$param]['error'])) { + throw new NoUploadedMediaException($param); } switch ($_FILES[$param]['error']) { diff --git a/lib/nouploadedmediaexception.php b/lib/nouploadedmediaexception.php new file mode 100644 index 0000000000..fb52db70cc --- /dev/null +++ b/lib/nouploadedmediaexception.php @@ -0,0 +1,31 @@ + + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 + * @link http://gnu.io/ + */ + +class NoUploadedMediaException extends ClientException +{ + public $fieldname = null; + + public function __construct($fieldname, $msg=null) + { + $this->fieldname = $fieldname; + + if ($msg === null) { + // TRANS: Exception text shown when no uploaded media was provided in POST + // TRANS: %s is the HTML input field name. + $msg = sprintf(_('There is no uploaded media for input field "%s".'), $this->fieldname); + } + + parent::__construct($msg, 400); + } +}