Last active
December 1, 2023 08:19
-
-
Save ns139426/aa4997886cef5b5c9e11de6e0fdffb5a to your computer and use it in GitHub Desktop.
Duplicate Resource Action for Laravel Nova
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Nova\Actions; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Queue\SerializesModels; | |
use Illuminate\Support\Collection; | |
use Laravel\Nova\Actions\Action; | |
use Laravel\Nova\Fields\ActionFields; | |
abstract class DuplicateResource extends Action { | |
use SerializesModels; | |
public $showOnDetail = true; | |
public $showOnIndex = false; | |
public $showOnTableRow = true; | |
public $confirmButtonText = 'Duplicate Resource'; | |
public $cancelButtonText = 'Cancel'; | |
public $confirmText = 'Are you sure you want to duplicate this resource?'; | |
public $withoutActionEvents = true; | |
protected $keepRelations = []; | |
protected $duplicateRelations = []; | |
/** | |
* Perform the action on the given models. | |
* | |
* @param ActionFields $fields | |
* @param Collection $models | |
* | |
* @return mixed | |
*/ | |
public function handle(ActionFields $fields, Collection $models) | |
{ | |
if ($models->count() !== 1) { | |
return Action::danger("Cannot duplicate multiple models simultaneously."); | |
} | |
$model = $models->first(); | |
$newModel = $model->replicate(); | |
// Override values from fields | |
foreach ($fields->getAttributes() as $key => $value) { | |
if(isset($value)){ | |
$newModel->$key = $value; | |
} | |
} | |
$newModel->push(); | |
if (!empty($this->duplicateRelations)) { | |
// load the relations | |
$model->load($this->duplicateRelations); | |
foreach ($model->getRelations() as $relation => $items) { | |
// works for hasMany | |
foreach ($items as $item) { | |
// clean up our models, remove the id and remove the appends | |
unset($item->id); | |
$item->setAppends([]); | |
// create a relation on the new model with the data. | |
$newModel->{$relation}()->create($item->toArray()); | |
} | |
} | |
} | |
if (!empty($this->keepRelations)) { | |
// load the fresh model with relations to maintain | |
unset($model->relations); | |
$model->load($this->keepRelations); | |
foreach ($model->getRelations() as $relation => $items) { | |
// works for hasMany | |
foreach ($items as $item) { | |
$newModel->{$relation}()->attach($item); | |
} | |
} | |
} | |
$newModel->save(); | |
return Action::message($this->getSuccessMessage($model, $newModel, $fields)); | |
} | |
protected function getSuccessMessage(Model $originalModel, Model $newModel, ActionFields $fields) : String { | |
return "Resource has been duplicated."; | |
} | |
/** | |
* Get the fields available on the action. | |
* | |
* @return array | |
*/ | |
public function fields() | |
{ | |
return []; | |
} | |
} |
@ns139426 thankyou thankyou thankyou. your work is greatly appreciated. :)
Thanks a lot. I appreciate you effort.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's written as an abstract class so that you extend it for your own needs rather than just using it directly. If you just want to hack it in place, probably remove
$model = $models->first();
and put in aforeach
on the$models
parameter.The PHP docs can be pretty tough to read but try https://www.php.net/manual/en/language.oop5.abstract.php. There are probably lots of other good resources on OOP that will help you better understand abstract classes too.