From 573503414db9032b78215721a89075218b185a72 Mon Sep 17 00:00:00 2001
From: wizonesolutions <wizonesolutions@739994.no-reply.drupal.org>
Date: Tue, 28 Apr 2020 16:06:36 +0200
Subject: [PATCH] Issue #3114541 by wizonesolutions: Drupal 9 Deprecated Code
 Report

---
 composer.json                                 |   1 +
 config/schema/fillpdf.schema.yml              |   1 +
 fillpdf.info.yml                              |   4 +-
 .../fillpdf_legacy/fillpdf_legacy.info.yml    |   8 --
 modules/fillpdf_legacy/fillpdf_legacy.module  |  44 ------
 .../fillpdf_legacy.services.yml               |  10 --
 .../src/Annotation/BackendService.php         |  35 -----
 .../LocalServerBackendService.php             |  95 ------------
 .../src/Plugin/BackendServiceInterface.php    |  62 --------
 .../src/Plugin/BackendServiceManager.php      |  37 -----
 .../JavaBridgeFillPdfBackend.php              | 129 -----------------
 .../src/Plugin/FillPdfBackendManager.php      |  37 -----
 .../PdfBackend/LegacyProviderPdfBackend.php   | 136 ------------------
 .../tests/Kernel/LegacyBackendTest.php        |  30 ----
 modules/fillpdf_next/fillpdf_next.info.yml    |   6 -
 src/Component/Utility/FillPdf.php             |   4 -
 src/Plugin/BackendServiceBase.php             |  18 ---
 .../PdfBackend/FillPdfServicePdfBackend.php   |  28 +---
 .../PdfBackend/LocalServerPdfBackend.php      |  29 +---
 src/Plugin/PdfBackend/PdftkPdfBackend.php     |  28 +---
 .../fillpdf_test/fillpdf_test.info.yml        |   4 +-
 .../src/Plugin/BackendService/Test.php        | 119 ---------------
 .../TestPdfBackend.php}                       |  32 +++--
 .../fillpdf_webform_test.info.yml             |   2 +-
 tests/src/Functional/FillPdfTestBase.php      |   8 --
 tests/src/Functional/PdfPopulationTest.php    |  68 +++------
 .../Functional/PdfWebformPopulationTest.php   |  21 ++-
 tests/src/Functional/UninstallTest.php        |   2 +-
 .../FieldMapping/ImageFieldMappingTest.php    |   2 +-
 29 files changed, 64 insertions(+), 936 deletions(-)
 delete mode 100644 modules/fillpdf_legacy/fillpdf_legacy.info.yml
 delete mode 100644 modules/fillpdf_legacy/fillpdf_legacy.module
 delete mode 100644 modules/fillpdf_legacy/fillpdf_legacy.services.yml
 delete mode 100644 modules/fillpdf_legacy/src/Annotation/BackendService.php
 delete mode 100644 modules/fillpdf_legacy/src/Plugin/BackendService/LocalServerBackendService.php
 delete mode 100644 modules/fillpdf_legacy/src/Plugin/BackendServiceInterface.php
 delete mode 100644 modules/fillpdf_legacy/src/Plugin/BackendServiceManager.php
 delete mode 100644 modules/fillpdf_legacy/src/Plugin/FillPdfBackend/JavaBridgeFillPdfBackend.php
 delete mode 100644 modules/fillpdf_legacy/src/Plugin/FillPdfBackendManager.php
 delete mode 100644 modules/fillpdf_legacy/src/Plugin/PdfBackend/LegacyProviderPdfBackend.php
 delete mode 100644 modules/fillpdf_legacy/tests/Kernel/LegacyBackendTest.php
 delete mode 100644 modules/fillpdf_next/fillpdf_next.info.yml
 delete mode 100644 src/Plugin/BackendServiceBase.php
 delete mode 100644 tests/modules/fillpdf_test/src/Plugin/BackendService/Test.php
 rename tests/modules/fillpdf_test/src/Plugin/{FillPdfBackend/TestFillPdfBackend.php => PdfBackend/TestPdfBackend.php} (77%)

