private function _get_virtual($n) { $sourcefield = $n . "_id"; if (array_key_exists($n, $this->_virtuals)) { #error_log("returning previously set value for virtual $n"); return array(true, $this->_virtuals[$n]); } # first, find out if this table references another table # through an *_id column # user_id => user # postedby_user_id => user # matches a single row, returns one object #error_log("checking for $sourcefield"); if (array_key_exists($sourcefield, $this->_fields)) { #error_log("$sourcefield found"); if (preg_match(self::$RETABLES, $sourcefield, $m)) { #lib::el($m); list($junk, $virtual, $junk, $foreigntab) = $m; # $virtual should equal $n at this point if ($foreigntab != get_class($this)) { # can't reference ourself, there would be confusion # over the virtual field names and single-vs-multiple # values with the forward and back references $fi = self::_modelinfo($foreigntab); if ($fi) { #error_log("joining ".get_class($this).".$sourcefield to $foreigntab"); # populate the virutals list for the model # not the best place to do this self::$MODELINFO[$foreigntab]['virtuals'][$foreigntab] = true; # TEMP, for testing $v = self::_find_first($foreigntab, array($this->{$sourcefield})); $this->_virtuals[$n] = $v; return array(true, $v); } } } } $ti = self::_modelinfo($this); $oi = self::_modelinfo($n); #error_log("looking for intermediary table"); if ($oi && count($ti['primarykey']) == 1) { # now, try to find an intermedary table that joins us to another table # it's going to be named either $n_$this or $this_$n # and it will contain a reference to this table # and a reference to the model named $n # returns an array of objects, could be a many-to-many mapping $o = array(sprintf('%s_%s', $ti['model'], $n), sprintf('%s_%s', $n, $ti['model'])); foreach ($o as $thrutbname) { $thruti = self::_modelinfo($thrutbname); if (!$thruti) { continue; } error_log("found {$thrutbname}"); $refme = sprintf('%s_id', $ti['model']); $refother = sprintf('%s_id', $oi['model']); if (isset($thruti['columns'][$refme]) && isset($thruti['columns'][$refother])) { # oi thruti oi x thruti x thruti x #select a.* from image a left join product_image b on a.id = b.image_id where b.product_id = 10; $q = sprintf('select a.* from %s a left join %s b on a.%s = b.%s where b.%s = ?:id', $oi['tableQ'], $thruti['tableQ'], $oi['primarykey']['id'], $refother, $refme); error_log($q); $v = self::_find($n, array(array($q, array('id' => $this->id)))); $x = new ModelCollection($n); $x->merge($v); $this->_virtuals[$n] = $x; return array(true, $x); } } } # otherwise, the other table may reference this one by having a column # that matches *_THISMODEL_id # returns an array #if (preg_match(self::$RETABLES, $ci['Field'], $m)) return array(false, false); #$ti = self::_modelinfo($n); #if (!$ti) return array(false, false); /* # resolve a virtual column $ti = self::_modelinfo($this); if (!$ti) return NULL; if (isset($ti['virtuals'][$n])) { if (!isset($this->_virtuals[$n])) { error_log("getting value for $n"); $fkmodel = $ti['virtuals'][$n]['fkmodel']; $sourcefield = $ti['virtuals'][$n]['sourcefield']; $this->_virtuals[$n] = self::_find($fkmodel, array($this->$sourcefield)); } return $this->_virtuals[$n]; } */ }
private function _run_virtual_conditions($vi) { switch ($vi['type']) { case MODELForeignRefFindByPrimaryKey: #error_log("doing by pk for ".var_export($vi, true)."<br/>"); $cond = $this->_Manipulation_real_columns[$vi['sourcecolumn']]; $value = self::_find_first($vi['model'], array($cond)); break; case MODELForeignRefFindByQuery: #error_log("doing by query for ".var_export($vi, true)); $searchval = $this->_Manipulation_real_columns[$vi['sourcecolumn']]; $cond = array($vi['query'], array('id' => $searchval)); $value = self::_find($vi['model'], array($cond)); $c = new ModelCollection($vi['model']); $c->merge($value); $value = $c; break; case MODELForeignRefFindByRelation: #error_log("doing by relation for ".var_export($vi, true)."<br />"); $searchcol = $vi['foreigncolumn']; $searchval = $this->_Manipulation_real_columns[$vi['sourcecolumn']]; $cond = array($searchcol => $searchval); $value = self::_find($vi['model'], array($cond)); $c = new ModelCollection($vi['model']); $c->merge($value); $value = $c; break; case MODELForeignRefFindByRelationSingle: #error_log("doing by single relation for ".var_export($vi, true)."<br />"); $searchcol = $vi['foreigncolumn']; $searchval = $this->_Manipulation_real_columns[$vi['sourcecolumn']]; $cond = array($searchcol => $searchval); $value = self::_find_first($vi['model'], array($cond)); break; default: throw new Exception("unimplemented Model Type value"); } return $value; }