/** * Validates a single attribute. * * @param CModel $object the data object being validated * @param string $attribute the name of the attribute to be validated. */ protected function validateAttribute($object, $attribute) { $value = $object->{$attribute}; if ($this->isEmpty($value)) { if ($this->allowEmpty) { return; } else { $arrValidators = $object->getValidators($attribute); foreach ($arrValidators as $objValidator) { // do not duplicate error message if attribute is already required if ($objValidator instanceof CRequiredValidator) { return; } } $message = $this->message !== null ? $this->message : Yii::t('yii', '{attribute} cannot be blank.'); $this->addError($object, $attribute, $message); } } else { $return = $this->validateIBAN($value); if (true !== $return) { $message = $this->message !== null ? $this->message : $this->getErrorMessage($return, $value); $this->addError($object, $attribute, $message); } } }
/** * Generates an input HTML tag for a model attribute. * This method generates an input HTML tag based on the given data model and attribute. * If the attribute has input error, the input field's CSS class will * be appended with {@link errorCss}. * This enables highlighting the incorrect input. * @param string $type the input type (e.g. 'text', 'radio') * @param CModel $model the data model * @param string $attribute the attribute * @param array $htmlOptions additional HTML attributes for the HTML tag * @return string the generated input tag */ protected static function activeInputField($type, $model, $attribute, $htmlOptions) { $htmlOptions['type'] = $type; if ($type === 'text' || $type === 'password') { if (!isset($htmlOptions['maxlength'])) { foreach ($model->getValidators($attribute) as $validator) { if ($validator instanceof CStringValidator && $validator->max !== null) { $htmlOptions['maxlength'] = $validator->max; break; } } } elseif ($htmlOptions['maxlength'] === false) { unset($htmlOptions['maxlength']); } } if ($type === 'file') { unset($htmlOptions['value']); } elseif (!isset($htmlOptions['value'])) { $htmlOptions['value'] = self::resolveValue($model, $attribute); } if ($model->hasErrors($attribute)) { self::addErrorCss($htmlOptions); } return self::tag('input', $htmlOptions); }
/** * Check for a property of CFileValidator * * @param CModel $model * @param string $attribute * @param string $property * * @return string property's value or null */ private function getFileValidatorProperty($model = null, $attribute = null, $property = null) { if (!isset($model, $attribute, $property)) { return null; } foreach ($model->getValidators($attribute) as $validator) { if ($validator instanceof CFileValidator) { $ret = $validator->{$property}; } } return isset($ret) ? $ret : null; }
/** * @param \CModel $model * @param null $path * @return array */ public function generateModelErrorFields(\CModel $model, $path = null) { $validators = \CValidator::$builtInValidators; if ($this->hasEventHandler('onBeforeGenerateError')) { $this->onBeforeGenerateError(new \CEvent($this, array('model' => $model))); } $errors = $model->getErrors(); $errorFields = array_keys($errors); $errorHandled = array(); $i = 0; $result = array(); foreach ($model->getValidators() as $validator) { if (isset($hasError) && $validator->skipOnError || !array_intersect($validator->attributes, $errorFields)) { continue; } $model->clearErrors(); $validator->validate($model); if ($model->hasErrors()) { $hasError = true; $code = array_search(get_class($validator), $validators); if ($validator instanceof \CInlineValidator) { $code = $validator->method; } foreach ($validator->attributes as $attribute) { if ($model->hasErrors($attribute)) { $result[$i]['code'] = $code; $result[$i]['message'] = $model->getError($attribute); $result[$i]['name'] = $path ? $path . '[' . $attribute . ']' : $attribute; $errorHandled[] = $attribute; $i++; } } } } foreach (array_diff($errorFields, $errorHandled) as $attribute) { $result[$i]['code'] = 'unknown'; $result[$i]['message'] = implode(',', $errors[$attribute]); $result[$i]['name'] = $path ? $path . '[' . $attribute . ']' : $attribute; } return $result; }
/** * Generates an input HTML tag for a model attribute. * This method generates an input HTML tag based on the given data model and attribute. * If the attribute has input error, the input field's CSS class will * be appended with {@link errorCss}. * This enables highlighting the incorrect input. * @param string $type the input type (e.g. 'text', 'radio') * @param CModel $model the data model * @param string $attribute the attribute * @param array $htmlOptions additional HTML attributes for the HTML tag * @return string the generated input tag */ protected static function activeInputField($type, $model, $attribute, $htmlOptions) { $htmlOptions['type'] = $type; if ($type === 'text' || $type === 'password' || $type === 'color' || $type === 'date' || $type === 'datetime' || $type === 'datetime-local' || $type === 'email' || $type === 'month' || $type === 'number' || $type === 'range' || $type === 'search' || $type === 'tel' || $type === 'time' || $type === 'url' || $type === 'week') { if (!isset($htmlOptions['maxlength'])) { foreach ($model->getValidators($attribute) as $validator) { if ($validator instanceof CStringValidator && $validator->max !== null) { $htmlOptions['maxlength'] = $validator->max; break; } } } elseif ($htmlOptions['maxlength'] === false) { unset($htmlOptions['maxlength']); } } $htmlOptions['class'] = 'form-control'; if ($type === 'file') { unset($htmlOptions['value']); } elseif (!isset($htmlOptions['value'])) { $htmlOptions['value'] = self::resolveValue($model, $attribute); } if ($model->hasErrors($attribute)) { self::addErrorCss($htmlOptions); } return self::tag('input', $htmlOptions); }
/** * @param \CModel $model * @return array */ protected function _generateModelErrorFields(\CModel $model) { $validators = \CValidator::$builtInValidators; $errors = $model->getErrors(); $errorFields = array_keys($errors); $errorHandled = array(); $i = 0; $result = array(); foreach ($model->getValidators() as $validator) { if (isset($hasError) && $validator->skipOnError || !array_intersect($validator->attributes, $errorFields)) { continue; } $model->clearErrors(); $validator->validate($model); if ($model->hasErrors()) { $hasError = true; $code = array_search(get_class($validator), $validators); if ($validator instanceof \CInlineValidator) { $code = $validator->method; } foreach ($validator->attributes as $attribute) { if ($model->hasErrors($attribute)) { $result[$i]['code'] = $code; $result[$i]['message'] = $model->getError($attribute); $result[$i]['name'] = $attribute; $errorHandled[] = $attribute; $i++; } } } } foreach (array_diff($errorFields, $errorHandled) as $attribute) { $result[$i]['code'] = 'unknown'; $result[$i]['message'] = implode(',', $errors[$attribute]); $result[$i]['name'] = $attribute; } return $result; }
/** * Registers the validators by adding validation HTML attributes to the given options. * @param CModel $model the model class. * @param string $attribute the attribute name. * @param array $htmlOptions the HTML attributes. */ protected function registerValidators($model, $attribute, &$htmlOptions) { foreach ($model->getValidators($attribute) as $validator) { if ($validator instanceof ParsleyValidator) { if (property_exists($validator, 'html5Mode')) { $validator->html5Mode = $this->html5Mode; } $validator->registerClientValidation($model, $attribute, $htmlOptions); } } }
/** * Override to properly get validators for an attribute when they are on the model. * Todo: Factor in scenario for model attributes. * (non-PHPdoc) * @see CModel::getValidators() */ public function getValidators($attribute = null) { if ($attribute != null && !property_exists($this, $attribute)) { return $this->model->getValidators($attribute); } return parent::getValidators($attribute); }
/** * Generates a control group with a text field using a juidatepicker for a model attribute. * @param CModel $model the data model. * @param string $attribute the attribute name. * @param array $htmlOptions additional HTML attributes. * @return string the generated row. * @see BsHtml::activeDateFieldControlGroup */ public function datetimeFieldControlGroup($model, $attribute, $htmlOptions = array()) { $allowEmpty = false; $validators = $model->getValidators($attribute); foreach ($validators as $validator) { if ($validator instanceof CDateValidator && $validator->allowEmpty === true) { $allowEmpty = true; break; } } //I would have liked to have used the i18n date format, but the Jui Datepicker //doesn't support the unicode date format //$dateFormat = Yii::app()->locale->getDateFormat('full'); $htmlOptions = BsHtml::addClassName('form-control', $htmlOptions); $htmlOptions['displaySize'] = isset($htmlOptions['displaySize']) ? $htmlOptions['displaySize'] : 1; $dateWidget = $this->widget('zii.widgets.jui.CJuiDatePicker', array('name' => $attribute . '_widget', 'htmlOptions' => $htmlOptions, 'options' => array('dateFormat' => 'DD, d MM yy', 'altFormat' => 'yy-mm-dd', 'altField' => '#' . CHtml::activeId($model, $attribute), 'changeYear' => true, 'changeMonth' => true), 'value' => date('l, j F Y', strtotime($model->{$attribute}))), true); $hourOptions = array(); $minuteOptions = array(); for ($i = 0; $i < 24; $i++) { $val = str_pad($i, 2, "0", STR_PAD_LEFT); $hourOptions[$val] = $val; } for ($i = 0; $i < 60; $i += 5) { $val = str_pad($i, 2, "0", STR_PAD_LEFT); $minuteOptions[$val] = $val; } $rowHtmlOptions = $htmlOptions; $rowHtmlOptions['input'] = '<div class="row">'; if ($allowEmpty) { $rowHtmlOptions['input'] .= '<div class="col-lg-1">' . BsHtml::activeLabel($model, $attribute . '_set', array('class' => 'control-label')) . BsHtml::activeCheckBox($model, $attribute . '_set', array('class' => 'control-label')) . '</div>'; } $rowHtmlOptions['input'] .= '<div class="col-lg-4">' . BsHtml::label('Date', $attribute . '_widget', array('class' => 'control-label')) . $dateWidget . '</div><div class="col-lg-2">' . BsHtml::activeLabel($model, $attribute . '_hour', array('class' => 'control-label')) . BsHtml::activeDropDownList($model, $attribute . '_hour', $hourOptions, $htmlOptions) . '</div><div class="col-lg-2">' . BsHtml::activeLabel($model, $attribute . '_minute', array('class' => 'control-label')) . BsHtml::activeDropDownList($model, $attribute . '_minute', $minuteOptions, $htmlOptions) . '</div></div>'; $rowHtmlOptions = $this->processRowOptions($model, $attribute, $rowHtmlOptions); return BsHTML::activeDateFieldControlGroup($model, $attribute, $rowHtmlOptions) . BsHTML::activeHiddenField($model, $attribute); }