| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 | <?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK ]// +----------------------------------------------------------------------// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +----------------------------------------------------------------------namespace think\model\concern;use think\Collection;use think\Exception;use think\Loader;use think\Model;use think\model\Collection as ModelCollection;/** * 模型数据转换处理 */trait Conversion{    /**     * 数据输出显示的属性     * @var array     */    protected $visible = [];    /**     * 数据输出隐藏的属性     * @var array     */    protected $hidden = [];    /**     * 数据输出需要追加的属性     * @var array     */    protected $append = [];    /**     * 数据集对象名     * @var string     */    protected $resultSetType;    /**     * 设置需要附加的输出属性     * @access public     * @param  array $append   属性列表     * @param  bool  $override 是否覆盖     * @return $this     */    public function append(array $append = [], $override = false)    {        $this->append = $override ? $append : array_merge($this->append, $append);        return $this;    }    /**     * 设置附加关联对象的属性     * @access public     * @param  string       $attr    关联属性     * @param  string|array $append  追加属性名     * @return $this     * @throws Exception     */    public function appendRelationAttr($attr, $append)    {        if (is_string($append)) {            $append = explode(',', $append);        }        $relation = Loader::parseName($attr, 1, false);        if (isset($this->relation[$relation])) {            $model = $this->relation[$relation];        } else {            $model = $this->getRelationData($this->$relation());        }        if ($model instanceof Model) {            foreach ($append as $key => $attr) {                $key = is_numeric($key) ? $attr : $key;                if (isset($this->data[$key])) {                    throw new Exception('bind attr has exists:' . $key);                } else {                    $this->data[$key] = $model->getAttr($attr);                }            }        }        return $this;    }    /**     * 设置需要隐藏的输出属性     * @access public     * @param  array $hidden   属性列表     * @param  bool  $override 是否覆盖     * @return $this     */    public function hidden(array $hidden = [], $override = false)    {        $this->hidden = $override ? $hidden : array_merge($this->hidden, $hidden);        return $this;    }    /**     * 设置需要输出的属性     * @access public     * @param  array $visible     * @param  bool  $override 是否覆盖     * @return $this     */    public function visible(array $visible = [], $override = false)    {        $this->visible = $override ? $visible : array_merge($this->visible, $visible);        return $this;    }    /**     * 转换当前模型对象为数组     * @access public     * @return array     */    public function toArray()    {        $item       = [];        $hasVisible = false;        foreach ($this->visible as $key => $val) {            if (is_string($val)) {                if (strpos($val, '.')) {                    list($relation, $name)      = explode('.', $val);                    $this->visible[$relation][] = $name;                } else {                    $this->visible[$val] = true;                    $hasVisible          = true;                }                unset($this->visible[$key]);            }        }        foreach ($this->hidden as $key => $val) {            if (is_string($val)) {                if (strpos($val, '.')) {                    list($relation, $name)     = explode('.', $val);                    $this->hidden[$relation][] = $name;                } else {                    $this->hidden[$val] = true;                }                unset($this->hidden[$key]);            }        }        // 合并关联数据        $data = array_merge($this->data, $this->relation);        foreach ($data as $key => $val) {            if ($val instanceof Model || $val instanceof ModelCollection) {                // 关联模型对象                if (isset($this->visible[$key]) && is_array($this->visible[$key])) {                    $val->visible($this->visible[$key]);                } elseif (isset($this->hidden[$key]) && is_array($this->hidden[$key])) {                    $val->hidden($this->hidden[$key]);                }                // 关联模型对象                if (!isset($this->hidden[$key]) || true !== $this->hidden[$key]) {                    $item[$key] = $val->toArray();                }            } elseif (isset($this->visible[$key])) {                $item[$key] = $this->getAttr($key);            } elseif (!isset($this->hidden[$key]) && !$hasVisible) {                $item[$key] = $this->getAttr($key);            }        }        // 追加属性(必须定义获取器)        if (!empty($this->append)) {            foreach ($this->append as $key => $name) {                if (is_array($name)) {                    // 追加关联对象属性                    $relation = $this->getRelation($key);                    if (!$relation) {                        $relation = $this->getAttr($key);                        if ($relation) {                            $relation->visible($name);                        }                    }                    $item[$key] = $relation ? $relation->append($name)->toArray() : [];                } elseif (strpos($name, '.')) {                    list($key, $attr) = explode('.', $name);                    // 追加关联对象属性                    $relation = $this->getRelation($key);                    if (!$relation) {                        $relation = $this->getAttr($key);                        if ($relation) {                            $relation->visible([$attr]);                        }                    }                    $item[$key] = $relation ? $relation->append([$attr])->toArray() : [];                } else {                    $item[$name] = $this->getAttr($name, $item);                }            }        }        return $item;    }    /**     * 转换当前模型对象为JSON字符串     * @access public     * @param  integer $options json参数     * @return string     */    public function toJson($options = JSON_UNESCAPED_UNICODE)    {        return json_encode($this->toArray(), $options);    }    /**     * 移除当前模型的关联属性     * @access public     * @return $this     */    public function removeRelation()    {        $this->relation = [];        return $this;    }    public function __toString()    {        return $this->toJson();    }    // JsonSerializable    public function jsonSerialize()    {        return $this->toArray();    }    /**     * 转换数据集为数据集对象     * @access public     * @param  array|Collection $collection 数据集     * @param  string           $resultSetType 数据集类     * @return Collection     */    public function toCollection($collection, $resultSetType = null)    {        $resultSetType = $resultSetType ?: $this->resultSetType;        if ($resultSetType && false !== strpos($resultSetType, '\\')) {            $collection = new $resultSetType($collection);        } else {            $collection = new ModelCollection($collection);        }        return $collection;    }}
 |