Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix remove files #496

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/js/field.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions resources/js/components/FormField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
@move-up="moveUp(group.key)"
@move-down="moveDown(group.key)"
@remove="remove(group.key)"
@file-deleted="$emit('file-deleted')"
/>
</div>

Expand Down
1 change: 1 addition & 0 deletions resources/js/components/FormGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
:mode="mode"
:show-help-text="item.helpText != null"
:class="{ 'remove-bottom-border': index == group.fields.length - 1 }"
@file-deleted="$emit('file-deleted')"
/>
</div>
</div>
Expand Down
115 changes: 115 additions & 0 deletions src/Collections/FieldCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

namespace Whitecube\NovaFlexibleContent\Collections;

use Laravel\Nova\Fields\Field;
use Laravel\Nova\Fields\FieldCollection as NovaFieldCollection;
use Laravel\Nova\Http\Requests\NovaRequest;
use Whitecube\NovaFlexibleContent\Flexible;

class FieldCollection extends NovaFieldCollection
{
/**
* Find a given field by its attribute.
*
* @param string $attribute
* @param mixed $default
*
* @return null|\Laravel\Nova\Fields\Field
*/
public function findFieldByAttribute($attribute, $default = null)
{
if (false !== strpos($attribute, '__')) {
$request = resolve(NovaRequest::class);
$resource = $request->findResourceOrFail();
$fields = $resource->updateFields($request);

$attribute_parts = explode('__', $attribute, 2);

$groups = [];
foreach ($fields as $i => $field) {
if ($field instanceof Flexible) {
$field->index = $i;
$groups = array_merge($groups, $this->flattenGroups($field));
}
}

foreach ($groups as $group) {
if ($group->inUseKey() !== $attribute_parts[0]) {
continue;
}

$field = $group->collectionFields()->first(function ($field) use ($attribute_parts, $group) {
$field->group = $group;

return isset($field->attribute)
&& $field->attribute == $attribute_parts[1];
}, $default);

return $this->addDeleteCallback($field);
}
}

return $this->first(function ($field) use ($attribute) {
return isset($field->attribute)
&& $field->attribute == $attribute;
}, $default);
}

/**
* Flatten all groups into a single array.
*
* @param $parentGroup
*
* @return array
*/
private function flattenGroups(Field $field, $parentGroup = null)
{
if (!$field->groups()) {
return [];
}

$flattened = [];

foreach ($field->groups() as $groupIndex => $group) {
$group->originalField = ($parentGroup ? $parentGroup->originalField.(isset($field->index) ? '.'.$field->index : '').'.attributes.' : '').$field->attribute.'.'.$groupIndex;

foreach ($group->collectionFields() as $groupField) {
if ($groupField instanceof Flexible) {
$flattened = array_merge($flattened, $this->flattenGroups($groupField, $group));
}
}

$flattened[] = $group;
}

return $flattened;
}

/**
* Add the delete callback helper.
*
* @return null|Field
*/
private function addDeleteCallback(?Field $field)
{
if (!$field || !isset($field->deleteCallback)) {
return $field;
}

$callback = false;
if (is_callable($field->deleteCallback)) {
$callback = $field->deleteCallback;
}

$field->delete(function (NovaRequest $request, $model) use ($callback, $field) {
if ($callback && true === $callback->call($field, ...func_get_args())) {
return true;
}

return Flexible::deleteFile($request, $model, $field);
});

return $field;
}
}
19 changes: 19 additions & 0 deletions src/Concerns/AvailableFieldsAsFieldCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Whitecube\NovaFlexibleContent\Concerns;

use Laravel\Nova\Http\Requests\NovaRequest;
use Whitecube\NovaFlexibleContent\Collections\FieldCollection;

trait AvailableFieldsAsFieldCollection
{
/**
* Get the fields that are available for the given request.
*
* @return \Laravel\Nova\Fields\FieldCollection
*/
public function availableFields(NovaRequest $request)
{
return new FieldCollection(array_values($this->filter($this->fields($request))));
}
}
49 changes: 49 additions & 0 deletions src/Flexible.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Whitecube\NovaFlexibleContent;

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\Field;
use Laravel\Nova\Fields\SupportsDependentFields;
Expand Down Expand Up @@ -80,6 +81,26 @@ public function __construct($name, $attribute = null, $resolveCallback = null)
$this->hideFromIndex();
}

/**
* Get the field layouts
*
* @return \Whitecube\NovaFlexibleContent\Layouts\Collection
*/
public function layouts()
{
return $this->layouts;
}

/**
* Get the field groups
*
* @return \Illuminate\Support\Collection
*/
public function groups()
{
return $this->groups;
}

/**
* @param string $component The name of the component to use for the menu
* @param array $data
Expand Down Expand Up @@ -295,6 +316,34 @@ public function isShownOnDetail(NovaRequest $request, $resource): bool
return parent::isShownOnDetail($request, $resource);
}

/**
* Correctly removes a file inside of a flexible layout.
*
* @param Laravel\Nova\Http\Requests\NovaRequest $request
* @param $model
* @param mixed $field
*
* @return bool
*/
public static function deleteFile(NovaRequest $request, $model, $field)
{
$path = explode('.', $field->group->originalField);
$path[] = 'attributes';
$path[] = $field->attribute;

$mainField = array_shift($path);
$data = $model->{$mainField};
if (is_string($data)) {
$data = json_decode($data, true);
}

Arr::set($data, implode('.', $path), '');

return [
$mainField => json_encode($data),
];
}

/**
* Hydrate the given attribute on the model based on the incoming request.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Layouts/Layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ public function fields()
return $this->fields ? $this->fields->all() : [];
}

/**
* Retrieve the layout's fields as a collection.
*
* @return \Illuminate\Support\Collection
*/
public function collectionFields()
{
return $this->fields;
}

/**
* Retrieve the layout's unique key
*
Expand Down