MediaWiki master
UploadDef.php
Go to the documentation of this file.
1<?php
2
4
5use InvalidArgumentException;
6use Psr\Http\Message\UploadedFileInterface;
7use UnexpectedValueException;
12
34class UploadDef extends TypeDef {
35
36 public function getValue( $name, array $settings, array $options ) {
37 $ret = $this->callbacks->getUploadedFile( $name, $options );
38
39 if ( $ret && $ret->getError() === UPLOAD_ERR_NO_FILE &&
40 !$this->callbacks->hasParam( $name, $options )
41 ) {
42 // This seems to be that the client explicitly specified "no file" for the field
43 // instead of just omitting the field completely. DWTM.
44 $ret = null;
45 } elseif ( !$ret && $this->callbacks->hasParam( $name, $options ) ) {
46 // The client didn't format their upload properly so it came in as an ordinary
47 // field. Convert it to an error.
48 $ret = new UploadedFile( [
49 'name' => '',
50 'type' => '',
51 'tmp_name' => '',
52 'error' => -42, // PHP's UPLOAD_ERR_* are all positive numbers.
53 'size' => 0,
54 ] );
55 }
56
57 return $ret;
58 }
59
69 protected function getIniSize() {
70 return ini_get( 'upload_max_filesize' );
71 }
72
73 public function validate( $name, $value, array $settings, array $options ) {
74 static $codemap = [
75 -42 => 'notupload', // Local from getValue()
76 UPLOAD_ERR_FORM_SIZE => 'formsize',
77 UPLOAD_ERR_PARTIAL => 'partial',
78 UPLOAD_ERR_NO_FILE => 'nofile',
79 UPLOAD_ERR_NO_TMP_DIR => 'notmpdir',
80 UPLOAD_ERR_CANT_WRITE => 'cantwrite',
81 UPLOAD_ERR_EXTENSION => 'phpext',
82 ];
83
84 if ( !$value instanceof UploadedFileInterface ) {
85 // Err?
86 $type = is_object( $value ) ? get_class( $value ) : gettype( $value );
87 throw new InvalidArgumentException( "\$value must be UploadedFileInterface, got $type" );
88 }
89
90 $err = $value->getError();
91 if ( $err === UPLOAD_ERR_OK ) {
92 return $value;
93 } elseif ( $err === UPLOAD_ERR_INI_SIZE ) {
94 static $prefixes = [
95 'g' => 1024 ** 3,
96 'm' => 1024 ** 2,
97 'k' => 1024 ** 1,
98 ];
99 $size = $this->getIniSize();
100 $last = strtolower( substr( $size, -1 ) );
101 $size = intval( $size, 10 ) * ( $prefixes[$last] ?? 1 );
102 $this->failure(
103 $this->failureMessage( 'badupload', [
104 'code' => 'inisize',
105 'size' => $size,
106 ], 'inisize' )->sizeParams( $size ),
107 $name, '', $settings, $options
108 );
109 } elseif ( isset( $codemap[$err] ) ) {
110 $this->failure(
111 $this->failureMessage( 'badupload', [ 'code' => $codemap[$err] ], $codemap[$err] ),
112 $name, '', $settings, $options
113 );
114 } else {
115 $constant = '';
116 foreach ( get_defined_constants() as $c => $v ) {
117 // @phan-suppress-next-line PhanTypeComparisonFromArray
118 if ( $v === $err && str_starts_with( $c, 'UPLOAD_ERR_' ) ) {
119 $constant = " ($c?)";
120 }
121 }
122 throw new UnexpectedValueException( "Unrecognized PHP upload error value $err$constant" );
123 }
124 }
125
126 public function checkSettings( string $name, $settings, array $options, array $ret ): array {
127 $ret = parent::checkSettings( $name, $settings, $options, $ret );
128
129 if ( isset( $settings[ParamValidator::PARAM_DEFAULT] ) ) {
130 $ret['issues'][ParamValidator::PARAM_DEFAULT] =
131 'Cannot specify a default for upload-type parameters';
132 }
133
134 if ( !empty( $settings[ParamValidator::PARAM_ISMULTI] ) &&
135 !isset( $ret['issues'][ParamValidator::PARAM_ISMULTI] )
136 ) {
137 $ret['issues'][ParamValidator::PARAM_ISMULTI] =
138 'PARAM_ISMULTI cannot be used for upload-type parameters';
139 }
140
141 return $ret;
142 }
143
144 public function stringifyValue( $name, $value, array $settings, array $options ) {
145 // Not going to happen.
146 return null;
147 }
148
149 public function getHelpInfo( $name, array $settings, array $options ) {
150 $info = parent::getHelpInfo( $name, $settings, $options );
151
152 $info[ParamValidator::PARAM_TYPE] = MessageValue::new( 'paramvalidator-help-type-upload' );
153
154 return $info;
155 }
156
157}
Value object representing a message for i18n.
Service for formatting and validating API parameters.
const PARAM_ISMULTI
(bool) Indicate that the parameter is multi-valued.
const PARAM_DEFAULT
(mixed) Default value of the parameter.
const PARAM_TYPE
(string|array) Type of the parameter.
Type definition for upload types.
Definition UploadDef.php:34
checkSettings(string $name, $settings, array $options, array $ret)
Validate a parameter settings array.
getHelpInfo( $name, array $settings, array $options)
Describe parameter settings in human-readable format.
getIniSize()
Fetch the value of PHP's upload_max_filesize ini setting.
Definition UploadDef.php:69
stringifyValue( $name, $value, array $settings, array $options)
Convert a value to a string representation.
getValue( $name, array $settings, array $options)
Get the value from the request.
Definition UploadDef.php:36
validate( $name, $value, array $settings, array $options)
Validate the value.
Definition UploadDef.php:73
Base definition for ParamValidator types.
Definition TypeDef.php:19
failureMessage( $code, array $data=null, $suffix=null)
Create a DataMessageValue representing a failure.
Definition TypeDef.php:96
failure( $failure, $name, $value, array $settings, array $options, $fatal=true)
Record a failure message.
Definition TypeDef.php:61
A simple implementation of UploadedFileInterface.