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:
32 class UploadDef
extends TypeDef
{
34 public function getValue( $name, array $settings, array $options ) {
35 $ret = $this->callbacks
->getUploadedFile( $name, $options );
37 if ( $ret && $ret->getError() === UPLOAD_ERR_NO_FILE
&&
38 !$this->callbacks
->hasParam( $name, $options )
40 // This seems to be that the client explicitly specified "no file" for the field
41 // instead of just omitting the field completely. DWTM.
43 } elseif ( !$ret && $this->callbacks
->hasParam( $name, $options ) ) {
44 // The client didn't format their upload properly so it came in as an ordinary
45 // field. Convert it to an error.
46 $ret = new UploadedFile( [
50 'error' => -42, // PHP's UPLOAD_ERR_* are all positive numbers.
59 * Fetch the value of PHP's upload_max_filesize ini setting
61 * This method exists so it can be mocked by unit tests that can't
62 * affect ini_get() directly.
65 * @return string|false
67 protected function getIniSize() {
68 return ini_get( 'upload_max_filesize' );
71 public function validate( $name, $value, array $settings, array $options ) {
73 -42 => 'notupload', // Local from getValue()
74 UPLOAD_ERR_FORM_SIZE
=> 'formsize',
75 UPLOAD_ERR_PARTIAL
=> 'partial',
76 UPLOAD_ERR_NO_FILE
=> 'nofile',
77 UPLOAD_ERR_NO_TMP_DIR
=> 'notmpdir',
78 UPLOAD_ERR_CANT_WRITE
=> 'cantwrite',
79 UPLOAD_ERR_EXTENSION
=> 'phpext',
82 if ( !$value instanceof UploadedFileInterface
) {
84 throw new ValidationException( $name, $value, $settings, 'badupload', [] );
87 $err = $value->getError();
88 if ( $err === UPLOAD_ERR_OK
) {
90 } elseif ( $err === UPLOAD_ERR_INI_SIZE
) {
96 $size = $this->getIniSize();
97 $last = strtolower( substr( $size, -1 ) );
98 $size = intval( $size, 10 ) * ( $prefixes[$last] ??
1 );
99 throw new ValidationException( $name, $value, $settings, 'badupload-inisize', [
102 } elseif ( isset( $codemap[$err] ) ) {
103 throw new ValidationException( $name, $value, $settings, 'badupload-' . $codemap[$err], [] );
105 throw new ValidationException( $name, $value, $settings, 'badupload-unknown', [
111 public function stringifyValue( $name, $value, array $settings, array $options ) {
112 // Not going to happen.