1 | <?php |
||||||
2 | |||||||
3 | namespace RaziAlsayyed\LaravelCascadedSoftDeletes\Traits; |
||||||
4 | |||||||
5 | use Illuminate\Support\Str; |
||||||
6 | use RaziAlsayyed\LaravelCascadedSoftDeletes\Exceptions\LogicException; |
||||||
7 | use RaziAlsayyed\LaravelCascadedSoftDeletes\Exceptions\RuntimeException; |
||||||
8 | use RaziAlsayyed\LaravelCascadedSoftDeletes\Jobs\CascadeSoftDeletes; |
||||||
9 | |||||||
10 | trait CascadedSoftDeletes |
||||||
11 | { |
||||||
12 | /** |
||||||
13 | * Keeps track of Instance deleted_at time. |
||||||
14 | * |
||||||
15 | * @var \Carbon\Carbon |
||||||
16 | */ |
||||||
17 | public static $instanceDeletedAt; |
||||||
18 | |||||||
19 | /** |
||||||
20 | * Sign on model events. |
||||||
21 | */ |
||||||
22 | protected static function bootCascadedSoftDeletes() |
||||||
23 | { |
||||||
24 | static::deleted(function ($model) { |
||||||
25 | $model->deleteCascadedSoftDeletes(); |
||||||
26 | }); |
||||||
27 | |||||||
28 | if (static::instanceUsesSoftDelete()) { |
||||||
29 | static::restoring(function ($model) { |
||||||
30 | static::$instanceDeletedAt = $model->{$model->getDeletedAtColumn()}; |
||||||
31 | }); |
||||||
32 | |||||||
33 | static::restored(function ($model) { |
||||||
34 | $model->restoreCascadedSoftDeleted(); |
||||||
35 | }); |
||||||
36 | } |
||||||
37 | } |
||||||
38 | |||||||
39 | /** |
||||||
40 | * Delete the cascaded relations. |
||||||
41 | */ |
||||||
42 | protected function deleteCascadedSoftDeletes() : void |
||||||
43 | { |
||||||
44 | if ($this->isHardDeleting()) { |
||||||
45 | return; |
||||||
46 | } |
||||||
47 | |||||||
48 | if (config('cascaded-soft-deletes.queue_cascades_by_default') === true) { |
||||||
49 | CascadeSoftDeletes::dispatch($this, 'delete', null)->onQueue(config('cascaded-soft-deletes.queue_name')); |
||||||
50 | } else { |
||||||
51 | // @codeCoverageIgnoreStart |
||||||
52 | Str::startsWith(app()->version(), '7') ? |
||||||
0 ignored issues
–
show
introduced
by
![]() |
|||||||
53 | CascadeSoftDeletes::dispatchNow($this, 'delete', null) : |
||||||
0 ignored issues
–
show
The function
RaziAlsayyed\LaravelCasc...tDeletes::dispatchNow() has been deprecated: Will be removed in a future Laravel version.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||||
54 | CascadeSoftDeletes::dispatchSync($this, 'delete', null); |
||||||
55 | // @codeCoverageIgnoreEnd |
||||||
56 | } |
||||||
57 | } |
||||||
58 | |||||||
59 | /** |
||||||
60 | * Restore the cascaded relations. |
||||||
61 | */ |
||||||
62 | protected function restoreCascadedSoftDeleted() : void |
||||||
63 | { |
||||||
64 | if (config('cascaded-soft-deletes.queue_cascades_by_default') === true) { |
||||||
65 | CascadeSoftDeletes::dispatch($this, 'restore', static::$instanceDeletedAt)->onQueue(config('cascaded-soft-deletes.queue_name')); |
||||||
66 | } else { |
||||||
67 | // @codeCoverageIgnoreStart |
||||||
68 | Str::startsWith(app()->version(), '7') ? |
||||||
69 | CascadeSoftDeletes::dispatchNow($this, 'restore', static::$instanceDeletedAt) : |
||||||
0 ignored issues
–
show
The function
RaziAlsayyed\LaravelCasc...tDeletes::dispatchNow() has been deprecated: Will be removed in a future Laravel version.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||||
70 | CascadeSoftDeletes::dispatchSync($this, 'restore', static::$instanceDeletedAt); |
||||||
71 | // @codeCoverageIgnoreEnd |
||||||
72 | } |
||||||
73 | // CascadeSoftDeletes::dispatch($this, 'restore', static::$instanceDeletedAt); |
||||||
74 | } |
||||||
75 | |||||||
76 | /** |
||||||
77 | * Delete/Restore Cascaded Relationships. |
||||||
78 | * |
||||||
79 | * @param $action |
||||||
80 | */ |
||||||
81 | public function cascadeSoftDeletes(string $action, ?\Carbon\Carbon $instanceDeletedAt = null) : void |
||||||
82 | { |
||||||
83 | if (method_exists($this, 'getCascadedSoftDeletes')) { |
||||||
84 | $relations = collect($this->getCascadedSoftDeletes()); |
||||||
85 | } elseif (property_exists($this, 'cascadedSoftDeletes')) { |
||||||
86 | $relations = collect($this->cascadedSoftDeletes); |
||||||
87 | } else { |
||||||
88 | throw new RuntimeException('neither getCascadedSoftDeletes function or cascaded_soft_deletes property exists!'); |
||||||
89 | } |
||||||
90 | |||||||
91 | $relations->each(function ($item, $key) use ($action, $instanceDeletedAt) { |
||||||
92 | $relation = $key; |
||||||
93 | if (is_numeric($key)) { |
||||||
94 | $relation = $item; |
||||||
95 | } |
||||||
96 | |||||||
97 | if (!is_callable($item) && !$this->relationUsesSoftDelete($relation)) { |
||||||
98 | throw new LogicException('relationship ' . $relation . ' does not use SoftDeletes trait.'); |
||||||
99 | } |
||||||
100 | |||||||
101 | if (is_callable($item)) { |
||||||
102 | $query = $item(); |
||||||
103 | } else { |
||||||
104 | $query = $this->{$relation}(); |
||||||
105 | } |
||||||
106 | |||||||
107 | if ($action == 'delete') { |
||||||
108 | $query->get()->each->delete(); |
||||||
109 | } else { |
||||||
110 | $query |
||||||
111 | ->onlyTrashed() |
||||||
112 | ->where($this->getDeletedAtColumn(), '>=', $instanceDeletedAt->format('Y-m-d H:i:s.u')) |
||||||
0 ignored issues
–
show
The method
format() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() It seems like
getDeletedAtColumn() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
113 | ->get() |
||||||
114 | ->each |
||||||
115 | ->restore(); |
||||||
116 | } |
||||||
117 | |||||||
118 | // else { |
||||||
119 | // $query = $query |
||||||
120 | // ->withTrashed() |
||||||
121 | // ->where($query->qualifyColumn($this->getDeletedAtColumn()), '>=', $instanceDeletedAt); |
||||||
122 | |||||||
123 | // dd($query->toSql(), $query->getBindings(), $query->pluck('deleted_at')); |
||||||
124 | |||||||
125 | // } |
||||||
126 | }); |
||||||
127 | } |
||||||
128 | |||||||
129 | /** |
||||||
130 | * Get whether user is intended to delete the model from database entirely. |
||||||
131 | * |
||||||
132 | * @return bool |
||||||
133 | */ |
||||||
134 | protected function isHardDeleting() : bool |
||||||
135 | { |
||||||
136 | return !$this->instanceUsesSoftDelete() || $this->forceDeleting; |
||||||
137 | } |
||||||
138 | |||||||
139 | /** |
||||||
140 | * Check if the instance uses SoftDeletes trait. |
||||||
141 | * |
||||||
142 | * @return bool |
||||||
143 | */ |
||||||
144 | protected static function instanceUsesSoftDelete() : bool |
||||||
145 | { |
||||||
146 | static $softDelete; |
||||||
147 | |||||||
148 | if (is_null($softDelete)) { |
||||||
149 | $instance = new static; |
||||||
150 | |||||||
151 | return $softDelete = method_exists($instance, 'bootSoftDeletes'); |
||||||
152 | } |
||||||
153 | |||||||
154 | return $softDelete; |
||||||
155 | } |
||||||
156 | |||||||
157 | /** |
||||||
158 | * Check if the relation uses SoftDeletes trait. |
||||||
159 | * |
||||||
160 | * @return bool |
||||||
161 | */ |
||||||
162 | public static function relationUsesSoftDelete($relation) : bool |
||||||
163 | { |
||||||
164 | static $softDeletes; |
||||||
165 | |||||||
166 | if (is_null($softDeletes)) { |
||||||
167 | $softDeletes = collect([]); |
||||||
0 ignored issues
–
show
array() of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
168 | } |
||||||
169 | |||||||
170 | return $softDeletes->get($relation, function () use ($relation, $softDeletes) { |
||||||
171 | $instance = new static; |
||||||
172 | $cls = $instance->{$relation}()->getRelated(); |
||||||
173 | $relationInstance = new $cls; |
||||||
174 | |||||||
175 | return $softDeletes->put($relation, method_exists($relationInstance, 'bootSoftDeletes'))->get($relation); |
||||||
176 | }); |
||||||
177 | } |
||||||
178 | } |
||||||
179 |