For example, to create a new record or document:
$post = Posts::create(); // Creates a new object, which doesn't exist in the database yet
$post->title = "My post";
$success = $post->save();
It is also used to update existing database objects, as in the following:
$post = Posts::first($id);
$post->title = "Revised title";
$success = $post->save();
By default, an object's data will be checked against the validation rules of the model it is
bound to. Any validation errors that result can then be accessed through the errors()
method.
if (!$post->save($someData)) {
return array('errors' => $post->errors());
}
To override the validation checks and save anyway, you can pass the 'validate' option:
$post->title = "We Don't Need No Stinkin' Validation";
$post->body = "I know what I'm doing.";
$post->save(null, array('validate' => false));
By default only validates and saves fields from the schema (if available). This behavior
can be controlled via the 'whitelist' and 'locked' options.
public save ( object $entity, array $data = null, array $options = [] ) : boolean | ||
$entity | object | The record or document object to be saved in the database. This parameter is implicit and should not be passed under normal circumstances. In the above example, the call to `save()` on the `$post` object is transparently proxied through to the `Posts` model class, and `$post` is passed in as the `$entity` parameter. |
$data | array | Any data that should be assigned to the record before it is saved. |
$options | array | Options: - `'callbacks'` _boolean_: If `false`, all callbacks will be disabled before executing. Defaults to `true`. - `'validate'` _boolean|array_: If `false`, validation will be skipped, and the record will be immediately saved. Defaults to `true`. May also be specified as an array, in which case it will replace the default validation rules specified in the `$validates` property of the model. - `'events'` _string|array_: A string or array defining one or more validation _events_. Events are different contexts in which data events can occur, and correspond to the optional `'on'` key in validation rules. They will be passed to the validates() method if `'validate'` is not `false`. - `'whitelist'` _array_: An array of fields that are allowed to be saved to this record. When unprovided will - if available - default to fields of the current schema and the `'locked'` option is not `false`. - `'locked'` _boolean_: Whether to use schema for saving just fields from the schema or not. Defaults to `true`. |
리턴 | boolean | Returns `true` on a successful save operation, `false` on failure. |
/** * automatically adds timestamps on saving. * * In case of creation it correctly fills the `created` field with a unix timestamp. * Same holds true for `updated` on updates, accordingly. * * @see lithium\data\Model * @param object $entity current instance * @param array $data Any data that should be assigned to the record before it is saved. * @param array $options additional options * @return boolean true on success, false otherwise * @filter */ public function save($entity, $data = array(), array $options = array()) { if (!empty($data)) { $entity->set($data); } $schema = $entity->schema(); foreach ($schema->fields() as $name => $meta) { if (isset($meta['type']) && $meta['type'] !== 'list') { continue; } if (is_string($entity->{$name})) { $listData = explode("\n", $entity->{$name}); array_walk($listData, function (&$val) { $val = trim($val); }); $entity->{$name} = $listData; } } $versions = static::meta('versions'); if (!isset($options['callbacks']) || $options['callbacks'] !== false) { $field = $entity->exists() ? 'updated' : 'created'; $entity->set(array($field => time())); if ($versions === true || is_callable($versions) && $versions($entity, $options)) { $version_id = Versions::add($entity, $options); if ($version_id) { $entity->set(compact('version_id')); } } } $result = parent::save($entity, null, $options); if ($result && isset($field) && $field == 'created') { if ($versions === true || is_callable($versions) && $versions($entity, $options)) { $version_id = Versions::add($entity, array('force' => true)); if ($version_id) { $entity->set(compact('version_id')); return $entity->save(null, array('callbacks' => false)); } } } return $result; }
/** * Returns a filter closure that can be applied to models that needs a relationship save * * Use: * {{{ * // In controller: * $post->save($this->request->data, array('with' => array('Author'))); * }}} * * @param \lihtuim\data\Entity $entity * @param array $data * @param array $options * @return boolean */ public function save($entity, $data = null, array $options = array()) { // Return home early, we don't need anything else from this class. if (empty($options['with'])) { return parent::save($entity, $data, $options); } if (is_string($options['with'])) { $options['with'] = array($options['with']); } // Model options $model = $entity->model(); // Don't want to reset entity data entirely if $data is null $data = (!$data) ? $entity->data() : $data; // Set fields ment for root model to it's entity $fields = array_keys($model::schema()); $local = array(); foreach ($fields as $field) { if (isset($data[$field])) { $local[$field] = $data[$field]; } } $entity->set($local); $with = array(); foreach ($options['with'] as $related) { if (isset($data[$related])) { $with[$related] = array(); $relationship = $model::relations($related); $relatedModel = $relationship->to(); switch ($relationship->type()) { case 'hasOne': case 'belongsTo': $relatedData = !empty($data[$related]) ? $data[$related] : array(); $entity->{$related} = $with[$related] = $relatedModel::create($relatedData); break; case 'hasMany': foreach ($data[$related] as $k => $relatedData) { $local = array(); foreach ($relatedData as $field => $value) { $local[$field] = $value; } $with[$related][$k] = $relatedModel::create(); $with[$related][$k]->set($local); } $entity->{$related} = new RecordSet(array('data' => $with[$related])); break; } } } if (!$entity->validates()) { $entity->errors($model::errors($entity)); return false; } $result = parent::save($entity, $data, $options); if (!$result) throw new \Exception ('Save on main failed. Save-all opperation halted.'); foreach ($with as $related => $relatedEntities) { $relationship = $model::relations($related); $keys = $relationship->keys(); $fk = current($keys); $pk = key($keys); switch ($relationship->type()) { case 'hasOne': case 'belongsTo': $relatedEntities->$fk = $entity->$pk; if (!$relatedEntities->save()) throw new \Exception ('Save on related failed. Save-all opperation halted.'); break; case 'hasMany': foreach ($relatedEntities as $relatedEntity) { $relatedEntity->$fk = $entity->$pk; if (!$relatedEntity->save()) throw new \Exception ('Save on related failed. Save-all opperation halted.'); } break; } } return true; }