Issue #3061571 by Wim Leers, mradcliffe, webchick, heddn, mikelutz: If no Drupal 8 equivalent filter is found during migration, drop transformation-only filters, so that body fields show up

merge-requests/2419/head
Alex Pott 2020-02-21 14:21:50 +00:00
parent d23b4cc879
commit f8c0cf381d
No known key found for this signature in database
GPG Key ID: 31905460D4A69276
2 changed files with 374 additions and 0 deletions

View File

@ -5,7 +5,9 @@ namespace Drupal\filter\Plugin\migrate\process;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\filter\Plugin\FilterInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateSkipProcessException;
use Drupal\migrate\Plugin\migrate\process\StaticMap;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Row;
@ -75,6 +77,11 @@ class FilterID extends StaticMap implements ContainerFactoryPluginInterface {
return $plugin_id;
}
else {
if (in_array(static::getSourceFilterType($value), [FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE], TRUE)) {
$message = sprintf('Filter %s could not be mapped to an existing filter plugin; omitted since it is a transformation-only filter. Install and configure a successor after the migration.', $plugin_id);
$migrate_executable->saveMessage($message, MigrationInterface::MESSAGE_INFORMATIONAL);
throw new MigrateSkipProcessException("The transformation-only filter $plugin_id was skipped.");
}
$fallback = $this->filterManager->getFallbackPluginId($plugin_id);
// @see \Drupal\filter\Plugin\migrate\process\FilterSettings::transform()
@ -85,4 +92,350 @@ class FilterID extends StaticMap implements ContainerFactoryPluginInterface {
}
}
/**
* Gets the Drupal 8 filter type for a Drupal 7 filter.
*
* @param string $filter_id
* A Drupal 7 filter ID.
*
* @return int
* One of:
* - FilterInterface::TYPE_MARKUP_LANGUAGE
* - FilterInterface::TYPE_HTML_RESTRICTOR
* - FilterInterface::TYPE_TRANSFORM_REVERSIBLE
* - FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE
*
* @see \Drupal\filter\Plugin\FilterInterface::getType()
*/
protected static function getSourceFilterType($filter_id) {
switch ($filter_id) {
// Drupal 7 core filters.
// - https://git.drupalcode.org/project/drupal/blob/7.69/modules/filter/filter.module#L1229
// - https://git.drupalcode.org/project/drupal/blob/7.69/modules/php/php.module#L139
case 'filter_html':
return FilterInterface::TYPE_HTML_RESTRICTOR;
case 'filter_url':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
case 'filter_autop':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
case 'filter_htmlcorrector':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
case 'filter_html_escape':
return FilterInterface::TYPE_HTML_RESTRICTOR;
case 'php_code':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
// Drupal 7 contrib filters.
// https://www.drupal.org/project/abbrfilter
case 'abbrfilter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/ace_editor
case 'ace_editor':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/adsense
case 'adsense':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/api
case 'api_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/api_tokens
case 'api_tokens':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/autofloat
case 'filter_autofloat':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/bbcode
case 'bbcode':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
// https://www.drupal.org/project/biblio
case 'biblio_filter_reference':
case 'biblio_filter_inline_reference':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/caption
case 'caption':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/caption_filter
case 'caption_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/cincopa
case 'filter_cincopa':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/ckeditor_blocks
case 'ckeditor_blocks':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/ckeditor_filter
case 'ckeditor_filter':
return FilterInterface::TYPE_HTML_RESTRICTOR;
// https://www.drupal.org/project/ckeditor_link
case 'ckeditor_link_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/ckeditor_swf
case 'ckeditor_swf_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/codefilter
case 'codefilter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/collapse_text
case 'collapse_text_filter':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/columns_filter
case 'columns_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/commonmark
case 'commonmark':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
// https://www.drupal.org/project/commons_hashtags
case 'filter_hashtags':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/deepzoom
case 'deepzoom':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/editor
case 'editor_align':
case 'editor_caption':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/elf
case 'elf':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/emogrifier
case 'filter_emogrifier':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/emptyparagraphkiller
case 'emptyparagraphkiller':
return FilterInterface::TYPE_HTML_RESTRICTOR;
// https://www.drupal.org/project/entity_embed
case 'emtity_embed':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
case 'filter_align':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/ext_link_page
case 'ext_link_page':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/filter_html_image_secure
case 'filter_html_image_secure':
return FilterInterface::TYPE_HTML_RESTRICTOR;
// https://www.drupal.org/project/filter_transliteration
case 'filter_transliteration':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/flickr
case 'flickr_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/float_filter
case 'float_filter':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/footnotes
case 'filter_footnotes':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/forena
case 'forena_report':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/g2
case 'filter_g2':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/geo_filter
case 'geo_filter_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/google_analytics_counter
case 'filter_google_analytics_counter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/google_analytics_referrer
case 'filter_google_analytics_referrer':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/gotwo
case 'gotwo_link':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/h5p
case 'h5p_content':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/highlightjs
case 'highlight_js':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/htmLawed
case 'htmLawed':
return FilterInterface::TYPE_HTML_RESTRICTOR;
// https://www.drupal.org/project/htmlpurifier
case 'htmlpurifier_basic':
case 'htmlpurifier_advanced':
return FilterInterface::TYPE_HTML_RESTRICTOR;
// https://www.drupal.org/project/htmltidy
case 'htmltidy':
return FilterInterface::TYPE_HTML_RESTRICTOR;
// https://www.drupal.org/project/icon
case 'icon_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/iframe_filter
case 'iframe':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/image_resize_filter
case 'image_resize_filter':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/insert_view
case 'insert_view':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/intlinks
case 'intlinks title':
case 'intlinks hide bad':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/jquery_ui_filter
case 'accordion':
case 'dialog':
case 'tabs':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
// https://www.drupal.org/project/language_sections
case 'language_sections':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
// https://www.drupal.org/project/lazy
case 'lazy_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/lazyloader_filter
case 'lazyloader_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/link_node
case 'filter_link_node':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/linktitle
case 'linktitle':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/markdown
case 'filter_markdown':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
// https://www.drupal.org/project/media_wysiwyg
case 'media_filter':
case 'media_filter_paragraph_fix':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/mentions
case 'filter_mentions':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/menu_filter
case 'menu_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/mobile_codes
case 'mobile_codes':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/multicolumn
case 'multicolumn':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/multilink
case 'multilink_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/mytube
case 'mytube':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/node_embed
case 'node_embed':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/node_field_embed
case 'node_field_embed':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/noindex_external_links
case 'external_links':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/noreferrer
case 'noreferrer':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/oembed
case 'oembed':
case 'oembed_legacy':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/office_html
case 'office_html_strip':
return FilterInterface::TYPE_HTML_RESTRICTOR;
case 'office_html_convert':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/openlayers_filters
case 'openlayers':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/opengraph_filter
case 'opengraph_filter':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/pathologic
case 'pathologic':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/popup
case 'popup_tags':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/prettify
case 'prettify':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/rel_to_abs
case 'rel_to_abs':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/rollover_filter
case 'rollover_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/sanitizable
case 'sanitizable':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/smart_paging
case 'smart_paging_filter':
case 'smart_paging_filter_autop':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/spamspan
case 'spamspan':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/scald
case 'mee_scald_widgets':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/script_filter
case 'script_filter':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/shortcode
case 'shortcode':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
case 'shortcode_text_corrector':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/smiley
case 'smiley':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/svg_embed
case 'filter_svg_embed':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/spoiler
case 'spoiler':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/tableofcontents
case 'filter_toc':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/tables
case 'filter_tables':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/target_filter_url
case 'target_filter_url':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/textile
case 'textile':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
// https://www.drupal.org/project/theme_filter
case 'theme_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/token_filter
case 'filter_tokens':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/transliteration
case 'transliteration':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/typogrify
case 'typogrify':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/uuid_link
case 'uuid_link_filter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/wysiwyg
case 'wysiwyg':
case 'wysiwyg_template_cleanup':
return FilterInterface::TYPE_HTML_RESTRICTOR;
// https://www.drupal.org/project/word_link
case 'word_link':
return FilterInterface::TYPE_TRANSFORM_REVERSIBLE;
// https://www.drupal.org/project/wordfilter
case 'wordfilter':
return FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE;
// https://www.drupal.org/project/xbbcode
case 'xbbcode':
return FilterInterface::TYPE_MARKUP_LANGUAGE;
}
return NULL;
}
}

