Skip to content

Commit 029f666

Browse files
committed
Fix: save of nested repeaters
1 parent 5c2c58d commit 029f666

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

src/Repositories/Behaviors/HandleRepeaters.php

+32-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
use A17\Twill\Repositories\ModuleRepository;
1010
use Carbon\Carbon;
1111
use Exception;
12+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
13+
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
14+
use Illuminate\Database\Eloquent\Relations\Relation;
1215
use Illuminate\Support\Arr;
1316
use Illuminate\Support\Collection;
1417
use Illuminate\Support\Str;
@@ -124,6 +127,7 @@ public function updateRepeaterMorphMany(
124127

125128
// @todo: This needs refactoring in 3.x
126129
foreach ($relationFields as $index => $relationField) {
130+
$this->extractRepeaters($repeaterName, $fields, $relationField);
127131
$relationField['position'] = $index + 1;
128132
$relationField[$morphFieldId] = $object->id;
129133
$relationField[$morphFieldType] = $object->getMorphClass();
@@ -186,6 +190,7 @@ public function updateRepeaterWithPivot(
186190
$currentRelations = $object->{$relation}()->withPivot('id')->get();
187191

188192
foreach ($relationFields as $index => $relationField) {
193+
$this->extractRepeaters($repeaterName, $fields, $relationField);
189194
$relationField['position'] = $index + 1;
190195

191196
// If the relation is not an "existing" one try to match it with our session.
@@ -280,20 +285,30 @@ public function updateRepeater(
280285

281286
$relationRepository = $this->getModelRepository($relation, $modelOrRepository);
282287

288+
if (method_exists($this->model, $relation)) {
289+
/** @var Relation $relationInstance */
290+
$relationInstance = $this->model->$relation();
291+
if ($relationInstance instanceof BelongsTo || $relationInstance instanceof HasOneOrMany) {
292+
$fk = $relationInstance->getForeignKeyName();
293+
}
294+
}
295+
$fk ??= $this->model->getForeignKey();
296+
283297
// If no relation field submitted, soft deletes all associated rows.
284298
// We only do this when the model is already existing.
285299
if (! $relationFields && ! $object->wasRecentlyCreated) {
286300
$relationRepository->updateBasic(null, [
287301
'deleted_at' => Carbon::now(),
288302
], [
289-
$this->model->getForeignKey() => $object->id,
303+
$fk => $object->id,
290304
]);
291305
}
292306

293307
// keep a list of updated and new rows to delete (soft delete?) old rows that were deleted from the frontend
294308
$currentIdList = [];
295309

296310
foreach ($relationFields as $index => $relationField) {
311+
$this->extractRepeaters($repeaterName, $fields, $relationField);
297312
$relationField['position'] = $index + 1;
298313
// If the relation is not an "existing" one try to match it with our session.
299314
if (
@@ -322,7 +337,7 @@ public function updateRepeater(
322337
$currentIdList[] = (int)$id;
323338
} else {
324339
// new row, let's attach to our object and create
325-
$relationField[$this->model->getForeignKey()] = $object->id;
340+
$relationField[$fk] = $object->id;
326341
$frontEndId = $relationField['id'];
327342
unset($relationField['id']);
328343
$newRelation = $relationRepository->create($relationField);
@@ -344,6 +359,21 @@ public function updateRepeater(
344359
}
345360
}
346361

362+
private function extractRepeaters(string $repeaterName, array $fields, ?array &$relationField): void
363+
{
364+
if (!isset($relationField) || empty($fields['repeaters'])) {
365+
return;
366+
}
367+
368+
$prefix = $repeaterName . '|blocks-' . $relationField['id'] . '|';
369+
foreach ($fields['repeaters'] as $key => $repeater) {
370+
if (str_starts_with($key, $prefix)) {
371+
unset($fields['repeaters'][$key]);
372+
$relationField['repeaters'][substr($key, strlen($prefix))] = $repeater;
373+
}
374+
}
375+
}
376+
347377
/**
348378
* This makes sure that arrays are json encode (translations).
349379
*/

0 commit comments

Comments
 (0)