From 1f5f19df13036d66aed3fb74689cbefab425dc90 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Sat, 7 Dec 2013 18:16:56 -0500 Subject: [PATCH] Fixes #1457: support using AR relations as input. --- framework/yii/db/BaseActiveRecord.php | 11 --------- framework/yii/helpers/BaseHtml.php | 46 +++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/framework/yii/db/BaseActiveRecord.php b/framework/yii/db/BaseActiveRecord.php index 767ab00..00360c4 100644 --- a/framework/yii/db/BaseActiveRecord.php +++ b/framework/yii/db/BaseActiveRecord.php @@ -93,17 +93,6 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface /** - * Returns the string representation of this AR instance. - * The default implementation will return the primary key (or JSON representation of the primary key if it is composite). - * @return string the string representation of this AR instance. - */ - public function __toString() - { - $pk = $this->getPrimaryKey(); - return is_array($pk) ? json_encode($pk) : $pk; - } - - /** * Creates an [[ActiveQuery]] instance for query purpose. * * @include @yii/db/ActiveRecord-find.md diff --git a/framework/yii/helpers/BaseHtml.php b/framework/yii/helpers/BaseHtml.php index 93c988a..2cfcb15 100644 --- a/framework/yii/helpers/BaseHtml.php +++ b/framework/yii/helpers/BaseHtml.php @@ -9,6 +9,7 @@ namespace yii\helpers; use Yii; use yii\base\InvalidParamException; +use yii\db\ActiveRecordInterface; use yii\web\Request; use yii\base\Model; @@ -1208,11 +1209,11 @@ class BaseHtml public static function activeDropDownList($model, $attribute, $items, $options = []) { $name = isset($options['name']) ? $options['name'] : static::getInputName($model, $attribute); - $checked = static::getAttributeValue($model, $attribute); + $selection = static::getAttributeValue($model, $attribute); if (!array_key_exists('id', $options)) { $options['id'] = static::getInputId($model, $attribute); } - return static::dropDownList($name, $checked, $items, $options); + return static::dropDownList($name, $selection, $items, $options); } /** @@ -1256,14 +1257,14 @@ class BaseHtml public static function activeListBox($model, $attribute, $items, $options = []) { $name = isset($options['name']) ? $options['name'] : static::getInputName($model, $attribute); - $checked = static::getAttributeValue($model, $attribute); + $selection = static::getAttributeValue($model, $attribute); if (!array_key_exists('unselect', $options)) { $options['unselect'] = '0'; } if (!array_key_exists('id', $options)) { $options['id'] = static::getInputId($model, $attribute); } - return static::listBox($name, $checked, $items, $options); + return static::listBox($name, $selection, $items, $options); } /** @@ -1297,14 +1298,14 @@ class BaseHtml public static function activeCheckboxList($model, $attribute, $items, $options = []) { $name = isset($options['name']) ? $options['name'] : static::getInputName($model, $attribute); - $checked = static::getAttributeValue($model, $attribute); + $selection = static::getAttributeValue($model, $attribute); if (!array_key_exists('unselect', $options)) { $options['unselect'] = '0'; } if (!array_key_exists('id', $options)) { $options['id'] = static::getInputId($model, $attribute); } - return static::checkboxList($name, $checked, $items, $options); + return static::checkboxList($name, $selection, $items, $options); } /** @@ -1337,14 +1338,14 @@ class BaseHtml public static function activeRadioList($model, $attribute, $items, $options = []) { $name = isset($options['name']) ? $options['name'] : static::getInputName($model, $attribute); - $checked = static::getAttributeValue($model, $attribute); + $selection = static::getAttributeValue($model, $attribute); if (!array_key_exists('unselect', $options)) { $options['unselect'] = '0'; } if (!array_key_exists('id', $options)) { $options['id'] = static::getInputId($model, $attribute); } - return static::radioList($name, $checked, $items, $options); + return static::radioList($name, $selection, $items, $options); } /** @@ -1546,9 +1547,12 @@ class BaseHtml * For an attribute expression like `[0]dates[0]`, this method will return the value of `$model->dates[0]`. * See [[getAttributeName()]] for more details about attribute expression. * + * If an attribute value is an instance of [[ActiveRecordInterface]] or an array of such instances, + * the primary value(s) of the AR instance(s) will be returned instead. + * * @param Model $model the model object * @param string $attribute the attribute name or expression - * @return mixed the corresponding attribute value + * @return string|array the corresponding attribute value * @throws InvalidParamException if the attribute name contains non-word characters. */ public static function getAttributeValue($model, $attribute) @@ -1557,20 +1561,30 @@ class BaseHtml throw new InvalidParamException('Attribute name must contain word characters only.'); } $attribute = $matches[2]; - $index = $matches[3]; - if ($index === '') { - return $model->$attribute; - } else { - $value = $model->$attribute; - foreach (explode('][', trim($index, '[]')) as $id) { + $value = $model->$attribute; + if ($matches[3] !== '') { + foreach (explode('][', trim($matches[3], '[]')) as $id) { if ((is_array($value) || $value instanceof \ArrayAccess) && isset($value[$id])) { $value = $value[$id]; } else { return null; } } - return $value; } + + // https://github.com/yiisoft/yii2/issues/1457 + if (is_array($value)) { + foreach ($value as $i => $v) { + if ($v instanceof ActiveRecordInterface) { + $v = $v->getPrimaryKey(false); + $value[$i] = is_array($v) ? json_encode($v) : $v; + } + } + } elseif ($value instanceof ActiveRecordInterface) { + $value = $value->getPrimaryKey(false); + return is_array($value) ? json_encode($value) : $value; + } + return $value; } /**