Skip to content

Commit

Permalink
Fix: save of nested repeaters
Browse files Browse the repository at this point in the history
  • Loading branch information
Tofandel committed Feb 24, 2024
1 parent 5c2c58d commit e8f84a1
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions src/Repositories/Behaviors/HandleRepeaters.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use A17\Twill\Repositories\ModuleRepository;
use Carbon\Carbon;
use Exception;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
Expand Down Expand Up @@ -124,13 +127,15 @@ public function updateRepeaterMorphMany(

// @todo: This needs refactoring in 3.x
foreach ($relationFields as $index => $relationField) {
$this->extractRepeaters($repeaterName, $fields, $relationField);

Check warning on line 130 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L130

Added line #L130 was not covered by tests
$relationField['position'] = $index + 1;
$relationField[$morphFieldId] = $object->id;
$relationField[$morphFieldType] = $object->getMorphClass();

if (isset($relationField['id']) && Str::startsWith($relationField['id'], $relation)) {
// row already exists, let's update
$id = str_replace($relation . '-', '', $relationField['id']);

$relationRepository->update($id, $relationField);
$currentIdList[] = (int)$id;
} else {
Expand Down Expand Up @@ -175,6 +180,7 @@ public function updateRepeaterWithPivot(
$object->{$relation}()->detach();
}


// Add the position to the pivot fields.
$pivotFields[] = 'position';

Expand All @@ -186,6 +192,7 @@ public function updateRepeaterWithPivot(
$currentRelations = $object->{$relation}()->withPivot('id')->get();

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

// If the relation is not an "existing" one try to match it with our session.
Expand Down Expand Up @@ -280,20 +287,31 @@ public function updateRepeater(

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


if (method_exists($this->model, $relation)) {

Check warning on line 291 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L291

Added line #L291 was not covered by tests
/** @var Relation $relationInstance */
$relationInstance = $this->model->$relation();
if ($relationInstance instanceof BelongsTo || $relationInstance instanceof HasOneOrMany) {
$fk = $relationInstance->getForeignKeyName();

Check warning on line 295 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L293-L295

Added lines #L293 - L295 were not covered by tests
}
}
$fk ??= $this->model->getForeignKey();

Check warning on line 298 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L298

Added line #L298 was not covered by tests

// If no relation field submitted, soft deletes all associated rows.
// We only do this when the model is already existing.
if (! $relationFields && ! $object->wasRecentlyCreated) {
$relationRepository->updateBasic(null, [
'deleted_at' => Carbon::now(),
], [
$this->model->getForeignKey() => $object->id,
$fk => $object->id,

Check warning on line 306 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L306

Added line #L306 was not covered by tests
]);
}

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

foreach ($relationFields as $index => $relationField) {
$this->extractRepeaters($repeaterName, $fields, $relationField);

Check warning on line 314 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L314

Added line #L314 was not covered by tests
$relationField['position'] = $index + 1;
// If the relation is not an "existing" one try to match it with our session.
if (
Expand All @@ -317,12 +335,13 @@ public function updateRepeater(
if (isset($relationField['id']) && Str::startsWith($relationField['id'], $relation)) {
// row already exists, let's update
$id = str_replace($relation . '-', '', $relationField['id']);

$relationRepository->update($id, $relationField);

$currentIdList[] = (int)$id;
} else {
// new row, let's attach to our object and create
$relationField[$this->model->getForeignKey()] = $object->id;
$relationField[$fk] = $object->id;

Check warning on line 344 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L344

Added line #L344 was not covered by tests
$frontEndId = $relationField['id'];
unset($relationField['id']);
$newRelation = $relationRepository->create($relationField);
Expand All @@ -344,6 +363,21 @@ public function updateRepeater(
}
}

private function extractRepeaters(string $repeaterName, array $fields, ?array &$relationField): void
{
if (!isset($relationField) || empty($fields['repeaters'])) {
return;

Check warning on line 369 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L369

Added line #L369 was not covered by tests
}

$prefix = $repeaterName . '|blocks-' . $relationField['id'] . '|';
foreach ($fields['repeaters'] as $key => $repeater) {
if (str_starts_with($key, $prefix)) {
unset($fields['repeaters'][$key]);
$relationField['repeaters'][substr($key, strlen($prefix))] = $repeater;

Check warning on line 376 in src/Repositories/Behaviors/HandleRepeaters.php

View check run for this annotation

Codecov / codecov/patch

src/Repositories/Behaviors/HandleRepeaters.php#L375-L376

Added lines #L375 - L376 were not covered by tests
}
}
}

/**
* This makes sure that arrays are json encode (translations).
*/
Expand Down

0 comments on commit e8f84a1

Please sign in to comment.