Skip to content
Snippets Groups Projects
Commit 0443439e authored by Kevin Kaland's avatar Kevin Kaland
Browse files

Issue #2359213: Port import/export form.

parent b354da5c
No related branches found
No related tags found
No related merge requests found
...@@ -9,3 +9,4 @@ dependencies: ...@@ -9,3 +9,4 @@ dependencies:
- link - link
- token - token
- views - views
- serialization
...@@ -101,3 +101,10 @@ function fillpdf_update_8104() { ...@@ -101,3 +101,10 @@ function fillpdf_update_8104() {
->setDescription(FillPdfAdminFormHelper::getReplacementsDescription()); ->setDescription(FillPdfAdminFormHelper::getReplacementsDescription());
$edum->installFieldStorageDefinition('replacements', 'fillpdf_form', 'fillpdf_form', $replacements); $edum->installFieldStorageDefinition('replacements', 'fillpdf_form', 'fillpdf_form', $replacements);
} }
/**
* Enable Serialization module.
*/
function fillpdf_update_8105() {
\Drupal::getContainer()->get('module_installer')->install(['serialization']);
}
...@@ -46,6 +46,26 @@ entity.fillpdf_form.delete_form: ...@@ -46,6 +46,26 @@ entity.fillpdf_form.delete_form:
options: options:
_admin_route: TRUE _admin_route: TRUE
entity.fillpdf_form.export_form:
path: '/admin/structure/fillpdf/{fillpdf_form}/export'
defaults:
_entity_form: fillpdf_form.export
_title: 'Export FillPDF form configuration and field mappings'
requirements:
_entity_access: fillpdf_form.view
options:
_admin_route: TRUE
entity.fillpdf_form.import_form:
path: '/admin/structure/fillpdf/{fillpdf_form}/import'
defaults:
_entity_form: fillpdf_form.import
_title: 'Import FillPDF form configuration and field mappings'
requirements:
_entity_access: fillpdf_form.view
options:
_admin_route: TRUE
entity.fillpdf_form_field.edit_form: entity.fillpdf_form_field.edit_form:
path: '/admin/structure/fillpdf/{fillpdf_form}/{fillpdf_form_field}' path: '/admin/structure/fillpdf/{fillpdf_form}/{fillpdf_form_field}'
defaults: defaults:
......
...@@ -37,3 +37,6 @@ services: ...@@ -37,3 +37,6 @@ services:
class: Drupal\fillpdf\TokenResolver class: Drupal\fillpdf\TokenResolver
arguments: ["@token"] arguments: ["@token"]
fillpdf.entity_helper:
class: Drupal\fillpdf\EntityHelper
arguments: ["@entity.query"]
...@@ -8,11 +8,9 @@ namespace Drupal\fillpdf\Controller; ...@@ -8,11 +8,9 @@ namespace Drupal\fillpdf\Controller;
use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Utility\Token;
use Drupal\fillpdf\Component\Helper\FillPdfMappingHelper; use Drupal\fillpdf\Component\Helper\FillPdfMappingHelper;
use Drupal\fillpdf\Entity\FillPdfForm; use Drupal\fillpdf\Entity\FillPdfForm;
use Drupal\fillpdf\Entity\FillPdfFormField; use Drupal\fillpdf\EntityHelper;
use Drupal\fillpdf\FillPdfBackendManager; use Drupal\fillpdf\FillPdfBackendManager;
use Drupal\fillpdf\FillPdfBackendPluginInterface; use Drupal\fillpdf\FillPdfBackendPluginInterface;
use Drupal\fillpdf\FillPdfContextManagerInterface; use Drupal\fillpdf\FillPdfContextManagerInterface;
...@@ -37,8 +35,8 @@ class HandlePdfController extends ControllerBase { ...@@ -37,8 +35,8 @@ class HandlePdfController extends ControllerBase {
/** @var FillPdfBackendManager $backendManager */ /** @var FillPdfBackendManager $backendManager */
protected $backendManager; protected $backendManager;
/** @var QueryFactory $entityQuery */ /** @var EntityHelper */
protected $entityQuery; protected $entityHelper;
/** @var FillPdfContextManagerInterface $contextManager */ /** @var FillPdfContextManagerInterface $contextManager */
protected $contextManager; protected $contextManager;
...@@ -46,14 +44,14 @@ class HandlePdfController extends ControllerBase { ...@@ -46,14 +44,14 @@ class HandlePdfController extends ControllerBase {
/** @var TokenResolverInterface */ /** @var TokenResolverInterface */
protected $tokenResolver; protected $tokenResolver;
public function __construct(FillPdfLinkManipulatorInterface $link_manipulator, FillPdfContextManagerInterface $context_manager, TokenResolverInterface $token_resolver, RequestStack $request_stack, FillPdfBackendManager $backend_manager, FillPdfActionPluginManager $action_manager, QueryFactory $entity_query) { public function __construct(FillPdfLinkManipulatorInterface $link_manipulator, FillPdfContextManagerInterface $context_manager, EntityHelper $entity_helper, TokenResolverInterface $token_resolver, RequestStack $request_stack, FillPdfBackendManager $backend_manager, FillPdfActionPluginManager $action_manager) {
$this->linkManipulator = $link_manipulator; $this->linkManipulator = $link_manipulator;
$this->contextManager = $context_manager; $this->contextManager = $context_manager;
$this->tokenResolver = $token_resolver; $this->tokenResolver = $token_resolver;
$this->requestStack = $request_stack; $this->requestStack = $request_stack;
$this->backendManager = $backend_manager; $this->backendManager = $backend_manager;
$this->actionManager = $action_manager; $this->actionManager = $action_manager;
$this->entityQuery = $entity_query; $this->entityHelper = $entity_helper;
} }
/** /**
...@@ -63,6 +61,7 @@ class HandlePdfController extends ControllerBase { ...@@ -63,6 +61,7 @@ class HandlePdfController extends ControllerBase {
return new static( return new static(
$container->get('fillpdf.link_manipulator'), $container->get('fillpdf.link_manipulator'),
$container->get('fillpdf.context_manager'), $container->get('fillpdf.context_manager'),
$container->get('fillpdf.entity_helper'),
$container->get('fillpdf.token_resolver'), $container->get('fillpdf.token_resolver'),
$container->get('request_stack'), $container->get('request_stack'),
$container->get('plugin.manager.fillpdf_backend'), $container->get('plugin.manager.fillpdf_backend'),
...@@ -90,10 +89,7 @@ class HandlePdfController extends ControllerBase { ...@@ -90,10 +89,7 @@ class HandlePdfController extends ControllerBase {
return new RedirectResponse('/'); return new RedirectResponse('/');
} }
$fields = FillPdfFormField::loadMultiple( $fields = $this->entityHelper->getFormFields($fillpdf_form);
$this->entityQuery->get('fillpdf_form_field')
->condition('fillpdf_form', $fillpdf_form->id())
->execute());
// Populate entities array based on what user passed in // Populate entities array based on what user passed in
$entities = $this->contextManager->loadEntities($context); $entities = $this->contextManager->loadEntities($context);
......
...@@ -26,6 +26,8 @@ use Drupal\fillpdf\Service\FillPdfAdminFormHelper; ...@@ -26,6 +26,8 @@ use Drupal\fillpdf\Service\FillPdfAdminFormHelper;
* "form" = { * "form" = {
* "edit" = "Drupal\fillpdf\Form\FillPdfFormForm", * "edit" = "Drupal\fillpdf\Form\FillPdfFormForm",
* "delete" = "Drupal\fillpdf\Form\FillPdfFormDeleteForm", * "delete" = "Drupal\fillpdf\Form\FillPdfFormDeleteForm",
* "export" = "Drupal\fillpdf\Form\FillPdfFormExportForm",
* "import" = "Drupal\fillpdf\Form\FillPdfFormImportForm",
* }, * },
* "access" = "Drupal\fillpdf\FillPdfFormAccessControlHandler", * "access" = "Drupal\fillpdf\FillPdfFormAccessControlHandler",
* }, * },
......
<?php
/**
* @file
* Contains \Drupal\fillpdf\EntityHelper.
*/
namespace Drupal\fillpdf;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\fillpdf\Entity\FillPdfFormField;
/**
* Class EntityHelper.
*
* @package Drupal\fillpdf
*/
class EntityHelper implements EntityHelperInterface {
/**
* Drupal\Core\Entity\Query\QueryFactory definition.
*
* @var \Drupal\Core\Entity\Query\QueryFactory
*/
protected $entityQuery;
/**
* Constructor.
*/
public function __construct(QueryFactory $entity_query) {
$this->entityQuery = $entity_query;
}
public function getFormFields(FillPdfFormInterface $fillpdf_form) {
return FillPdfFormField::loadMultiple(
$this->entityQuery->get('fillpdf_form_field')
->condition('fillpdf_form', $fillpdf_form->id())
->execute());
}
}
<?php
/**
* @file
* Contains \Drupal\fillpdf\EntityHelperInterface.
*/
namespace Drupal\fillpdf;
/**
* Interface EntityHelperInterface.
*
* @package Drupal\fillpdf
*/
interface EntityHelperInterface {
}
<?php
/**
* @file
* Contains \Drupal\fillpdf\Form\FillPdfFormExportForm.
*/
namespace Drupal\fillpdf\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\fillpdf\EntityHelper;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\Serializer;
class FillPdfFormExportForm extends EntityForm {
/** @var \Symfony\Component\Serializer\Serializer */
protected $serializer;
/** @var \Drupal\fillpdf\EntityHelper */
protected $entityHelper;
public function __construct(Serializer $serializer, EntityHelper $entity_helper) {
$this->serializer = $serializer;
$this->entityHelper = $entity_helper;
}
public static function create(ContainerInterface $container) {
return new static($container->get('serializer'), $container->get('fillpdf.entity_helper'));
}
public function form(array $form, FormStateInterface $form_state) {
parent::form($form, $form_state);
$entity = $this->getEntity();
$fields = $this->entityHelper->getFormFields($entity);
$form_config = array(
'form' => $this->serializer->normalize($entity),
'fields' => $this->serializer->normalize($fields),
);
$code = $this->serializer->serialize($form_config, 'json');
$form = array();
$form['export'] = array(
'#type' => 'textarea',
'#title' => t('FillPDF form configuration and mappings'),
'#default_value' => $code,
'#rows' => 30,
'#description' => t('Copy this code and then on the site you want to import to, go to the Edit page for the FillPDF form for which you want to import these mappings, and paste it in there.'),
'#attributes' => array(
'style' => 'width: 97%;',
),
);
return $form;
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
unset($form['actions']);
$form['#after_build'] = [];
return $form;
}
}
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
namespace Drupal\fillpdf\Form; namespace Drupal\fillpdf\Form;
use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File; use Drupal\file\Entity\File;
use Drupal\file\FileInterface; use Drupal\file\FileInterface;
...@@ -20,14 +21,17 @@ class FillPdfFormForm extends ContentEntityForm { ...@@ -20,14 +21,17 @@ class FillPdfFormForm extends ContentEntityForm {
protected $adminFormHelper; protected $adminFormHelper;
protected $linkManipulator; protected $linkManipulator;
public function __construct(FillPdfAdminFormHelperInterface $admin_form_helper, public function __construct(EntityManagerInterface $entity_manager, FillPdfAdminFormHelperInterface $admin_form_helper,
FillPdfLinkManipulatorInterface $link_manipulator) { FillPdfLinkManipulatorInterface $link_manipulator) {
$this->entityManager = $entity_manager;
parent::__construct($this->entityManager);
$this->adminFormHelper = $admin_form_helper; $this->adminFormHelper = $admin_form_helper;
$this->linkManipulator = $link_manipulator; $this->linkManipulator = $link_manipulator;
} }
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
return new static( return new static(
$container->get('entity.manager'),
$container->get('fillpdf.admin_form_helper'), $container->get('fillpdf.admin_form_helper'),
$container->get('fillpdf.link_manipulator') $container->get('fillpdf.link_manipulator')
); );
......
<?php
/**
* @file
* Contains \Drupal\fillpdf\Form\FillPdfFormImportForm.
*/
namespace Drupal\fillpdf\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\fillpdf\EntityHelper;
use Drupal\fillpdf\FillPdfFormFieldInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\SerializerInterface;
class FillPdfFormImportForm extends EntityForm {
/** @var \Drupal\serialization\Normalizer\ContentEntityNormalizer */
protected $serializer;
/** @var \Drupal\fillpdf\EntityHelper */
protected $entityHelper;
public function __construct(SerializerInterface $serializer, EntityHelper $entity_helper) {
$this->serializer = $serializer;
$this->entityHelper = $entity_helper;
}
public static function create(ContainerInterface $container) {
return new static($container->get('serializer'), $container->get('fillpdf.entity_helper'));
}
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$entity = $this->getEntity();
$form['paste'] = [
'#type' => 'details',
'#title' => t('Paste code'),
'#open' => TRUE,
];
$form['paste']['code'] = [
'#type' => 'textarea',
'#default_value' => '',
'#rows' => 30,
'#description' => $this->t('Cut and paste the results of a <em>FillPDF configuration and mappings export</em> here.'),
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Import'),
];
return $form;
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
unset($form['actions']);
$form['#after_build'] = [];
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$code = $form_state->getValue('code');
$mappings_raw = json_decode($code, TRUE);
$fillpdf_form = $this->serializer->denormalize($mappings_raw['form'], 'Drupal\fillpdf\Entity\FillPdfForm');
// Denormalization is a pain; we had to iterate over the fields to actually
// recompose the $fields array.
$field_json = $mappings_raw['fields'];
$fields = [];
foreach ($field_json as $id => $normalized_field) {
$field = $this->serializer->denormalize($normalized_field, 'Drupal\fillpdf\Entity\FillPdfFormField');
$fields[$field->pdf_key->value] = $field;
}
if (!is_object($fillpdf_form) || !count($fields)) {
$form_state->setErrorByName('code', $this->t('There was a problem processing your FillPDF form code. Please do a fresh export from the source and try pasting it again.'));
}
else {
$form_state->setValue('mappings', [
'form' => $fillpdf_form,
'fields' => $fields,
]);
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->cleanValues();
/** @var \Drupal\fillpdf\FillPdfFormInterface $fillpdf_form */
$fillpdf_form = $this->getEntity();
$mappings = $form_state->getValue('mappings');
/** @var \Drupal\fillpdf\FillPdfFormInterface $imported_form */
$imported_form = $mappings['form'];
/** @var array $imported_fields */
$imported_fields = $mappings['fields'];
// Key the existing FillPDF fields on PDF keys.
$existing_fields = $this->entityHelper->getFormFields($fillpdf_form);
$existing_fields_by_key = [];
foreach ($existing_fields as $existing_field) {
$existing_fields_by_key[$existing_field->pdf_key->value] = $existing_field;
}
// Iterate over FillPdfForm fields and copy them, EXCEPT for IDs and references.
$fillpdf_form_type = $this->entityTypeManager->getDefinition('fillpdf_form');
$form_fields_to_ignore = array_filter(array_values($fillpdf_form_type->getKeys()));
$form_fields_to_ignore[] = 'file';
foreach ($imported_form->getFields() as $name => $data) {
if (!in_array($name, $form_fields_to_ignore, TRUE)) {
$fillpdf_form->{$name} = $data;
}
}
$fillpdf_form->save();
drupal_set_message($this->t('Successfully imported FillPDF form configuration.'));
// Iterate over each FillPdfFormField and override matching PDF keys
// (if any current fields have them).
$fillpdf_field_type = $this->entityTypeManager->getDefinition('fillpdf_form_field');
$field_fields_to_ignore = array_filter(array_values($fillpdf_field_type->getKeys()));
$field_fields_to_ignore[] = 'fillpdf_form';
$existing_field_pdf_keys = array_keys($existing_fields_by_key);
/**
* @var string $pdf_key
* @var FillPdfFormFieldInterface $imported_field
*/
foreach ($imported_fields as $pdf_key => $imported_field) {
// If the imported field's PDF key matching the PDF key of the
// existing field, then copy the constituent entity fields.
// I know: they're both called fields. It's confusing as hell.
// I am sorry.
if (in_array($pdf_key, $existing_field_pdf_keys, TRUE)) {
/** @var FillPdfFormFieldInterface $existing_field_by_key */
$existing_field_by_key = $existing_fields_by_key[$pdf_key];
foreach ($imported_field->getFields() as $imported_field_name => $imported_field_data) {
if (!in_array($imported_field_name, $field_fields_to_ignore, TRUE)) {
$existing_field_by_key->{$imported_field_name} = $imported_field_data;
}
}
$existing_field_by_key->save();
}
else {
drupal_set_message($this->t('Your code contained field mappings for the PDF field key <em>@pdf_key</em>, but it does not exist on this form. Therefore, it was ignored.', ['@pdf_key' => $pdf_key]), 'warning');
}
}
drupal_set_message($this->t('Successfully imported matching PDF field keys. If any field mappings failed to import, they are listed above.'));
$form_state->setRedirect('entity.fillpdf_form.edit_form', ['fillpdf_form' => $fillpdf_form->id()]);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment