/** * This method kind of does... everything. It's the backbone of every read operation * and is a bit difficult to understand/explain * @param query - (optional) a query to load from (otherwise loadQuery is called) * @access private * @see fetch */ public function loadMultiple($query = '') { $ret = array(); $all_objects = array(); if (!$query instanceof Query) { $query = $this->loadQuery(); } $path = $this->queryCache($query); if (!$query->done()) { $query->doQuery(); } $all_objects = array(); $keys = array(); $rel_map = array(); $to_load = $this->flatten($keys, $rel_map); $my_keys = $keys[$this->getClass()]; $index = 0; $exc = array(); $class_counts = array(); foreach ($this->exclude as $exc_obj) { DbObject::addKeys($exc_obj, $keys); } if (!($ret = $this->cached($path))) { while ($row = $query->next()) { foreach ($to_load as $load) { $load_class = $load->getClass(); //true); $load_fetch_class = $load->getFetchClass(); //true); if (!isset($class_counts[$load_class])) { $class_counts[$load_class] = 0; } $class_counts[$load_class]++; if ($key = DbObject::completeKeyFromKeysAndArray($keys[$load_class], $row)) { $ref = $load_class . $key; if (!isset($all_objects[$ref])) { $all_objects[$ref] = $load->constructFromCompleteKey($key); $all_objects[$ref]->requires_insert = false; $all_objects[$ref]->table->setQuery($query, $index); } if (isset($rel_map[$load_class])) { if ($rel_map[$load_class]->rels[$load_fetch_class] == DbObject::JOIN_REL) { $rel_class = $rel_map[$load_class]->joins[$load_fetch_class]; $rel_obj = new $rel_class(); if ($key = DbObject::completeKeyFromKeysAndArray($keys[$rel_class], $row)) { $to_add = $rel_obj->constructFromCompleteKey($key); $to_add->table->setQuery($query, $index); $to_add->requires_insert = false; $all_objects[$ref]->add($to_add); } } else { if ($rel_map[$load_class]->rels[$load_fetch_class] == DbObject::FOREIGN_REL) { $parent_ref = $rel_map[$load_class]->getClass() . $rel_map[$load_class]->completeKeyFromArray($row); $all_objects[$parent_ref]->add($all_objects[$ref]); } } } } } $index = $query->currentIndex(); } $exc = array(); $this_class = $this->getClass(true); foreach ($all_objects as $obj) { if ($obj instanceof $this_class) { $obj->load_foreign = $this->load_foreign; } $class = $obj->getClass(); if (isset($rel_map[$class])) { $parent_class = $rel_map[$class]->getClass(); $parent_keys = DbObject::parentKeys($obj, $rel_map, $keys); if ($rel_map[$class]->rels[$class] == DbObject::DEPEND_REL) { $complete = implode('-', $parent_keys); foreach ($all_objects as $depend_add_key => $depend_add_obj) { if (strpos($depend_add_key, $parent_class . $complete) !== FALSE) { //$all_objects[$depend_add_key]->add($obj); try { if (isset($all_objects[$depend_add_key]->existing_objects[$obj->getClass()]) && count($all_objects[$depend_add_key]->existing_objects[$obj->getClass()]) <= $obj->getLimit() || !isset($all_objects[$depend_add_key]->existing_objects[$obj->getClass()])) { $all_objects[$depend_add_key]->add($obj); } } catch (Exception $e) { $all_objects[$depend_add_key]->add($obj); } } } } else { if ($parent_keys) { foreach ($parent_keys as $parent_key) { if (isset($all_objects[$parent_class . $parent_key]) && !in_array($class, $this->exclude_classes)) { try { if (isset($all_objects[$parent_class . $parent_key]->existing_objects[$obj->getClass()]) && count($all_objects[$parent_class . $parent_key]->existing_objects[$obj->getClass()]) <= $obj->getLimit() || !isset($all_objects[$parent_class . $parent_key]->existing_objects[$obj->getClass()])) { $all_objects[$parent_class . $parent_key]->add($obj); } } catch (Exception $e) { $all_objects[$parent_class . $parent_key]->add($obj); } } else { if (in_array($class, $this->exclude_classes)) { unset($ret[$parent_key]); $exc[] = $parent_key; } } } } } } else { if (!in_array($obj->completeKey(), $exc)) { $ret[$obj->completeKey()] = $obj; } } } $this->cache($path, $ret); } else { $stack = array(); $cur = $ret; while ($cur) { foreach ($cur as $obj) { if (count($obj->existing_objects) && is_array($obj->existing_objects)) { $arr = array(); foreach ($obj->existing_objects as $objs) { $arr = array_merge($arr, $objs); } array_push($stack, $arr); } $obj->table->setQuery($query); } $cur = array_pop($stack); } } $this->reset(); return $ret; }