CancellableScope   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 32
dl 0
loc 136
rs 10
c 1
b 0
f 1
wmc 12

8 Methods

Rating   Name   Duplication   Size   Complexity  
A extend() 0 4 2
A addWithoutCancelled() 0 8 1
A apply() 0 5 2
A getCancelledAtColumn() 0 7 2
A addCancel() 0 7 1
A addWithCancelled() 0 8 2
A addUnCancel() 0 9 1
A addOnlyCancelled() 0 8 1
1
<?php
2
3
namespace LaravelCancellable\Scopes;
4
5
use Carbon\Carbon;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Scope;
9
10
class CancellableScope implements Scope
11
{
12
    /**
13
     * All the extensions to be added to the builder.
14
     *
15
     * @var array
16
     */
17
    protected $extensions = ['Cancel', 'UnCancel', 'WithCancelled', 'WithoutCancelled', 'OnlyCancelled'];
18
19
    /**
20
     * Apply the scope to a given Eloquent query builder.
21
     *
22
     * @param Builder $builder
23
     * @param Model $model
24
     * @return void
25
     */
26
    public function apply(Builder $builder, Model $model)
27
    {
28
        if (is_callable([$model, 'getQualifiedCancelledAtColumn'], true, $name)) {
29
            $builder->whereNull($model->getQualifiedCancelledAtColumn())
30
                ->orWhere($model->getQualifiedCancelledAtColumn(), '>', Carbon::now());
0 ignored issues
show
Bug introduced by
It seems like $model->getQualifiedCancelledAtColumn() can also be of type Illuminate\Database\Eloquent\Builder and Illuminate\Database\Eloq...gHasThroughRelationship; however, parameter $column of Illuminate\Database\Query\Builder::orWhere() does only seem to accept Closure|array|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

30
                ->orWhere(/** @scrutinizer ignore-type */ $model->getQualifiedCancelledAtColumn(), '>', Carbon::now());
Loading history...
31
        }
32
    }
33
34
    /**
35
     * Extend the query builder with the needed functions.
36
     *
37
     * @param Builder $builder
38
     * @return void
39
     */
40
    public function extend(Builder $builder)
41
    {
42
        foreach ($this->extensions as $extension) {
43
            $this->{"add{$extension}"}($builder);
44
        }
45
    }
46
47
    /**
48
     * Get the "cancelled at" column for the builder.
49
     *
50
     * @param Builder $builder
51
     * @return string
52
     */
53
    protected function getCancelledAtColumn(Builder $builder)
54
    {
55
        if (count((array) $builder->getQuery()->joins) > 0) {
56
            return $builder->getModel()->getQualifiedCancelledAtColumn();
57
        }
58
59
        return $builder->getModel()->getCancelledAtColumn();
60
    }
61
62
    /**
63
     * Add the cancel extension to the builder.
64
     *
65
     * @param Builder $builder
66
     * @return void
67
     */
68
    protected function addCancel(Builder $builder)
69
    {
70
        $builder->macro('cancel', function (Builder $builder) {
71
            $column = $this->getCancelledAtColumn($builder);
72
73
            return $builder->update([
74
                $column => $builder->getModel()->freshTimestampString(),
75
            ]);
76
        });
77
    }
78
79
    /**
80
     * Add the un-cancel extension to the builder.
81
     *
82
     * @param Builder $builder
83
     * @return void
84
     */
85
    protected function addUnCancel(Builder $builder)
86
    {
87
        $builder->macro('unCancel', function (Builder $builder) {
88
            $builder->withCancelled();
89
90
            $column = $this->getCancelledAtColumn($builder);
91
92
            return $builder->update([
93
                $column => null,
94
            ]);
95
        });
96
    }
97
98
    /**
99
     * Add the with-cancel extension to the builder.
100
     *
101
     * @param Builder $builder
102
     * @return void
103
     */
104
    protected function addWithCancelled(Builder $builder)
105
    {
106
        $builder->macro('withCancelled', function (Builder $builder, $withCancelled = true) {
107
            if (! $withCancelled) {
108
                return $builder->withoutCancelled();
109
            }
110
111
            return $builder->withoutGlobalScope($this);
112
        });
113
    }
114
115
    /**
116
     * Add the without-cancel extension to the builder.
117
     *
118
     * @param Builder $builder
119
     * @return void
120
     */
121
    protected function addWithoutCancelled(Builder $builder)
122
    {
123
        $builder->macro('withoutCancelled', function (Builder $builder) {
124
            $model = $builder->getModel();
125
126
            return $builder->withoutGlobalScope($this)->whereNull(
127
                $model->getQualifiedCancelledAtColumn()
128
            )->orWhere($model->getQualifiedCancelledAtColumn(), '>', Carbon::now());
129
        });
130
    }
131
132
    /**
133
     * Add the only-cancel extension to the builder.
134
     *
135
     * @param Builder $builder
136
     * @return void
137
     */
138
    protected function addOnlyCancelled(Builder $builder)
139
    {
140
        $builder->macro('onlyCancelled', function (Builder $builder) {
141
            $model = $builder->getModel();
142
143
            $builder->withoutGlobalScope($this)->where($model->getQualifiedCancelledAtColumn(), '<=', Carbon::now());
144
145
            return $builder;
146
        });
147
    }
148
}
149