mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-27 12:33:09 +08:00
Added client-side image validation
This commit is contained in:
@@ -69,25 +69,27 @@ yii.validation = (function ($) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
file: function (value, messages, options, attribute) {
|
globalFiles: function(files, messages, options) {
|
||||||
var files = $(attribute.input).get(0).files,
|
|
||||||
index, ext;
|
|
||||||
|
|
||||||
if (options.message && !files) {
|
if (options.message && !files) {
|
||||||
pub.addMessage(messages, options.message, value);
|
pub.addMessage(messages, options.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.skipOnEmpty && files.length == 0) {
|
if (!options.skipOnEmpty && files.length === 0) {
|
||||||
pub.addMessage(messages, options.uploadRequired, value);
|
pub.addMessage(messages, options.uploadRequired);
|
||||||
} else if (files.length == 0) {
|
} else if (files.length === 0) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.maxFiles && options.maxFiles < files.length) {
|
if (options.maxFiles && options.maxFiles < files.length) {
|
||||||
pub.addMessage(messages, options.tooMany);
|
pub.addMessage(messages, options.tooMany);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.each(files, function (i, file) {
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
singleFile: function(file, messages, options) {
|
||||||
|
var index, ext;
|
||||||
|
|
||||||
if (options.extensions && options.extensions.length > 0) {
|
if (options.extensions && options.extensions.length > 0) {
|
||||||
index = file.name.lastIndexOf('.');
|
index = file.name.lastIndexOf('.');
|
||||||
|
|
||||||
@@ -98,27 +100,101 @@ yii.validation = (function ($) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!~options.extensions.indexOf(ext)) {
|
if (!~options.extensions.indexOf(ext)) {
|
||||||
messages.push(options.wrongExtension.replace(/\{file\}/g, file.name));
|
pub.addMessage(messages, options.wrongExtension.replace(/\{file\}/g, file.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.mimeTypes && options.mimeTypes.length > 0) {
|
if (options.mimeTypes && options.mimeTypes.length > 0) {
|
||||||
if (!~options.mimeTypes.indexOf(file.type)) {
|
if (!~options.mimeTypes.indexOf(file.type)) {
|
||||||
messages.push(options.wrongMimeType.replace(/\{file\}/g, file.name));
|
pub.addMessage(messages, options.wrongMimeType.replace(/\{file\}/g, file.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.maxSize && options.maxSize < file.size) {
|
if (options.maxSize && options.maxSize < file.size) {
|
||||||
messages.push(options.tooBig.replace(/\{file\}/g, file.name));
|
pub.addMessage(messages, options.tooBig.replace(/\{file\}/g, file.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.maxSize && options.minSize > file.size) {
|
if (options.maxSize && options.minSize > file.size) {
|
||||||
messages.push(options.tooSmall.replace(/\{file\}/g, file.name));
|
pub.addMessage(messages, options.tooSmall.replace(/\{file\}/g, file.name));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
file: function (messages, options, attribute) {
|
||||||
|
var files = $(attribute.input).get(0).files,
|
||||||
|
self = this;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( !self.globalFiles(files, messages, options) ) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$.each(files, function (i, file) {
|
||||||
|
self.singleFile(file, messages, options);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
image: function (messages, options, deferred, attribute) {
|
||||||
|
var files = $(attribute.input).get(0).files,
|
||||||
|
self = this;
|
||||||
|
|
||||||
|
if ( !self.globalFiles(files, messages, options) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(files, function (i, file) {
|
||||||
|
// Perform file validation
|
||||||
|
self.singleFile(file, messages, options);
|
||||||
|
|
||||||
|
// Skip image validation if FileReader API is not available
|
||||||
|
if (typeof FileReader === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var def = $.Deferred(),
|
||||||
|
fr = new FileReader(),
|
||||||
|
img = new Image();
|
||||||
|
|
||||||
|
img.onload = function () {
|
||||||
|
if (options.minWidth && this.width < options.minWidth) {
|
||||||
|
pub.addMessage(messages, options.underWidth.replace(/\{file\}/g, file.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.maxWidth && this.width > options.maxWidth) {
|
||||||
|
pub.addMessage(messages, options.overWidth.replace(/\{file\}/g, file.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.minHeight && this.height < options.minHeight) {
|
||||||
|
pub.addMessage(messages, options.underHeight.replace(/\{file\}/g, file.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.maxHeight && this.height > options.maxHeight) {
|
||||||
|
pub.addMessage(messages, options.overHeight.replace(/\{file\}/g, file.name));
|
||||||
|
}
|
||||||
|
def.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
img.onerror = function () {
|
||||||
|
pub.addMessage(messages, options.notImage);
|
||||||
|
def.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
fr.onload = function () {
|
||||||
|
img.src = fr.result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resolve deferred if there was error while reading data
|
||||||
|
fr.onerror = function () {
|
||||||
|
def.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
fr.readAsDataURL(file);
|
||||||
|
|
||||||
|
deferred.push(def);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
number: function (value, messages, options) {
|
number: function (value, messages, options) {
|
||||||
if (options.skipOnEmpty && pub.isEmpty(value)) {
|
if (options.skipOnEmpty && pub.isEmpty(value)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ class FileValidator extends Validator
|
|||||||
*/
|
*/
|
||||||
public $wrongMimeType;
|
public $wrongMimeType;
|
||||||
|
|
||||||
|
protected $_clientOptions;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
@@ -342,12 +344,15 @@ class FileValidator extends Validator
|
|||||||
$options['skipOnEmpty'] = $this->skipOnEmpty;
|
$options['skipOnEmpty'] = $this->skipOnEmpty;
|
||||||
|
|
||||||
if ( !$this->skipOnEmpty ) {
|
if ( !$this->skipOnEmpty ) {
|
||||||
$options['uploadRequired'] = Yii::$app->getI18n()->format($this->uploadRequired, [], Yii::$app->language);
|
$options['uploadRequired'] = Yii::$app->getI18n()->format($this->uploadRequired, [
|
||||||
|
'attribute' => $label,
|
||||||
|
], Yii::$app->language);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->mimeTypes !== null ) {
|
if ( $this->mimeTypes !== null ) {
|
||||||
$options['mimeTypes'] = $this->mimeTypes;
|
$options['mimeTypes'] = $this->mimeTypes;
|
||||||
$options['wrongMimeType'] = Yii::$app->getI18n()->format($this->wrongMimeType, [
|
$options['wrongMimeType'] = Yii::$app->getI18n()->format($this->wrongMimeType, [
|
||||||
|
'attribute' => $label,
|
||||||
'mimeTypes' => join(', ', $this->mimeTypes)
|
'mimeTypes' => join(', ', $this->mimeTypes)
|
||||||
], Yii::$app->language);
|
], Yii::$app->language);
|
||||||
}
|
}
|
||||||
@@ -355,6 +360,7 @@ class FileValidator extends Validator
|
|||||||
if ( $this->extensions !== null ) {
|
if ( $this->extensions !== null ) {
|
||||||
$options['extensions'] = $this->extensions;
|
$options['extensions'] = $this->extensions;
|
||||||
$options['wrongExtension'] = Yii::$app->getI18n()->format($this->wrongExtension, [
|
$options['wrongExtension'] = Yii::$app->getI18n()->format($this->wrongExtension, [
|
||||||
|
'attribute' => $label,
|
||||||
'extensions' => join(', ', $this->extensions)
|
'extensions' => join(', ', $this->extensions)
|
||||||
], Yii::$app->language);
|
], Yii::$app->language);
|
||||||
}
|
}
|
||||||
@@ -362,6 +368,7 @@ class FileValidator extends Validator
|
|||||||
if ( $this->minSize !== null ) {
|
if ( $this->minSize !== null ) {
|
||||||
$options['minSize'] = $this->minSize;
|
$options['minSize'] = $this->minSize;
|
||||||
$options['tooSmall'] = Yii::$app->getI18n()->format($this->tooSmall, [
|
$options['tooSmall'] = Yii::$app->getI18n()->format($this->tooSmall, [
|
||||||
|
'attribute' => $label,
|
||||||
'limit' => $this->minSize
|
'limit' => $this->minSize
|
||||||
], Yii::$app->language);
|
], Yii::$app->language);
|
||||||
}
|
}
|
||||||
@@ -369,6 +376,7 @@ class FileValidator extends Validator
|
|||||||
if ( $this->maxSize !== null ) {
|
if ( $this->maxSize !== null ) {
|
||||||
$options['maxSize'] = $this->maxSize;
|
$options['maxSize'] = $this->maxSize;
|
||||||
$options['tooBig'] = Yii::$app->getI18n()->format($this->tooBig, [
|
$options['tooBig'] = Yii::$app->getI18n()->format($this->tooBig, [
|
||||||
|
'attribute' => $label,
|
||||||
'limit' => $this->maxSize
|
'limit' => $this->maxSize
|
||||||
], Yii::$app->language);
|
], Yii::$app->language);
|
||||||
}
|
}
|
||||||
@@ -376,12 +384,16 @@ class FileValidator extends Validator
|
|||||||
if ( $this->maxFiles !== null ) {
|
if ( $this->maxFiles !== null ) {
|
||||||
$options['maxFiles'] = $this->maxFiles;
|
$options['maxFiles'] = $this->maxFiles;
|
||||||
$options['tooMany'] = Yii::$app->getI18n()->format($this->tooMany, [
|
$options['tooMany'] = Yii::$app->getI18n()->format($this->tooMany, [
|
||||||
|
'attribute' => $label,
|
||||||
'limit' => $this->maxFiles
|
'limit' => $this->maxFiles
|
||||||
], Yii::$app->language);
|
], Yii::$app->language);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidationAsset::register($view);
|
ValidationAsset::register($view);
|
||||||
|
|
||||||
return 'yii.validation.file(value, messages, ' . json_encode($options) . ', attribute);';
|
// Store options for ImageValidator
|
||||||
|
$this->_clientOptions = $options;
|
||||||
|
|
||||||
|
return 'yii.validation.file(messages, ' . json_encode($options) . ', attribute);';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,4 +158,57 @@ class ImageValidator extends FileValidator
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function clientValidateAttribute($object, $attribute, $view)
|
||||||
|
{
|
||||||
|
parent::clientValidateAttribute($object, $attribute, $view);
|
||||||
|
|
||||||
|
$label = $object->getAttributeLabel($attribute);
|
||||||
|
|
||||||
|
// Inherit options from FileValidator
|
||||||
|
$options = $this->_clientOptions;
|
||||||
|
|
||||||
|
if ( $this->notImage !== null ) {
|
||||||
|
$options['notImage'] = Yii::$app->getI18n()->format($this->notImage, [
|
||||||
|
'attribute' => $label
|
||||||
|
], Yii::$app->language);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->minWidth !== null ) {
|
||||||
|
$options['minWidth'] = $this->minWidth;
|
||||||
|
$options['underWidth'] = Yii::$app->getI18n()->format($this->underWidth, [
|
||||||
|
'attribute' => $label,
|
||||||
|
'limit' => $this->minWidth
|
||||||
|
], Yii::$app->language);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->maxWidth !== null ) {
|
||||||
|
$options['maxWidth'] = $this->maxWidth;
|
||||||
|
$options['overWidth'] = Yii::$app->getI18n()->format($this->overWidth, [
|
||||||
|
'attribute' => $label,
|
||||||
|
'limit' => $this->maxWidth
|
||||||
|
], Yii::$app->language);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->minHeight !== null ) {
|
||||||
|
$options['minHeight'] = $this->minHeight;
|
||||||
|
$options['underHeight'] = Yii::$app->getI18n()->format($this->underHeight, [
|
||||||
|
'attribute' => $label,
|
||||||
|
'limit' => $this->maxHeight
|
||||||
|
], Yii::$app->language);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->maxHeight !== null ) {
|
||||||
|
$options['maxHeight'] = $this->maxHeight;
|
||||||
|
$options['overHeight'] = Yii::$app->getI18n()->format($this->overHeight, [
|
||||||
|
'attribute' => $label,
|
||||||
|
'limit' => $this->maxHeight
|
||||||
|
], Yii::$app->language);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'yii.validation.image(messages, ' . json_encode($options) . ', deferred, attribute);';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user