Skip to content

Commit 52fc665

Browse files
committed
wip
1 parent bf1546b commit 52fc665

File tree

2 files changed

+69
-16
lines changed

2 files changed

+69
-16
lines changed

src/Fields/RichEditor.php

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44

55
use Backstage\Enums\ToolbarButton;
66
use Backstage\Fields\Contracts\FieldContract;
7-
<<<<<<< Updated upstream
87
use Backstage\Fields\Models\Field;
98
use Filament\Forms;
10-
=======
119
use Backstage\Fields\Services\ContentCleaningService;
12-
>>>>>>> Stashed changes
1310
use Filament\Forms\Components\RichEditor as Input;
11+
use Illuminate\Support\Facades\Log;
12+
1413

1514
class RichEditor extends Base implements FieldContract
1615
{
@@ -23,6 +22,7 @@ public static function getDefaultConfig(): array
2322
'disableToolbarButtons' => [],
2423
'autoCleanContent' => true,
2524
'preserveCustomCaptions' => false,
25+
'hideCaptions' => true,
2626
];
2727
}
2828

@@ -35,22 +35,59 @@ public static function make(string $name, ?Field $field = null): Input
3535
->disableGrammarly($field->config['disableGrammarly'] ?? self::getDefaultConfig()['disableGrammarly'])
3636
->disableToolbarButtons($field->config['disableToolbarButtons'] ?? self::getDefaultConfig()['disableToolbarButtons']);
3737

38+
// Add data attribute for hiding captions if enabled
39+
$hideCaptions = $field->config['hideCaptions'] ?? self::getDefaultConfig()['hideCaptions'];
40+
if ($hideCaptions) {
41+
$input->extraAttributes(['data-hide-captions' => 'true']);
42+
}
43+
3844
// Add content processing to automatically clean HTML
3945
$autoCleanContent = $field->config['autoCleanContent'] ?? self::getDefaultConfig()['autoCleanContent'];
4046

4147
if ($autoCleanContent) {
42-
$input->afterStateUpdated(function ($state) use ($field) {
43-
$options = [
44-
'preserveCustomCaptions' => $field->config['preserveCustomCaptions'] ?? self::getDefaultConfig()['preserveCustomCaptions'],
45-
];
46-
47-
return ContentCleaningService::cleanHtmlContent($state, $options);
48+
$options = [
49+
'preserveCustomCaptions' => $field->config['preserveCustomCaptions'] ?? self::getDefaultConfig()['preserveCustomCaptions'],
50+
];
51+
52+
// Clean content when state is updated (including file uploads)
53+
$input->afterStateUpdated(function ($state) use ($options) {
54+
if (!empty($state)) {
55+
return ContentCleaningService::cleanHtmlContent($state, $options);
56+
}
57+
return $state;
58+
});
59+
60+
// Ensure cleaned content is saved to database
61+
$input->dehydrateStateUsing(function ($state) use ($options) {
62+
if (!empty($state)) {
63+
return ContentCleaningService::cleanHtmlContent($state, $options);
64+
}
65+
return $state;
4866
});
4967
}
5068

5169
return $input;
5270
}
5371

72+
public static function mutateBeforeSaveCallback($record, $field, array $data): array
73+
{
74+
$autoCleanContent = $field->config['autoCleanContent'] ?? self::getDefaultConfig()['autoCleanContent'];
75+
76+
if ($autoCleanContent && isset($data['values'][$field->ulid])) {
77+
\Illuminate\Support\Facades\Log::info('RichEditor mutateBeforeSaveCallback before cleaning:', ['content' => $data['values'][$field->ulid]]);
78+
79+
$options = [
80+
'preserveCustomCaptions' => $field->config['preserveCustomCaptions'] ?? self::getDefaultConfig()['preserveCustomCaptions'],
81+
];
82+
83+
$data['values'][$field->ulid] = ContentCleaningService::cleanHtmlContent($data['values'][$field->ulid], $options);
84+
85+
\Illuminate\Support\Facades\Log::info('RichEditor mutateBeforeSaveCallback after cleaning:', ['content' => $data['values'][$field->ulid]]);
86+
}
87+
88+
return $data;
89+
}
90+
5491
public function getForm(): array
5592
{
5693
return [
@@ -76,15 +113,20 @@ public function getForm(): array
76113
->multiple()
77114
->options(ToolbarButton::array())
78115
->columnSpanFull(),
79-
Toggle::make('config.autoCleanContent')
116+
Forms\Components\Toggle::make('config.autoCleanContent')
80117
->label(__('Auto-clean content'))
81118
->helperText(__('Automatically remove figcaption and unwrap images from links'))
82-
->default(true)
119+
->inline(false)
83120
->columnSpanFull(),
84-
Toggle::make('config.preserveCustomCaptions')
121+
Forms\Components\Toggle::make('config.preserveCustomCaptions')
85122
->label(__('Preserve custom captions'))
86123
->helperText(__('Only remove default captions, keep custom ones'))
87-
->default(false)
124+
->inline(false)
125+
->columnSpanFull(),
126+
Forms\Components\Toggle::make('config.hideCaptions')
127+
->label(__('Hide caption fields'))
128+
->helperText(__('Hide the caption input field that appears when uploading images'))
129+
->inline(false)
88130
->columnSpanFull(),
89131
]),
90132
]),

src/Services/ContentCleaningService.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,29 @@ public static function cleanHtmlContent(?string $content, array $options = []):
5757
}
5858

5959
if ($options['unwrapImages']) {
60-
// Unwrap img tags from anchor links, keeping only the img tag
61-
$content = preg_replace('/<a[^>]*>(<img[^>]*>).*?<\/a>/is', '$1', $content);
60+
// Handle complex nested structures where img is inside a link inside a figure
61+
// This pattern matches: <figure...><a...><img...></a></figure> and extracts just the img
62+
$content = preg_replace('/<figure[^>]*>\s*<a[^>]*>\s*(<img[^>]*>)\s*.*?<\/a>\s*<\/figure>/is', '$1', $content);
63+
64+
// Handle cases where img is wrapped in a link but not in a figure
65+
$content = preg_replace('/<a[^>]*>\s*(<img[^>]*>)\s*.*?<\/a>/is', '$1', $content);
66+
67+
// Handle cases where there might be other content in the link besides the img
68+
$content = preg_replace('/<a[^>]*>.*?(<img[^>]*>).*?<\/a>/is', '$1', $content);
6269
}
6370

6471
if ($options['removeEmptyFigures']) {
6572
// Clean up any empty figure tags that might be left
6673
$content = preg_replace('/<figure[^>]*>\s*<\/figure>/is', '', $content);
6774

6875
// Clean up any figure tags that only contain img
69-
$content = preg_replace('/<figure[^>]*>(<img[^>]*>)<\/figure>/is', '$1', $content);
76+
$content = preg_replace('/<figure[^>]*>\s*(<img[^>]*>)\s*<\/figure>/is', '$1', $content);
7077
}
7178

79+
// Clean up any extra whitespace that might be left
80+
$content = preg_replace('/\s+/', ' ', $content);
81+
$content = trim($content);
82+
7283
return $content;
7384
}
7485
}

0 commit comments

Comments
 (0)