F
Filament15mo ago
Matthew

How can I get record when calling a custom Action?

Basically, I want to create a ZIP file of all the elements that are in the repeater, But how can I get the record in the Action?
<?php

namespace App\Actions;
use Filament\Actions\Action;
use Illuminate\Database\Eloquent\Model;

class ZipAction extends Action{

public static function getDefaultName(): ?string
{
return 'Zip Action';
}

protected function setUp(): void
{
parent::setUp();

// $this->label(__('filament-actions::delete.single.label'));
$this->label("Zip Action");

// $this->modalHeading(fn (): string => __('filament-actions::delete.single.modal.heading', ['label' => $this->getRecordTitle()]));

// $this->modalSubmitActionLabel(__('filament-actions::delete.single.modal.actions.delete.label'));

// $this->successNotificationTitle(__('filament-actions::delete.single.notifications.deleted.title'));

$this->color('info');

$this->groupedIcon('heroicon-m-inbox-arrow-down');

// $this->requiresConfirmation();

$this->modalIcon('heroicon-o-inbox-arrow-down');

$this->keyBindings(['mod+d']);

$this->hidden(static function (Model $record): bool {
if (! method_exists($record, 'trashed')) {
return false;
}

return $record->trashed();
});

$this->action(function (): void {
$result = $this->process(static fn (Model $record) => $record);
dd($result);

// $this->success();
});
}
}
<?php

namespace App\Actions;
use Filament\Actions\Action;
use Illuminate\Database\Eloquent\Model;

class ZipAction extends Action{

public static function getDefaultName(): ?string
{
return 'Zip Action';
}

protected function setUp(): void
{
parent::setUp();

// $this->label(__('filament-actions::delete.single.label'));
$this->label("Zip Action");

// $this->modalHeading(fn (): string => __('filament-actions::delete.single.modal.heading', ['label' => $this->getRecordTitle()]));

// $this->modalSubmitActionLabel(__('filament-actions::delete.single.modal.actions.delete.label'));

// $this->successNotificationTitle(__('filament-actions::delete.single.notifications.deleted.title'));

$this->color('info');

$this->groupedIcon('heroicon-m-inbox-arrow-down');

// $this->requiresConfirmation();

$this->modalIcon('heroicon-o-inbox-arrow-down');

$this->keyBindings(['mod+d']);

$this->hidden(static function (Model $record): bool {
if (! method_exists($record, 'trashed')) {
return false;
}

return $record->trashed();
});

$this->action(function (): void {
$result = $this->process(static fn (Model $record) => $record);
dd($result);

// $this->success();
});
}
}
<?php

namespace App\Filament\Resources\TestResource\Pages;

//...

class EditTest extends EditRecord
{
protected static string $resource = TestResource::class;

protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
ZipAction::make()
];
}
}
<?php

namespace App\Filament\Resources\TestResource\Pages;

//...

class EditTest extends EditRecord
{
protected static string $resource = TestResource::class;

protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
ZipAction::make()
];
}
}
10 Replies
Matthew
MatthewOP15mo ago
<?php

namespace App\Filament\Resources;

use App\Actions\ZipAction;
use App\Filament\Awcodes\CustomPathGenerator;
use App\Filament\Resources\TestResource\Pages;
use App\Filament\Resources\TestResource\RelationManagers;
use App\Models\Test;
use Awcodes\Curator\Components\Forms\CuratorPicker;
use Awcodes\Curator\Components\Tables\CuratorColumn;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;

class TestResource extends Resource
{
protected static ?string $model = Test::class;

protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

public static function form(Form $form): Form
{
// $record = $form->getRecord();

return $form
->schema([
Section::make('Course')
->description('Prevent abuse by limiting the number of requests per period')
->schema([
Repeater::make('items')
->columnSpanFull()
->grid(2)
->schema([
TextInput::make('name')
->label('Name')
->required(),
CuratorPicker::make('attachment')
->lazyLoad()
->multiple(),
])
->addAction(fn(Action $action) => $action->label('Collapse all members')),
])
]);
}
// ...
}
<?php

namespace App\Filament\Resources;

use App\Actions\ZipAction;
use App\Filament\Awcodes\CustomPathGenerator;
use App\Filament\Resources\TestResource\Pages;
use App\Filament\Resources\TestResource\RelationManagers;
use App\Models\Test;
use Awcodes\Curator\Components\Forms\CuratorPicker;
use Awcodes\Curator\Components\Tables\CuratorColumn;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;

