<?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 []; | |
} | |
} |
This comment has been minimized.
This comment has been minimized.
Glad you found it useful. |
This comment has been minimized.
This comment has been minimized.
Thank you, it works great! But I need to copy more than one row. Any idea how to do it? |
This comment has been minimized.
This comment has been minimized.
Off the top of my head, I'd remove the lines
then wrap the body of the code in I can't recall why I intentionally avoided duplicating multiple resources. Hopefully this works for you. |
This comment has been minimized.
This comment has been minimized.
But, in my code I don't have this lines :-( `<?php class DuplicateResource extends Action {
}` |
This comment has been minimized.
This comment has been minimized.
And also when I have: abstract class DuplicateResource extends Action it shows error. So, I removed abstract and it works for one record. |
This comment has been minimized.
This comment has been minimized.
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 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. |
This comment has been minimized.
Thank You, It's work👍