public function __get($name)
{
if (!$this->_init) {
// The constructor must always be called first
$this->__construct();
// This object is about to be loaded by mysql_fetch_object() or similar
$this->state('loading');
}
if (!isset($this->_fields[$name])) {
throw new Sprig_Exception(':name model does not have a field :field', array(':name' => get_class($this), ':field' => $name));
}
if (isset($this->_related[$name])) {
// Shortcut to any related object
return $this->_related[$name];
}
$field = $this->_fields[$name];
if ($this->changed($name)) {
$value = $this->_changed[$name];
} elseif (array_key_exists($name, $this->_original)) {
$value = $this->_original[$name];
}
if ($field instanceof Sprig_Field_ForeignKey) {
if (!isset($this->_related[$name])) {
$model = Sprig::factory($field->model);
if ($field instanceof Sprig_Field_HasMany) {
if ($field instanceof Sprig_Field_ManyToMany) {
if (isset($value)) {
if (empty($value)) {
return new Database_Result_Cached(array(), '');
} else {
// TODO this needs testing
$wrapped = array_map(array($model->field($model->pk()), '_database_wrap'), $value);
$query = DB::select()->where($model->pk(), 'IN', $wrapped);
}
} else {
// We can grab the PK from the field definition.
// If it doesn't exist, revert to the model choice
if (isset($field->left_foreign_key) and $field->left_foreign_key) {
$fk = $field->through . '.' . $field->left_foreign_key;
$fk2 = $field->through . '.' . $model->pk();
} else {
$fk = $this->fk($field->through);
$fk2 = $model->fk($field->through);
}
$query = DB::select()->join($field->through)->on($fk2, '=', $model->pk(TRUE))->where($fk, '=', $this->_fields[$this->_primary_key]->_database_wrap($this->{$this->_primary_key}));
}
} else {
if (isset($value)) {
$query = DB::select()->where($model->pk(), '=', $field->_database_wrap($value));
} else {
if (isset($field->foreign_key) and $field->foreign_key) {
$fk = $field->foreign_key;
} else {
$fk = $this->fk();
}
$query = DB::select()->where($fk, '=', $this->_fields[$this->_primary_key]->_database_wrap($this->{$this->_primary_key}));
}
}
$related = $model->load($query, NULL);
if (!$this->changed($name)) {
// We can assume this is the original value because no
// changed value exists
$this->_original[$name] = $field->value($related);
}
} elseif ($field instanceof Sprig_Field_BelongsTo) {
if (isset($field->primary_key) and $field->primary_key) {
$pk = $field->primary_key;
} else {
$pk = $model->pk();
}
$related = $model->values(array($pk => $value));
} elseif ($field instanceof Sprig_Field_HasOne) {
$related = $model->values(array($this->_model => $this->{$this->_primary_key}));
}
$value = $this->_related[$name] = $related;
}
}
return $value;
}