-
-
Save ns139426/aa4997886cef5b5c9e11de6e0fdffb5a to your computer and use it in GitHub Desktop.
<?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 []; | |
} | |
} |
Thank You, It's work 👍
Glad you found it useful.
Thank you, it works great! But I need to copy more than one row. Any idea how to do it?
Thank you, it works great! But I need to copy more than one row. Any idea how to do it?
Off the top of my head, I'd remove the lines
if ($models->count() !== 1) {
return Action::danger("Cannot duplicate multiple models simultaneously.");
}
then wrap the body of the code in foreach($models as $model)
before finally returning an appropriate error message.
I can't recall why I intentionally avoided duplicating multiple resources. Hopefully this works for you.
But, in my code I don't have this lines :-(
`<?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;
class DuplicateResource extends Action {
use SerializesModels;
public $showOnDetail = true;
public $showOnIndex = true;
public $showOnTableRow = false;
public $confirmButtonText = '...';
public $cancelButtonText = '...';
public $confirmText = '...';
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)
{
$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 "...";
}
/**
* Get the fields available on the action.
*
* @return array
*/
public function fields()
{
return [];
}
}`
And also when I have: abstract class DuplicateResource extends Action it shows error. So, I removed abstract and it works for one record.
And also when I have: abstract class DuplicateResource extends Action it shows error. So, I removed abstract and it works for one record.
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 a foreach
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.
@ns139426 thankyou thankyou thankyou. your work is greatly appreciated. :)
Thanks a lot. I appreciate you effort.
Thank You, It's work 👍