class TestResource extends Resource
{
protected static ?string $model = Test::class;

protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

public static function form(Form $form): Form
{
// $record = $form->getRecord();

return $form
->schema([
Section::make('Course')
->description('Prevent abuse by limiting the number of requests per period')
->schema([
Repeater::make('items')
->columnSpanFull()
->grid(2)
->schema([
TextInput::make('name')
->label('Name')
->required(),
CuratorPicker::make('attachment')
->lazyLoad()
->multiple(),
])
->addAction(fn(Action $action) => $action->label('Collapse all members')),
])
]);
}
// ...
}
Patrick Boivin
Patrick Boivin15mo ago
Have you tried something like this?
$this->action(function ($record): void {
// ...
});
$this->action(function ($record): void {
// ...
});
Matthew
MatthewOP15mo ago
Havent. I will try it now
Matthew
MatthewOP15mo ago
When using $record
<?php
class ZipAction extends Action
{
protected function setUp(): void
{

$this->action(function ($record): string {
// dd($record);
$formItems = $this->$record->getState();

$final = []; // Initialize an empty array

foreach ($formItems['items'] as $item) {
$currentValue = $item["attachment"];

foreach ($currentValue as $attachmentId) {
// Find the path of the media id
$currentValuePath = DB::table('media')->where('id', $attachmentId)->pluck('path')->first();
$currentValueName = DB::table('media')->where('id', $attachmentId)->pluck('title')->first();

// Get the Storage directory
$currentValuePath = Storage::disk('public')->path($currentValuePath);

// Add the current path and rename it in the ZIP archive
if ($currentValuePath) {
$final[] = [
'path' => $currentValuePath,
'name' => $currentValueName, // Set the desired name
];
}
}
}

// Create a zip file
$zip = new ZipArchive;
$zipFileName = public_path('images.zip');

if ($zip->open($zipFileName, ZipArchive::CREATE) === true) {
foreach ($final as $file) {
// Check if the file exists before adding it to the zip
if (file_exists($file['path'])) {
$zip->addFile($file['path'], $file['name']);
}
}

$zip->close();

return response()->download($zipFileName)->deleteFileAfterSend(true);
} else {
return "Failed to create the zip file.";
}
});
}
}
<?php
class ZipAction extends Action
{
protected function setUp(): void
{

$this->action(function ($record): string {
// dd($record);
$formItems = $this->$record->getState();

$final = []; // Initialize an empty array

foreach ($formItems['items'] as $item) {
$currentValue = $item["attachment"];

foreach ($currentValue as $attachmentId) {
// Find the path of the media id
$currentValuePath = DB::table('media')->where('id', $attachmentId)->pluck('path')->first();
$currentValueName = DB::table('media')->where('id', $attachmentId)->pluck('title')->first();

// Get the Storage directory
$currentValuePath = Storage::disk('public')->path($currentValuePath);

// Add the current path and rename it in the ZIP archive
if ($currentValuePath) {
$final[] = [
'path' => $currentValuePath,
'name' => $currentValueName, // Set the desired name
];
}
}
}

// Create a zip file
$zip = new ZipArchive;
$zipFileName = public_path('images.zip');

if ($zip->open($zipFileName, ZipArchive::CREATE) === true) {
foreach ($final as $file) {
// Check if the file exists before adding it to the zip
if (file_exists($file['path'])) {
$zip->addFile($file['path'], $file['name']);
}
}

$zip->close();

return response()->download($zipFileName)->deleteFileAfterSend(true);
} else {
return "Failed to create the zip file.";
}
});
}
}
No description
Matthew
MatthewOP15mo ago
When using form
Action::make('zip')
->label('Zip Files')
->action(function (array $data) {
$formItems = $this->form->getState();
dd($this->form);
$final = []; // Initialize an empty array

foreach ($formItems['items'] as $item) {
$currentValue = $item["attachment"];

foreach ($currentValue as $attachmentId) {
// Find the path of the media id
$currentValuePath = DB::table('media')->where('id', $attachmentId)->pluck('path')->first();
$currentValueName = DB::table('media')->where('id', $attachmentId)->pluck('title')->first();

// Get the Storage directory
$currentValuePath = Storage::disk('public')->path($currentValuePath);

// Add the current path and rename it in the ZIP archive
if ($currentValuePath) {
$final[] = [
'path' => $currentValuePath,
'name' => $currentValueName, // Set the desired name
];
}
}
}
// ... (exceeded discord )

Action::make('zip')
->label('Zip Files')
->action(function (array $data) {
$formItems = $this->form->getState();
dd($this->form);
$final = []; // Initialize an empty array

foreach ($formItems['items'] as $item) {
$currentValue = $item["attachment"];

foreach ($currentValue as $attachmentId) {
// Find the path of the media id
$currentValuePath = DB::table('media')->where('id', $attachmentId)->pluck('path')->first();
$currentValueName = DB::table('media')->where('id', $attachmentId)->pluck('title')->first();

// Get the Storage directory
$currentValuePath = Storage::disk('public')->path($currentValuePath);

// Add the current path and rename it in the ZIP archive
if ($currentValuePath) {
$final[] = [
'path' => $currentValuePath,
'name' => $currentValueName, // Set the desired name
];
}
}
}
// ... (exceeded discord )

No description
Matthew
MatthewOP15mo ago
Basically The sctruture is very different and my code then wont work, because I get this:
Matthew
MatthewOP15mo ago
No description
Matthew
MatthewOP15mo ago
I think its possible using $this->livewire. Looking into it atm
Matthew
MatthewOP15mo ago
Managed to get the same data in both cases. So the code should techinically work fine. But it doesnt. The Action just doesnt do anthing and I have no idea why
No description
No description
Matthew
MatthewOP15mo ago
Code in the ZipAction
$this->action(function ($record): string {
// dd($record);
$formItems = $this->livewire->form->getState();
dd($formItems);

$final = []; // Initialize an empty array

foreach ($formItems['items'] as $item) {
$currentValue = $item["attachment"];

foreach ($currentValue as $attachmentId) {
// Find the path of the media id
$currentValuePath = DB::table('media')->where('id', $attachmentId)->pluck('path')->first();
$currentValueName = DB::table('media')->where('id', $attachmentId)->pluck('title')->first();

// Get the Storage directory
$currentValuePath = Storage::disk('public')->path($currentValuePath);

// Add the current path and rename it in the ZIP archive
if ($currentValuePath) {
$final[] = [
'path' => $currentValuePath,
'name' => $currentValueName, // Set the desired name
];
}
}
}

// Create a zip file
$zip = new ZipArchive;
$zipFileName = public_path('images.zip'); // Define the name and path of the zip file

if ($zip->open($zipFileName, ZipArchive::CREATE) === true) {
foreach ($final as $file) {
// Check if the file exists before adding it to the zip
if (file_exists($file['path'])) {
$zip->addFile($file['path'], $file['name']); // Specify the new name in the ZIP archive
}
}

$zip->close();

return response()->download($zipFileName)->deleteFileAfterSend(true);
} else {
return "Failed to create the zip file.";
}
});
$this->action(function ($record): string {
// dd($record);
$formItems = $this->livewire->form->getState();
dd($formItems);

$final = []; // Initialize an empty array

foreach ($formItems['items'] as $item) {
$currentValue = $item["attachment"];

foreach ($currentValue as $attachmentId) {
// Find the path of the media id
$currentValuePath = DB::table('media')->where('id', $attachmentId)->pluck('path')->first();
$currentValueName = DB::table('media')->where('id', $attachmentId)->pluck('title')->first();

// Get the Storage directory
$currentValuePath = Storage::disk('public')->path($currentValuePath);

// Add the current path and rename it in the ZIP archive
if ($currentValuePath) {
$final[] = [
'path' => $currentValuePath,
'name' => $currentValueName, // Set the desired name
];
}
}
}

// Create a zip file
$zip = new ZipArchive;
$zipFileName = public_path('images.zip'); // Define the name and path of the zip file

if ($zip->open($zipFileName, ZipArchive::CREATE) === true) {
foreach ($final as $file) {
// Check if the file exists before adding it to the zip
if (file_exists($file['path'])) {
$zip->addFile($file['path'], $file['name']); // Specify the new name in the ZIP archive
}
}

$zip->close();

return response()->download($zipFileName)->deleteFileAfterSend(true);
} else {
return "Failed to create the zip file.";
}
});
I found it. Im technically supposed to return a string in the function and the response is blocked. I just removed the : string and now it works!
Want results from more Discord servers?
Add your server