Example #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;
 }
Example #2
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];
 }
Example #3
0
 /**
  * 根据index获取一个唯一的缓存key
  * @param string $index
  * @return string
  */
 public static function get_offset_cache_key(\OOP_ORM_Data $data_obj, $index)
 {
     $id_field_name = $data_obj->id_field_name();
     $id_value = $data_obj->{$id_field_name};
     return '_ORM_OFFSET_CACHE_' . \str_replace('\\', '__', \get_class($data_obj)) . '_' . $id_value . '_' . $index;
 }
Example #4
0
 /**
  * 设置用户
  *
  * @param Member $member
  * @return Session
  */
 public function set_member(OOP_ORM_Data $member)
 {
     Session::$member = $member;
     if ($member->id > 0) {
         # 设置用户数据
         $member_data = $member->get_field_data();
         $_SESSION['member'] = $member_data;
     } else {
         # 游客数据则清空
         unset($_SESSION['member']);
     }
     return $this;
 }
Example #5
0
 /**
  * 用于给ORM回调设置数据
  * @param array $data 待设置的数据
  * @param boolean $is_field_key 待设置的数据的key是否数据库的字段,true是,false则为offset
  */
 protected function __orm_callback_ini_data_($data = null, $is_field_key = false)
 {
     if (!is_array($data)) {
         return false;
     }
     # 记录当前orm是否构造完成
     $created = $this->_orm_data_is_created;
     # 将orm设置为未构造状态,因为set_data时会根据构造状态执行不同的操作
     $this->_orm_data_is_created = false;
     # 如果是字段数据,则整理为offset数据
     if ($is_field_key) {
         foreach ($data as $key => $value) {
             # 获取当前字段的首个offset
             $offset = current($this->_get_offset_name_by_field($key));
             if (!$offset) {
                 $offset = $key;
             }
             $this->set_data($offset, $value, false);
         }
     } else {
         # 设置数据
         $this->set_data($data, null, false);
     }
     # 还原状态
     $this->_orm_data_is_created = $created;
     # ID数据缓存,用于重复ID主键数据查询时直接返回
     if (IS_CLI && $is_field_key) {
         $id_field_name = $this->id_field_name();
         $id = $data[$id_field_name];
         if (OOP_ORM_Data::$_id_field_cache_data_num > OOP_ORM_Data::$max_id_cache_num) {
             // 超过最大cache数则清除掉
             OOP_ORM_Data::$_id_field_cache_data = array();
         }
         if ($id && !isset(OOP_ORM_Data::$_id_field_cache_data[$this->_class_name][$id])) {
             OOP_ORM_Data::$_id_field_cache_data[$this->_class_name][$id] = $data;
             OOP_ORM_Data::$_id_field_cache_data_num += 1;
         }
     }
 }
Example #6
0
 /**
  * 根据$bulider条件解析获取已缓存在PHP的数据
  * @param array $bulider
  * @param array $id_cache_data
  * @return boolean 是否需要再次读取
  */
 protected function _get_id_field_cache_data(&$bulider, &$id_cache_data)
 {
     $not_need_find = false;
     # $bulider条件中只有1个where,则尝试在数据ID缓存中获取
     if (count($bulider['where']) == 1 && ($bulider['where'][0]['AND'][1] == '=' || $bulider['where'][0]['AND'][1] == 'in')) {
         #
         foreach ($bulider['where'] as $k => $v) {
             if ($v && $k != 'where') {
                 return $not_need_find;
             }
         }
         $field_name = $bulider['where'][0]['AND'][0];
         if ($field_name == $this->id_field_name()) {
             $value = $bulider['where'][0]['AND'][2];
             $id_data = OOP_ORM_Data::id_field_cache_data($this->get_orm_name('Data'), $value);
             if ($id_data) {
                 # 获取到数据
                 if ($bulider['where'][0]['AND'][1] == 'in') {
                     $new_value = array();
                     foreach ($value as $v) {
                         if (!isset($id_data[$v])) {
                             $new_value[] = $v;
                         }
                     }
                     if ($new_value) {
                         # 更新where条件
                         $bulider['where'][0]['AND'][2] = $new_value;
                     } else {
                         $not_need_find = true;
                     }
                     $id_cache_data = $id_data;
                 } else {
                     $not_need_find = true;
                     $id_cache_data = array($id_data);
                 }
             }
         }
     }
     return $not_need_find;
 }
Example #7
0
 /**
  * 删除当前管理员
  *
  * @see OOP_ORM_Data::delete()
  * @return integer 操作行数
  * @throws Exception
  */
 public function delete()
 {
     $id = $this->id;
     $rs = parent::delete();
     if ($rs) {
         # 删除管理员对应的用户组设置
         $orm_group = new ORM_Admin_MemberGroup_Finder();
         $orm_group->db()->where('admin_id', $id)->delete($orm_group->ids_tablename());
     }
     return $rs;
 }
