/**
* Method to load a row from the database by primary key and bind the fields to the Table instance properties.
*
* @param mixed $keys An optional primary key value to load the row by, or an array of fields to match.
* If not set the instance property value is used.
* @param boolean $reset True to reset the default values before loading the new row.
*
* @return boolean True if successful. False if row not found.
*
* @since 1.7.0
* @throws \InvalidArgumentException
* @throws \RuntimeException
* @throws \UnexpectedValueException
*/
public function load($keys = null, $reset = true)
{
// Pre-processing by observers
$event = AbstractEvent::create('onTableBeforeLoad', ['subject' => $this, 'keys' => $keys, 'reset' => $reset]);
$this->getDispatcher()->dispatch('onTableBeforeLoad', $event);
if (empty($keys)) {
$empty = true;
$keys = array();
// If empty, use the value of the current key
foreach ($this->_tbl_keys as $key) {
$empty = $empty && empty($this->{$key});
$keys[$key] = $this->{$key};
}
// If empty primary key there's is no need to load anything
if ($empty) {
return true;
}
} elseif (!\is_array($keys)) {
// Load by primary key.
$keyCount = \count($this->_tbl_keys);
if ($keyCount) {
if ($keyCount > 1) {
throw new \InvalidArgumentException('Table has multiple primary keys specified, only one primary key value provided.');
}
$keys = array($this->getKeyName() => $keys);
} else {
throw new \RuntimeException('No table keys defined.');
}
}
if ($reset) {
$this->reset();
}
// Initialise the query.
$query = $this->_db->getQuery(true)->select('*')->from($this->_tbl);
$fields = array_keys($this->getProperties());
foreach ($keys as $field => $value) {
// Check that $field is in the table.
if (!\in_array($field, $fields)) {
throw new \UnexpectedValueException(sprintf('Missing field in database: %s %s.', \get_class($this), $field));
}
// Add the search tuple to the query.
$query->where($this->_db->quoteName($field) . ' = ' . $this->_db->quote($value));
}
$this->_db->setQuery($query);
$row = $this->_db->loadAssoc();
// Check that we have a result.
if (empty($row)) {
$result = false;
} else {
// Bind the object with the row and return.
$result = $this->bind($row);
}
// Post-processing by observers
$event = AbstractEvent::create('onTableAfterLoad', ['subject' => $this, 'result' => &$result, 'row' => $row]);
$this->getDispatcher()->dispatch('onTableAfterLoad', $event);
return $result;
}