public function save($validate = true)
{
// save document
// if document already in db and not modified - skip this method
if (!$this->isSaveRequired()) {
return $this;
}
if ($validate) {
$this->validate();
}
// handle beforeSave event
if ($this->triggerEvent('beforeSave')->isCancelled()) {
return $this;
}
if ($this->isStored()) {
if ($this->triggerEvent('beforeUpdate')->isCancelled()) {
return $this;
}
// locking
$query = array('_id' => $this->getId());
if ($this->getOption('lock') === Definition::LOCK_OPTIMISTIC) {
$query['__version__'] = $this->get('__version__');
$this->getOperator()->increment('__version__');
}
// update
$status = $this->collection->getMongoCollection()->update($query, $this->getOperator()->toArray());
// check update status
if ($status['ok'] != 1) {
throw new \Sokil\Mongo\Exception(sprintf('Update error: %s: %s', $status['err'], $status['errmsg']));
}
// check if document modified due to specified lock
if ($this->getOption('lock') === Definition::LOCK_OPTIMISTIC) {
if ($status['n'] === 0) {
throw new OptimisticLockFailureException();
}
}
if ($this->getOperator()->isReloadRequired()) {
$this->refresh();
} else {
$this->getOperator()->reset();
}
$this->triggerEvent('afterUpdate');
} else {
if ($this->triggerEvent('beforeInsert')->isCancelled()) {
return $this;
}
$document = $this->toArray();
$this->collection->getMongoCollection()->insert($document);
// set id
$this->defineId($document['_id']);
// after insert event
$this->triggerEvent('afterInsert');
}
// handle afterSave event
$this->triggerEvent('afterSave');
$this->apply();
return $this;
}