/** * Hydrate model instances with retrieved data * * @param array &$row Row from the database * @param array $models Relations to be expected * @param array $result Current result array (by reference) * @param string $model Optionally. Model classname to hydrate * @param array $select Optionally. Columns to use * @param array $primary_key Optionally. Primary key(s) for this model * * @return Model */ public function hydrate(&$row, $models, &$result, $model = null, $select = null, $primary_key = null) { // First check the PKs, if null it's an empty row foreach ($select as $column) { if (is_string($column[0])) { $r1c1 = $column; break; } } $prefix = substr($r1c1[0], 0, strpos($r1c1[0], '.') + 1); $obj = array(); foreach ($primary_key as $pk) { $pk_c = null; foreach ($select as $s) { $s[0] === $prefix . $pk and $pk_c = $s[1]; } if (is_null($row[$pk_c])) { return false; } $obj[$pk] = $row[$pk_c]; } // Check for cached object $pk = count($primary_key) == 1 ? reset($obj) : '[' . implode('][', $obj) . ']'; $obj = $this->from_cache ? Model::cached_object($pk, $model) : false; // Create the object when it wasn't found if (!$obj) { // Retrieve the object array from the row $obj = array(); foreach ($select as $s) { if ($s[0] instanceof \Fuel\Core\Database_Expression) { $f = isset($this->select[$s[1]][1]) ? $this->select[$s[1]][1] : $s[1]; } else { $f = substr($s[0], strpos($s[0], '.') + 1); } $obj[$f] = $row[$s[1]]; if (in_array($f, $primary_key)) { $obj[$f] = \Orm\Observer_Typing::typecast($f, $obj[$f], call_user_func($model . '::property', $f)); } unset($row[$s[1]]); } $obj = $model::forge($obj, false, $this->view ? $this->view['_name'] : null, $this->from_cache); } else { // add fields not present in the already cached version foreach ($select as $s) { $f = substr($s[0], strpos($s[0], '.') + 1); if (!isset($obj->{$f})) { $obj->{$f} = $row[$s[1]]; } } } // if the result to be generated is an array and the current object is not yet in there if (is_array($result) and !array_key_exists($pk, $result)) { $result[$pk] = $obj; } elseif (!is_array($result) and empty($result)) { $result = $obj; } // start fetching relationships $rel_objs = $obj->_relate(); $relations_updated = array(); foreach ($models as $m) { // when the expected model is empty, there's nothing to be done if (empty($m['model'])) { continue; } $relations_updated[] = $m['rel_name']; // when not yet set, create the relation result var with null or array if (!array_key_exists($m['rel_name'], $rel_objs)) { $rel_objs[$m['rel_name']] = $m['relation']->singular ? null : array(); } // when result is array or singular empty, try to fetch the new relation from the row $this->hydrate($row, !empty($m['models']) ? $m['models'] : array(), $rel_objs[$m['rel_name']], $m['model'], $m['columns'], $m['primary_key']); } // attach the retrieved relations to the object and update its original DB values $obj->_relate($rel_objs); $obj->_update_original_relations($relations_updated); return $obj; }
/** * Hydrate model instances with retrieved data * * @param array row from the database * @param array relations to be expected * @param array current result array (by reference) * @param string model classname to hydrate * @param array columns to use */ public function hydrate(&$row, $models, &$result, $model = null, $select = null, $primary_key = null) { // First check the PKs, if null it's an empty row $r1c1 = reset($select); $prefix = substr($r1c1[0], 0, strpos($r1c1[0], '.') + 1); $obj = array(); foreach ($primary_key as $pk) { $pk_c = null; foreach ($select as $s) { $s[0] === $prefix . $pk and $pk_c = $s[1]; } if (is_null($row[$pk_c])) { return false; } $obj[$pk] = $row[$pk_c]; } // Check for cached object $pk = count($primary_key) == 1 ? reset($obj) : '[' . implode('][', $obj) . ']'; $obj = Model::cached_object($pk, $model); // Create the object when it wasn't found if (!$obj) { // Retrieve the object array from the row $obj = array(); foreach ($select as $s) { $obj[substr($s[0], strpos($s[0], '.') + 1)] = $row[$s[1]]; unset($row[$s[1]]); } $obj = $model::factory($obj, false); } // if the result to be generated is an array and the current object is not yet in there if (is_array($result) and !array_key_exists($pk, $result)) { $result[$pk] = $obj; } elseif (!is_array($result) and empty($result)) { $result = $obj; } // start fetching relationships $rel_objs = $obj->_relate(); foreach ($models as $m) { // when the expected model is empty, there's nothing to be done if (empty($m['model'])) { continue; } // when not yet set, create the relation result var with null or array if (!array_key_exists($m['rel_name'], $rel_objs)) { $rel_objs[$m['rel_name']] = $m['relation']->singular ? null : array(); } // when result is array or singular empty, try to fetch the new relation from the row $this->hydrate($row, !empty($m['models']) ? $m['models'] : array(), $rel_objs[$m['rel_name']], $m['model'], $m['columns'], $m['primary_key']); } // attach the retrieved relations to the object and update its original DB values $obj->_relate($rel_objs); $obj->_update_original_relations(); return $obj; }