예제 #1
0
 /**
  * 获取当前类型的数据
  *
  * @param OOP_ORM_Data $obj
  * @param $data
  * @param $compiled_data
  * @return mixed
  */
 public function &get_data(OOP_ORM_Data $obj, &$data, &$compiled_data, &$compiled_raw_data)
 {
     $config = $this->config();
     $fun = $config['func'];
     $args = $config['args'];
     foreach ($args as &$item) {
         if ($item === '$this') {
             $item = $obj;
         } elseif (is_string($item) && substr($item, 0, 7) === '$this->') {
             $key = substr($item, 7);
             $item = $obj->{$key};
         }
     }
     if (count($fun) === 1) {
         $tmp_data = call_user_func_array($fun[0], $args);
     } else {
         if ($fun[0] === '$this') {
             $fun[0] = $obj;
             $tmp_data = $obj->__orm_callback('get_by_function_di', $fun, $args);
         } else {
             $tmp_data = call_user_func_array($fun, $args);
         }
     }
     if (false === $config['runtime']) {
         # 非实时运行
         $compiled_data[$this->key] = $tmp_data;
         $compiled_raw_data[$this->key] = $tmp_data;
     }
     return $tmp_data;
 }
예제 #2
0
 protected function format_field_value(OOP_ORM_Data $obj, &$data, $new_data, $format_type)
 {
     # 数据主键
     $id = $obj->pk(',');
     # 这个是对应主表的表名称,它和元数据的 table_name 字段是对应的
     $table = $obj->finder()->tablename();
     # 这个是metadata所在的表名称
     $my_table = $this->table_name;
     $meta_group = $this->meta_group;
     if (null === $new_data || '' === $new_data || array() === $new_data) {
         # 删除了
         # 读取已经加载的所有元数据
         $old_metadata = $obj->__orm_callback('get_metadata');
         if (isset($old_metadata[$my_table][$meta_group])) {
             foreach ($old_metadata[$my_table][$meta_group] as $hash => $item) {
                 # 遍历所有当前组的数据
                 if ($item['table_name'] === $table && $item['field_name'] === $this->field_name) {
                     # 把当前字段的数据全部设置成 null 以便进行删除处理
                     $data[$my_table][$hash] = null;
                 }
             }
         }
         return;
     }
     # 读取已经加载的所有元数据
     $old_metadata = $obj->__orm_callback('get_metadata');
     $old_item_data = array();
     if (isset($old_metadata[$my_table][$meta_group])) {
         foreach ($old_metadata[$my_table][$meta_group] as $hash => $item) {
             # 把数据整理到一个数组里
             if ($item['table_name'] === $table && $item['field_name'] === $this->field_name) {
                 # 把当前字段的数据全部设置成 null 以便进行删除处理
                 $old_item_data[$hash] = $item;
             }
         }
     }
     # 读取新数据
     if ($this->config['depth']) {
         # 处理多行数据
         $new_item_data = array();
         foreach ($new_data as $k => $v) {
             $tmp = $this->get_meta_item($table, $id, $k, $v);
             $new_item_data[$tmp['hash']] = $tmp;
         }
     } else {
         $tmp = $this->get_meta_item($table, $id, 0, $new_data);
         $new_item_data[$tmp['hash']] = $tmp;
     }
     foreach ($new_item_data as $hash => $item) {
         $tmp_value = $item['meta_value'];
         if ($tmp_value !== array() && null !== $tmp_value) {
             if ($format_type) {
                 # 动态格式化
                 if (is_array($tmp_value) || is_object($tmp_value)) {
                     $tmp_value = serialize($tmp_value);
                 }
             } elseif (isset($this->config['format']) && $this->config['format']) {
                 # 格式化数据
                 $this->_format_data($tmp_value);
             }
         }
         $tmp_value = (string) $tmp_value;
         if ('' === $tmp_value) {
             # 空字符串,则移除 null
             unset($new_item_data[$hash]);
         } else {
             $new_item_data[$hash]['meta_value'] = $tmp_value;
             if (isset($old_item_data[$hash]) || array_key_exists($hash, $old_item_data)) {
                 if ($old_item_data[$hash]['meta_value'] === $tmp_value) {
                     # 相同数据,全部去掉掉则不更新
                     unset($new_item_data[$hash]);
                     unset($old_item_data[$hash]);
                 } else {
                     unset($old_item_data[$hash]);
                 }
             }
         }
     }
     # 把老数据清理掉
     if ($old_item_data) {
         foreach ($old_item_data as $hash => $item) {
             $new_item_data[$hash] = null;
         }
     }
     $new_data = $new_item_data;
     if (isset($data[$my_table])) {
         $data[$my_table] += $new_data;
     } else {
         $data[$my_table] = $new_data;
     }
 }
