Skip to content

Commit

Permalink
BNF: Library import forms. DDFHER-166
Browse files Browse the repository at this point in the history
Allowing the editor to input either a UUID or URL to a content.
We will then display a preview, where they can see the title.
If they wish to continue, they can import, and the node will
be created, and they will be redirected to the edit form.
  • Loading branch information
rasben committed Dec 23, 2024
1 parent 99a1fd3 commit 39953e0
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 120 deletions.
26 changes: 26 additions & 0 deletions web/modules/custom/bnf/bnf.module
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use Drupal\bnf\BnfStateEnum;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\node\NodeInterface;

/**
* Implements hook_entity_base_field_info().
Expand Down Expand Up @@ -41,3 +42,28 @@ function bnf_get_bnf_state_allowed_values(): array {
}
return $values;
}

/**
* Implements theme_preprocess_html().
*
* Adding the node UUID as a metatag, that we can use when the user submits
* a URL to the BNF import form.
*/
function bnf_preprocess_html(array &$variables): void {
$route = \Drupal::routeMatch();
$node = $route->getParameter('node');

if ($route->getRouteName() !== 'entity.node.canonical' || !($node instanceof NodeInterface)) {
return;
}

$uuid_metatag = [
'#tag' => 'meta',
'#attributes' => [
'name' => 'uuid',
'content' => $node->uuid(),
],
];

$variables['page']['#attached']['html_head'][] = [$uuid_metatag, 'node-uuid'];
}
6 changes: 6 additions & 0 deletions web/modules/custom/bnf/bnf_client/bnf_client.links.menu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
bnf_client.import_content:
title: 'Import BNF content'
parent: system.admin_content
route_name: bnf_client.import_form
weight: 10
2 changes: 2 additions & 0 deletions web/modules/custom/bnf/bnf_client/bnf_client.permissions.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
bnf client export nodes:
title: 'Can export nodes to BNF'
bnf client import nodes:
title: 'Can import nodes from BNF'
16 changes: 16 additions & 0 deletions web/modules/custom/bnf/bnf_client/bnf_client.routing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
bnf_client.import_form:
path: '/admin/bnf/import'
defaults:
_form: '\Drupal\bnf_client\Form\BnfImportForm'
_title: 'Import'
requirements:
_permission: 'bnf client import nodes'

bnf_client.import_confirm_form:
path: '/admin/bnf/import/{uuid}'
defaults:
_form: '\Drupal\bnf_client\Form\BnfImportConfirmForm'
_title: 'Confirm import'
requirements:
_permission: 'bnf client import nodes'
100 changes: 100 additions & 0 deletions web/modules/custom/bnf/bnf_client/src/Form/BnfImportConfirmForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

namespace Drupal\bnf_client\Form;

use Drupal\bnf\Services\BnfImporter;
use Drupal\Core\DependencyInjection\AutowireTrait;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Displaying an import preview, and allowing editor to import.
*/
class BnfImportConfirmForm implements FormInterface, ContainerInjectionInterface {
use StringTranslationTrait;

use AutowireTrait;

/**
* {@inheritDoc}
*/
public function __construct(
protected RouteMatchInterface $routeMatch,
protected BnfImporter $bnfImporter,
) {}

/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container): static {
return new static(
$container->get('current_route_match'),
$container->get('bnf.importer')
);
}

/**
* {@inheritDoc}
*/
public function getFormId(): string {
return 'bnf_import_form_form';
}

/**
* {@inheritDoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$form['#title'] = $this->t('Confirm import of BNF content', [], ['context' => 'BNF']);

$uuid = $this->routeMatch->getParameter('uuid');
$bnfServer = (string) getenv('BNF_SERVER_GRAPHQL_ENDPOINT');

$form_state->set('uuid', $uuid);
$form_state->set('bnfServer', $bnfServer);

$nodeData = $this->bnfImporter->loadNodeData($uuid, $bnfServer);

$form['uuid'] = [
'#title' => 'UUID',
'#type' => 'textfield',
'#default_value' => $uuid,
'#disabled' => TRUE,
];

$form['label'] = [
'#title' => $this->t('Content label', [], ['context' => 'BNF']),
'#type' => 'textfield',
'#default_value' => $nodeData['title'] ?? NULL,
'#disabled' => TRUE,
];

$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Import content'),
];

return $form;
}

/**
* {@inheritDoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {

}

/**
* {@inheritDoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$uuid = $form_state->get('uuid');
$bnfServer = $form_state->get('bnfServer');
$node = $this->bnfImporter->importNode($uuid, $bnfServer);
$form_state->setRedirect('entity.node.edit_form', ['node' => $node->id()]);
}

}
94 changes: 94 additions & 0 deletions web/modules/custom/bnf/bnf_client/src/Form/BnfImportForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace Drupal\bnf_client\Form;

use Drupal\Component\Uuid\Uuid;
use Drupal\Core\DependencyInjection\AutowireTrait;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use function Safe\get_meta_tags;

/**
* An import form, letting editors input URL or UUID from BNF.
*/
class BnfImportForm implements FormInterface, ContainerInjectionInterface {
use StringTranslationTrait;

use AutowireTrait;

/**
* {@inheritDoc}
*/
public function getFormId(): string {
return 'bnf_initial_form';
}

/**
* {@inheritDoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$form['#title'] = $this->t('Import nodes from BNF', [], ['context' => 'BNF']);
$form['reference'] = [
'#type' => 'textfield',
'#title' => $this->t('URL or UUID of content'),
];

$form['actions'] = [
'#type' => 'actions',
];

$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Preview content'),
];

return $form;
}

/**
* {@inheritDoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
$reference = $form_state->getValue('reference');
$uuid = $this->parseAndValidateUuid($reference);

if (empty($uuid)) {
$form_state->setErrorByName(
'reference',
$this->t('Invalid URL or UUID.', [], ['context' => 'BNF'])
);
}

$form_state->set('uuid', $uuid);
}

/**
* {@inheritDoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$uuid = $form_state->get('uuid');
$form_state->setRedirect('bnf_client.import_confirm_form', ['uuid' => $uuid]);
}

/**
* Getting and validate a UUID from string or URL.
*/
protected function parseAndValidateUuid(string $reference): string|false {
try {
// Detect if reference is a URL.
if (filter_var($reference, FILTER_VALIDATE_URL)) {
// Finding the metatag that contains the UUID.
$meta_tags = get_meta_tags($reference);
$reference = $meta_tags['uuid'] ?? NULL;
}

return Uuid::isValid((string) $reference) ? $reference : FALSE;
}
catch (\Exception) {
return FALSE;
}
}

}
Loading

0 comments on commit 39953e0

Please sign in to comment.