Skip to content

Commit

Permalink
Merge pull request #23 from saade/fix/relationships-always-being-setup
Browse files Browse the repository at this point in the history
fix: relationships always being setup
  • Loading branch information
saade authored Mar 20, 2024
2 parents 25bfb67 + 40fc1a1 commit 0788e35
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 258 deletions.
16 changes: 12 additions & 4 deletions src/Forms/Components/Actions/AddAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,18 @@ protected function setUp(): void
);

$this->form(
fn (Component $component, Form $form): ?Form => match ($component->hasModal()) {
true => $component->getForm($form)
->model($component->getRelatedModel()),
default => null,
function (Component $component, Form $form): ?Form {
if (! $component->hasModal()) {
return null;
}

$form = $component->getForm($form);

if ($model = $component->getRelatedModel()) {
$form->model($model);
}

return $form;
}
);

Expand Down
18 changes: 13 additions & 5 deletions src/Forms/Components/Actions/AddChildAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,23 @@ protected function setUp(): void
);

$this->form(
fn (Component $component, Form $form): ?Form => match ($component->hasModal()) {
true => $component->getForm($form)
->model($component->getRelatedModel()),
default => null,
function (Component $component, Form $form): ?Form {
if (! $component->hasModal()) {
return null;
}

$form = $component->getForm($form);

if ($model = $component->getRelatedModel()) {
$form->model($model);
}

return $form;
}
);

$this->action(function (Component $component, array $arguments): void {
$parentRecord = $component->getCachedExistingRecords()->get($arguments['cachedRecordKey']);
$parentRecord = $component->getRelatedModel() ? $component->getCachedExistingRecords()->get($arguments['cachedRecordKey']) : null;

$this->process(function (Component $component, array $arguments, array $data): void {
$statePath = $component->getRelativeStatePath($arguments['statePath']);
Expand Down
2 changes: 1 addition & 1 deletion src/Forms/Components/Actions/DeleteAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ protected function setUp(): void
$this->modalSubmitActionLabel(fn (): string => __('filament-adjacency-list::adjacency-list.actions.delete.modal.actions.confirm'));

$this->action(function (Component $component, array $arguments): void {
$record = $component->getCachedExistingRecords()->get($arguments['cachedRecordKey']);
$record = $component->getRelatedModel() ? $component->getCachedExistingRecords()->get($arguments['cachedRecordKey']) : null;

$this->process(function (Component $component, array $arguments): void {
$statePath = $component->getRelativeStatePath($arguments['statePath']);
Expand Down
11 changes: 8 additions & 3 deletions src/Forms/Components/Actions/EditAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@ protected function setUp(): void

$this->form(
function (Component $component, Form $form, array $arguments): Form {
return $component
$form = $component
->getForm($form)
->model($component->getCachedExistingRecords()->get($arguments['cachedRecordKey']))
->statePath($arguments['statePath']);

if ($component->getRelatedModel()) {
$form->model($component->getCachedExistingRecords()->get($arguments['cachedRecordKey']));
}

return $form;
}
);

Expand All @@ -43,7 +48,7 @@ function (Component $component, array $arguments): array {
);

$this->action(function (Component $component, array $arguments): void {
$record = $component->getCachedExistingRecords()->get($arguments['cachedRecordKey']);
$record = $component->getRelatedModel() ? $component->getCachedExistingRecords()->get($arguments['cachedRecordKey']) : null;

$this->process(function (Component $component, array $arguments, array $data): void {
$statePath = $component->getRelativeStatePath($arguments['statePath']);
Expand Down
241 changes: 0 additions & 241 deletions src/Forms/Components/AdjacencyList.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,248 +2,7 @@

namespace Saade\FilamentAdjacencyList\Forms\Components;

use Closure;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Arr;
use Saade\FilamentAdjacencyList\Forms\Components\Actions\Action;
use Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;

class AdjacencyList extends Component
{
use Concerns\HasRelationship;

protected array | Closure | null $pivotAttributes = null;

protected function setUp(): void
{
parent::setUp();

$this->afterStateHydrated(null);

$this->loadStateFromRelationshipsUsing(static function (AdjacencyList $component) {
$component->clearCachedExistingRecords();

$component->fillFromRelationship();
});

$this->addAction(function (Action $action): void {
$action->using(function (Component $component, array $data): void {
$relationship = $component->getRelationship();
$model = $component->getRelatedModel();
$pivotData = $component->getPivotAttributes() ?? [];

if ($relationship instanceof BelongsToMany) {
$pivotColumns = $relationship->getPivotColumns();

$pivotData = Arr::only($data, $pivotColumns);
$data = Arr::except($data, $pivotColumns);
}

$data = $component->mutateRelationshipDataBeforeCreate($data);

if ($translatableContentDriver = $component->getLivewire()->makeFilamentTranslatableContentDriver()) {
$record = $translatableContentDriver->makeRecord($model, $data);
} else {
$record = new $model();
$record->fill($data);
}

if ($orderColumn = $component->getOrderColumn()) {
$record->{$orderColumn} = $pivotData[$orderColumn] = count($component->getState());
}

if ($relationship instanceof BelongsToMany) {
$record->save();

$relationship->attach($record, $pivotData);

$component->cacheRecord($record);

return;
}

$relationship->save($record);

$component->cacheRecord($record);
});
});

$this->addChildAction(function (Action $action): void {
$action->using(function (Component $component, Model $parentRecord, array $data, array $arguments): void {
$relationship = $component->getRelationship();
$model = $component->getRelatedModel();

$pivotData = $component->getPivotAttributes() ?? [];

if ($relationship instanceof BelongsToMany) {
$pivotColumns = $relationship->getPivotColumns();

$pivotData = Arr::only($data, $pivotColumns);
$data = Arr::except($data, $pivotColumns);
}

$data = $component->mutateRelationshipDataBeforeCreate($data);

if ($translatableContentDriver = $component->getLivewire()->makeFilamentTranslatableContentDriver()) {
$record = $translatableContentDriver->makeRecord($model, $data);
} else {
$record = new $model();
$record->fill($data);
}

if ($orderColumn = $component->getOrderColumn()) {
$record->{$orderColumn} = $pivotData[$orderColumn] = count(
data_get(
$component->getState(),
$component->getRelativeStatePath($arguments['statePath']) . '.' . $component->getChildrenKey()
)
);
}

if ($relationship instanceof BelongsToMany) {
$record->save();

$parentRecord->{$component->getChildrenKey()}()->syncWithPivotValues(
[$record->getKey()],
$pivotData
);

$component->cacheRecord($record);

return;
}

$parentRecord->{$component->getChildrenKey()}()->save($record);

$component->cacheRecord($record);
});
});

$this->editAction(function (Action $action): void {
$action->using(function (Component $component, Model $record, array $data): void {
$relationship = $component->getRelationship();

$translatableContentDriver = $component->getLivewire()->makeFilamentTranslatableContentDriver();

if ($relationship instanceof BelongsToMany) {
$pivot = $record->{$relationship->getPivotAccessor()};

$pivotColumns = $relationship->getPivotColumns();
$pivotData = Arr::only($data, $pivotColumns);

if (count($pivotColumns)) {
if ($translatableContentDriver) {
$translatableContentDriver->updateRecord($pivot, $pivotData);
} else {
$pivot->update($pivotData);
}
}

$data = Arr::except($data, $pivotColumns);
}

$data = $component->mutateRelationshipDataBeforeSave($data, $record);

if ($translatableContentDriver) {
$translatableContentDriver->updateRecord($record, $data);
} else {
$record->update($data);
}
});
});

$this->deleteAction(function (Action $action): void {
$action->using(function (Component $component, Model $record): void {
$relationship = $component->getRelationship();

if ($relationship instanceof BelongsToMany) {
$pivot = $record->{$relationship->getPivotAccessor()};

$pivot->delete();
}

$record->delete();

$component->deleteCachedRecord($record);
});
});

$this->saveRelationshipsUsing(static function (AdjacencyList $component, ?array $state) {
if (! is_array($state)) {
$state = [];
}

$cachedExistingRecords = $component->getCachedExistingRecords();
$relationship = $component->getRelationship();
$childrenKey = $component->getChildrenKey();
$recordKeyName = $relationship->getRelated()->getKeyName();
$orderColumn = $component->getOrderColumn();
$pivotAttributes = $component->getPivotAttributes();

Arr::map(
$state,
$traverse = function (array $item, string $itemKey, array $siblings = []) use (&$traverse, &$cachedExistingRecords, $state, $relationship, $childrenKey, $recordKeyName, $orderColumn, $pivotAttributes): Model {
$record = $cachedExistingRecords->get($itemKey);

/* Update item order */
if ($orderColumn) {
$record->{$orderColumn} = $pivotAttributes[$orderColumn] = array_search($itemKey, array_keys($siblings ?: $state));
}

if ($relationship instanceof BelongsToMany) {
$record->save();
} else {
$relationship->save($record);
}

if ($children = data_get($item, $childrenKey)) {
$childrenRecords = collect($children)->map(fn (array $child, string $childKey) => $traverse($child, $childKey, $children));

if ($relationship instanceof BelongsToMany) {
$record->{$childrenKey}()->syncWithPivotValues(
$childrenRecords->pluck($recordKeyName),
$pivotAttributes()
);

return $record;
}

$record->{$childrenKey}()->saveMany($childrenRecords);
}

return $record;
}
);

// Clear cache
$component->fillFromRelationship();
});

$this->dehydrated(false);
}

public function getRelationship(): HasMany | BelongsToMany
{
if ($model = $this->getModelInstance()) {
if (! in_array(HasRecursiveRelationships::class, class_uses($model))) {
throw new \Exception('The model ' . $model::class . ' must use the ' . HasRecursiveRelationships::class . ' trait.');
}
}

return $model->{$this->getRelationshipName()}();
}

public function pivotAttributes(array | Closure | null $pivotAttributes): static
{
$this->pivotAttributes = $pivotAttributes;

return $this;
}

public function getPivotAttributes(): array
{
return $this->evaluate($this->pivotAttributes) ?? [];
}
}
Loading

0 comments on commit 0788e35

Please sign in to comment.