Example #8
0
 /**
  * 获取一个根据主键唯一的实例化对象
  *
  * @param $orm_data_name
  * @param $data
  * @param OOP_ORM $finder
  * @param bool $is_field_key
  * @param array $delay_data_setting 延迟读取参数
  * @return OOP_ORM_Data
  */
 public static function create_instance($orm_data_name, array $data = array(), $finder = null, $is_field_key = false, array $delay_data_setting = array())
 {
     $orm_data_name = strtolower($orm_data_name);
     if ('oop_orm_data' === $orm_data_name) {
         # $orm_data_name = OOP_ORM_Data 的话是虚拟对象,虚拟对象不缓存
         return new $orm_data_name($data, $finder, $is_field_key, $delay_data_setting);
     }
     if ($data && isset(OOP_ORM_Data::$INSTANCE_BY_PK[$orm_data_name]) && OOP_ORM_Data::$INSTANCE_BY_PK[$orm_data_name]) {
         # 复用寄存器中的对象
         /**
          * 利用一个临时对象获取主键名
          *
          * @var $tmp_obj OOP_ORM_Data
          */
         $tmp_obj = current(OOP_ORM_Data::$INSTANCE_BY_PK[$orm_data_name]);
         # 获取主键
         $pk_name = $tmp_obj->get_pk_name();
         unset($tmp_obj);
         if ($pk_name) {
             $tmp_id = array();
             if ($is_field_key) {
                 # 字段名
                 foreach ($pk_name as $field_name) {
                     $tmp_id[] = $data[$field_name];
                 }
                 $pk = implode(',', $tmp_id);
             } else {
                 /**
                  * 实例化一个新的对象
                  *
                  * @var $orm OOP_ORM_Data
                  */
                 $tmp_orm = new $orm_data_name($data, $finder, $is_field_key, $delay_data_setting);
                 # 字段名
                 foreach ($pk_name as $field_name) {
                     $tmp_id[] = $orm->{$field_name};
                 }
                 $pk = implode(',', $tmp_id);
             }
         } else {
             $pk = null;
         }
         if ($pk && isset(OOP_ORM_Data::$INSTANCE_BY_PK[$orm_data_name][$pk])) {
             /**
              * 获取唯一主键的对象
              *
              * @var $orm OOP_ORM_Data
              */
             $orm = OOP_ORM_Data::$INSTANCE_BY_PK[$orm_data_name][$pk];
             # 更新ORM数据
             if ($data) {
                 $orm->__orm_callback('renew_data', $data, $is_field_key);
             }
             if ($finder) {
                 $orm->__orm_callback('set_finder', $finder);
             }
             return $orm;
         }
     }
     if (isset($tmp_orm)) {
         $orm = $tmp_orm;
     } else {
         if (!class_exists($orm_data_name, true)) {
             throw new Exception("Class '{$orm_data_name}' not found", E_ERROR);
         }
         /**
          * 实例化一个新的对象
          *
          * @var $orm OOP_ORM_Data
          */
         $orm = new $orm_data_name($data, $finder, $is_field_key, $delay_data_setting);
     }
     if ($data && ($pk = $orm->pk())) {
         if (OOP_ORM_Data::$NEW_INSTANCE_COUNT >= OOP_ORM_Data::$RELEASE_INSTANCE_COUNT) {
             $old_released_count = OOP_ORM_Data::$RELEASED_COUNT;
             foreach (OOP_ORM_Data::$INSTANCE_BY_PK as $item) {
                 foreach ($item as $o) {
                     /**
                      * @var $o OOP_ORM_Data
                      */
                     $o->__orm_callback('try_release');
                 }
             }
             unset($item);
             unset($o);
             $released_count = OOP_ORM_Data::$RELEASED_COUNT - $old_released_count;
             # 重置计数器
             OOP_ORM_Data::$NEW_INSTANCE_COUNT = 0;
             OOP_ORM_Data::$ALL_INSTANCE_COUNT -= $released_count;
             if (IS_DEBUG && $released_count) {
                 Core::debug()->info("auto release {$released_count} orm.");
             }
         }
         OOP_ORM_Data::register_instance($orm, $orm_data_name, $pk);
     }
     return $orm;
 }