View File

@ -5,6 +5,7 @@ namespace Drupal\Tests\filter\Kernel\Plugin\migrate\process;
use Drupal\filter\Plugin\migrate\process\FilterID;
use Drupal\KernelTests\KernelTestBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateSkipProcessException;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Row;
@ -61,6 +62,18 @@ class FilterIdTest extends KernelTestBase {
];
$plugin = FilterID::create($this->container, $configuration, 'filter_id', []);
if ($expected_value instanceof MigrateSkipProcessException) {
$this->executable
->expects($this->exactly(1))
->method('saveMessage')
->with(
sprintf('Filter %s could not be mapped to an existing filter plugin; omitted since it is a transformation-only filter. Install and configure a successor after the migration.', $value),
MigrationInterface::MESSAGE_INFORMATIONAL
);
$this->expectException(MigrateSkipProcessException::class);
$this->expectExceptionMessage(sprintf("The transformation-only filter %s was skipped.", $value));
}
if (isset($invalid_id)) {
$this->executable
->expects($this->exactly(1))
@ -110,6 +123,14 @@ class FilterIdTest extends KernelTestBase {
'filter_null',
'filter:1',
],
'transformation-only D7 contrib filter' => [
'editor_align',
new MigrateSkipProcessException('The transformation-only filter editor_align was skipped.'),
],
'non-transformation-only D7 contrib filter' => [
'bbcode',
'filter_null',
],
];
}