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 BREAD rich text display issue #5840

Open
wants to merge 4 commits into
base: 1.6
Choose a base branch
from
Open
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
12 changes: 6 additions & 6 deletions resources/views/formfields/relationship.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
$model = app($options->model);
$query = $model::where($options->key,$relationshipData->{$options->column})->first();
@endphp

@if(isset($query))
<p>{{ $query->{$options->label} }}</p>
<p>{{ strip_tags(html_entity_decode($query->{$options->label})) }}</p>
@else
<p>{{ __('voyager::generic.no_results') }}</p>
@endif
Expand All @@ -40,7 +40,7 @@ class="form-control select2-ajax" name="{{ $options->column }}"
@endif

@foreach($query as $relationshipData)
<option value="{{ $relationshipData->{$options->key} }}" @if(old($options->column, $dataTypeContent->{$options->column}) == $relationshipData->{$options->key}) selected="selected" @endif>{{ $relationshipData->{$options->label} }}</option>
<option value="{{ $relationshipData->{$options->key} }}" @if(old($options->column, $dataTypeContent->{$options->column}) == $relationshipData->{$options->key}) selected="selected" @endif>{{ strip_tags(html_entity_decode($relationshipData->{$options->label})) }}</option>
@endforeach
</select>

Expand All @@ -57,7 +57,7 @@ class="form-control select2-ajax" name="{{ $options->column }}"
@endphp

@if(isset($query))
<p>{{ $query->{$options->label} }}</p>
<p>{{ strip_tags(html_entity_decode($query->{$options->label})) }}</p>
@else
<p>{{ __('voyager::generic.no_results') }}</p>
@endif
Expand All @@ -83,7 +83,7 @@ class="form-control select2-ajax" name="{{ $options->column }}"
@if(empty($selected_values))
<p>{{ __('voyager::generic.no_results') }}</p>
@else
<p>{{ $string_values }}</p>
<p>{{ strip_tags(html_entity_decode($string_values)) }}</p>
@endif
@else
@if(empty($selected_values))
Expand Down Expand Up @@ -136,7 +136,7 @@ class="form-control select2-ajax" name="{{ $options->column }}"
@if(empty($selected_values))
<p>{{ __('voyager::generic.no_results') }}</p>
@else
<p>{{ $string_values }}</p>
<p>{{ strip_tags(html_entity_decode($string_values)) }}</p>
@endif
@else
@if(empty($selected_values))
Expand Down
133 changes: 95 additions & 38 deletions src/Http/Controllers/VoyagerBaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use TCG\Voyager\Events\BreadImagesDeleted;
use TCG\Voyager\Facades\Voyager;
use TCG\Voyager\Http\Controllers\Traits\BreadRelationshipParser;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;

class VoyagerBaseController extends Controller
{
Expand Down Expand Up @@ -63,9 +65,9 @@ public function index(Request $request)
if (strlen($dataType->model_name) != 0) {
$model = app($dataType->model_name);

$query = $model::select($dataType->name.'.*');
$query = $model::select($dataType->name . '.*');

if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope'.ucfirst($dataType->scope))) {
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope' . ucfirst($dataType->scope))) {
$query->{$dataType->scope}();
}

Expand All @@ -84,9 +86,9 @@ public function index(Request $request)

if ($search->value != '' && $search->key && $search->filter) {
$search_filter = ($search->filter == 'equals') ? '=' : 'LIKE';
$search_value = ($search->filter == 'equals') ? $search->value : '%'.$search->value.'%';
$search_value = ($search->filter == 'equals') ? $search->value : '%' . $search->value . '%';

$searchField = $dataType->name.'.'.$search->key;
$searchField = $dataType->name . '.' . $search->key;
if ($row = $this->findSearchableRelationshipRow($dataType->rows->where('type', 'relationship'), $search->key)) {
$query->whereIn(
$searchField,
Expand All @@ -104,12 +106,12 @@ public function index(Request $request)
$querySortOrder = (!empty($sortOrder)) ? $sortOrder : 'desc';
if (!empty($row)) {
$query->select([
$dataType->name.'.*',
'joined.'.$row->details->label.' as '.$orderBy,
$dataType->name . '.*',
'joined.' . $row->details->label . ' as ' . $orderBy,
])->leftJoin(
$row->details->table.' as joined',
$dataType->name.'.'.$row->details->column,
'joined.'.$row->details->key
$row->details->table . ' as joined',
$dataType->name . '.' . $row->details->column,
'joined.' . $row->details->key
);
}

Expand Down Expand Up @@ -183,6 +185,9 @@ public function index(Request $request)
$view = "voyager::$slug.browse";
}

// Modify dataTypeContent collection with HTML tags stripped from string attributes
$dataTypeContent = $this->stripTagsFromCollection($dataTypeContent);

return Voyager::view($view, compact(
'actions',
'dataType',
Expand Down Expand Up @@ -230,7 +235,7 @@ public function show(Request $request, $id)
if ($model && in_array(SoftDeletes::class, class_uses_recursive($model))) {
$query = $query->withTrashed();
}
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope'.ucfirst($dataType->scope))) {
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope' . ucfirst($dataType->scope))) {
$query = $query->{$dataType->scope}();
}
$dataTypeContent = call_user_func([$query, 'findOrFail'], $id);
Expand Down Expand Up @@ -263,6 +268,9 @@ public function show(Request $request, $id)
$view = "voyager::$slug.read";
}

// Modify dataTypeContent collection with HTML tags stripped from string attributes
$dataTypeContent = $this->stripTagsFromObject($dataTypeContent);

return Voyager::view($view, compact('dataType', 'dataTypeContent', 'isModelTranslatable', 'isSoftDeleted'));
}

Expand Down Expand Up @@ -292,7 +300,7 @@ public function edit(Request $request, $id)
if ($model && in_array(SoftDeletes::class, class_uses_recursive($model))) {
$query = $query->withTrashed();
}
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope'.ucfirst($dataType->scope))) {
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope' . ucfirst($dataType->scope))) {
$query = $query->{$dataType->scope}();
}
$dataTypeContent = call_user_func([$query, 'findOrFail'], $id);
Expand Down Expand Up @@ -338,7 +346,7 @@ public function update(Request $request, $id)

$model = app($dataType->model_name);
$query = $model->query();
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope'.ucfirst($dataType->scope))) {
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope' . ucfirst($dataType->scope))) {
$query = $query->{$dataType->scope}();
}
if ($model && in_array(SoftDeletes::class, class_uses_recursive($model))) {
Expand All @@ -358,7 +366,7 @@ public function update(Request $request, $id)
->filter(function ($item, $key) use ($request) {
return $request->hasFile($item->field);
});
$original_data = clone($data);
$original_data = clone ($data);

$this->insertUpdateData($request, $slug, $dataType->editRows, $data);

Expand All @@ -374,7 +382,7 @@ public function update(Request $request, $id)
}

