/**
* Method to store a row in the database from the Table instance properties.
*
* If a primary key value is set the row with that primary key value will be updated with the instance property values.
* If no primary key value is set a new row will be inserted into the database with the properties from the Table instance.
*
* @param boolean $updateNulls True to update fields even if they are null.
*
* @return boolean True on success.
*
* @since 1.7.0
*/
public function store($updateNulls = false)
{
$result = true;
$k = $this->_tbl_keys;
// Pre-processing by observers
$event = AbstractEvent::create('onTableBeforeStore', ['subject' => $this, 'updateNulls' => $updateNulls, 'k' => $k]);
$this->getDispatcher()->dispatch('onTableBeforeStore', $event);
$currentAssetId = 0;
if (!empty($this->asset_id)) {
$currentAssetId = $this->asset_id;
}
// The asset id field is managed privately by this class.
if ($this->_trackAssets) {
unset($this->asset_id);
}
// We have to unset typeAlias since updateObject / insertObject will try to insert / update all public variables...
$typeAlias = $this->typeAlias;
unset($this->typeAlias);
try {
// If a primary key exists update the object, otherwise insert it.
if ($this->hasPrimaryKey()) {
$this->_db->updateObject($this->_tbl, $this, $this->_tbl_keys, $updateNulls);
} else {
$this->_db->insertObject($this->_tbl, $this, $this->_tbl_keys[0]);
}
} catch (\Exception $e) {
$this->setError($e->getMessage());
$result = false;
}
$this->typeAlias = $typeAlias;
// If the table is not set to track assets return true.
if ($this->_trackAssets) {
if ($this->_locked) {
$this->_unlock();
}
/*
* Asset Tracking
*/
$parentId = $this->_getAssetParentId();
$name = $this->_getAssetName();
$title = $this->_getAssetTitle();
/** @var Asset $asset */
$asset = self::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo()));
$asset->loadByName($name);
// Re-inject the asset id.
$this->asset_id = $asset->id;
// Check for an error.
$error = $asset->getError();
if ($error) {
$this->setError($error);
return false;
} else {
// Specify how a new or moved node asset is inserted into the tree.
if (empty($this->asset_id) || $asset->parent_id != $parentId) {
$asset->setLocation($parentId, 'last-child');
}
// Prepare the asset to be stored.
$asset->parent_id = $parentId;
$asset->name = $name;
// Respect the table field limits
$asset->title = StringHelper::substr($title, 0, 100);
if ($this->_rules instanceof Rules) {
$asset->rules = (string) $this->_rules;
}
if (!$asset->check() || !$asset->store($updateNulls)) {
$this->setError($asset->getError());
return false;
} else {
// Create an asset_id or heal one that is corrupted.
if (empty($this->asset_id) || $currentAssetId != $this->asset_id && !empty($this->asset_id)) {
// Update the asset_id field in this table.
$this->asset_id = (int) $asset->id;
$query = $this->_db->getQuery(true)->update($this->_db->quoteName($this->_tbl))->set('asset_id = ' . (int) $this->asset_id);
$this->appendPrimaryKeys($query);
$this->_db->setQuery($query)->execute();
}
}
}
}
// Post-processing by observers
$event = AbstractEvent::create('onTableAfterStore', ['subject' => $this, 'result' => &$result]);
$this->getDispatcher()->dispatch('onTableAfterStore', $event);
return $result;
}