Esempio n. 1
0
 /**
  * 设置数据
  *
  * 键名是对象的键名,而并非数据库字段的键名,可以批量设置
  * $has_created=是否已构造好的数据。若已构造好的数据则无需再经过_create_data()方法处理,默认false
  *
  * 	 set_data( array('a'=>'1','b'=>2) );
  *   set_data( array('a'=>'1','b'=>2) , null , true );
  *   set_data( 'a , '1' );
  *   set_data( 'a , '1' , true );
  *
  * @param array/string $key
  * @param fixed $value 值
  * @param boolean $has_parsed 是否已构造好的数据,默认false
  * @return boolean 是否设置成功
  */
 public function set_data($key, $value, $has_parsed = false)
 {
     if (is_array($key)) {
         foreach ($key as $k => $v) {
             $this->set_data($k, $v, $has_parsed);
         }
         return true;
     }
     # 获取当前设置
     $config = $this->_get_offset_config($key);
     if (!$config) {
         if (preg_match('#^[a-z]#i', $key) || $key == '__orm_sleep_data__') {
             # 没有相应的配置,直接快速设置后返回,其中__orm_sleep_data__为对象序列化时需要设置的key
             $this->{$key} = $value;
         }
         return;
     }
     # 当前节点是否已设置
     $offset_isset = isset($this->_offset_data[$key]);
     # 标记为已设置过的节点
     $this->_has_set_offset[$key] = true;
     if ($this->_orm_data_is_created) {
         # 对象已构造完毕
         if ($offset_isset && $config['is_readonly']) {
             if (null !== $this->_offset_data[$key] && false !== $this->_offset_data[$key]) {
                 # 只读字段不允许修改
                 return false;
             }
         }
     }
     # 映射字段
     if (isset($config['_parent_offset_name'])) {
         $parent_offset = $config['_parent_offset_name'];
         # 父节点名
         if (!$parent_offset || $parent_offset == $key) {
             return false;
         }
         $parent_data = $this->{$parent_offset};
         # 设置子节点数据
         $is_changed = OOP_ORM_Parse::set_sub_offset_data($parent_data, $value, explode('.', $config['_sub_key_name']));
         # 将数据设置到父节点
         if (false === $is_changed || false === $this->__set($parent_offset, $parent_data)) {
             # 若返回是false,则表示父类不允许设置(比如只读字段)
             return false;
         } else {
             # 父节点会推动所有子节点更新数据,所以这边直接返回true即可
             return true;
         }
     } elseif (isset($config['field_name'])) {
         if ($this->_orm_data_is_created) {
             $this->_data_is_changed = true;
         } else {
             # 记录到旧数据
             $this->_original_field_data[$config['field_name']] = $value;
         }
     }
     if ($has_parsed) {
         $this->_offset_data[$key] = $value;
         # 设为已构造
         $this->_created_offset[$key] = true;
     } else {
         # 反解格式化数据
         if (isset($config['format'])) {
             $value = OOP_ORM_Parse::de_format_data($value, $config['format']);
         }
         if (isset($this->_created_offset[$key])) {
             # 已经构造了
             if (is_object($this->_offset_data[$key])) {
                 # 对象
                 if (isset($config['object']['callback']['set_data'])) {
                     # 配置有设置数据的接口
                     $call_set_data_function = $config['object']['callback']['set_data'];
                     $obj = $this->_offset_data[$key];
                     $obj->{$call_set_data_function}($value);
                 } else {
                     $this->_offset_data[$key] = $value;
                     # 清理掉以便可以重新构造
                     unset($this->_created_offset[$key]);
                 }
             } else {
                 # 已创建了且不是对象,则可以直接替换掉
                 $this->_offset_data[$key] = $value;
             }
         } else {
             # 设置了一个未构造的数据,且当前也没有构造数据,则直接替换掉
             $this->_offset_data[$key] = $value;
         }
     }
     # 推动子字段进行更新数据
     if (isset($config['_all_sub_offset'])) {
         foreach ($config['_all_sub_offset'] as $sub_key) {
             # 子字段配置
             $sub_config = $this->_get_offset_config($sub_key);
             if (!$sub_config || !isset($sub_config['_sub_key_name'])) {
                 continue;
             }
             # 默认都需要清理子数据
             $need_reset = true;
             # 表示子字段已设置过
             $this->_has_set_offset[$sub_key] = true;
             if (isset($this->_created_offset[$sub_key])) {
                 if (is_object($this->_offset_data[$sub_key])) {
                     # 已构造对象需要处理
                     $obj = $this->_offset_data[$sub_key];
                     if (isset($config['object']['callback']['set_data'])) {
                         $sub_data = OOP_ORM_Parse::get_sub_offset_data($this->{$key}, explode('.', $sub_config['_sub_key_name']));
                         $call_set_data_function = $config['object']['callback']['set_data'];
                         $obj->{$call_set_data_function}($sub_data);
                         # 调用过设置数据的的回调函数后就不需要再清理了
                         $need_reset = false;
                     } else {
                         # 没有设置回调函数
                         if ($obj instanceof OOP_ORM_Data || method_exists($obj, 'getArrayCopy')) {
                             # 获取当前数据
                             $tmp_data = $obj->getArrayCopy();
                             # 获取父节点的子数据
                             $sub_data = OOP_ORM_Parse::get_sub_offset_data($this->{$key}, explode('.', $sub_config['_sub_key_name']));
                             if ($tmp_data === $sub_data) {
                                 # 未修改过,不需要清理
                                 $need_reset = false;
                             }
                         } elseif (method_exists($obj, '__toString')) {
                             # 获取当前数据
                             $tmp_data = $obj->__toString();
                             # 获取父节点的子数据
                             $sub_data = OOP_ORM_Parse::get_sub_offset_data($this->{$key}, explode('.', $sub_config['_sub_key_name']));
                             if ($tmp_data === $sub_data) {
                                 # 未修改过,不需要清理
                                 $need_reset = false;
                             }
                         }
                     }
                 }
             }
             if ($need_reset) {
                 # 清理设置,在重新get的时候会重新构造数据
                 unset($this->_created_offset[$sub_key]);
                 unset($this->_offset_data[$sub_key]);
             }
         }
     }
     return true;
 }