diff --git a/composer.json b/composer.json
index 897d11c..605f1fe 100644
--- a/composer.json
+++ b/composer.json
@@ -11,6 +11,7 @@
     ],
     "minimum-stability": "dev",
     "require": {
+        "drupal/core": "^8.8 || ^9",
         "drupal/token": "^1.0"
     },
     "require-dev": {
diff --git a/config/schema/fillpdf.schema.yml b/config/schema/fillpdf.schema.yml
index 46d83f4..cbe58fa 100644
--- a/config/schema/fillpdf.schema.yml
+++ b/config/schema/fillpdf.schema.yml
@@ -1,5 +1,6 @@
 fillpdf.settings:
   type: config_object
+  label: 'FillPDF Settings'
   mapping:
     backend:
       type: string
diff --git a/fillpdf.info.yml b/fillpdf.info.yml
index 9cf67bb..bda41df 100644
--- a/fillpdf.info.yml
+++ b/fillpdf.info.yml
@@ -1,7 +1,8 @@
 name: 'FillPDF'
 type: module
 description: 'Allows users to populate PDF forms from website data.'
-core_version_requirement: ^8.7.7
+core_version_requirement: ^8.8 || ^9
+php: 7.2.0
 package: Other
 configure: fillpdf.settings
 dependencies:
@@ -12,3 +13,4 @@ dependencies:
   - drupal:options
 test_dependencies:
   - webform:webform
+  - xmlrpc:xmlrpc
diff --git a/modules/fillpdf_legacy/fillpdf_legacy.info.yml b/modules/fillpdf_legacy/fillpdf_legacy.info.yml
deleted file mode 100644
index 8b29c5c..0000000
--- a/modules/fillpdf_legacy/fillpdf_legacy.info.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: 'FillPDF legacy backend support'
-type: module
-description: 'Provides support to legacy backend plugins.'
-core_version_requirement: ^8.7.7
-package: Other
-configure: fillpdf.settings
-dependencies:
-  - drupal:fillpdf
diff --git a/modules/fillpdf_legacy/fillpdf_legacy.module b/modules/fillpdf_legacy/fillpdf_legacy.module
deleted file mode 100644
index abb6c36..0000000
--- a/modules/fillpdf_legacy/fillpdf_legacy.module
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * @file
- * Legacy functionality and plugins.
- */
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\StringTranslation\TranslatableMarkup;
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function fillpdf_legacy_form_fillpdf_settings_alter(array &$form, FormStateInterface $form_state) {
-  $label = new TranslatableMarkup('Local PHP/JavaBridge');
-  $description = new TranslatableMarkup('Legacy. Use FillPDF LocalServer instead.');
-  $form['backend']['#options']['local'] = "<strong>{$label}</strong>: {$description}";
-
-  $form['local']['warning'] = [
-    '#type' => 'item',
-    '#markup' => '<div class="messages messages--warning">' . new TranslatableMarkup('Please note that the Local PHP/JavaBridge backend is deprecated and will be removed from FillPDF 5.x. Use FillPDF LocalServer instead.') . '</div>',
-    '#states' => [
-      'visible' => [
-        ':radio[name="backend"]' => ['value' => 'local'],
-      ],
-    ],
-  ];
-
-  $form['#validate'][] = '_fillpdf_legacy_form_fillpdf_settings_validate';
-}
-
-/**
- * Extra validation handler for fillpdf_legacy_form_fillpdf_settings_alter().
- *
- * @see fillpdf_legacy_form_fillpdf_settings_alter()
- */
-function _fillpdf_legacy_form_fillpdf_settings_validate($form, FormStateInterface $form_state) {
-  if ($form_state->getValue('backend') == 'local') {
-    $status = file_exists(drupal_get_path('module', 'fillpdf') . '/lib/JavaBridge/java/Java.inc');
-    if ($status === FALSE) {
-      $form_state->setError($form['backend'], new TranslatableMarkup('JavaBridge is not installed locally.'));
-    }
-  }
-}
diff --git a/modules/fillpdf_legacy/fillpdf_legacy.services.yml b/modules/fillpdf_legacy/fillpdf_legacy.services.yml
deleted file mode 100644
index 6fbcfe3..0000000
--- a/modules/fillpdf_legacy/fillpdf_legacy.services.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-services:
-  plugin.manager.fillpdf_backend:
-    class: Drupal\fillpdf_legacy\Plugin\FillPdfBackendManager
-    parent: default_plugin_manager
-    deprecated: The "%service_id%" service is deprecated. You should use the 'plugin.manager.fillpdf.pdf_backend' service instead.
-
-  plugin.manager.fillpdf_backend_service:
-    class: Drupal\fillpdf_legacy\Plugin\BackendServiceManager
-    parent: default_plugin_manager
-    deprecated: The "%service_id%" service is deprecated. You should use the 'plugin.manager.fillpdf.pdf_backend' service instead.
diff --git a/modules/fillpdf_legacy/src/Annotation/BackendService.php b/modules/fillpdf_legacy/src/Annotation/BackendService.php
deleted file mode 100644
index 2b41c14..0000000
--- a/modules/fillpdf_legacy/src/Annotation/BackendService.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_legacy\Annotation;
-
-use Drupal\Component\Annotation\Plugin;
-
-/**
- * Defines a FillPDF BackendService item annotation object.
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
- *   Use the PdfBackend plugin type instead.
- * @see https://www.drupal.org/node/3059476
- * @see \Drupal\fillpdf\Annotation\PdfBackend
- *
- * @Annotation
- */
-class BackendService extends Plugin {
-
-  /**
-   * The plugin ID.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The label of the plugin.
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   *
-   * @ingroup plugin_translatable
-   */
-  public $label;
-
-}
diff --git a/modules/fillpdf_legacy/src/Plugin/BackendService/LocalServerBackendService.php b/modules/fillpdf_legacy/src/Plugin/BackendService/LocalServerBackendService.php
deleted file mode 100644
index 95bfdb0..0000000
--- a/modules/fillpdf_legacy/src/Plugin/BackendService/LocalServerBackendService.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_legacy\Plugin\BackendService;
-
-use Drupal\Core\File\FileSystem;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\fillpdf\Plugin\PdfBackendManager;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Legacy LocalServer BackendService plugin.
- *
- * @BackendService(
- *   id = "local_service",
- *   label = @Translation("FillPDF LocalServer")
- * )
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
- *   Use the new LocalServerPdfBackend plugin instead.
- * @see https://www.drupal.org/node/3059476
- * @see \Drupal\fillpdf\Plugin\PdfBackend\LocalServerPdfBackend
- */
-class LocalServerBackendService extends PdfBackendManager implements ContainerFactoryPluginInterface {
-
-  /**
-   * The FillPDF legacy backend manager.
-   *
-   * @var \Drupal\fillpdf\Plugin\PdfBackendInterface
-   */
-  private $pdfBackend;
-
-  /**
-   * The configuration.
-   *
-   * @var array
-   */
-  protected $configuration;
-
-  /**
-   * The file system.
-   *
-   * @var \Drupal\Core\File\FileSystem
-   */
-  protected $fileSystem;
-
-  /**
-   * Constructs a \Drupal\Component\Plugin\PluginBase object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\File\FileSystem $file_system
-   *   The file system.
-   * @param \Drupal\fillpdf\Plugin\PdfBackendManager $pdf_backend_manager
-   *   The FillPDF legacy backend manager.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, FileSystem $file_system, PdfBackendManager $pdf_backend_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-
-    $this->configuration = $configuration;
-    $this->fileSystem = $file_system;
-    $this->pdfBackend = $pdf_backend_manager->createInstance($configuration['backend'], $configuration);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('file_system'),
-      $container->get('plugin.manager.fillpdf.pdf_backend')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function parse($pdf_content) {
-    return $this->pdfBackend->parseStream($pdf_content);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function merge($pdf_content, array $field_mappings, array $context) {
-    return $this->pdfBackend->mergeStream($pdf_content, $field_mappings, $context);
-  }
-
-}
diff --git a/modules/fillpdf_legacy/src/Plugin/BackendServiceInterface.php b/modules/fillpdf_legacy/src/Plugin/BackendServiceInterface.php
deleted file mode 100644
index 26b50c9..0000000
--- a/modules/fillpdf_legacy/src/Plugin/BackendServiceInterface.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_legacy\Plugin;
-
-use Drupal\Component\Plugin\PluginInspectionInterface;
-
-/**
- * Defines an interface for FillPDF BackendService plugins.
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
- *   Extend PdfBackendBase instead.
- * @see https://www.drupal.org/node/3059476
- * @see \Drupal\fillpdf\Plugin\PdfBackendBase
- */
-interface BackendServiceInterface extends PluginInspectionInterface {
-
-  /**
-   * Parse a PDF and return a list of its fields.
-   *
-   * @param string $pdf_content
-   *   The PDF whose fields are going to be parsed. This should be the contents
-   *   of a PDF loaded with something like file_get_contents() or equivalent.
-   *
-   * @return array[]
-   *   An array of arrays containing metadata about the fields in the PDF. These
-   *   can be iterated over and saved by the caller.
-   */
-  public function parse($pdf_content);
-
-  /**
-   * Populate a PDF file with field data.
-   *
-   * @param string $pdf_content
-   *   The PDF into which to merge the field values specified in the mapping.
-   * @param \Drupal\fillpdf\FieldMapping[] $field_mappings
-   *   An array of FieldMapping-derived objects mapping PDF field keys to the
-   *   values with which they should be replaced. Strings are also acceptable
-   *   and converted to TextFieldMapping objects.
-   *   Example array:
-   *   @code
-   *   [
-   *     'Foo' => new TextFieldMapping('bar'),
-   *     'Foo2' => new TextFieldMapping('bar2'),
-   *     'Image1' => new ImageFieldMapping(base64_encode(file_get_contents($image)), 'jpg'),
-   *   ]
-   *   @endcode
-   * @param array $context
-   *   The request context as returned by
-   *   FillPdfLinkManipulatorInterface::parseLink().
-   *
-   * @return string|null
-   *   The raw file contents of the new PDF, or NULL if merging failed. The
-   *   caller has to handle saving or serving the file accordingly.
-   *
-   * @see \Drupal\fillpdf\FieldMapping
-   * @see \Drupal\fillpdf\FieldMapping\TextFieldMapping
-   * @see \Drupal\fillpdf\FieldMapping\ImageFieldMapping
-   * @see \Drupal\fillpdf\FillPdfLinkManipulatorInterface::parseLink()
-   */
-  public function merge($pdf_content, array $field_mappings, array $context);
-
-}
diff --git a/modules/fillpdf_legacy/src/Plugin/BackendServiceManager.php b/modules/fillpdf_legacy/src/Plugin/BackendServiceManager.php
deleted file mode 100644
index c0c3cc6..0000000
--- a/modules/fillpdf_legacy/src/Plugin/BackendServiceManager.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_legacy\Plugin;
-
-use Drupal\Core\Plugin\DefaultPluginManager;
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-
-/**
- * Provides the legacy FillPDF BackendService plugin manager.
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
- *   Use PdfBackendManager and the new PdfBackend plugins instead.
- * @see https://www.drupal.org/node/3059476
- * @see \Drupal\fillpdf\Plugin\PdfBackendManager
- */
-class BackendServiceManager extends DefaultPluginManager {
-
-  /**
-   * Constructs a new LegacyBackendServiceManager object.
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler to invoke the alter hook with.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
-    parent::__construct('Plugin/BackendService', $namespaces, $module_handler, 'Drupal\fillpdf_legacy\Plugin\BackendServiceInterface', 'Drupal\fillpdf_legacy\Annotation\BackendService');
-
-    $this->alterInfo('fillpdf_fillpdf_backend_info');
-    $this->setCacheBackend($cache_backend, 'fillpdf_fillpdf_backend_plugins');
-  }
-
-}
diff --git a/modules/fillpdf_legacy/src/Plugin/FillPdfBackend/JavaBridgeFillPdfBackend.php b/modules/fillpdf_legacy/src/Plugin/FillPdfBackend/JavaBridgeFillPdfBackend.php
deleted file mode 100644
index e527786..0000000
--- a/modules/fillpdf_legacy/src/Plugin/FillPdfBackend/JavaBridgeFillPdfBackend.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_legacy\Plugin\FillPdfBackend;
-
-use Drupal\Core\File\FileSystem;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Plugin\PluginBase;
-use Drupal\file\Entity\File;
-use Drupal\fillpdf\FillPdfBackendPluginInterface;
-use Drupal\fillpdf\FillPdfFormInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Legacy JavaBridge FillPdfBackend plugin.
- *
- * @Plugin(
- *   id = "local"
- * )
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
- *   Use FillPDF LocalServer with the new LocalServerPdfBackend plugin instead.
- * @see https://www.drupal.org/node/3059476
- * @see \Drupal\fillpdf\Plugin\PdfBackend\LocalServerPdfBackend
- */
-class JavaBridgeFillPdfBackend extends PluginBase implements FillPdfBackendPluginInterface, ContainerFactoryPluginInterface {
-
-  /**
-   * The file system.
-   *
-   * @var \Drupal\Core\File\FileSystem
-   */
-  protected $fileSystem;
-
-  /**
-   * Constructs a LocalFillPdfBackend plugin object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\File\FileSystem $file_system
-   *   The file system.
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, FileSystem $file_system) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->fileSystem = $file_system;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('file_system')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function parse(FillPdfFormInterface $fillpdf_form) {
-    /** @var \Drupal\file\FileInterface $file */
-    $file = File::load($fillpdf_form->file->target_id);
-    $content = file_get_contents($file->getFileUri());
-
-    $require = drupal_get_path('module', 'fillpdf') . '/lib/JavaBridge/java/Java.inc';
-    require_once DRUPAL_ROOT . '/' . $require;
-    try {
-      $fillpdf = new \java('com.ocdevel.FillpdfService', base64_encode($content), 'bytes');
-      $fields = java_values($fillpdf->parse());
-    }
-    catch (\JavaException $e) {
-      $this->messenger()->addError(java_truncate((string) $e));
-    }
-
-    return $fields;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function populateWithFieldData(FillPdfFormInterface $fillpdf_form, array $field_mapping, array $context) {
-    /** @var \Drupal\file\FileInterface $original_file */
-    $original_file = File::load($fillpdf_form->file->target_id);
-    $pdf_data = file_get_contents($original_file->getFileUri());
-    $fields = $field_mapping['fields'];
-
-    $require = drupal_get_path('module', 'fillpdf') . '/lib/JavaBridge/java/Java.inc';
-    require_once DRUPAL_ROOT . '/' . $require;
-    try {
-      $fillpdf = new \java('com.ocdevel.FillpdfService', base64_encode($pdf_data), 'bytes');
-      foreach ($fields as $key => $field) {
-        if (substr($field, 0, 7) == '{image}') {
-          // Remove {image} marker.
-          $image_filepath = substr($field, 7);
-          $image_realpath = $this->fileSystem->realpath($image_filepath);
-          $fillpdf->image($key, $image_realpath, 'file');
-        }
-        else {
-          $fillpdf->text($key, $field);
-        }
-      }
-    }
-    catch (\JavaException $e) {
-      $this->messenger()->addError(java_truncate((string) $e));
-      return NULL;
-    }
-    try {
-      if ($context['flatten']) {
-        $populated_pdf = java_values(base64_decode($fillpdf->toByteArray()));
-      }
-      else {
-        $populated_pdf = java_values(base64_decode($fillpdf->toByteArrayUnflattened()));
-      }
-    }
-    catch (\JavaException $e) {
-      $this->messenger()->addError(java_truncate((string) $e));
-      return NULL;
-    }
-
-    return $populated_pdf;
-  }
-
-}
diff --git a/modules/fillpdf_legacy/src/Plugin/FillPdfBackendManager.php b/modules/fillpdf_legacy/src/Plugin/FillPdfBackendManager.php
deleted file mode 100644
index 285ebe8..0000000
--- a/modules/fillpdf_legacy/src/Plugin/FillPdfBackendManager.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_legacy\Plugin;
-
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Plugin\DefaultPluginManager;
-
-/**
- * Provides the legacy FillPDF FillPdfBackend plugin manager.
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
- *   Use PdfBackendManager and the new PdfBackend plugins instead.
- * @see https://www.drupal.org/node/3059476
- * @see \Drupal\fillpdf\Plugin\PdfBackendManager
- */
-class FillPdfBackendManager extends DefaultPluginManager {
-
-  /**
-   * Constructs a FillPdfBackendManager object.
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler to invoke the alter hook with.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
-    parent::__construct('Plugin/FillPdfBackend', $namespaces, $module_handler, '\Drupal\fillpdf\FillPdfBackendPluginInterface');
-
-    $this->alterInfo('fillpdf_backend_info');
-    $this->setCacheBackend($cache_backend, 'fillpdf_backend_info_plugins');
-  }
-
-}
diff --git a/modules/fillpdf_legacy/src/Plugin/PdfBackend/LegacyProviderPdfBackend.php b/modules/fillpdf_legacy/src/Plugin/PdfBackend/LegacyProviderPdfBackend.php
deleted file mode 100644
index 30b38dc..0000000
--- a/modules/fillpdf_legacy/src/Plugin/PdfBackend/LegacyProviderPdfBackend.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_legacy\Plugin\PdfBackend;
-
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\file\FileInterface;
-use Drupal\fillpdf\Entity\FillPdfForm;
-use Drupal\fillpdf\FieldMapping\ImageFieldMapping;
-use Drupal\fillpdf\FieldMapping\TextFieldMapping;
-use Drupal\fillpdf_legacy\Plugin\FillPdfBackendManager;
-use Drupal\fillpdf\Plugin\PdfBackendBase;
-use Drupal\fillpdf\FillPdfBackendPluginInterface;
-use Drupal\fillpdf\FillPdfFormInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Legacy provider PdfBackend plugin.
- *
- * Provides backwards compatibility with legacy FillPdfBackend plugins.
- *
- * @PdfBackend(
- *   id = "legacy_provider",
- * )
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0. This is
- *   only a BC wrapper. Once you turned your legacy FillPdfBackend plugins into
- *   new PdfBackend plugins, this wrapper will not be needed anymore.
- * @see https://www.drupal.org/node/3059476
- */
-final class LegacyProviderPdfBackend extends PdfBackendBase implements ContainerFactoryPluginInterface, FillPdfBackendPluginInterface {
-
-  /**
-   * The FillPDF legacy backend.
-   *
-   * @var \Drupal\fillpdf\FillPdfBackendPluginInterface
-   */
-  private $legacyBackend;
-
-  /**
-   * Constructs a LegacyProviderPdfBackend plugin object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\fillpdf_legacy\Plugin\FillPdfBackendManager $legacy_backend_manager
-   *   The FillPDF legacy backend manager.
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, FillPdfBackendManager $legacy_backend_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->legacyBackend = $legacy_backend_manager->createInstance($configuration['backend'], $configuration);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('plugin.manager.fillpdf_backend')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function parse(FillPdfFormInterface $fillpdf_form) {
-    return $this->legacyBackend->parse($fillpdf_form);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function parseFile(FileInterface $template_file) {
-    $fillpdf_form = FillPdfForm::create([
-      'file' => $template_file,
-    ]);
-    return $this->parse($fillpdf_form);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function parseStream($pdf_content) {
-    $template_file = file_save_data($pdf_content);
-    return $this->parseFile($template_file);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function populateWithFieldData(FillPdfFormInterface $fillpdf_form, array $field_mapping, array $context) {
-    return $this->legacyBackend->populateWithFieldData($fillpdf_form, $field_mapping, $context);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function mergeFile(FileInterface $template_file, array $field_mappings, array $context) {
-    $legacy_mapping = [];
-    foreach ($field_mappings as $pdf_key => $mapping) {
-      if ($mapping instanceof TextFieldMapping) {
-        $legacy_mapping['fields'][$pdf_key] = (string) $mapping->getData();
-      }
-      elseif ($mapping instanceof ImageFieldMapping) {
-        $uri = (string) $mapping->getUri();
-        if ($uri) {
-          $legacy_mapping['fields'][$pdf_key] = "{image}{$uri}";
-          $image_path_info = pathinfo($uri);
-          $legacy_mapping['images'][$pdf_key] = [
-            'data' => base64_encode($mapping->getData()),
-            'filenamehash' => md5($image_path_info['filename']) . '.' . $image_path_info['extension'],
-          ];
-        }
-      }
-    }
-
-    $fillpdf_form = FillPdfForm::create([
-      'file' => $template_file,
-    ]);
-    return $this->legacyBackend->populateWithFieldData($fillpdf_form, $legacy_mapping, $context);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function mergeStream($pdf_content, array $field_mappings, array $context) {
-    $template_file = file_save_data($pdf_content);
-    return $this->mergeFile($template_file);
-  }
-
-}
diff --git a/modules/fillpdf_legacy/tests/Kernel/LegacyBackendTest.php b/modules/fillpdf_legacy/tests/Kernel/LegacyBackendTest.php
deleted file mode 100644
index 1deebf9..0000000
--- a/modules/fillpdf_legacy/tests/Kernel/LegacyBackendTest.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace Drupal\Tests\fillpdf_legacy\Kernel;
-
-use Drupal\fillpdf_legacy\Plugin\PdfBackend\LegacyProviderPdfBackend;
-use Drupal\Tests\fillpdf\Kernel\FillPdfKernelTestBase;
-
-/**
- * Tests that backend-related functions work.
- *
- * @group fillpdf
- * @group legacy
- */
-class LegacyBackendTest extends FillPdfKernelTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['fillpdf_legacy'];
-
-  /**
-   * Tests the legacy test backend.
-   */
-  public function testTestBackend() {
-    $backend_manager = $this->container->get('plugin.manager.fillpdf.pdf_backend');
-    $test_backend = $backend_manager->createInstance('test');
-    self::assertInstanceOf(LegacyProviderPdfBackend::class, $test_backend);
-  }
-
-}
diff --git a/modules/fillpdf_next/fillpdf_next.info.yml b/modules/fillpdf_next/fillpdf_next.info.yml
deleted file mode 100644
index 475c3e8..0000000
--- a/modules/fillpdf_next/fillpdf_next.info.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: 'FillPDF Next [EXPERIMENTAL]'
-type: module
-description: 'Deprecated, please remove.'
-core: 8.x
-package: Other
-hidden: true
diff --git a/src/Component/Utility/FillPdf.php b/src/Component/Utility/FillPdf.php
index c8863a4..121b30d 100644
--- a/src/Component/Utility/FillPdf.php
+++ b/src/Component/Utility/FillPdf.php
@@ -85,10 +85,6 @@ class FillPdf {
     $uri = $scheme . '://' . $path;
     /** @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $streamWrapperManager */
     $streamWrapperManager = \Drupal::service('stream_wrapper_manager');
-    // @todo: Remove once Drupal 8.7 is no longer supported.
-    if (!method_exists(StreamWrapperManagerInterface::class, 'normalizeUri')) {
-      return file_stream_wrapper_uri_normalize($uri);
-    }
     return $streamWrapperManager->normalizeUri($uri);
   }
 
diff --git a/src/Plugin/BackendServiceBase.php b/src/Plugin/BackendServiceBase.php
deleted file mode 100644
index 64543ee..0000000
--- a/src/Plugin/BackendServiceBase.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf\Plugin;
-
-use Drupal\Component\Plugin\PluginBase;
-use Drupal\fillpdf_legacy\Plugin\BackendServiceInterface;
-
-/**
- * Base class for FillPDF BackendService plugins.
- *
- * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
- *   Extend PdfBackendBase instead.
- * @see https://www.drupal.org/node/3059476
- * @see \Drupal\fillpdf\Plugin\PdfBackendBase
- */
-abstract class BackendServiceBase extends PluginBase implements BackendServiceInterface {
-
-}
diff --git a/src/Plugin/PdfBackend/FillPdfServicePdfBackend.php b/src/Plugin/PdfBackend/FillPdfServicePdfBackend.php
index d2ad931..1667576 100644
--- a/src/Plugin/PdfBackend/FillPdfServicePdfBackend.php
+++ b/src/Plugin/PdfBackend/FillPdfServicePdfBackend.php
@@ -26,20 +26,7 @@ use Drupal\fillpdf\Plugin\PdfBackendBase;
  *   weight = -10
  * )
  */
-class FillPdfServicePdfBackend extends PdfBackendBase implements FillPdfBackendPluginInterface {
-
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
-   *   Instead use PdfBackendInterface::parseFile().
-   * @see https://www.drupal.org/node/3059476
-   * @see \Drupal\fillpdf\Plugin\PdfBackendInterface::parseFile()
-   */
-  public function parse(FillPdfFormInterface $fillpdf_form) {
-    $template_file = File::load($fillpdf_form->file->target_id);
-    return $this->parseFile($template_file);
-  }
+class FillPdfServicePdfBackend extends PdfBackendBase {
 
   /**
    * {@inheritdoc}
@@ -104,19 +91,6 @@ class FillPdfServicePdfBackend extends PdfBackendBase implements FillPdfBackendP
     return $ret;
   }
 
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
-   *   Instead use PdfBackendInterface::mergeFile().
-   * @see https://www.drupal.org/node/3059476
-   * @see \Drupal\fillpdf\Plugin\PdfBackendInterface::mergeFile()
-   */
-  public function populateWithFieldData(FillPdfFormInterface $fillpdf_form, array $field_mapping, array $context) {
-    $template_file = File::load($fillpdf_form->file->target_id);
-    return $this->mergeFile($template_file, $field_mapping, $context);
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/src/Plugin/PdfBackend/LocalServerPdfBackend.php b/src/Plugin/PdfBackend/LocalServerPdfBackend.php
index e95e7fc..8b4cc6f 100644
--- a/src/Plugin/PdfBackend/LocalServerPdfBackend.php
+++ b/src/Plugin/PdfBackend/LocalServerPdfBackend.php
@@ -24,7 +24,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *   weight = 5
  * )
  */
-class LocalServerPdfBackend extends PdfBackendBase implements ContainerFactoryPluginInterface, FillPdfBackendPluginInterface {
+class LocalServerPdfBackend extends PdfBackendBase implements ContainerFactoryPluginInterface {
 
   /**
    * The file system.
@@ -69,19 +69,6 @@ class LocalServerPdfBackend extends PdfBackendBase implements ContainerFactoryPl
     );
   }
 
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
-   *   Instead use PdfBackendInterface::parseFile().
-   * @see https://www.drupal.org/node/3059476
-   * @see \Drupal\fillpdf\Plugin\PdfBackendInterface::parseFile()
-   */
-  public function parse(FillPdfFormInterface $fillpdf_form) {
-    $template_file = File::load($fillpdf_form->file->target_id);
-    return $this->parseFile($template_file);
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -125,20 +112,6 @@ class LocalServerPdfBackend extends PdfBackendBase implements ContainerFactoryPl
     return $fields;
   }
 
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
-   *   Instead use PdfBackendInterface::mergeFile().
-   *
-   * @see https://www.drupal.org/node/3059476
-   * @see \Drupal\fillpdf\Plugin\PdfBackendInterface::mergeFile()
-   */
-  public function populateWithFieldData(FillPdfFormInterface $fillpdf_form, array $field_mapping, array $context) {
-    $template_file = File::load($fillpdf_form->file->target_id);
-    return $this->mergeFile($template_file, $field_mapping, $context);
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/src/Plugin/PdfBackend/PdftkPdfBackend.php b/src/Plugin/PdfBackend/PdftkPdfBackend.php
index da50836..83f1ee7 100644
--- a/src/Plugin/PdfBackend/PdftkPdfBackend.php
+++ b/src/Plugin/PdfBackend/PdftkPdfBackend.php
@@ -33,7 +33,7 @@ use Drupal\Core\File\FileSystemInterface;
  *   weight = -5
  * )
  */
-class PdftkPdfBackend extends PdfBackendBase implements ContainerFactoryPluginInterface, FillPdfBackendPluginInterface {
+class PdftkPdfBackend extends PdfBackendBase implements ContainerFactoryPluginInterface {
 
   /**
    * The file system.
@@ -93,19 +93,6 @@ class PdftkPdfBackend extends PdfBackendBase implements ContainerFactoryPluginIn
     );
   }
 
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
-   *   Instead use PdfBackendInterface::parseFile().
-   * @see https://www.drupal.org/node/3059476
-   * @see \Drupal\fillpdf\Plugin\PdfBackendInterface::parseFile()
-   */
-  public function parse(FillPdfFormInterface $fillpdf_form) {
-    $template_file = File::load($fillpdf_form->file->target_id);
-    return $this->parseFile($template_file);
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -180,19 +167,6 @@ class PdftkPdfBackend extends PdfBackendBase implements ContainerFactoryPluginIn
     return isset($this->configuration['pdftk_path']) ? $this->configuration['pdftk_path'] : 'pdftk';
   }
 
-  /**
-   * {@inheritdoc}
-   *
-   * @deprecated in fillpdf:8.x-4.9 and is removed from fillpdf:8.x-5.0.
-   *   Instead use PdfBackendInterface::mergeFile().
-   * @see https://www.drupal.org/node/3059476
-   * @see \Drupal\fillpdf\Plugin\PdfBackendInterface::mergeFile()
-   */
-  public function populateWithFieldData(FillPdfFormInterface $fillpdf_form, array $field_mapping, array $context) {
-    $template_file = File::load($fillpdf_form->file->target_id);
-    return $this->mergeFile($template_file, $field_mapping, $context);
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/tests/modules/fillpdf_test/fillpdf_test.info.yml b/tests/modules/fillpdf_test/fillpdf_test.info.yml
index cf6f528..b4188bd 100644
--- a/tests/modules/fillpdf_test/fillpdf_test.info.yml
+++ b/tests/modules/fillpdf_test/fillpdf_test.info.yml
@@ -1,7 +1,7 @@
 name: FillPDF Testing
 type: module
 description: Fixtures/support for FillPDF tests.
-core: 8.x
+core_version_requirement: ^8.8 || ^9
 package: Testing
 dependencies:
-  - fillpdf:fillpdf_legacy
+  - fillpdf:fillpdf
diff --git a/tests/modules/fillpdf_test/src/Plugin/BackendService/Test.php b/tests/modules/fillpdf_test/src/Plugin/BackendService/Test.php
deleted file mode 100644
index 78f3478..0000000
--- a/tests/modules/fillpdf_test/src/Plugin/BackendService/Test.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-
-namespace Drupal\fillpdf_test\Plugin\BackendService;
-
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\State\StateInterface;
-use Drupal\fillpdf\Plugin\BackendServiceBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Backend used in tests.
- *
- * @BackendService(
- *   id = "test",
- *   label = @Translation("FillPDF Test Backend Service"),
- * )
- */
-class Test extends BackendServiceBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The state.
-   *
-   * @var \Drupal\Core\State\StateInterface
-   */
-  protected $state;
-
-  /**
-   * Constructs a \Drupal\Component\Plugin\PluginBase object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\State\StateInterface $state
-   *   The state.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, StateInterface $state) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-
-    $this->configuration = $configuration;
-    $this->state = $state;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('state')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function parse($pdf_content) {
-    return static::getParseResult();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function merge($pdf_content, array $field_mappings, array $options) {
-    $this->state->set('fillpdf_test.last_populated_metadata', [
-      'field_mapping' => $field_mappings,
-      'options' => $options,
-    ]);
-
-    return file_get_contents(drupal_get_path('module', 'fillpdf_test') . '/files/fillpdf_test_v3.pdf');
-  }
-
-  /**
-   * Returns a list of fields, as if a PDF file was parsed.
-   *
-   * Note that there is a duplicate field that get consolidated in
-   * InputHelper::attachPdfToForm() at the latest.
-   * The expected number of fields is therefore three, not four.
-   *
-   * @return array
-   *   List of associative arrays representing fields.
-   *
-   * @see \Drupal\fillpdf\InputHelper::attachPdfToForm()
-   */
-  public static function getParseResult() {
-    return [
-      0 => [
-        'name' => 'ImageField',
-        'value' => '',
-        'type' => 'Pushbutton',
-      ],
-      1 => [
-        'name' => 'TestButton',
-        'value' => '',
-        'type' => 'Pushbutton',
-      ],
-      2 => [
-        'name' => 'TextField1',
-        'value' => '',
-        'type' => 'Text',
-      ],
-      3 => [
-        'name' => 'TextField2',
-        'value' => '',
-        'type' => 'Text',
-      ],
-      4 => [
-        'name' => 'ImageField',
-        'value' => '',
-        'type' => 'Pushbutton',
-      ],
-    ];
-  }
-
-}
diff --git a/tests/modules/fillpdf_test/src/Plugin/FillPdfBackend/TestFillPdfBackend.php b/tests/modules/fillpdf_test/src/Plugin/PdfBackend/TestPdfBackend.php
similarity index 77%
rename from tests/modules/fillpdf_test/src/Plugin/FillPdfBackend/TestFillPdfBackend.php
rename to tests/modules/fillpdf_test/src/Plugin/PdfBackend/TestPdfBackend.php
index f532624..1d1d05c 100644
--- a/tests/modules/fillpdf_test/src/Plugin/FillPdfBackend/TestFillPdfBackend.php
+++ b/tests/modules/fillpdf_test/src/Plugin/PdfBackend/TestPdfBackend.php
@@ -1,22 +1,22 @@
 <?php
 
-namespace Drupal\fillpdf_test\Plugin\FillPdfBackend;
+namespace Drupal\fillpdf_test\Plugin\PdfBackend;
 
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\State\StateInterface;
-use Drupal\fillpdf\FillPdfBackendPluginInterface;
-use Drupal\fillpdf\FillPdfFormInterface;
+use Drupal\file\FileInterface;
+use Drupal\fillpdf\Plugin\PdfBackendBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Backend used in tests.
  *
- * @Plugin(
+ * @PdfBackend(
  *   id = "test",
  *   label = @Translation("Pass-through plugin for testing")
  * )
  */
-class TestFillPdfBackend implements FillPdfBackendPluginInterface, ContainerFactoryPluginInterface {
+class TestPdfBackend extends PdfBackendBase implements ContainerFactoryPluginInterface {
 
   /**
    * The plugin's configuration.
@@ -45,7 +45,7 @@ class TestFillPdfBackend implements FillPdfBackendPluginInterface, ContainerFact
    *   The state.
    */
   public function __construct(array $configuration, $plugin_id, array $plugin_definition, StateInterface $state) {
-    $this->configuration = $configuration;
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->state = $state;
   }
 
@@ -64,19 +64,33 @@ class TestFillPdfBackend implements FillPdfBackendPluginInterface, ContainerFact
   /**
    * {@inheritdoc}
    */
-  public function parse(FillPdfFormInterface $fillpdf_form) {
+  public function parseFile(FileInterface $template_file) {
+    return $this->parseStream('');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function parseStream($pdf_content) {
     return static::getParseResult();
   }
 
   /**
    * {@inheritdoc}
    */
-  public function populateWithFieldData(FillPdfFormInterface $pdf_form, array $field_mapping, array $context) {
+  public function mergeFile(FileInterface $template_file, array $field_mappings, array $context) {
+    return $this->mergeStream('', $field_mappings, $context);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function mergeStream($pdf_content, array $field_mappings, array $context) {
     // Not really populated, but that isn't our job.
     $populated_pdf = file_get_contents(drupal_get_path('module', 'fillpdf_test') . '/files/fillpdf_test_v3.pdf');
 
     $this->state->set('fillpdf_test.last_populated_metadata', [
-      'field_mapping' => $field_mapping,
+      'field_mapping' => $field_mappings,
       'context' => $context,
     ]);
 
diff --git a/tests/modules/fillpdf_webform_test/fillpdf_webform_test.info.yml b/tests/modules/fillpdf_webform_test/fillpdf_webform_test.info.yml
index 2311f58..3aebf70 100644
--- a/tests/modules/fillpdf_webform_test/fillpdf_webform_test.info.yml
+++ b/tests/modules/fillpdf_webform_test/fillpdf_webform_test.info.yml
@@ -1,7 +1,7 @@
 name: FillPDF webform Testing
 type: module
 description: Fixtures/support for FillPDF webform tests.
-core: 8.x
+core_version_requirement: ^8.8 || ^9
 package: Testing
 dependencies:
   - fillpdf:fillpdf_test
diff --git a/tests/src/Functional/FillPdfTestBase.php b/tests/src/Functional/FillPdfTestBase.php
index 060a899..a514406 100644
--- a/tests/src/Functional/FillPdfTestBase.php
+++ b/tests/src/Functional/FillPdfTestBase.php
@@ -33,13 +33,6 @@ abstract class FillPdfTestBase extends FileFieldTestBase {
    */
   public static $modules = ['image', 'fillpdf_test'];
 
-  /**
-   * The FillPdf backend service manager.
-   *
-   * @var \Drupal\fillpdf\Plugin\PdfBackendManager
-   */
-  protected $backendServiceManager;
-
   /**
    * The FillPDF link manipulator service.
    *
@@ -118,7 +111,6 @@ abstract class FillPdfTestBase extends FileFieldTestBase {
 
     $this->configureFillPdf();
 
-    $this->backendServiceManager = $this->container->get('plugin.manager.fillpdf_backend_service');
     $this->linkManipulator = $this->container->get('fillpdf.link_manipulator');
   }
 
diff --git a/tests/src/Functional/PdfPopulationTest.php b/tests/src/Functional/PdfPopulationTest.php
index 8790c7b..d46475f 100644
--- a/tests/src/Functional/PdfPopulationTest.php
+++ b/tests/src/Functional/PdfPopulationTest.php
@@ -7,7 +7,8 @@ use Drupal\fillpdf\Component\Utility\FillPdf;
 use Drupal\fillpdf\Entity\FillPdfForm;
 use Drupal\fillpdf\FieldMapping\ImageFieldMapping;
 use Drupal\fillpdf\FieldMapping\TextFieldMapping;
-use Drupal\fillpdf_test\Plugin\FillPdfBackend\TestFillPdfBackend;
+use Drupal\fillpdf_test\Plugin\PdfBackend\TestFillPdfBackend;
+use Drupal\fillpdf_test\Plugin\PdfBackend\TestPdfBackend;
 use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;
 use Drupal\user\Entity\Role;
 
@@ -106,13 +107,13 @@ class PdfPopulationTest extends FillPdfTestBase {
 
     self::assertEquals(
       'Hello & how are you doing?',
-      $populate_result['field_mapping']['fields']['TextField1'],
+      $populate_result['field_mapping']['TextField1']->getData(),
       'PDF is populated with the title of the node with all HTML stripped.'
     );
 
     self::assertEquals(
       "PDF form fields don't accept any HTML.\n",
-      $populate_result['field_mapping']['fields']['TextField2'],
+      $populate_result['field_mapping']['TextField2']->getData(),
       'PDF is populated with the node body. HTML is stripped but a newline
        replaces the <p> tags.'
     );
@@ -141,7 +142,7 @@ class PdfPopulationTest extends FillPdfTestBase {
 
     self::assertEquals(
       '<TextField1>',
-      $populate_result['field_mapping']['fields']['TextField1'],
+      $populate_result['field_mapping']['TextField1']->getData(),
       'Sample field mapped properly.'
     );
   }
@@ -189,33 +190,36 @@ class PdfPopulationTest extends FillPdfTestBase {
 
       $file = File::load($entity->field_fillpdf_test_image->target_id);
 
-      self::assertArrayHasKey('ImageField', $populate_result['field_mapping']['images'], "$entity_type isn't populated with an image.");
+      self::assertArrayHasKey('ImageField', $populate_result['field_mapping'], "$entity_type isn't populated with an image.");
+      $image_field_mapping = $populate_result['field_mapping']['ImageField'];
       self::assertEquals(
-        $populate_result['field_mapping']['images']['ImageField']['data'],
+        base64_encode($image_field_mapping->getData()),
         base64_encode(file_get_contents($file->getFileUri())),
         'Encoded image matches known image.'
       );
 
       $path_info = pathinfo($file->getFileUri());
       $expected_file_hash = md5($path_info['filename']) . '.' . $path_info['extension'];
+      $actual_path_info = pathinfo($image_field_mapping->getUri());
+      $actual_file_hash = md5($actual_path_info['filename']) . '.' . $actual_path_info['extension'];
       self::assertEquals(
-        $populate_result['field_mapping']['images']['ImageField']['filenamehash'],
+        $actual_file_hash,
         $expected_file_hash,
         'Hashed filename matches known hash.'
       );
 
       self::assertEquals(
-        $populate_result['field_mapping']['fields']['ImageField'],
-        "{image}{$file->getFileUri()}",
+        $image_field_mapping->getUri(),
+        $file->getFileUri(),
         'URI in metadata matches expected URI.'
       );
     }
   }
 
   /**
-   * Test plugin APIs directly to make sure third-party consumers can use them.
+   * Test that duplicate fields get filtered out.
    */
-  public function testPluginApi() {
+  public function testDuplicateFieldHandling() {
     $this->uploadTestPdf('fillpdf_test_v3.pdf');
     $fillpdf_form = FillPdfForm::load($this->getLatestFillPdfForm());
 
@@ -228,7 +232,7 @@ class PdfPopulationTest extends FillPdfTestBase {
 
     // Get the fields from the fixture and sort.
     $expected_keys = [];
-    foreach (TestFillPdfBackend::getParseResult() as $expected_field) {
+    foreach (TestPdfBackend::getParseResult() as $expected_field) {
       $expected_keys[] = $expected_field['name'];
     }
     sort($expected_keys);
@@ -239,42 +243,6 @@ class PdfPopulationTest extends FillPdfTestBase {
     $this->assertCount(4, $actual_keys);
     $differences = array_diff($expected_keys, $actual_keys);
     self::assertEmpty($differences, 'Parsed fields are in fixture match.');
-
-    // Now create an instance of the backend service and test directly.
-    /** @var \Drupal\fillpdf_test\Plugin\BackendService\Test $backend_service */
-    $backend_service = $this->backendServiceManager->createInstance('test');
-    $original_pdf = file_get_contents($this->getTestPdfPath('fillpdf_test_v3.pdf'));
-
-    // Get the fields from the backend service and sort.
-    $actual_keys = [];
-    foreach ($backend_service->parse($original_pdf) as $parsed_field) {
-      $actual_keys[] = $parsed_field['name'];
-    }
-    sort($actual_keys);
-
-    // Compare the values.
-    $this->assertCount(5, $expected_keys);
-    $this->assertCount(5, $actual_keys);
-    $differences = array_diff($expected_keys, $actual_keys);
-    self::assertEmpty($differences, 'Parsed fields from plugin are in fixture match.');
-
-    // Test the merge method. We'd normally pass in values for $webform_fields
-    // and $options, but since this is a stub anyway, there isn't much point.
-    // @todo: Test deeper using the State API.
-    $merged_pdf = $backend_service->merge($original_pdf, [
-      'Foo' => new TextFieldMapping('bar'),
-      'Foo2' => new TextFieldMapping('bar2'),
-      'Image1' => new ImageFieldMapping(file_get_contents($this->testImage->getFileUri()), 'png'),
-    ], []);
-    self::assertEquals($original_pdf, $merged_pdf);
-
-    $merge_state = $this->container->get('state')
-      ->get('fillpdf_test.last_populated_metadata');
-
-    // Check that fields are set as expected.
-    self::assertInstanceOf(TextFieldMapping::class, $merge_state['field_mapping']['Foo'], 'Field "Foo" was mapped to a TextFieldMapping object.');
-    self::assertInstanceOf(TextFieldMapping::class, $merge_state['field_mapping']['Foo2'], 'Field "Foo2" was mapped to a TextFieldMapping object.');
-    self::assertInstanceOf(ImageFieldMapping::class, $merge_state['field_mapping']['Image1'], 'Field "Image1" was mapped to an ImageFieldMapping object.');
   }
 
   /**
@@ -320,8 +288,8 @@ class PdfPopulationTest extends FillPdfTestBase {
     // These are not that important. They just work because of other tests.
     // We're just testing that token replacement works in general, not the
     // details of it. We have other tests for that.
-    self::assertEquals('Hello & how are you doing?', $merge_state['field_mapping']['fields']['TextField1']);
-    self::assertEquals("PDF form fields don't accept any HTML.\n", $merge_state['field_mapping']['fields']['TextField2']);
+    self::assertEquals('Hello & how are you doing?', $merge_state['field_mapping']['TextField1']->getData());
+    self::assertEquals("PDF form fields don't accept any HTML.\n", $merge_state['field_mapping']['TextField2']->getData());
   }
 
   /**
diff --git a/tests/src/Functional/PdfWebformPopulationTest.php b/tests/src/Functional/PdfWebformPopulationTest.php
index 61ab615..7d80a1e 100644
--- a/tests/src/Functional/PdfWebformPopulationTest.php
+++ b/tests/src/Functional/PdfWebformPopulationTest.php
@@ -93,41 +93,40 @@ class PdfWebformPopulationTest extends FillPdfTestBase {
 
     $submission_values = $this->testSubmission->getData();
     self::assertEquals(
-      $populate_result['field_mapping']['fields']['TextField1'],
+      $populate_result['field_mapping']['TextField1']->getData(),
       $this->testSubmission->getWebform()->label(),
       'PDF is populated with the title of the Webform Submission.'
     );
 
     $submission_file = File::load($submission_values['image'][0]);
+    /** @var \Drupal\fillpdf\FieldMapping\ImageFieldMapping $image_field_mapping */
+    $image_field_mapping = $populate_result['field_mapping']['ImageField'];
     self::assertEquals(
-      $populate_result['field_mapping']['images']['ImageField']['data'],
+      base64_encode($image_field_mapping->getData()),
       base64_encode(file_get_contents($submission_file->getFileUri())),
       'Encoded image matches known image.'
     );
 
     $path_info = pathinfo($submission_file->getFileUri());
     $expected_file_hash = md5($path_info['filename']) . '.' . $path_info['extension'];
+    $actual_path_info = pathinfo($image_field_mapping->getUri());
+    $actual_file_hash = md5($actual_path_info['filename']) . '.' . $actual_path_info['extension'];
     self::assertEquals(
-      $populate_result['field_mapping']['images']['ImageField']['filenamehash'],
+      $actual_file_hash,
       $expected_file_hash,
       'Hashed filename matches known hash.'
     );
 
     self::assertEquals(
-      $populate_result['field_mapping']['fields']['ImageField'],
-      "{image}{$submission_file->getFileUri()}",
+      $image_field_mapping->getUri(),
+      $submission_file->getFileUri(),
       'URI in metadata matches expected URI.'
     );
 
-    self::assertEquals(
-      '{image}webform_signature.png',
-      $populate_result['field_mapping']['fields']['TestButton'],
-      'Signature matches signature from Webform.'
-    );
     $signature_image = TokenResolver::getSignatureImage($submission_values['test_signature']);
     self::assertEquals(
       base64_encode($signature_image),
-      $populate_result['field_mapping']['images']['TestButton']['data'],
+      base64_encode($populate_result['field_mapping']['TestButton']->getData()),
       'Signature matches signature from Webform.'
     );
   }
diff --git a/tests/src/Functional/UninstallTest.php b/tests/src/Functional/UninstallTest.php
index 17bb0ff..3df44c9 100644
--- a/tests/src/Functional/UninstallTest.php
+++ b/tests/src/Functional/UninstallTest.php
@@ -75,7 +75,7 @@ class UninstallTest extends BrowserTestBase {
     $this->assertSession()->pageTextContains('There are 0 fillpdf form field entities to delete');
 
     // Now go back to the uninstall page and uninstall fillpdf_test and fillpdf.
-    foreach (['fillpdf_test', 'fillpdf_legacy', 'fillpdf'] as $module) {
+    foreach (['fillpdf_test', 'fillpdf'] as $module) {
       $this->drupalPostForm(Url::fromRoute('system.modules_uninstall'), ["uninstall[$module]" => TRUE], 'Uninstall');
       $this->assertSession()->pageTextContains('The following modules will be completely uninstalled from your site, and all data from these modules will be lost');
       $this->drupalPostForm(NULL, [], 'Uninstall');
diff --git a/tests/src/Unit/FieldMapping/ImageFieldMappingTest.php b/tests/src/Unit/FieldMapping/ImageFieldMappingTest.php
index 9a7b61f..3d7a9dc 100644
--- a/tests/src/Unit/FieldMapping/ImageFieldMappingTest.php
+++ b/tests/src/Unit/FieldMapping/ImageFieldMappingTest.php
@@ -21,7 +21,7 @@ class ImageFieldMappingTest extends UnitTestCase {
     $image_field_mapping = new ImageFieldMapping('Dummy image', 'jpg');
     self::assertInstanceOf(ImageFieldMapping::class, $image_field_mapping);
 
-    $this->setExpectedException(\InvalidArgumentException::class);
+    $this->expectException(\InvalidArgumentException::class);
     new ImageFieldMapping('Dummy image', 'bmp');
   }
 
-- 
GitLab