예제 #3
0
 /**
  * 批量获取数据
  *
  * @param OOP_ORM $finder
  * @param OOP_ORM_Data $obj
  * @return null|OOP_ORM_Data
  */
 protected function get_data_batch_type(OOP_ORM $finder, OOP_ORM_Data $obj, $type)
 {
     $config = $this->config();
     $mapping = $config['mapping'];
     $where = $config['where'];
     $bind = isset($config['bind']) ? $config['bind'] : null;
     $bind_field = $this->field_name;
     $group = array();
     if ($group_ids = $obj->__orm_callback('get_group_ids')) {
         $obj_class = get_class($obj);
         $next = true;
         // 用来判断使得要跳出while循环
         $offset = 0;
         // 起始位置
         $limit = 100;
         // 单组批量获取数,这样可以避免某些组数量特别多时导致异常问题
         while ($next) {
             $found_count = 0;
             foreach ($group_ids as $group_id) {
                 $tmp_group_data = OOP_ORM_Result::get_data_by_group_id($group_id, $offset, $limit);
                 $found_count += count($tmp_group_data);
                 foreach ($tmp_group_data as $item) {
                     if (get_class($item) !== $obj_class) {
                         # 不是相同类型的对象
                         continue;
                     }
                     if ($item === $obj) {
                         # 同一个对象
                         $next = false;
                     }
                     if ($item->__orm_callback('is_compiled', $this->key)) {
                         # 已经构造过的数据忽略
                         continue;
                     }
                     if ($found_count > $limit) {
                         $next = false;
                     }
                     $group[] = $item;
                 }
             }
             if (!$found_count) {
                 # 没有可用的返回数
                 break;
             }
             $offset += $limit;
         }
     }
     if (!$group) {
         # 没有获取到任何组,则采样单个获取的方法
         OOP_ORM_DI_ORM::set_query_info($obj, $finder, $config);
         return $finder->find()->current();
     }
     $batch_where = array();
     foreach ($group as $item) {
         /**
          * @var $item OOP_ORM_Data
          */
         foreach ($mapping as $k => $v) {
             $batch_where[$k][] = $item->{$v};
         }
         foreach ($where as $k => $v) {
             $batch_where[$k][] = $v;
         }
         if ($bind) {
             $batch_where[$bind][] = $item->get_data_by_field_name($bind_field, true);
         }
     }
     # 对数据进行去重处理
     $batch_where = array_map('array_unique', $batch_where);
     $return = null;
     if (1 === count($batch_where)) {
         # 只有1个条件
         $c_key = key($batch_where);
         //当前字段名
         $in = current($batch_where);
         //获取where条件
         $rs = array();
         $g = $finder->in($c_key, $in)->find();
         $obj->__orm_callback('set_key_batch_orm_group', $g);
         foreach ($g as $item) {
             $k = $item->get_data_by_field_name($c_key, true);
             $item->__orm_callback('add_parent_group_id', $group_ids);
             $rs[$k][] = $item;
         }
         foreach ($group as $item) {
             if ($mapping) {
                 $v = current($mapping);
                 $k = $item->{$v};
             } elseif ($where) {
                 $k = current($where);
             } elseif ($bind) {
                 $k = $item->get_data_by_field_name($bind_field, true);
             } else {
                 $k = null;
             }
             if (!isset($rs[$k])) {
                 if ($type !== OOP_ORM::PARAM_TYPE_O2O) {
                     $current = array();
                 } else {
                     $current = null;
                 }
             } else {
                 $current = $rs[$k];
                 if ($type === OOP_ORM::PARAM_TYPE_O2O) {
                     $current = current($current);
                 }
             }
             if ($item === $obj) {
                 $return = $current;
             } else {
                 # 通过回调设置ORM批量获取的数据
                 $item->__orm_callback('set_batch_orm_data', $this->key, $current);
             }
         }
     } else {
         foreach ($batch_where as $k => $v) {
             $finder->in($k, $v);
             $finder->group_by($k);
         }
         # 组织数据
         $rs = array();
         foreach ($finder->find() as $item) {
             /**
              * @var $item OOP_ORM_Data
              */
             $k = '';
             foreach ($mapping as $m_k => $v) {
                 $k .= ',' . $item->{$m_k};
             }
             foreach ($where as $m_value) {
                 $k .= ',' . $m_value;
             }
             if ($bind) {
                 $k .= ',' . $item->get_data_by_field_name($bind, true);
             }
             if (!isset($rs[$k])) {
                 $rs[$k] = $item;
             }
         }
         foreach ($group as $i => $item) {
             $k = '';
             foreach ($mapping as $m_key) {
                 $k .= ',' . $item->{$m_key};
             }
             foreach ($where as $m_value) {
                 $k .= ',' . $m_value;
             }
             if ($bind) {
                 $k .= ',' . $item->get_data_by_field_name($bind_field, true);
             }
             if (!isset($rs[$k])) {
                 # 有可能数据库中没有对应的数据
                 if ($type !== OOP_ORM::PARAM_TYPE_O2O) {
                     $current = array();
                 } else {
                     $current = null;
                 }
             } else {
                 $current = $rs[$k];
                 if ($type === OOP_ORM::PARAM_TYPE_O2O) {
                     $current = current($current);
                 }
             }
             if ($item === $obj) {
                 $return = $current;
             } else {
                 # 通过回调设置ORM批量获取的数据
                 $item->__orm_callback('set_batch_orm_data', $this->key, $current);
             }
         }
     }
     return $return;
 }
