Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add model methods to the Activity contract #1314

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions src/Contracts/Activity.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,108 @@ public function scopeCausedBy(Builder $query, Model $causer): Builder;
public function scopeForEvent(Builder $query, string $event): Builder;

public function scopeForSubject(Builder $query, Model $subject): Builder;

/**
* Update the model in the database.
*
* @param array $attributes
* @param array $options
* @return bool
*/
public function update(array $attributes = [], array $options = []);

/**
* Update the model in the database within a transaction.
*
* @param array $attributes
* @param array $options
* @return bool
*
* @throws \Throwable
*/
public function updateOrFail(array $attributes = [], array $options = []);

/**
* Update the model in the database without raising any events.
*
* @param array $attributes
* @param array $options
* @return bool
*/
public function updateQuietly(array $attributes = [], array $options = []);

/**
* Save the model to the database.
*
* @param array $options
* @return bool
*/
public function save(array $options = []);

/**
* Save the model to the database without raising any events.
*
* @param array $options
* @return bool
*/
public function saveQuietly(array $options = []);

/**
* Save the model to the database within a transaction.
*
* @param array $options
* @return bool
*
* @throws \Throwable
*/
public function saveOrFail(array $options = []);

/**
* Delete the model from the database.
*
* @return bool|null
*
* @throws \LogicException
*/
public function delete();

/**
* Delete the model from the database without raising any events.
*
* @return bool
*/
public function deleteQuietly();

/**
* Delete the model from the database within a transaction.
*
* @return bool|null
*
* @throws \Throwable
*/
public function deleteOrFail();

/**
* Force a hard delete on a soft deleted model.
*
* This method protects developers from running forceDelete when the trait is missing.
*
* @return bool|null
*/
public function forceDelete();

/**
* Reload a fresh model instance from the database.
*
* @param array|string $with
* @return static|null
*/
public function fresh($with = []);

/**
* Reload the current model instance with fresh attributes from the database.
*
* @return $this
*/
public function refresh();
}
248 changes: 248 additions & 0 deletions tests/Models/AnotherInvalidActivity.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,252 @@ public function scopeForEvent(Builder $query, string $event): Builder
{
return $query->where('event', $event);
}

/**
* Update the model in the database.
*
* @param array $attributes
* @param array $options
* @return bool
*/
public function update(array $attributes = [], array $options = [])
{
if (! $this->exists) {
return false;
}

return $this->fill($attributes)->save($options);
}

/**
* Update the model in the database within a transaction.
*
* @param array $attributes
* @param array $options
* @return bool
*
* @throws \Throwable
*/
public function updateOrFail(array $attributes = [], array $options = [])
{
if (! $this->exists) {
return false;
}

return $this->fill($attributes)->saveOrFail($options);
}

/**
* Update the model in the database without raising any events.
*
* @param array $attributes
* @param array $options
* @return bool
*/
public function updateQuietly(array $attributes = [], array $options = [])
{
if (! $this->exists) {
return false;
}

return $this->fill($attributes)->saveQuietly($options);
}

/**
* Save the model to the database without raising any events.
*
* @param array $options
* @return bool
*/
public function saveQuietly(array $options = [])
{
return static::withoutEvents(fn () => $this->save($options));
}

/**
* Save the model to the database.
*
* @param array $options
* @return bool
*/
public function save(array $options = [])
{
$this->mergeAttributesFromCachedCasts();

$query = $this->newModelQuery();

// If the "saving" event returns false we'll bail out of the save and return
// false, indicating that the save failed. This provides a chance for any
// listeners to cancel save operations if validations fail or whatever.
if ($this->fireModelEvent('saving') === false) {
return false;
}

// If the model already exists in the database we can just update our record
// that is already in this database using the current IDs in this "where"
// clause to only update this model. Otherwise, we'll just insert them.
if ($this->exists) {
$saved = $this->isDirty() ?
$this->performUpdate($query) : true;
}

// If the model is brand new, we'll insert it into our database and set the
// ID attribute on the model to the value of the newly inserted row's ID
// which is typically an auto-increment value managed by the database.
else {
$saved = $this->performInsert($query);

if (! $this->getConnectionName() &&
$connection = $query->getConnection()) {
$this->setConnection($connection->getName());
}
}

// If the model is successfully saved, we need to do a few more things once
// that is done. We will call the "saved" method here to run any actions
// we need to happen after a model gets successfully saved right here.
if ($saved) {
$this->finishSave($options);
}

return $saved;
}

/**
* Save the model to the database within a transaction.
*
* @param array $options
* @return bool
*
* @throws \Throwable
*/
public function saveOrFail(array $options = [])
{
return $this->getConnection()->transaction(fn () => $this->save($options));
}

/**
* Delete the model from the database.
*
* @return bool|null
*
* @throws \LogicException
*/
public function delete()
{
$this->mergeAttributesFromCachedCasts();

if (is_null($this->getKeyName())) {
throw new LogicException('No primary key defined on model.');
}

// If the model doesn't exist, there is nothing to delete so we'll just return
// immediately and not do anything else. Otherwise, we will continue with a
// deletion process on the model, firing the proper events, and so forth.
if (! $this->exists) {
return;
}

if ($this->fireModelEvent('deleting') === false) {
return false;
}

// Here, we'll touch the owning models, verifying these timestamps get updated
// for the models. This will allow any caching to get broken on the parents
// by the timestamp. Then we will go ahead and delete the model instance.
$this->touchOwners();

$this->performDeleteOnModel();

// Once the model has been deleted, we will fire off the deleted event so that
// the developers may hook into post-delete operations. We will then return
// a boolean true as the delete is presumably successful on the database.
$this->fireModelEvent('deleted', false);

return true;
}

/**
* Delete the model from the database without raising any events.
*
* @return bool
*/
public function deleteQuietly()
{
return static::withoutEvents(fn () => $this->delete());
}

/**
* Delete the model from the database within a transaction.
*
* @return bool|null
*
* @throws \Throwable
*/
public function deleteOrFail()
{
if (! $this->exists) {
return false;
}

return $this->getConnection()->transaction(fn () => $this->delete());
}

/**
* Force a hard delete on a soft deleted model.
*
* This method protects developers from running forceDelete when the trait is missing.
*
* @return bool|null
*/
public function forceDelete()
{
return $this->delete();
}

/**
* Reload a fresh model instance from the database.
*
* @param array|string $with
* @return static|null
*/
public function fresh($with = [])
{
if (! $this->exists) {
return;
}

return $this->setKeysForSelectQuery($this->newQueryWithoutScopes())
->useWritePdo()
->with(is_string($with) ? func_get_args() : $with)
->first();
}

/**
* Reload the current model instance with fresh attributes from the database.
*
* @return $this
*/
public function refresh()
{
if (! $this->exists) {
return $this;
}

$this->setRawAttributes(
$this->setKeysForSelectQuery($this->newQueryWithoutScopes())
->useWritePdo()
->firstOrFail()
->attributes
);

$this->load(collect($this->relations)->reject(function ($relation) {
return $relation instanceof Pivot
|| (is_object($relation) && in_array(AsPivot::class, class_uses_recursive($relation), true));
})->keys()->all());

$this->syncOriginal();

return $this;
}
}