return $redirect->with([
'message' => __('voyager::generic.successfully_updated')." {$dataType->getTranslatedAttribute('display_name_singular')}",
'message' => __('voyager::generic.successfully_updated') . " {$dataType->getTranslatedAttribute('display_name_singular')}",
'alert-type' => 'success',
]);
}
Expand Down Expand Up @@ -402,8 +410,8 @@ public function create(Request $request)
$this->authorize('add', app($dataType->model_name));

$dataTypeContent = (strlen($dataType->model_name) != 0)
? new $dataType->model_name()
: false;
? new $dataType->model_name()
: false;

foreach ($dataType->addRows as $key => $row) {
$dataType->addRows[$key]['col_width'] = $row->details->width ?? 100;
Expand Down Expand Up @@ -457,7 +465,7 @@ public function store(Request $request)
}

return $redirect->with([
'message' => __('voyager::generic.successfully_added_new')." {$dataType->getTranslatedAttribute('display_name_singular')}",
'message' => __('voyager::generic.successfully_added_new') . " {$dataType->getTranslatedAttribute('display_name_singular')}",
'alert-type' => 'success',
]);
} else {
Expand Down Expand Up @@ -494,7 +502,7 @@ public function destroy(Request $request, $id)
}

$affected = 0;

foreach ($ids as $id) {
$data = call_user_func([$dataType->model_name, 'findOrFail'], $id);

Expand All @@ -519,11 +527,11 @@ public function destroy(Request $request, $id)

$data = $affected
? [
'message' => __('voyager::generic.successfully_deleted')." {$displayName}",
'message' => __('voyager::generic.successfully_deleted') . " {$displayName}",
'alert-type' => 'success',
]
: [
'message' => __('voyager::generic.error_deleting')." {$displayName}",
'message' => __('voyager::generic.error_deleting') . " {$displayName}",
'alert-type' => 'error',
];

Expand All @@ -542,7 +550,7 @@ public function restore(Request $request, $id)

// Get record
$query = $model->withTrashed();
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope'.ucfirst($dataType->scope))) {
if ($dataType->scope && $dataType->scope != '' && method_exists($model, 'scope' . ucfirst($dataType->scope))) {
$query = $query->{$dataType->scope}();
}
$data = $query->findOrFail($id);
Expand All @@ -552,11 +560,11 @@ public function restore(Request $request, $id)
$res = $data->restore($id);
$data = $res
? [
'message' => __('voyager::generic.successfully_restored')." {$displayName}",
'message' => __('voyager::generic.successfully_restored') . " {$displayName}",
'alert-type' => 'success',
]
: [
'message' => __('voyager::generic.error_restoring')." {$displayName}",
'message' => __('voyager::generic.error_restoring') . " {$displayName}",
'alert-type' => 'error',
];

Expand Down Expand Up @@ -617,7 +625,7 @@ public function remove_media(Request $request)

// Check if we're dealing with a nested array for the case of multiple files
if (is_array($fieldData[0])) {
foreach ($fieldData as $index=>$file) {
foreach ($fieldData as $index => $file) {
// file type has a different structure than images
if (!empty($file['original_name'])) {
if ($file['original_name'] == $filename) {
Expand Down Expand Up @@ -769,13 +777,13 @@ public function deleteBreadImages($data, $rows, $single_image = null)
if (isset($row->details->thumbnails)) {
foreach ($row->details->thumbnails as $thumbnail) {
$ext = explode('.', $image);
$extension = '.'.$ext[count($ext) - 1];
$extension = '.' . $ext[count($ext) - 1];

$path = str_replace($extension, '', $image);

$thumb_name = $thumbnail->name;

$this->deleteFileIfExists($path.'-'.$thumb_name.$extension);
$this->deleteFileIfExists($path . '-' . $thumb_name . $extension);
}
}
}
Expand Down Expand Up @@ -805,11 +813,11 @@ public function order(Request $request)

if (empty($dataType->order_column) || empty($dataType->order_display_column)) {
return redirect()
->route("voyager.{$dataType->slug}.index")
->with([
'message' => __('voyager::bread.ordering_not_set'),
'alert-type' => 'error',
]);
->route("voyager.{$dataType->slug}.index")
->with([
'message' => __('voyager::bread.ordering_not_set'),
'alert-type' => 'error',
]);
}

$model = app($dataType->model_name);
Expand All @@ -829,6 +837,9 @@ public function order(Request $request)
$view = "voyager::$slug.order";
}

// Modify results collection with HTML tags stripped from string attributes
$results = $this->stripTagsFromCollection($results);

return Voyager::view($view, compact(
'dataType',
'display_column',
Expand Down Expand Up @@ -899,7 +910,7 @@ public function relation(Request $request)

$this->authorize($method, $model);

$rows = $dataType->{$method.'Rows'};
$rows = $dataType->{$method . 'Rows'};
foreach ($rows as $key => $row) {
if ($row->field === $request->input('type')) {
$options = $row->details;
Expand All @@ -909,7 +920,7 @@ public function relation(Request $request)
$additional_attributes = $model->additional_attributes ?? [];

// Apply local scope if it is defined in the relationship-options
if (isset($options->scope) && $options->scope != '' && method_exists($model, 'scope'.ucfirst($options->scope))) {
if (isset($options->scope) && $options->scope != '' && method_exists($model, 'scope' . ucfirst($options->scope))) {
$model = $model->{$options->scope}();
}

Expand All @@ -924,9 +935,9 @@ public function relation(Request $request)
$total_count = $relationshipOptions->count();
$relationshipOptions = $relationshipOptions->forPage($page, $on_page);
} else {
$total_count = $model->where($options->label, 'LIKE', '%'.$search.'%')->count();
$total_count = $model->where($options->label, 'LIKE', '%' . $search . '%')->count();
$relationshipOptions = $model->take($on_page)->skip($skip)
->where($options->label, 'LIKE', '%'.$search.'%')
->where($options->label, 'LIKE', '%' . $search . '%')
->get();
}
} else {
Expand Down Expand Up @@ -955,7 +966,8 @@ public function relation(Request $request)
foreach ($relationshipOptions as $relationshipOption) {
$results[] = [
'id' => $relationshipOption->{$options->key},
'text' => $relationshipOption->{$options->label},
// Strip tags and entity codes for relation texts
'text' => strip_tags(html_entity_decode($relationshipOption->{$options->label})),
];
}

Expand Down Expand Up @@ -998,12 +1010,57 @@ protected function getSortableColumns($rows)

return !$this->relationIsUsingAccessorAsLabel($item->details);
})
->pluck('field')
->toArray();
->pluck('field')
->toArray();
}

protected function relationIsUsingAccessorAsLabel($details)
{
return in_array($details->label, app($details->model)->additional_attributes ?? []);
}

/**
* Strip HTML tags from string attributes of each model in a collection.
*
* @param \Illuminate\Support\Collection $collection The collection of models to process.
* @return \Illuminate\Support\Collection The modified collection with HTML tags stripped from string attributes.
*/
private function stripTagsFromCollection(Collection $collection)
{
return $collection->map(function ($item) {
// Get the attributes of the model
$attributes = $item->getAttributes();

// Loop through each attribute
foreach ($attributes as $key => $value) {
// Check if the value is a string
if (is_string($value)) {
// Strip HTML tags from the value
$item->{$key} = strip_tags(html_entity_decode($value));
}
}
return $item;
});
}

/**
* Strip HTML tags from string attributes of an object.
*
* @param mixed $object The object whose attributes need HTML tags stripped.
* @return mixed The modified object with HTML tags stripped from string attributes.
*/
private function stripTagsFromObject(Model $model)
{
// Get the object's attributes
$attributes = $model->getAttributes();
// Loop through each attribute
foreach ($attributes as $key => $value) {
// Check if the value is a string
if (is_string($value)) {
// Strip HTML tags from the value
$model->$key = strip_tags(html_entity_decode($value));
}
}
return $model;
}
}