Example #9
0
 /**
  * 创建一条数据
  *
  * 如果 `$data` 是数据库获取的内容,`$is_field_key` 请设置成 true
  *
  * `$is_field_key` 详细说明:
  * `$is_field_key` 是所传进来的数据的key是对象的键名还是字段的键名,true:对应字段的键名,false:对应对象的键名
  * 差别在于:
  * 由于ORM DATA的键名可以和数据库的字段名称不一样,所以在设置数据的时候需要指定是哪个数据,如果键名和数据库的字段名完全一样,这样的话则没有区别
  *
  * @param array $data 数据
  * @param boolean $is_field_key 数据的键名是否数据库字段,默认false
  * @param string $group_id 分组ID,可不传
  * @throws Exception
  */
 public function create(array $data = array(), $is_field_key = false, $group_id = null)
 {
     $orm_data_name = $this->get_orm_name('data');
     /**
      * @var $orm OOP_ORM_Data
      */
     $orm = OOP_ORM_Data::create_instance($orm_data_name, $data, $this, $is_field_key);
     if ($group_id) {
         # 设置组ID
         $orm->__orm_callback('add_group_id', $group_id);
     }
     return $orm;
 }
Example #10
0
 protected static function set_query_info(OOP_ORM_Data $obj, OOP_ORM $finder, $config)
 {
     # WHERE
     if ($config['where']) {
         $finder->where($config['where']);
     }
     # MAPPING
     if ($config['mapping']) {
         foreach ($config['mapping'] as $k => $v) {
             $finder->where($k, $obj->{$v});
         }
     }
     # 绑定数据
     if (isset($config['bind']) && $config['bind']) {
         $finder->where($config['bind'], $obj->get_data_by_field_name($config['bind'], true));
     }
     if (isset($config['order_by']) && $config['order_by']) {
         foreach ($config['order_by'] as $k => $v) {
             $finder->order_by($k, $v);
         }
     }
     # OFFSET
     if (isset($config['offset']) && $config['offset'] > 0) {
         $finder->offset($config['offset']);
     }
     # GROUP BY
     if (isset($config['group_by']) && $config['group_by']) {
         foreach ($config['group_by'] as $item) {
             $finder->group_by($item);
         }
     }
     # ORDER BY
     if (isset($config['order_by']) && $config['order_by']) {
         foreach ($config['order_by'] as $key => $item) {
             $finder->order_by($key, $item);
         }
     }
     # IN
     if (isset($config['in']) && $config['in']) {
         foreach ($config['in'] as $key => $item) {
             $finder->in($key, $item);
         }
     }
     # LIMIT
     if (isset($config['limit']) && $config['limit']) {
         $finder->limit($config['limit']);
     }
     # LIKE
     if (isset($config['like']) && $config['like']) {
         $finder->like($config['like']);
     }
     # HAVING
     if (isset($config['having']) && $config['having']) {
         $finder->having($config['having']);
     }
     # 支持扩展所有的方法
     if (isset($config['other']) && $config['other']) {
         foreach ($config['other'] as $argv) {
             $k = array_pop($argv);
             call_user_func_array(array($finder, $k), $argv);
         }
     }
 }
Example #11
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;
     }
 }
Example #12
0
 /**
  * 根据index获取一个唯一的缓存key
  * @param string $index
  * @return string
  */
 public static function get_offset_cache_key(OOP_ORM_Data $data_obj, $index)
 {
     $id_field_name = $data_obj->id_field_name();
     $id_value = $data_obj->{$id_field_name};
     return '_ORM_OFFSET_CACHE_' . get_class($data_obj) . '_' . $id_value . '_' . $index;
 }
Example #13
0
 /**
  * 加载对应数据库所有元数据
  *
  * @param OOP_ORM_Data $obj
  * @return $this
  * @throws Exception
  */
 public function load_all_metadata(OOP_ORM_Data $obj)
 {
     $class_name = $obj->class_name();
     $meta_table_of_key = OOP_ORM_DI::get_meta_table_of_key($class_name);
     $meta_group_of_key = OOP_ORM_DI::get_meta_group_of_key($class_name);
     if (!$meta_table_of_key) {
         # 没有元数据
         return $this;
     }
     # 没有主键
     if (!$obj->pk()) {
         return $this;
     }
     $keys_of_table = array();
     foreach ($meta_table_of_key as $key => $table) {
         $keys_of_table[$table][] = $key;
     }
     $data = array();
     $groups_of_table = array();
     # 读数据
     foreach ($keys_of_table as $table => $keys) {
         foreach ($this->load_metadata($obj, $table) as $hash => $item) {
             $data[$table][$item['meta_group']][$hash] = $item;
         }
         foreach ($keys as $key) {
             $group = $meta_group_of_key[$key];
             $groups_of_table[$table][$group] = $group;
         }
     }
     foreach ($groups_of_table as $table => $groups) {
         foreach ($groups as $group) {
             # 预置空数据
             $obj->__orm_callback('set_metadata', $table, $group, array());
         }
     }
     foreach ($data as $table => $group_data) {
         foreach ($group_data as $group => $item) {
             $obj->__orm_callback('set_metadata', $table, $group, $item);
         }
     }
     return $this;
 }