Skip to content

Commit

Permalink
morph to field
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgergo committed Nov 23, 2023
1 parent d3be9be commit 3ffb4c2
Show file tree
Hide file tree
Showing 22 changed files with 284 additions and 73 deletions.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions public/build/assets/app-a38a1c81.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import{a as f}from"./app-7da8a33a.js";export{f as default};
1 change: 0 additions & 1 deletion public/build/assets/app-bc3780fe.js

This file was deleted.

1 change: 0 additions & 1 deletion public/build/assets/dropdown-613489dc.js

This file was deleted.

1 change: 1 addition & 0 deletions public/build/assets/dropdown-a3328dbc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import"./app-7da8a33a.js";
1 change: 0 additions & 1 deletion public/build/assets/editor-613489dc.js

This file was deleted.

1 change: 1 addition & 0 deletions public/build/assets/editor-a3328dbc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import"./app-7da8a33a.js";
1 change: 0 additions & 1 deletion public/build/assets/media-manager-613489dc.js

This file was deleted.

1 change: 1 addition & 0 deletions public/build/assets/media-manager-a3328dbc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import"./app-7da8a33a.js";
1 change: 0 additions & 1 deletion public/build/assets/repeater-613489dc.js

This file was deleted.

1 change: 1 addition & 0 deletions public/build/assets/repeater-a3328dbc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import"./app-7da8a33a.js";
12 changes: 6 additions & 6 deletions public/build/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,44 @@
"css": [
"assets/app-d00ef1bd.css"
],
"file": "assets/app-455c4098.js",
"file": "assets/app-7da8a33a.js",
"isEntry": true,
"src": "resources/js/app.js"
},
"resources/js/dropdown.js": {
"file": "assets/dropdown-613489dc.js",
"file": "assets/dropdown-a3328dbc.js",
"imports": [
"resources/js/app.js"
],
"isEntry": true,
"src": "resources/js/dropdown.js"
},
"resources/js/editor.js": {
"file": "assets/editor-613489dc.js",
"file": "assets/editor-a3328dbc.js",
"imports": [
"resources/js/app.js"
],
"isEntry": true,
"src": "resources/js/editor.js"
},
"resources/js/media-manager.js": {
"file": "assets/media-manager-613489dc.js",
"file": "assets/media-manager-a3328dbc.js",
"imports": [
"resources/js/app.js"
],
"isEntry": true,
"src": "resources/js/media-manager.js"
},
"resources/js/repeater.js": {
"file": "assets/repeater-613489dc.js",
"file": "assets/repeater-a3328dbc.js",
"imports": [
"resources/js/app.js"
],
"isEntry": true,
"src": "resources/js/repeater.js"
},
"resources/sass/app.scss": {
"file": "assets/app-bc3780fe.js",
"file": "assets/app-a38a1c81.js",
"imports": [
"resources/js/app.js"
],
Expand Down
3 changes: 3 additions & 0 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import './notifications';
import './theme';
import * as Turbo from '@hotwired/turbo';

// Turbo
window.Turbo = Turbo;

// Alpine
Alpine.plugin(focus);
window.Alpine = Alpine;
Expand Down
55 changes: 55 additions & 0 deletions resources/views/fields/morph-to.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<div class="form-group--row">
<label class="form-label" for="{{ $attrs->get('id') }}">
{{ $label }}
@if($attrs->get('required'))
<span class="required-marker">*</span>
@endif
</label>
<div class="form-row--mixed">
<select
class="form-control"
x-on:change="(function (event) {
Turbo.visit('{{ $url }}?{{ $morphTypeName }}='+event.target.value, { frame: '{{ $attrs->get('id') }}-select' })
})"
>
<option value="" @disabled(! $nullable)>{{ __('Choose Type') }}</option>
@foreach($types as $type => $name)
<option value="{{ $type }}" @selected($type === $morphType)>{{ $name }}</option>
@endforeach
</select>
<turbo-frame id="{{ $attrs->get('id') }}-select">
<div>
<div class="form-group--stacked">
@if($prefix)
<div class="form-group-label">{!! $prefix !!}</div>
@endif
<select {{ $attrs }}>
@if($nullable)
<option value="">--- {{ $label }} ---</option>
@endif
@foreach($options as $option)
@if(isset($option['options']))
<optgroup label="{{ $option['label'] }}">
@foreach($option['options'] as $o)
<option {{ $o['attrs'] }}>{{ $o['label'] }}</option>
@endforeach
</optgroup>
@else
<option {{ $option['attrs'] }}>{{ $option['label'] }}</option>
@endif
@endforeach
</select>
@if($suffix)
<div class="form-group-label">{!! $suffix !!}</div>
@endif
</div>
@if($invalid)
<span class="field-feedback field-feedback--invalid">{!! $error !!}</span>
@endif
@if($help)
<span class="form-description">{!! $help !!}</span>
@endif
</div>
</turbo-frame>
</div>
</div>
16 changes: 15 additions & 1 deletion resources/views/fields/select.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
<span class="required-marker">*</span>
@endif
</label>
<select {{ $attrs }}>
<div class="form-group--stacked">
@if($prefix)
<div class="form-group-label">{!! $prefix !!}</div>
@endif
<select {{ $attrs }}>
@if($nullable)
<option value="">--- {{ $label }} ---</option>
@endif
Expand All @@ -21,4 +25,14 @@
@endif
@endforeach
</select>
@if($suffix)
<div class="form-group-label">{!! $suffix !!}</div>
@endif
</div>
@if($invalid)
<span class="field-feedback field-feedback--invalid">{!! $error !!}</span>
@endif
@if($help)
<span class="form-description">{!! $help !!}</span>
@endif
</div>
18 changes: 8 additions & 10 deletions src/Fields/BelongsToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,15 @@ public function fields(Request $request): array
$model->getForeignKey(),
'related'
)->withDefault();
})
->withRelatableQuery(function (Request $request, Builder $query, Pivot $model): Builder {
})->withRelatableQuery(function (Request $request, Builder $query, Pivot $model): Builder {
return $this->resolveRelatableQuery($request, $model->pivotParent)
->unless($this->allowDuplicateRelations, function (Builder $query) use ($model): Builder {
return $query->whereNotIn(
$query->getModel()->getQualifiedKeyName(),
$this->getRelation($model->pivotParent)->select($query->getModel()->getQualifiedKeyName())
);
});
})
->display(function (Model $model): mixed {
})->display(function (Model $model): mixed {
return $this->resolveDisplay($model);
}),
];
Expand Down Expand Up @@ -195,9 +193,9 @@ public function resolveHydrate(Request $request, Model $model, mixed $value): vo
/**
* {@inheritdoc}
*/
public function resolveRouteBinding(Request $request, Model $model, string $id): Model
public function resolveRouteBinding(Request $request, string $id): Model
{
$relation = $this->getRelation($model);
$relation = $this->getRelation($request->route()->parentOfParameter($this->getRouteKeyName()));

$related = $relation->wherePivot($relation->newPivot()->getQualifiedKeyName(), $id)->firstOrFail();

Expand Down Expand Up @@ -230,11 +228,11 @@ public function routes(Router $router): void
if ($this->isSubResource()) {
$router->get('/', [BelongsToManyController::class, 'index']);
$router->get('/create', [BelongsToManyController::class, 'create']);
$router->get('/{resourceRelation}', [BelongsToManyController::class, 'show']);
$router->get("/{{$this->getRouteKeyName()}", [BelongsToManyController::class, 'show']);
$router->post('/', [BelongsToManyController::class, 'store']);
$router->get('/{resourceRelation}/edit', [BelongsToManyController::class, 'edit']);
$router->patch('/{resourceRelation}', [BelongsToManyController::class, 'update']);
$router->delete('/{resourceRelation}', [BelongsToManyController::class, 'destroy']);
$router->get("/{{$this->getRouteKeyName()}/edit", [BelongsToManyController::class, 'edit']);
$router->patch("/{{$this->getRouteKeyName()}", [BelongsToManyController::class, 'update']);
$router->delete("/{{$this->getRouteKeyName()}", [BelongsToManyController::class, 'destroy']);
}
}

