• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SameOldNick / SameOldWebsite / 21471360437

29 Jan 2026 08:41AM UTC coverage: 87.487% (-0.02%) from 87.511%
21471360437

push

github

web-flow
Continues to next action if tests fail

28499 of 32575 relevant lines covered (87.49%)

696.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.52
/app/Models/File.php
1
<?php
2

3
namespace App\Models;
4

5
use App\Models\Presenters\FilePresenter;
6
use App\Traits\Models\HasPresenter;
7
use Illuminate\Database\Eloquent\Casts\Attribute;
8
use Illuminate\Database\Eloquent\Concerns\HasUuids;
9
use Illuminate\Database\Eloquent\Factories\HasFactory;
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Database\Eloquent\Relations\BelongsTo;
12
use Illuminate\Database\Eloquent\Relations\MorphTo;
13
use Illuminate\Database\Eloquent\SoftDeletes;
14
use Illuminate\Support\Carbon;
15
use Illuminate\Support\Facades\Storage;
16
use Illuminate\Support\Str;
17

18
/**
19
 * @property string $id
20
 * @property string $name
21
 * @property string $path
22
 * @property string $disk
23
 * @property bool $is_public
24
 * @property ?int $user_id
25
 * @property ?string $fileable_type
26
 * @property ?string $fileable_id
27
 * @property ?Carbon $created_at
28
 * @property ?Carbon $updated_at
29
 * @property ?Carbon $deleted_at
30
 * @property-read ?User $user
31
 * @property-read ?Model $fileable
32
 * @property-read array $path_info
33
 */
34
final class File extends Model
35
{
36
    /** @use HasFactory<\Database\Factories\FileFactory> */
37
    use HasFactory;
38

39
    /** @use HasPresenter<FilePresenter> */
40
    use HasPresenter;
41

42
    use HasUuids;
43
    use SoftDeletes;
44

45
    /**
46
     * The "type" of the primary key ID.
47
     *
48
     * @var string
49
     */
50
    protected $keyType = 'string';
51

52
    /**
53
     * Indicates if the IDs are auto-incrementing.
54
     *
55
     * @var bool
56
     */
57
    public $incrementing = false;
58

59
    /**
60
     * The attributes that are mass assignable.
61
     *
62
     * @var list<string>
63
     */
64
    protected $fillable = [
65
        'path',
66
        'name',
67
        'is_public',
68
        'disk',
69
    ];
70

71
    /**
72
     * The attributes that should be visible in serialization.
73
     *
74
     * @var list<string>
75
     */
76
    protected $visible = [
77
        'id',
78
        'name',
79
        'meta',
80
        'created_at',
81
    ];
82

83
    /**
84
     * The attributes that should be cast.
85
     *
86
     * @var array<string, string>
87
     */
88
    protected $casts = [
89
        'is_public' => 'boolean',
90
    ];
91

92
    /**
93
     * The accessors to append to the model's array form.
94
     *
95
     * @var list<string>
96
     */
97
    protected $appends = [];
98

99
    /**
100
     * The presenter class
101
     *
102
     * @var class-string
103
     */
104
    protected static string $presenter = FilePresenter::class;
105

106
    /**
107
     * Gets the parent fileable model (ProductImage, Download, or Release)
108
     */
109
    public function fileable(): MorphTo
110
    {
111
        return $this->morphTo();
×
112
    }
113

114
    /**
115
     * Gets the user who uploaded this file.
116
     */
117
    public function user(): BelongsTo
118
    {
119
        return $this->belongsTo(User::class);
102✔
120
    }
121

122
    /**
123
     * Deletes file (if removeFileOnDelete in morph model is true) before deleting record from database.
124
     *
125
     * @return bool|null
126
     */
127
    public function delete()
128
    {
129
        if (! is_null($this->fileable)) {
×
130
            if (method_exists($this->fileable, 'removeFileOnDelete') && $this->fileable->removeFileOnDelete()) {
×
131
                $this->removeFile();
×
132
            }
133

134
            $this->fileable->delete();
×
135
        }
136

137
        return parent::delete();
×
138
    }
139

140
    /**
141
     * Gets the storage disk the file is from.
142
     *
143
     * @return \Illuminate\Contracts\Filesystem\Filesystem
144
     */
145
    public function getStorageDisk()
146
    {
147
        return Storage::disk($this->disk);
×
148
    }
149

150
    /**
151
     * Removes file from storage.
152
     *
153
     * @return bool
154
     */
155
    public function removeFile()
156
    {
157
        return $this->getStorageDisk()->delete($this->path);
×
158
    }
159

160
    /**
161
     * Gets whether the file exists or not
162
     */
163
    protected function fileExists(): Attribute
164
    {
165
        return Attribute::get(function ($value, $attributes = []) {
3✔
166
            try {
167
                return $this->getStorageDisk()->exists($attributes['path']);
×
168
            } catch (\InvalidArgumentException) {
×
169
                return false;
×
170
            }
171
        });
3✔
172
    }
173

174
    /**
175
     * Get and set the filename
176
     */
177
    protected function name(): Attribute
178
    {
179
        return Attribute::make(
69✔
180
            get: fn ($value, $attributes) => is_null($value) ? Str::of($attributes['path'])->basename() : $value,
69✔
181
            set: fn ($value) => $value,
69✔
182
        );
69✔
183
    }
184

185
    /**
186
     * Get the meta-data for the file
187
     */
188
    protected function meta(): Attribute
189
    {
190
        $defaults = [];
3✔
191

192
        return Attribute::get(fn ($value, $attributes = []) => $this->file_exists ? [
3✔
193
            'size' => $this->getStorageDisk()->size($attributes['path']),
3✔
194
            'last_modified' => Carbon::parse($this->getStorageDisk()->lastModified($attributes['path'])),
3✔
195
            'mime_type' => $this->getStorageDisk()->mimeType($attributes['path']),
3✔
196
        ] : $defaults);
3✔
197
    }
198

199
    /**
200
     * Gets the pathinfo for the file.
201
     */
202
    protected function pathInfo(): Attribute
203
    {
204
        return Attribute::get(fn ($value, $attributes = []) => pathinfo(Storage::path($attributes['path'])));
60✔
205
    }
206

207
    /**
208
     * Creates File model from file path
209
     *
210
     * @param  string  $path  Path of file
211
     * @param  string|null  $name  Filename. If null, filename is generated from path. (default: null)
212
     * @param  bool  $public  If file is public (default: false)
213
     * @param  string  $disk  Name of the disk (default: null)
214
     * @return static
215
     */
216
    public static function createFromFilePath(string $path, ?string $name = null, bool $public = false, ?string $disk = null): self
217
    {
218
        return new self([
15✔
219
            'path' => $path,
15✔
220
            'name' => $name,
15✔
221
            'is_public' => $public,
15✔
222
            'disk' => $disk,
15✔
223
        ]);
15✔
224
    }
225
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc