Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rasben committed Dec 9, 2024
1 parent 3de8a72 commit 45c5b00
Show file tree
Hide file tree
Showing 10 changed files with 303 additions and 2 deletions.
1 change: 1 addition & 0 deletions config/sync/core.extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module:
basic_auth: 0
better_exposed_filters: 0
block: 0
bnf: 0
breakpoint: 0
ckeditor5: 0
collation_fixer: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ name: 'BNF Common'
type: module
description: 'Common code between BNF (Bibliotekernes Nationale Formidling) client and server modules'
package: 'DPL - BNF'
# It doesn't make sense to enable this module on its own.
hidden: true
core_version_requirement: ^10
61 changes: 61 additions & 0 deletions web/modules/custom/bnf/bnf_client/bnf_client.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\node\NodeInterface;

/**
* Implements hook_form_FORM_ID_alter().
*/
function bnf_client_form_node_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void
{
$current_user = \Drupal::currentUser();

if (!$current_user->hasPermission('bnf client export nodes')) {
return;
}

$form['bnf'] = [
'#type' => 'details',
'#title' => t('BNF Client'),
'#open' => TRUE,
'bnf_confirm' => [
'#type' => 'checkbox',
'#title' => t('Assets are cleared to share'),
'#description' => t('All content and media as part of this article is cleared to be shared among other libraries'),
'#default_value' => FALSE,
],
'bnf_submit' => [
'#type' => 'submit',
'#value' => 'Save, publish and send to BNF',
'#submit' => [
'bnf_client_form_node_form_submit'
],
'#states' => [
'disabled' => [':input[name="bnf_confirm"]' => ['checked' => FALSE]],
]
]
];
}

function bnf_client_form_node_form_submit(array $form, FormStateInterface $form_state): void {
// Publishing the node. It needs to be done as a userinput, because it
// is the only way you can alter data in a form submit.
$user_inputs = $form_state->getUserInput();
$user_inputs['status']['value'] = NodeInterface::PUBLISHED;
$form_state->setUserInput($user_inputs);


if (true) {}
/** @var NodeInterface $node */
$node = $form_state->getformObject()->getEntity();

// After the form has been submitted, redirect to the BNF pinger, that will
// tell BNF that this node should be imported.
$url = Url::fromRoute('bnf_client.export', ['uuid' => $node->uuid()]);
$form_state->setRedirectUrl($url);

//$form_state->setRebuild();

\Drupal::service('messenger')->addMessage("Hello :)");
}
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
@@ -0,0 +1,2 @@
bnf client export nodes:
title: 'Can export nodes to BNF'
6 changes: 6 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,6 @@
bnf_client.export:
path: '/admin/bnf/export/{uuid}'
defaults:
_controller: '\Drupal\bnf_client\Controller\Exporter::exportNode'
requirements:
_permission: 'bnf client export nodes'
77 changes: 77 additions & 0 deletions web/modules/custom/bnf/bnf_client/src/Controller/Exporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Drupal\bnf_client\Controller;

use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\RedirectResponse;
use GuzzleHttp\Client;
use Symfony\Component\HttpFoundation\Response;

class Exporter extends ControllerBase {

/**
* HTTP client.
*
* @var \GuzzleHttp\Client
*/
protected $httpClient;

/**
* Constructs a new ChatService object.
*/
public function __construct(
Client $http_client,
) {
$this->httpClient = $http_client;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('http_client'),
);
}


public function exportNode(string $uuid): RedirectResponse {

// @todo
$callback_url = 'http://varnish.dpl-cms.orb.local/graphql';

$mutation = <<<GRAPHQL
mutation {
receiveClientPing(uuid: "$uuid", callbackUrl: "$callback_url") {
status
message
}
}
GRAPHQL;

// @todo
$bnf_server = $callback_url;

try {
$this->httpClient->post($bnf_server, [
'headers' => [
'Content-Type' => 'application/json',
],
'auth' => ['external_system', 'test'],
'json' => [
'query' => $mutation,
],
]);

$this->messenger()->addStatus($this->t('Content created.'));
}
catch (\Exception $e) {
$this->messenger()->addError($e->getMessage());
}


return new RedirectResponse(Url::fromRoute('system.admin_content')->toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Base file, necessary for GraphQL module to load our extension.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extend type Mutation {
receiveClientPing(uuid: String!, callbackUrl: String!): PingResponse
}

type PingResponse {
status: String
message: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

namespace Drupal\bnf_server\Plugin\GraphQL\DataProducer;

use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase;
use Drupal\node\Entity\Node;
use GuzzleHttp\Client;

/**
* Resolves the `receiveClientPing` mutation.
*
* @DataProducer(
* id = "receive_client_ping_producer",
* name = "Receive Client Ping Producer",
* description = "Handles the receiveClientPing mutation.",
* produces = @ContextDefinition("any",
* label = "Ping Response"
* ),
* consumes = {
* "uuid" = @ContextDefinition("string",
* label = "UUID"
* ),
* "callbackUrl" = @ContextDefinition("string",
* label = "Callback URL"
* )
* }
* )
*/
class ReceiveClientPingProducer extends DataProducerPluginBase {

/**
* Resolves the mutation.
*
* @param string $uuid
* The client UUID.
* @param string $callbackUrl
* The callback URL.
*
* @return array
* The response data.
*/
public function resolve(string $uuid, string $callbackUrl): array {
\Drupal::logger('bnf_server')->info('Received ping from UUID: @uuid with callback URL: @callbackUrl', [
'@uuid' => $uuid,
'@callbackUrl' => $callbackUrl,
]);

// For now, we only support articles. In the future, this should be
// sent along as a parameter, as GraphQL exposes different queries
// for each node type (nodeArticle)
$node_type = 'article';
$query_name = 'node' . ucfirst($node_type);

// For now, we only support the title of the nodes.
$query = <<<GRAPHQL
query {
$query_name(id: "$uuid") {
title
}
}
GRAPHQL;

$client = new Client();
try {
$response = $client->post($callbackUrl, [
'headers' => [
'Content-Type' => 'application/json',
],
'auth' => ['external_system', 'test'],
'json' => [
'query' => $query,
],
]);

$data = json_decode($response->getBody()->getContents(), TRUE);
$node_data = $data['data'][$query_name] ?? NULL;

if (empty($node_data)) {
throw new \Exception('Could not retrieve node data.');
}

$node_data['type'] = $node_type;

$node = Node::create($node_data);
$node->save();



if (true) {}
} catch (\Exception $e) {
\Drupal::logger('bnf_server')->warning('Could not load node of type @node_type with UUID @uuid at @callbackUrl', [
'@uuid' => $uuid,
'@node_type' => $node_type,
'@callbackUrl' => $callbackUrl,
]);

return [
'status' => 'failure',
'message' => 'Could not load node from callback URL.',
];


}


\Drupal::logger('bnf_server')->info('Created new @node_type node with BNF ID @uuid', [
'@uuid' => $uuid,
'@node_type' => $node_type,
]);

return [
'status' => 'success',
'message' => 'Node created successfully.',
];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Drupal\bnf_server\Plugin\GraphQL\SchemaExtension;

use Drupal\graphql\GraphQL\ResolverBuilder;
use Drupal\graphql\GraphQL\ResolverRegistryInterface;
use Drupal\graphql\Plugin\GraphQL\SchemaExtension\SdlSchemaExtensionPluginBase;

/**
* @SchemaExtension(
* id = "receive_client_ping_extension",
* name = "Receive Client Ping Extension",
* schema = "graphql_compose"
* )
*/
class ReceiveClientPingExtension extends SdlSchemaExtensionPluginBase {

/**
* Registers the resolvers for the schema.
*/
public function registerResolvers(ResolverRegistryInterface $registry) {
$builder = new ResolverBuilder();
$registry->addFieldResolver('Mutation', 'receiveClientPing',
$builder->produce('receive_client_ping_producer')
->map('uuid', $builder->fromArgument('uuid'))
->map('callbackUrl', $builder->fromArgument('callbackUrl'))
);
}

}

0 comments on commit 45c5b00

Please sign in to comment.