Expand Down
100 changes: 100 additions & 0 deletions src/Fields/MorphTo.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,116 @@

namespace Cone\Root\Fields;

use Cone\Root\Http\Controllers\MorphToController;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo as EloquentRelation;
use Illuminate\Http\Request;
use Illuminate\Routing\Router;
use Illuminate\Support\Str;

class MorphTo extends BelongsTo
{
/**
* The Blade template.
*/
protected string $template = 'root::fields.morph-to';

/**
* The morph types.
*/
protected array $types = [];

/**
* {@inheritdoc}
*/
public function getRelation(Model $model): EloquentRelation
{
return parent::getRelation($model);
}

/**
* {@inheritdoc}
*/
public function resolveRelatableQuery(Request $request, Model $model): Builder
{
$relation = $this->getRelation($model);

$type = Str::before((string) $this->getOldValue($request), ':') ?: $request->query($relation->getMorphType());

$model->setAttribute(
$relation->getMorphType(),
$type ?: $model->getAttribute($relation->getMorphType()) ?: ($this->types[0] ?? null)
);

return parent::resolveRelatableQuery($request, $model);
}

/**
* {@inheritdoc}
*/
public function resolveHydrate(Request $request, Model $model, mixed $value): void
{
$value = explode(':', $value);

$model->setAttribute($this->getRelation($model)->getMorphType(), $value[0]);

$related = new $value[0];

$related->forceFill([$related->getKeyName() => $value[1]]);

parent::resolveHydrate($request, $model, $related);
}

/**
* {@inheritdoc}
*/
public function newOption(Model $related, string $label): Option
{
return new Option(sprintf('%s:%s', $related::class, $related->getKey()), $label);
}

/**
* Set the morph types.
*/
public function types(array $types): static
{
$this->types = $types;

return $this;
}

/**
* {@inheritdoc}
*/
public function routes(Router $router): void
{
$router->get('/', MorphToController::class);
}

/**
* {@inheritdoc}
*/
public function toArray(): array
{
return array_merge(parent::toArray(), [
'types' => array_map(static function (string $type): string {
return __(Str::of($type)->classBasename()->headline()->value());
}, array_combine($this->types, $this->types)),
]);
}

/**
* {@inheritdoc}
*/
public function toInput(Request $request, Model $model): array
{
$relation = $this->getRelation($model);

return array_merge(parent::toInput($request, $model), [
'url' => $this->replaceRoutePlaceholders($request->route()),
'morphTypeName' => $name = $relation->getMorphType(),
'morphType' => $model->getAttribute($name),
]);
}
}
6 changes: 2 additions & 4 deletions src/Fields/MorphToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,15 @@ public function fields(Request $request): array
$model->getRelatedKey(),
$model->getForeignKey(),
)->withDefault();
})
->withRelatableQuery(function (Request $request, Builder $query, MorphPivot $model): Builder {
})->withRelatableQuery(function (Request $request, Builder $query, MorphPivot $model): Builder {
return $this->resolveRelatableQuery($request, $model->pivotParent)
->unless($this->allowDuplicateRelations, function (Builder $query) use ($model): Builder {
return $query->whereNotIn(
$query->getModel()->getQualifiedKeyName(),
$this->getRelation($model->pivotParent)->select($query->getModel()->getQualifiedKeyName())
);
});
})
->display(function (Model $model): mixed {
})->display(function (Model $model): mixed {
return $this->resolveDisplay($model);
}),
];
Expand Down
Loading

0 comments on commit 3ffb4c2

Please sign in to comment.