//---------- meta behavior --------------------------------------
/** Returns an instance of the described class
* or if polymorphismPropName is set, from class according to data
* initialized from the data in the supplied associative array.
* When loading several tables may have been JOINed by the database. Eventually
* missing data is loaded using an extra query. In case of polymorphic retrieval
* that starts with a supertype, the mechanism is not efficient for the habit of
* MySQL not to include keys for null values: it causes en extra query to load
* 'missing' fields that are already queried for. It would be better to fetch the
* data as an indexed array, than map the indexes directly to fields...
* @return PntDbObject (new or from chache)
* @throws PntError
*/
function ($assocArray, $delegator) {
//polymorhism support: delegate to appropriate classDescriptor
if (!$delegator && $this->polymorphismPropName && $assocArray[$this->polymorphismPropName]
&& $assocArray[$this->polymorphismPropName] != $this->() ) {
if (!class_exists($assocArray[$this->polymorphismPropName])) {
$this->($assocArray[$this->polymorphismPropName]); //throws PntError
Gen::includeClass($assocArray[$this->polymorphismPropName], $this->() ); //checked by checkPolyClassName
}
$clsDes = $this->($assocArray[$this->polymorphismPropName]);
return $clsDes->($assocArray, $this);
}
//create instance of described class and initialize it
$map = $this->();
if (isSet($map['id']) && isSet($this->peanutsById[$assocArray[$map['id']]])) {
return $this->peanutsById[$assocArray[$map['id']]];
} else {
$toInstantiate = $this->();
$peanut = new $toInstantiate();
$missingFieldsMap =& $peanut->($assocArray, $map);
if (count($missingFieldsMap) != 0)
if ($delegator) {
$result = $this->($peanut, $assocArray['id'], $missingFieldsMap, $delegator);
if ($result) return $result; //query error
} else {
$peanut->($missingFieldsMap);
}
$id = isSet($map['id']) ? $assocArray[$map['id']] : $peanut->();
$this->peanutsById[$id] = $peanut;
return $this->peanutsById[$id];
}
}
|