예제 #4
0
 /**
  * 构造数据
  *
  * @param OOP_ORM_Data $obj
  * @param $data
  * @param $compiled_data
  * @return bool
  * @throws Exception
  */
 public function &get_data(OOP_ORM_Data $obj, &$data, &$compiled_data, &$compiled_raw_data)
 {
     $parent_offset = $this->config['parent_offset'];
     $sub_offsets = $this->config['sub_offsets'];
     $tmp_data =& $obj->{$parent_offset};
     foreach ($sub_offsets as $key) {
         if (null === $tmp_data) {
             throw new Exception("Illegal string offset '{$key}' of class {$this->class_name}, key:{$this->key}");
         }
         if (is_object($tmp_data)) {
             if (isset($tmp_data->{$key})) {
                 $tmp =& $tmp_data->{$key};
             } else {
                 $tmp = null;
             }
         } elseif (is_array($tmp_data)) {
             if (isset($tmp_data[$key])) {
                 $tmp =& $tmp_data[$key];
             } else {
                 $tmp = null;
             }
         } else {
             throw new Exception("Illegal string offset '{$key}' of class {$this->class_name}, key:{$this->key}");
         }
         unset($tmp_data);
         $tmp_data =& $tmp;
         unset($tmp);
     }
     # 移除指针
     unset($compiled_data[$this->key]);
     # 重新赋值
     $compiled_data[$this->key] =& $tmp_data;
     # 记录一个副本用于判断是否修改
     $compiled_raw_data[$this->key] = $tmp_data;
     # 回调
     $obj->__orm_callback('set_virtual_field_update', $parent_offset, $this->key);
     return $compiled_data[$this->key];
 }