SoftDeletes.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace Illuminate\Database\Eloquent;
  3. /**
  4. * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withTrashed()
  5. * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder onlyTrashed()
  6. * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withoutTrashed()
  7. */
  8. trait SoftDeletes
  9. {
  10. /**
  11. * Indicates if the model is currently force deleting.
  12. *
  13. * @var bool
  14. */
  15. protected $forceDeleting = false;
  16. /**
  17. * Boot the soft deleting trait for a model.
  18. *
  19. * @return void
  20. */
  21. public static function bootSoftDeletes()
  22. {
  23. static::addGlobalScope(new SoftDeletingScope);
  24. }
  25. /**
  26. * Initialize the soft deleting trait for an instance.
  27. *
  28. * @return void
  29. */
  30. public function initializeSoftDeletes()
  31. {
  32. $this->dates[] = $this->getDeletedAtColumn();
  33. }
  34. /**
  35. * Force a hard delete on a soft deleted model.
  36. *
  37. * @return bool|null
  38. */
  39. public function forceDelete()
  40. {
  41. $this->forceDeleting = true;
  42. return tap($this->delete(), function ($deleted) {
  43. $this->forceDeleting = false;
  44. if ($deleted) {
  45. $this->fireModelEvent('forceDeleted', false);
  46. }
  47. });
  48. }
  49. /**
  50. * Perform the actual delete query on this model instance.
  51. *
  52. * @return mixed
  53. */
  54. protected function performDeleteOnModel()
  55. {
  56. if ($this->forceDeleting) {
  57. $this->exists = false;
  58. return $this->setKeysForSaveQuery($this->newModelQuery())->forceDelete();
  59. }
  60. return $this->runSoftDelete();
  61. }
  62. /**
  63. * Perform the actual delete query on this model instance.
  64. *
  65. * @return void
  66. */
  67. protected function runSoftDelete()
  68. {
  69. $query = $this->setKeysForSaveQuery($this->newModelQuery());
  70. $time = $this->freshTimestamp();
  71. $columns = [$this->getDeletedAtColumn() => $this->fromDateTime($time)];
  72. $this->{$this->getDeletedAtColumn()} = $time;
  73. if ($this->timestamps && ! is_null($this->getUpdatedAtColumn())) {
  74. $this->{$this->getUpdatedAtColumn()} = $time;
  75. $columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);
  76. }
  77. $query->update($columns);
  78. }
  79. /**
  80. * Restore a soft-deleted model instance.
  81. *
  82. * @return bool|null
  83. */
  84. public function restore()
  85. {
  86. // If the restoring event does not return false, we will proceed with this
  87. // restore operation. Otherwise, we bail out so the developer will stop
  88. // the restore totally. We will clear the deleted timestamp and save.
  89. if ($this->fireModelEvent('restoring') === false) {
  90. return false;
  91. }
  92. $this->{$this->getDeletedAtColumn()} = null;
  93. // Once we have saved the model, we will fire the "restored" event so this
  94. // developer will do anything they need to after a restore operation is
  95. // totally finished. Then we will return the result of the save call.
  96. $this->exists = true;
  97. $result = $this->save();
  98. $this->fireModelEvent('restored', false);
  99. return $result;
  100. }
  101. /**
  102. * Determine if the model instance has been soft-deleted.
  103. *
  104. * @return bool
  105. */
  106. public function trashed()
  107. {
  108. return ! is_null($this->{$this->getDeletedAtColumn()});
  109. }
  110. /**
  111. * Register a restoring model event with the dispatcher.
  112. *
  113. * @param \Closure|string $callback
  114. * @return void
  115. */
  116. public static function restoring($callback)
  117. {
  118. static::registerModelEvent('restoring', $callback);
  119. }
  120. /**
  121. * Register a restored model event with the dispatcher.
  122. *
  123. * @param \Closure|string $callback
  124. * @return void
  125. */
  126. public static function restored($callback)
  127. {
  128. static::registerModelEvent('restored', $callback);
  129. }
  130. /**
  131. * Determine if the model is currently force deleting.
  132. *
  133. * @return bool
  134. */
  135. public function isForceDeleting()
  136. {
  137. return $this->forceDeleting;
  138. }
  139. /**
  140. * Get the name of the "deleted at" column.
  141. *
  142. * @return string
  143. */
  144. public function getDeletedAtColumn()
  145. {
  146. return defined('static::DELETED_AT') ? static::DELETED_AT : 'deleted_at';
  147. }
  148. /**
  149. * Get the fully qualified "deleted at" column.
  150. *
  151. * @return string
  152. */
  153. public function getQualifiedDeletedAtColumn()
  154. {
  155. return $this->qualifyColumn($this->getDeletedAtColumn());
  156. }
  157. }