View source
<?php
namespace Drupal\hubspot\Plugin\WebformHandler;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\WebformSubmissionInterface;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use Symfony\Component\DependencyInjection\ContainerInterface;
class HubspotWebformHandler extends WebformHandlerBase {
protected $entityTypeManager;
protected $mailManager;
protected $hubspot;
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->entityTypeManager = $container
->get('entity_type.manager');
$instance->mailManager = $container
->get('plugin.manager.mail');
$instance->hubspot = $container
->get('hubspot.hubspot');
return $instance;
}
public function getSummary() : array {
return [];
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) : array {
if (!$this->hubspot
->isConfigured()) {
$form['mapping']['notice'] = [
'#type' => 'item',
'#title' => $this
->t('Notice'),
'#markup' => $this
->t('Your site account is not connected to a Hubspot account, please @admin_link first.', [
'@admin_link' => Link::createFromRoute('connect to Hubspot', 'hubspot.admin_settings'),
]),
];
return $form;
}
$settings = $this
->getSettings();
$default_hubspot_guid = $settings['form_guid'] ?? NULL;
$this->webform = $this
->getWebform();
$form['mapping'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Field Mapping'),
];
$options = [
'--donotmap--' => 'Do Not Map',
];
try {
$hubspot_forms = $this->hubspot
->getHubspotForms();
} catch (GuzzleException $e) {
$this
->messenger()
->addWarning('Unable to load hubspot form info.');
return $form;
}
$hubspot_forms = array_column($hubspot_forms, NULL, 'guid');
$options = array_column($hubspot_forms, 'name', 'guid');
asort($options, SORT_STRING | SORT_FLAG_CASE);
$form['mapping']['hubspot_form'] = [
'#type' => 'select',
'#title' => $this
->t('Choose a hubspot form:'),
'#options' => $options,
'#default_value' => $default_hubspot_guid,
'#ajax' => [
'callback' => [
$this,
'showWebformFields',
],
'event' => 'change',
'wrapper' => 'field_mapping_list',
],
];
$form['mapping']['original_hubspot_id'] = [
'#type' => 'hidden',
'#value' => $default_hubspot_guid,
];
$form['mapping']['field_group'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Fields to map for form: @label', [
'@label' => $this->webform
->label(),
]),
'#states' => [
'invisible' => [
':input[name="settings[mapping][hubspot_form]"]' => [
'value' => '--donotmap--',
],
],
],
];
$form['mapping']['field_group']['fields'] = [
'#type' => 'container',
'#prefix' => '<div id="field_mapping_list">',
'#suffix' => '</div>',
'#markup' => '',
];
$form_values = $form_state
->getValues();
if (!empty($form_values['mapping']['hubspot_form']) || !empty($default_hubspot_guid)) {
$exclude_elements = [
'webform_actions',
'webform_flexbox',
'webform_markup',
'webform_more',
'webform_section',
'webform_wizard_page',
'webform_message',
'webform_horizontal_rule',
'webform_terms_of_service',
'webform_computed_token',
'webform_computed_twig',
'webform_element',
'processed_text',
'captcha',
'container',
'details',
'fieldset',
'item',
'label',
];
if (!empty($form_values['mapping']['hubspot_form'])) {
$hubspot_guid = $form_values['mapping']['hubspot_form'];
}
else {
$hubspot_guid = $default_hubspot_guid;
}
$hubspot_fields = $hubspot_forms[$hubspot_guid] ?? [];
$options = [
'--donotmap--' => 'Do Not Map',
];
foreach ($hubspot_fields['formFieldGroups'] as $hubspot_field) {
foreach ($hubspot_field['fields'] as $field) {
$options[$field['name']] = $field['label'];
}
}
$components = $this->webform
->getElementsInitializedAndFlattened();
foreach ($components as $webform_field => $value) {
if (!in_array($value['#type'], $exclude_elements)) {
if ($value['#webform_composite']) {
foreach ($value['#webform_composite_elements'] as $composite_field => $composite_value) {
$key = $webform_field . ':' . $composite_field;
$form['mapping']['field_group']['fields'][$key] = [
'#title' => (@$webform_field . ':' . $composite_value['#title'] ?: $key) . ' (' . $composite_value['#type'] . ')',
'#type' => 'select',
'#options' => $options,
];
if (isset($settings['field_mapping'][$key])) {
$form['mapping']['field_group']['fields'][$key]['#default_value'] = $settings['field_mapping'][$key];
}
}
}
else {
$form['mapping']['field_group']['fields'][$webform_field] = [
'#title' => (@$value['#title'] ?: $webform_field) . ' (' . $value['#type'] . ')',
'#type' => 'select',
'#options' => $options,
];
if (isset($settings['field_mapping'][$webform_field])) {
$form['mapping']['field_group']['fields'][$webform_field]['#default_value'] = $settings['field_mapping'][$webform_field];
}
}
}
}
}
return $form;
}
public function showWebformFields(array $form, FormStateInterface $form_state) : array {
return $form['settings']['mapping']['field_group']['fields'];
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
if (!$this->hubspot
->isConfigured()) {
return;
}
$hubspot_id = $form_state
->getValues()['mapping']['hubspot_form'];
$fields = $form_state
->getValues()['mapping']['field_group']['fields'];
$settings = [];
if ($hubspot_id != '--donotmap--') {
$settings['form_guid'] = $hubspot_id;
$settings['field_mapping'] = array_filter($fields, function ($hubspot_field) {
return $hubspot_field !== '--donotmap--';
});
$this
->messenger()
->addMessage($this
->t('Saved new field mapping.'));
}
$this
->setSettings($settings);
}
public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
$operation = $update ? 'update' : 'insert';
$this
->remotePost($operation, $webform_submission);
}
public function getSettings() : array {
$configuration = $this
->getConfiguration();
return $configuration['settings'] ?? [];
}
public function setSettings(array $settings) {
$configuration = $this
->getConfiguration();
$configuration['settings'] = $settings;
$this
->setConfiguration($configuration);
}
protected function remotePost($operation, WebformSubmissionInterface $webform_submission) {
$request_post_data = $this
->getPostData($operation, $webform_submission);
$entity_type = $request_post_data['entity_type'];
$context = [];
$webform = $this
->getWebform();
$elements = $webform
->getElementsDecodedAndFlattened();
foreach ($elements as $component_key => $component) {
if ($component['#type'] == 'checkbox') {
$webform_submission
->setElementData($component_key, $webform_submission
->getElementData($component_key) ? 'true' : 'false');
}
}
if ($entity_type) {
$entity_storage = $this->entityTypeManager
->getStorage($entity_type);
$entity = $entity_storage
->load($request_post_data['entity_id']);
$form_title = $entity
->label();
$context['pageUrl'] = Url::fromUserInput($request_post_data['uri'], [
'absolute' => TRUE,
])
->toString();
}
else {
$form_title = $this
->getWebform()
->label();
$context['pageUrl'] = $this->webform
->toUrl('canonical', [
'absolute' => TRUE,
])
->toString();
}
$settings = $this
->getSettings();
$form_guid = $settings['form_guid'];
$field_mapping = $settings['field_mapping'];
$webform_values = $webform_submission
->getData();
$form_values = [];
foreach ($field_mapping as $webform_path => $hubspot_field) {
if ($hubspot_field != '--donotmap--') {
if (strpos($webform_path, ':') !== FALSE) {
$composite = explode(':', $webform_path);
$composite_value = NestedArray::getValue($webform_values, $composite);
$form_values[$hubspot_field] = $composite_value;
}
else {
$form_values[$hubspot_field] = $webform_values[$webform_path];
}
}
}
try {
$hubspot_response = $this->hubspot
->submitHubspotForm($form_guid, $form_values, $context);
$response = $hubspot_response['response'] ?? NULL;
$config = $this->configFactory
->get('hubspot.settings');
$hubspot_url = 'https://app.hubspot.com';
$to = $config
->get('hubspot_debug_email');
$default_language = \Drupal::languageManager()
->getDefaultLanguage()
->getId();
$from = $config
->get('site_mail');
if ($response) {
$data = (string) $response
->getBody();
if ($response
->getStatusCode() == '200' || $response
->getStatusCode() == '204') {
$this->loggerFactory
->get('HubSpot')
->notice('Webform "@form" results successfully submitted to HubSpot.', [
'@form' => $form_title,
]);
}
else {
$this->loggerFactory
->get('HubSpot')
->notice('HTTP notice when submitting HubSpot data from Webform "@form". @code: <pre>@msg</pre>', [
'@form' => $form_title,
'@code' => $response
->getStatusCode(),
'@msg' => $response
->getBody()
->getContents(),
]);
}
if ($config
->get('hubspot_debug_on')) {
$this->mailManager
->mail('hubspot', 'hub_error', $to, $default_language, [
'errormsg' => $data,
'hubspot_url' => $hubspot_url,
'node_title' => $form_title,
], $from);
}
}
else {
$this->loggerFactory
->get('HubSpot')
->notice('HTTP error when submitting HubSpot data from Webform "@form": <pre>@msg</pre>', [
'@form' => $form_title,
'@msg' => $hubspot_response['error'],
]);
}
} catch (RequestException $e) {
$this->loggerFactory
->get('HubSpot')
->notice('HTTP error when submitting HubSpot data from Webform "@form": <pre>@error</pre>', [
'@form' => $form_title,
'@error' => $e
->getResponse()
->getBody()
->getContents(),
]);
watchdog_exception('HubSpot', $e);
} catch (GuzzleException $e) {
$this->loggerFactory
->get('HubSpot')
->notice('HTTP error when submitting HubSpot data from Webform "@form": <pre>@error</pre>', [
'@form' => $form_title,
'@error' => $e
->getMessage(),
]);
watchdog_exception('HubSpot', $e);
}
}
protected function getPostData($operation, WebformSubmissionInterface $webform_submission) {
$data = $webform_submission
->toArray(TRUE);
$data = $data['data'] + $data;
unset($data['data']);
return $data;
}
}