Last active
December 12, 2015 06:38
-
-
Save crisu83/4730649 to your computer and use it in GitHub Desktop.
Yii form model that allows for using multiple models in the same form.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Class ModelGroupForm | |
* | |
* Note! Attributes must be defined as "modelName.attributeName", e.g. "user.name" in forms. | |
*/ | |
class ModelGroupForm extends CFormModel { | |
/** | |
* @var CModel[] $models the model instances (name=>config). | |
*/ | |
public $models = array(); | |
/** | |
* Does magic for getting attributes within in group models. | |
* @param string $name the property name or event name | |
* @return mixed the property value, event handlers attached to the event, or the named behavior | |
* @throws CException if the property or event is not defined | |
*/ | |
public function __get($name) { | |
$name = $this->resolveModelAttribute($name); | |
if (is_array($name)) { | |
list($modelName, $attribute) = $name; | |
if (!empty($attribute) && isset($this->models[$modelName])) { | |
return $this->models[$modelName]->{$attribute}; | |
} | |
} | |
return parent::__get($name); | |
} | |
/** | |
* Sets the attribute values in a massive way. | |
* @param array $values attribute values (name=>value) to be set. | |
* @param boolean $safeOnly whether the assignments should only be done to the safe attributes. | |
*/ | |
public function setAttributes($values, $safeOnly = true) { | |
parent::setAttributes($values, $safeOnly); | |
foreach ($values as $name => $value) { | |
$name = $this->resolveModelAttribute($name); | |
if (is_array($name)) { | |
list($name, $attribute) = $name; | |
if (isset($this->models[$name])) { | |
$this->models[$name]->{$attribute} = $value; | |
} | |
} | |
} | |
} | |
/** | |
* Performs the validation. | |
* @param array $attributes list of attributes that should be validated. Defaults to null, | |
* @param boolean $clearErrors whether to call {@link clearErrors} before performing validation | |
* @return boolean whether the validation is successful without any error. | |
*/ | |
public function validate($attributes = null, $clearErrors = true) { | |
$valid = parent::validate($attributes, $clearErrors); | |
foreach ($this->models as $model) { | |
$valid = $model->validate(null, $clearErrors) && $valid; | |
} | |
return $valid; | |
} | |
/** | |
* Returns the text label for the specified attribute. | |
* @param string $attribute the attribute name | |
* @return string the attribute label | |
*/ | |
public function getAttributeLabel($attribute) { | |
$attribute = $this->resolveModelAttribute($attribute); | |
if (is_array($attribute)) { | |
list($modelName, $attributeName) = $attribute; | |
if (!empty($attributeName) && isset($this->models[$modelName])) { | |
return $this->models[$modelName]->getAttributeLabel($attributeName); | |
} | |
return ''; | |
} else { | |
return parent::getAttributeLabel($attribute); | |
} | |
} | |
/** | |
* Returns a value indicating whether there is any validation error. | |
* @param string $attribute attribute name. Use null to check all attributes. | |
* @return boolean whether there is any error. | |
*/ | |
public function hasErrors($attribute = null) { | |
$attribute = $this->resolveModelAttribute($attribute); | |
if (is_array($attribute)) { | |
list($modelName, $attributeName) = $attribute; | |
if (isset($this->models[$modelName])) { | |
return $this->models[$modelName]->hasErrors($attributeName); | |
} | |
} | |
return parent::hasErrors($attribute); | |
} | |
/** | |
* Returns the errors for all attribute or a single attribute. | |
* @param string $attribute attribute name. Use null to retrieve errors for all attributes. | |
* @return array errors for all attributes or the specified attribute. Empty array is returned if no error. | |
*/ | |
public function getErrors($attribute = null) { | |
$errors = parent::getErrors($attribute); | |
foreach ($this->models as $model) { | |
$errors = array_merge($errors, $model->getErrors($attribute)); | |
} | |
return $errors; | |
} | |
/** | |
* Returns the first error of the specified attribute. | |
* @param string $attribute attribute name. | |
* @return string the error message. Null is returned if no error. | |
*/ | |
public function getError($attribute) { | |
$attribute = $this->resolveModelAttribute($attribute); | |
if (is_array($attribute)) { | |
list($modelName, $attribute) = $attribute; | |
if (!empty($attribute) && isset($this->models[$modelName])) { | |
return $this->models[$modelName]->getError($attribute); | |
} | |
return ''; | |
} | |
return parent::getError($attribute); | |
} | |
/** | |
* Turns model.attribute into array($model, $attribute) | |
* @param $attribute | |
* @return array | |
*/ | |
public function resolveModelAttribute($attribute) { | |
return strpos($attribute, '.') > 0 ? explode('.', $attribute) : $attribute; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment