Issue #3404431 by claudiu.cristea, Wim Leers, borisson_, quietone: Filter settings schema types are incorrect
parent
e1312a3d8b
commit
d8c4e4cfac
|
@ -46,14 +46,11 @@ filter.format.*:
|
|||
label: 'Dependencies'
|
||||
|
||||
filter_settings.*:
|
||||
type: sequence
|
||||
type: mapping
|
||||
label: 'Filter settings'
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Value'
|
||||
|
||||
filter_settings.filter_html:
|
||||
type: filter
|
||||
type: mapping
|
||||
label: 'Filter HTML'
|
||||
mapping:
|
||||
allowed_html:
|
||||
|
@ -66,9 +63,8 @@ filter_settings.filter_html:
|
|||
type: boolean
|
||||
label: 'HTML nofollow'
|
||||
|
||||
|
||||
filter_settings.filter_url:
|
||||
type: filter
|
||||
type: mapping
|
||||
label: 'Filter URL'
|
||||
mapping:
|
||||
filter_url_length:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityUpdater;
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\filter\FilterFormatInterface;
|
||||
|
||||
/**
|
||||
* Sorts filter format filter configuration.
|
||||
|
@ -19,3 +20,17 @@ function filter_post_update_sort_filters(?array &$sandbox = NULL): void {
|
|||
return $sorted_filters !== $filters;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Change filter_settings to type mapping.
|
||||
*/
|
||||
function filter_post_update_consolidate_filter_config(?array &$sandbox = NULL): void {
|
||||
\Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'filter_format', function (FilterFormatInterface $format): bool {
|
||||
foreach ($format->get('filters') as $config) {
|
||||
if (empty($config['id']) || empty($config['provider'])) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -208,6 +208,11 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface, En
|
|||
// read and there is a minimal changeset. If the save is not trusted then
|
||||
// the configuration will be sorted by StorableConfigBase.
|
||||
ksort($this->filters);
|
||||
// Ensure the filter configuration is well-formed.
|
||||
array_walk($this->filters, function (array &$config, string $filter): void {
|
||||
$config['id'] ??= $filter;
|
||||
$config['provider'] ??= $this->filters($filter)->getPluginDefinition()['provider'];
|
||||
});
|
||||
}
|
||||
|
||||
assert(is_string($this->label()), 'Filter format label is expected to be a string.');
|
||||
|
|
|
@ -131,6 +131,20 @@ abstract class FilterFormatFormBase extends EntityForm {
|
|||
'#attributes' => ['class' => ['filter-order-weight']],
|
||||
];
|
||||
|
||||
// Ensure the resulting FilterFormat complies with `type: filter`.
|
||||
// @see core.data_types.schema.yml
|
||||
// @see \Drupal\filter\FilterFormatFormBase::submitForm()
|
||||
$form['filters']['order'][$name]['id'] = [
|
||||
'#type' => 'value',
|
||||
'#value' => $filter->getPluginId(),
|
||||
'#parents' => ['filters', $name, 'id'],
|
||||
];
|
||||
$form['filters']['order'][$name]['provider'] = [
|
||||
'#type' => 'value',
|
||||
'#value' => $filter->provider,
|
||||
'#parents' => ['filters', $name, 'provider'],
|
||||
];
|
||||
|
||||
// Retrieve the settings form of the filter plugin. The plugin should not be
|
||||
// aware of the text format. Therefore, it only receives a set of minimal
|
||||
// base properties to allow advanced implementations to work.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Schema for the configuration files of the Filter test module.
|
||||
|
||||
filter_settings.filter_test_restrict_tags_and_attributes:
|
||||
type: filter
|
||||
type: mapping
|
||||
label: 'Filter to restrict HTML tags and attributes'
|
||||
mapping:
|
||||
restrictions:
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Fixture file to test filter_post_update_consolidate_filter_config().
|
||||
*
|
||||
* @see https://www.drupal.org/project/drupal/issues/3404431
|
||||
* @see \Drupal\Tests\filter\Functional\FilterFormatConsolidateFilterConfigUpdateTest
|
||||
* @see filter_post_update_consolidate_filter_config()
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$db = Database::getConnection();
|
||||
|
||||
$format = unserialize($db->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'filter.format.plain_text')
|
||||
->execute()
|
||||
->fetchField());
|
||||
|
||||
unset($format['filters']['filter_autop']['id']);
|
||||
unset($format['filters']['filter_html_escape']['provider']);
|
||||
unset($format['filters']['filter_url']['id']);
|
||||
unset($format['filters']['filter_url']['provider']);
|
||||
|
||||
$db->update('config')
|
||||
->fields(['data' => serialize($format)])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'filter.format.plain_text')
|
||||
->execute();
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\filter\Functional;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests the upgrade path for filter formats.
|
||||
*
|
||||
* @see filter_post_update_consolidate_filter_config()
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class FilterFormatConsolidateFilterConfigUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles(): void {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-9.4.0.bare.standard.php.gz',
|
||||
__DIR__ . '/../../fixtures/update/filter_post_update_consolidate_filter_config-3404431.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \filter_post_update_consolidate_filter_config
|
||||
*/
|
||||
public function testConsolidateFilterConfig() {
|
||||
$format = $this->config('filter.format.plain_text');
|
||||
$this->assertArrayNotHasKey('id', $format->get('filters.filter_autop'));
|
||||
$this->assertSame('filter', $format->get('filters.filter_autop.provider'));
|
||||
$this->assertSame('filter_html_escape', $format->get('filters.filter_html_escape.id'));
|
||||
$this->assertArrayNotHasKey('provider', $format->get('filters.filter_html_escape'));
|
||||
$this->assertArrayNotHasKey('id', $format->get('filters.filter_url'));
|
||||
$this->assertArrayNotHasKey('provider', $format->get('filters.filter_url'));
|
||||
|
||||
$this->runUpdates();
|
||||
|
||||
$format = $this->config('filter.format.plain_text');
|
||||
$this->assertSame('filter_autop', $format->get('filters.filter_autop.id'));
|
||||
$this->assertSame('filter', $format->get('filters.filter_autop.provider'));
|
||||
$this->assertSame('filter_html_escape', $format->get('filters.filter_html_escape.id'));
|
||||
$this->assertSame('filter', $format->get('filters.filter_html_escape.provider'));
|
||||
$this->assertSame('filter_url', $format->get('filters.filter_url.id'));
|
||||
$this->assertSame('filter', $format->get('filters.filter_url.provider'));
|
||||
}
|
||||
|
||||
}
|
|
@ -119,7 +119,7 @@ media.source.field_aware:
|
|||
label: 'Source field'
|
||||
|
||||
filter_settings.media_embed:
|
||||
type: filter
|
||||
type: mapping
|
||||
label: 'Media Embed'
|
||||
mapping:
|
||||
default_view_mode:
|
||||
|
|
Loading…
Reference in New Issue