3 namespace Wikimedia\ParamValidator\TypeDef
;
5 use Psr\Http\Message\UploadedFileInterface
;
6 use Wikimedia\ParamValidator\TypeDef
;
7 use Wikimedia\ParamValidator\Util\UploadedFile
;
8 use Wikimedia\ParamValidator\ValidationException
;
11 * Type definition for upload types
13 * The result from validate() is an object implementing UploadedFileInterface.
15 * ValidationException codes:
16 * - 'badupload': The upload is not valid. No data.
17 * - 'badupload-inisize': The upload exceeded the maximum in php.ini. Data:
18 * - 'size': The configured size (in bytes).
19 * - 'badupload-formsize': The upload exceeded the maximum in the form post. No data.
20 * - 'badupload-partial': The file was only partially uploaded. No data.
21 * - 'badupload-nofile': There was no file. No data.
22 * - 'badupload-notmpdir': PHP has no temporary directory to store the upload. No data.
23 * - 'badupload-cantwrite': PHP could not store the upload. No data.
24 * - 'badupload-phpext': A PHP extension rejected the upload. No data.
25 * - 'badupload-notupload': The field was present in the submission but was not encoded as
27 * - 'badupload-unknown': Some unknown PHP upload error code. Data:
33 class UploadDef
extends TypeDef
{
35 public function getValue( $name, array $settings, array $options ) {
36 $ret = $this->callbacks
->getUploadedFile( $name, $options );
38 if ( $ret && $ret->getError() === UPLOAD_ERR_NO_FILE
&&
39 !$this->callbacks
->hasParam( $name, $options )
41 // This seems to be that the client explicitly specified "no file" for the field
42 // instead of just omitting the field completely. DWTM.
44 } elseif ( !$ret && $this->callbacks
->hasParam( $name, $options ) ) {
45 // The client didn't format their upload properly so it came in as an ordinary
46 // field. Convert it to an error.
47 $ret = new UploadedFile( [
51 'error' => -42, // PHP's UPLOAD_ERR_* are all positive numbers.
60 * Fetch the value of PHP's upload_max_filesize ini setting
62 * This method exists so it can be mocked by unit tests that can't
63 * affect ini_get() directly.
66 * @return string|false
68 protected function getIniSize() {
69 return ini_get( 'upload_max_filesize' );
72 public function validate( $name, $value, array $settings, array $options ) {
74 -42 => 'notupload', // Local from getValue()
75 UPLOAD_ERR_FORM_SIZE
=> 'formsize',
76 UPLOAD_ERR_PARTIAL
=> 'partial',
77 UPLOAD_ERR_NO_FILE
=> 'nofile',
78 UPLOAD_ERR_NO_TMP_DIR
=> 'notmpdir',
79 UPLOAD_ERR_CANT_WRITE
=> 'cantwrite',
80 UPLOAD_ERR_EXTENSION
=> 'phpext',
83 if ( !$value instanceof UploadedFileInterface
) {
85 throw new ValidationException( $name, $value, $settings, 'badupload', [] );
88 $err = $value->getError();
89 if ( $err === UPLOAD_ERR_OK
) {
91 } elseif ( $err === UPLOAD_ERR_INI_SIZE
) {
97 $size = $this->getIniSize();
98 $last = strtolower( substr( $size, -1 ) );
99 $size = intval( $size, 10 ) * ( $prefixes[$last] ??
1 );
100 throw new ValidationException( $name, $value, $settings, 'badupload-inisize', [
103 } elseif ( isset( $codemap[$err] ) ) {
104 throw new ValidationException( $name, $value, $settings, 'badupload-' . $codemap[$err], [] );
106 throw new ValidationException( $name, $value, $settings, 'badupload-unknown', [
112 public function stringifyValue( $name, $value, array $settings, array $options ) {
113 // Not going to happen.