Skip to content

Commit add04c2

Browse files
committed
upload images to nova
1 parent 2d999a6 commit add04c2

3 files changed

Lines changed: 144 additions & 0 deletions

File tree

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
3+
namespace App\Nova\Actions;
4+
5+
use App\MediaUpload;
6+
use Illuminate\Bus\Queueable;
7+
use Illuminate\Queue\InteractsWithQueue;
8+
use Illuminate\Queue\SerializesModels;
9+
use Illuminate\Support\Collection;
10+
use Illuminate\Support\Str;
11+
use Laravel\Nova\Actions\Action;
12+
use Laravel\Nova\Fields\ActionFields;
13+
use Laravel\Nova\Fields\File;
14+
use Laravel\Nova\Http\Requests\NovaRequest;
15+
16+
class BulkUploadMediaFiles extends Action
17+
{
18+
use InteractsWithQueue, Queueable, SerializesModels;
19+
20+
/**
21+
* The displayable name of the action.
22+
*
23+
* @var string
24+
*/
25+
public $name = 'Bulk Upload Files';
26+
27+
/**
28+
* Perform the action on the given models.
29+
*
30+
* @param \Laravel\Nova\Fields\ActionFields $fields
31+
* @param \Illuminate\Support\Collection $models
32+
* @return mixed
33+
*/
34+
public function handle(ActionFields $fields, Collection $models)
35+
{
36+
$uploadedFiles = $fields->files ?? request()->file('files');
37+
if (!$uploadedFiles) {
38+
return Action::danger('Please select one or more files.');
39+
}
40+
41+
if (!is_array($uploadedFiles)) {
42+
$uploadedFiles = [$uploadedFiles];
43+
}
44+
45+
$allowedExtensions = [
46+
'jpg', 'jpeg', 'png', 'gif', 'webp', 'svg',
47+
'pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'txt',
48+
];
49+
50+
$uploaded = 0;
51+
$skipped = 0;
52+
53+
foreach ($uploadedFiles as $file) {
54+
if (!$file) {
55+
$skipped++;
56+
continue;
57+
}
58+
59+
$extension = strtolower((string) $file->getClientOriginalExtension());
60+
if (!in_array($extension, $allowedExtensions, true)) {
61+
$skipped++;
62+
continue;
63+
}
64+
65+
$baseName = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
66+
$safeBaseName = Str::slug($baseName) ?: 'upload-file';
67+
$destination = 'nova/uploads/' . now()->format('Y/m');
68+
$storedPath = $file->storeAs(
69+
$destination,
70+
$safeBaseName . '-' . Str::random(8) . '.' . $extension,
71+
'resources'
72+
);
73+
74+
if (!$storedPath) {
75+
$skipped++;
76+
continue;
77+
}
78+
79+
MediaUpload::create([
80+
'title' => trim(str_replace(['-', '_'], ' ', $baseName)),
81+
'file_path' => $storedPath,
82+
'disk' => 'resources',
83+
]);
84+
85+
$uploaded++;
86+
}
87+
88+
return Action::message("Bulk upload completed: {$uploaded} uploaded, {$skipped} skipped.");
89+
}
90+
91+
/**
92+
* Get the fields available on the action.
93+
*
94+
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
95+
* @return array
96+
*/
97+
public function fields(NovaRequest $request): array
98+
{
99+
return [
100+
File::make('Files', 'files')
101+
->withMeta([
102+
'extraAttributes' => [
103+
'multiple' => true,
104+
'accept' => '.jpg,.jpeg,.png,.gif,.webp,.svg,.pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx,.txt',
105+
],
106+
])
107+
->rules('required')
108+
->help('Drag and drop multiple files or click to select. Supported: images, PDF, Office docs, and TXT.'),
109+
];
110+
}
111+
112+
/**
113+
* Indicate that this action can be run without any models.
114+
*/
115+
public function standalone()
116+
{
117+
return true;
118+
}
119+
}

app/Nova/MediaUpload.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
namespace App\Nova;
44

5+
use App\Nova\Actions\BulkUploadMediaFiles;
56
use Illuminate\Http\Request;
67
use Laravel\Nova\Fields\File;
78
use Laravel\Nova\Fields\ID;
89
use Laravel\Nova\Fields\Text;
10+
use Laravel\Nova\Http\Requests\NovaRequest;
911

1012
class MediaUpload extends Resource
1113
{
@@ -40,6 +42,10 @@ public function fields(Request $request): array
4042
->nullable()
4143
->help('Optional label to help identify this file in Nova.'),
4244

45+
Text::make('File Name', function () {
46+
return basename((string) $this->file_path);
47+
})->onlyOnIndex(),
48+
4349
File::make('File', 'file_path')
4450
->disk('resources')
4551
->path('nova/uploads')
@@ -65,4 +71,16 @@ public function fields(Request $request): array
6571
})->onlyOnIndex(),
6672
];
6773
}
74+
75+
public static function indexQuery(NovaRequest $request, $query)
76+
{
77+
return $query->orderBy('created_at', 'desc');
78+
}
79+
80+
public function actions(Request $request): array
81+
{
82+
return [
83+
new BulkUploadMediaFiles,
84+
];
85+
}
6886
}

app/School.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Model;
66
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
7+
use Spatie\Activitylog\LogOptions;
78
use Spatie\Activitylog\Traits\LogsActivity;
89

910
/**
@@ -49,6 +50,12 @@ public function getDescriptionForEvent(string $eventName): string
4950

5051
protected static $logFillable = true;
5152

53+
public function getActivitylogOptions(): LogOptions
54+
{
55+
return LogOptions::defaults()
56+
->setDescriptionForEvent(fn (string $eventName) => "School {$this->id} has been {$eventName}");
57+
}
58+
5259
public function path()
5360
{
5461
return '/school/'.$this->id;

0 commit comments

Comments
 (0)