1 | <?php |
||
2 | |||
3 | namespace LinkRestrictedAccess\Models; |
||
4 | |||
5 | use Carbon\Carbon; |
||
6 | use Illuminate\Database\Eloquent\Builder; |
||
7 | use Illuminate\Database\Eloquent\Casts\Attribute; |
||
8 | use Illuminate\Database\Eloquent\Factories\HasFactory; |
||
9 | use Illuminate\Database\Eloquent\Model; |
||
10 | use Illuminate\Database\Eloquent\Relations\HasMany; |
||
11 | use Illuminate\Database\Eloquent\Relations\MorphTo; |
||
12 | use Illuminate\Support\Str; |
||
13 | use JsonFieldCast\Casts\SimpleJsonField; |
||
14 | use LinkRestrictedAccess\Database\Factories\RestrictedLinkFactory; |
||
15 | use LinkRestrictedAccess\RestrictedAccess; |
||
16 | |||
17 | /** |
||
18 | * @property \JsonFieldCast\Json\SimpleJsonField $access_configuration |
||
19 | * @property \JsonFieldCast\Json\SimpleJsonField $meta |
||
20 | */ |
||
21 | class RestrictedLink extends Model |
||
22 | { |
||
23 | use HasFactory; |
||
24 | |||
25 | protected $guarded = []; |
||
26 | |||
27 | protected $casts = [ |
||
28 | 'use_pin' => 'datetime', |
||
29 | 'access_configuration' => SimpleJsonField::class, |
||
30 | 'meta' => SimpleJsonField::class, |
||
31 | ]; |
||
32 | |||
33 | protected $accessConfigsMap = [ |
||
34 | 'checkName' => 'use_name', |
||
35 | 'checkEmail' => 'use_email', |
||
36 | ]; |
||
37 | |||
38 | 14 | public function getTable(): string |
|
39 | { |
||
40 | 14 | return config('restricted-access.tables.links'); |
|
41 | } |
||
42 | |||
43 | 15 | protected static function boot(): void |
|
44 | { |
||
45 | 15 | parent::boot(); |
|
46 | |||
47 | 15 | static::saving(function ($model) { |
|
48 | 14 | if (!$model->uuid) { |
|
49 | 14 | $model->uuid = (string)Str::uuid(); |
|
50 | } |
||
51 | 15 | }); |
|
52 | } |
||
53 | |||
54 | 3 | public function linkable(): MorphTo |
|
55 | { |
||
56 | 3 | return $this->morphTo('linkable'); |
|
57 | } |
||
58 | |||
59 | |||
60 | 7 | public function openActions(): HasMany |
|
61 | { |
||
62 | 7 | return $this->hasMany(RestrictedAccess::linkOpenActionModel(), 'link_id', 'id'); |
|
63 | } |
||
64 | |||
65 | 6 | public function checkPin(): Attribute |
|
66 | { |
||
67 | 6 | return Attribute::make( |
|
68 | 6 | fn () => (bool)$this->use_pin, |
|
0 ignored issues
–
show
|
|||
69 | 6 | fn ($value) => [ |
|
70 | 6 | 'use_pin' => $value ? $this->use_pin ?? Carbon::now() : null, |
|
0 ignored issues
–
show
|
|||
71 | 6 | ], |
|
72 | 6 | ); |
|
73 | } |
||
74 | |||
75 | 5 | protected function getAccessConfig(?string $key = null): ?Attribute |
|
76 | { |
||
77 | 5 | if (!$key) { |
|
78 | return Attribute::get(fn () => null); |
||
79 | } |
||
80 | |||
81 | 5 | $field = $this->accessConfigsMap[$key] ?? Str::snake($key); |
|
82 | |||
83 | 5 | return Attribute::make( |
|
84 | 5 | fn () => (bool)$this->access_configuration->getDateAttribute($field), |
|
85 | 5 | function ($value) use ($field) { |
|
86 | 2 | if ($value) { |
|
87 | 2 | $this->access_configuration->setDate($field, $this->access_configuration->getDateAttribute($field, Carbon::now())); |
|
88 | } else { |
||
89 | 1 | $this->access_configuration->removeAttribute($field); |
|
90 | } |
||
91 | |||
92 | 2 | return []; |
|
93 | 5 | }, |
|
94 | 5 | ); |
|
95 | } |
||
96 | |||
97 | 5 | public function checkName(): Attribute |
|
98 | { |
||
99 | 5 | return $this->getAccessConfig(__FUNCTION__); |
|
100 | } |
||
101 | |||
102 | 4 | public function checkEmail(): Attribute |
|
103 | { |
||
104 | 4 | return $this->getAccessConfig(__FUNCTION__); |
|
105 | } |
||
106 | |||
107 | 1 | public function needVerification(): bool |
|
108 | { |
||
109 | 1 | return $this->check_pin || |
|
0 ignored issues
–
show
|
|||
110 | 1 | $this->check_email || |
|
0 ignored issues
–
show
|
|||
111 | 1 | $this->check_name; |
|
0 ignored issues
–
show
|
|||
112 | } |
||
113 | |||
114 | 1 | public function link(): string |
|
115 | { |
||
116 | 1 | return $this->linkable->restrictedLink($this); |
|
0 ignored issues
–
show
|
|||
117 | } |
||
118 | |||
119 | 4 | public function cookieName(): string |
|
120 | { |
||
121 | 4 | return "ral_{$this->uuid}"; |
|
122 | } |
||
123 | |||
124 | 1 | public function openActionFromCookie(\Illuminate\Http\Request $request): ?RestrictedLinkOpenAction |
|
125 | { |
||
126 | 1 | $openUuid = $request->cookie($this->cookieName()); |
|
127 | 1 | if ($openUuid) { |
|
128 | 1 | return RestrictedAccess::linkOpenActionModel()::query()->where('uuid', $openUuid)->first(); |
|
129 | } |
||
130 | |||
131 | return null; |
||
132 | } |
||
133 | |||
134 | 1 | public function verifiedOpenActionFromCookie(\Illuminate\Http\Request $request): ?RestrictedLinkOpenAction |
|
135 | { |
||
136 | 1 | $open = $this->openActionFromCookie($request); |
|
137 | 1 | if ($open?->verified($request)) { |
|
138 | 1 | return $open; |
|
139 | } |
||
140 | |||
141 | 1 | return null; |
|
142 | } |
||
143 | |||
144 | 1 | public static function scopeByKey(Builder $query, string $uuid, Model|int|null $relatedModel = null): Builder |
|
145 | { |
||
146 | 1 | $query->where('uuid', $uuid); |
|
147 | |||
148 | 1 | if ($relatedModel) { |
|
149 | 1 | if ($relatedModel instanceof Model) { |
|
150 | 1 | $relatedModel = $relatedModel->getKey(); |
|
151 | } |
||
152 | |||
153 | 1 | $query->whereHas('linkable', fn (Builder $q) => $q->whereKey($relatedModel)); |
|
154 | } |
||
155 | |||
156 | 1 | return $query; |
|
157 | } |
||
158 | |||
159 | 14 | protected static function newFactory(): RestrictedLinkFactory |
|
160 | { |
||
161 | 14 | return RestrictedLinkFactory::new(); |
|
162 | } |
||
163 | } |
||
164 |
Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.