mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-16 22:39:52 +08:00
Merge branch 'master' of https://github.com/yiisoft/yii2
This commit is contained in:
@@ -26,7 +26,7 @@ return array(
|
||||
'js' => array(
|
||||
'yii.activeForm.js',
|
||||
),
|
||||
'depends' => array('yii', 'yii/validation'),
|
||||
'depends' => array('yii'),
|
||||
),
|
||||
'yii/captcha' => array(
|
||||
'sourcePath' => __DIR__ . '/assets',
|
||||
@@ -42,4 +42,10 @@ return array(
|
||||
),
|
||||
'depends' => array('yii'),
|
||||
),
|
||||
'punycode' => array(
|
||||
'sourcePath' => __DIR__ . '/vendor/bestiejs/punycode.js',
|
||||
'js' => array(
|
||||
'punycode.min.js',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -110,9 +110,19 @@ yii.validation = (function ($) {
|
||||
return;
|
||||
}
|
||||
|
||||
var valid = value.match(options.pattern) && (!options.allowName || value.match(options.fullPattern));
|
||||
var valid = true;
|
||||
|
||||
if (!valid) {
|
||||
if (options.enableIDN) {
|
||||
var regexp = /^(.*)@(.*)$/,
|
||||
matches = regexp.exec(value);
|
||||
if (matches === null) {
|
||||
valid = false;
|
||||
} else {
|
||||
value = punycode.toASCII(matches[1]) + '@' + punycode.toASCII(matches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid || !(value.match(options.pattern) && (!options.allowName || value.match(options.fullPattern)))) {
|
||||
messages.push(options.message);
|
||||
}
|
||||
},
|
||||
@@ -126,7 +136,19 @@ yii.validation = (function ($) {
|
||||
value = options.defaultScheme + '://' + value;
|
||||
}
|
||||
|
||||
if (!value.match(options.pattern)) {
|
||||
var valid = true;
|
||||
|
||||
if (options.enableIDN) {
|
||||
var regexp = /^([^:]+):\/\/([^\/]+)(.*)$/,
|
||||
matches = regexp.exec(value);
|
||||
if (matches === null) {
|
||||
valid = false;
|
||||
} else {
|
||||
value = matches[1] + '://' + punycode.toASCII(matches[2]) + matches[3];
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid || !value.match(options.pattern)) {
|
||||
messages.push(options.message);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -75,8 +75,11 @@ class ErrorHandler extends Component
|
||||
\Yii::$app->runAction($this->errorAction);
|
||||
} elseif (\Yii::$app instanceof \yii\web\Application) {
|
||||
if (!headers_sent()) {
|
||||
$errorCode = $exception instanceof HttpException ? $exception->statusCode : 500;
|
||||
header("HTTP/1.0 $errorCode " . get_class($exception));
|
||||
if ($exception instanceof HttpException) {
|
||||
header('HTTP/1.0 ' . $exception->statusCode . ' ' . $exception->getName());
|
||||
} else {
|
||||
header('HTTP/1.0 500 ' . get_class($exception));
|
||||
}
|
||||
}
|
||||
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
|
||||
\Yii::$app->renderException($exception);
|
||||
|
||||
@@ -79,9 +79,11 @@ class BooleanValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$options = array(
|
||||
'trueValue' => $this->trueValue,
|
||||
@@ -100,6 +102,7 @@ class BooleanValidator extends Validator
|
||||
$options['strict'] = 1;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.boolean(value, messages, ' . json_encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,9 +91,11 @@ class CaptchaValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$captcha = $this->getCaptchaAction();
|
||||
$code = $captcha->getVerifyCode(false);
|
||||
@@ -111,6 +113,7 @@ class CaptchaValidator extends Validator
|
||||
$options['skipOnEmpty'] = 1;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.captcha(value, messages, ' . json_encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,9 +178,11 @@ class CompareValidator extends Validator
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated
|
||||
* @return string the client-side validation script
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @throws InvalidConfigException if CompareValidator::operator is invalid
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$options = array('operator' => $this->operator);
|
||||
|
||||
@@ -203,6 +205,7 @@ class CompareValidator extends Validator
|
||||
'{compareValue}' => $compareValue,
|
||||
)));
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.compare(value, messages, ' . json_encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@ class EmailValidator extends Validator
|
||||
* Defaults to false.
|
||||
*/
|
||||
public $checkPort = false;
|
||||
/**
|
||||
* @var boolean whether validation process should take into account IDN (internationalized domain
|
||||
* names). Defaults to false meaning that validation of emails containing IDN will always fail.
|
||||
*/
|
||||
public $enableIDN = false;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the validator.
|
||||
@@ -81,10 +87,18 @@ class EmailValidator extends Validator
|
||||
public function validateValue($value)
|
||||
{
|
||||
// make sure string length is limited to avoid DOS attacks
|
||||
$valid = is_string($value) && strlen($value) <= 254
|
||||
&& (preg_match($this->pattern, $value) || $this->allowName && preg_match($this->fullPattern, $value));
|
||||
if (!is_string($value) || strlen($value) >= 255) {
|
||||
return false;
|
||||
}
|
||||
if (($atPosition = strpos($value, '@')) === false) {
|
||||
return false;
|
||||
}
|
||||
$domain = rtrim(substr($value, $atPosition + 1), '>');
|
||||
if ($this->enableIDN) {
|
||||
$value = idn_to_ascii(ltrim(substr($value, 0, $atPosition), '<')) . '@' . idn_to_ascii($domain);
|
||||
}
|
||||
$valid = preg_match($this->pattern, $value) || $this->allowName && preg_match($this->fullPattern, $value);
|
||||
if ($valid) {
|
||||
$domain = rtrim(substr($value, strpos($value, '@') + 1), '>');
|
||||
if ($this->checkMX && function_exists('checkdnsrr')) {
|
||||
$valid = checkdnsrr($domain, 'MX');
|
||||
}
|
||||
@@ -99,9 +113,11 @@ class EmailValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$options = array(
|
||||
'pattern' => new JsExpression($this->pattern),
|
||||
@@ -111,11 +127,16 @@ class EmailValidator extends Validator
|
||||
'{attribute}' => $object->getAttributeLabel($attribute),
|
||||
'{value}' => $object->$attribute,
|
||||
))),
|
||||
'enableIDN' => (boolean)$this->enableIDN,
|
||||
);
|
||||
if ($this->skipOnEmpty) {
|
||||
$options['skipOnEmpty'] = 1;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
if ($this->enableIDN) {
|
||||
$view->registerAssetBundle('punycode');
|
||||
}
|
||||
return 'yii.validation.email(value, messages, ' . Json::encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,12 +79,14 @@ class InlineValidator extends Validator
|
||||
*
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script. Null if the validator does not support
|
||||
* client-side validation.
|
||||
* @see enableClientValidation
|
||||
* @see \yii\web\ActiveForm::enableClientValidation
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
if ($this->clientValidate !== null) {
|
||||
$method = $this->clientValidate;
|
||||
|
||||
@@ -114,9 +114,11 @@ class NumberValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$label = $object->getAttributeLabel($attribute);
|
||||
$value = $object->$attribute;
|
||||
@@ -149,6 +151,7 @@ class NumberValidator extends Validator
|
||||
$options['skipOnEmpty'] = 1;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.number(value, messages, ' . Json::encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +81,11 @@ class RangeValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$range = array();
|
||||
foreach ($this->range as $value) {
|
||||
@@ -101,6 +103,7 @@ class RangeValidator extends Validator
|
||||
$options['skipOnEmpty'] = 1;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.range(value, messages, ' . json_encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,10 +79,12 @@ class RegularExpressionValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
* @throws InvalidConfigException if the "pattern" is not a valid regular expression
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$pattern = $this->pattern;
|
||||
$pattern = preg_replace('/\\\\x\{?([0-9a-fA-F]+)\}?/', '\u$1', $pattern);
|
||||
@@ -110,6 +112,7 @@ class RegularExpressionValidator extends Validator
|
||||
$options['skipOnEmpty'] = 1;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.regularExpression(value, messages, ' . Json::encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,9 +102,11 @@ class RequiredValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$options = array();
|
||||
if ($this->requiredValue !== null) {
|
||||
@@ -124,6 +126,7 @@ class RequiredValidator extends Validator
|
||||
'{value}' => $object->$attribute,
|
||||
)));
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.required(value, messages, ' . json_encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,9 +126,11 @@ class StringValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
$label = $object->getAttributeLabel($attribute);
|
||||
$value = $object->$attribute;
|
||||
@@ -168,6 +170,7 @@ class StringValidator extends Validator
|
||||
$options['skipOnEmpty'] = 1;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
return 'yii.validation.string(value, messages, ' . json_encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,12 @@ class UrlValidator extends Validator
|
||||
* contain the scheme part.
|
||||
**/
|
||||
public $defaultScheme;
|
||||
/**
|
||||
* @var boolean whether validation process should take into account IDN (internationalized
|
||||
* domain names). Defaults to false meaning that validation of URLs containing IDN will always
|
||||
* fail.
|
||||
*/
|
||||
public $enableIDN = false;
|
||||
|
||||
|
||||
/**
|
||||
@@ -87,6 +93,12 @@ class UrlValidator extends Validator
|
||||
$pattern = $this->pattern;
|
||||
}
|
||||
|
||||
if ($this->enableIDN) {
|
||||
$value = preg_replace_callback('/:\/\/([^\/]+)/', function($matches) {
|
||||
return '://' . idn_to_ascii($matches[1]);
|
||||
}, $value);
|
||||
}
|
||||
|
||||
if (preg_match($pattern, $value)) {
|
||||
return true;
|
||||
}
|
||||
@@ -98,10 +110,12 @@ class UrlValidator extends Validator
|
||||
* Returns the JavaScript needed for performing client-side validation.
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script.
|
||||
* @see \yii\Web\ActiveForm::enableClientValidation
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
if (strpos($this->pattern, '{schemes}') !== false) {
|
||||
$pattern = str_replace('{schemes}', '(' . implode('|', $this->validSchemes) . ')', $this->pattern);
|
||||
@@ -115,6 +129,7 @@ class UrlValidator extends Validator
|
||||
'{attribute}' => $object->getAttributeLabel($attribute),
|
||||
'{value}' => $object->$attribute,
|
||||
))),
|
||||
'enableIDN' => (boolean)$this->enableIDN,
|
||||
);
|
||||
if ($this->skipOnEmpty) {
|
||||
$options['skipOnEmpty'] = 1;
|
||||
@@ -123,7 +138,10 @@ class UrlValidator extends Validator
|
||||
$options['defaultScheme'] = $this->defaultScheme;
|
||||
}
|
||||
|
||||
$view->registerAssetBundle('yii/validation');
|
||||
if ($this->enableIDN) {
|
||||
$view->registerAssetBundle('punycode');
|
||||
}
|
||||
return 'yii.validation.url(value, messages, ' . Json::encode($options) . ');';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,11 +211,13 @@ abstract class Validator extends Component
|
||||
*
|
||||
* @param \yii\base\Model $object the data object being validated
|
||||
* @param string $attribute the name of the attribute to be validated.
|
||||
* @param \yii\base\View $view the view object that is going to be used to render views or view files
|
||||
* containing a model form with this validator applied.
|
||||
* @return string the client-side validation script. Null if the validator does not support
|
||||
* client-side validation.
|
||||
* @see \yii\web\ActiveForm::enableClientValidation
|
||||
*/
|
||||
public function clientValidateAttribute($object, $attribute)
|
||||
public function clientValidateAttribute($object, $attribute, $view)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
namespace yii\web;
|
||||
|
||||
use Yii;
|
||||
use yii\base\HttpException;
|
||||
use yii\helpers\FileHelper;
|
||||
use yii\helpers\Html;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
@@ -31,27 +33,76 @@ class Response extends \yii\base\Response
|
||||
* @param string $content content to be set.
|
||||
* @param string $mimeType mime type of the content. If null, it will be guessed automatically based on the given file name.
|
||||
* @param boolean $terminate whether to terminate the current application after calling this method
|
||||
* @todo
|
||||
* @throws \yii\base\HttpException when range request is not satisfiable.
|
||||
*/
|
||||
public function sendFile($fileName, $content, $mimeType = null, $terminate = true)
|
||||
{
|
||||
if ($mimeType === null && ($mimeType = FileHelper::getMimeType($fileName)) === null) {
|
||||
if ($mimeType === null && (($mimeType = FileHelper::getMimeTypeByExtension($fileName)) === null)) {
|
||||
$mimeType = 'application/octet-stream';
|
||||
}
|
||||
|
||||
$fileSize = StringHelper::strlen($content);
|
||||
$contentStart = 0;
|
||||
$contentEnd = $fileSize - 1;
|
||||
|
||||
// tell the client that we accept range requests
|
||||
header('Accept-Ranges: bytes');
|
||||
|
||||
if (isset($_SERVER['HTTP_RANGE'])) {
|
||||
// client sent us a multibyte range, can not hold this one for now
|
||||
if (strpos(',', $_SERVER['HTTP_RANGE']) !== false) {
|
||||
header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
|
||||
throw new HttpException(416, 'Requested Range Not Satisfiable');
|
||||
}
|
||||
|
||||
$range = str_replace('bytes=', '', $_SERVER['HTTP_RANGE']);
|
||||
|
||||
// range requests starts from "-", so it means that data must be dumped the end point.
|
||||
if ($range[0] === '-') {
|
||||
$contentStart = $fileSize - substr($range, 1);
|
||||
} else {
|
||||
$range = explode('-', $range);
|
||||
$contentStart = $range[0];
|
||||
$contentEnd = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $fileSize - 1;
|
||||
}
|
||||
|
||||
/* Check the range and make sure it's treated according to the specs.
|
||||
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
*/
|
||||
// End bytes can not be larger than $end.
|
||||
$contentEnd = ($contentEnd > $fileSize) ? $fileSize : $contentEnd;
|
||||
|
||||
// Validate the requested range and return an error if it's not correct.
|
||||
$wrongContentStart = ($contentStart > $contentEnd || $contentStart > $fileSize - 1 || $contentStart < 0);
|
||||
|
||||
if ($wrongContentStart) {
|
||||
header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
|
||||
throw new HttpException(416, 'Requested Range Not Satisfiable');
|
||||
}
|
||||
|
||||
header('HTTP/1.1 206 Partial Content');
|
||||
header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
|
||||
} else {
|
||||
header('HTTP/1.1 200 OK');
|
||||
}
|
||||
|
||||
$length = $contentEnd - $contentStart + 1; // Calculate new content length
|
||||
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header("Content-type: $mimeType");
|
||||
if (ob_get_length() === false) {
|
||||
header('Content-Length: ' . (function_exists('mb_strlen') ? mb_strlen($content, '8bit') : strlen($content)));
|
||||
}
|
||||
header("Content-Disposition: attachment; filename=\"$fileName\"");
|
||||
header('Content-Type: ' . $mimeType);
|
||||
header('Content-Length: ' . $length);
|
||||
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
$content = StringHelper::substr($content, $contentStart, $length);
|
||||
|
||||
if ($terminate) {
|
||||
// clean up the application first because the file downloading could take long time
|
||||
// which may cause timeout of some resources (such as DB connection)
|
||||
Yii::app()->end(0, false);
|
||||
ob_start();
|
||||
Yii::$app->end(0, false);
|
||||
ob_end_clean();
|
||||
echo $content;
|
||||
exit(0);
|
||||
} else {
|
||||
|
||||
@@ -138,7 +138,7 @@ class ActiveField extends Component
|
||||
$validators = array();
|
||||
foreach ($this->model->getActiveValidators($attribute) as $validator) {
|
||||
/** @var \yii\validators\Validator $validator */
|
||||
$js = $validator->clientValidateAttribute($this->model, $attribute);
|
||||
$js = $validator->clientValidateAttribute($this->model, $attribute, $this->form->getView());
|
||||
if ($validator->enableClientValidation && $js != '') {
|
||||
$validators[] = $js;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user