You are here

pardot.module in Pardot Integration 2.x

Same filename and directory in other branches
  1. 8 pardot.module
  2. 6 pardot.module
  3. 7.2 pardot.module
  4. 7 pardot.module

Contains pardot.module.

File

pardot.module
View source
<?php

/**
 * @file
 * Contains pardot.module.
 */
use Drupal\contact\MessageForm;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\pardot\FormMap;
use Drupal\pardot\MappedEmailField;
use Drupal\pardot\ToolbarHandler;
use Drupal\webform\Entity\WebformSubmission;
use Drupal\webform\WebformSubmissionForm;
use Drupal\webform\WebformSubmissionInterface;
use GuzzleHttp\Exception\RequestException;

/**
 * Implements hook_help().
 */
function pardot_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the pardot module.
    case 'help.page.pardot':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Module to allow Pardot tracking for Drupal websites.') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_entity_type_alter().
 *
 * @see Drupal\Core\Entity\EntityTypeInterface[]
 */
function pardot_entity_type_alter(array &$entity_types) {
  if (!empty($entity_types['contact_form'])) {
    $entity_types['contact_form']
      ->setLinkTemplate('pardot-form-mapping', "/admin/structure/contact/manage/{contact_form}/pardot-form-settings");
  }
  if (!empty($entity_types['webform'])) {
    $entity_types['webform']
      ->setLinkTemplate('pardot-form-mapping', "/admin/structure/webform/manage/{webform}/pardot-form-settings");
  }
}

/**
 * Implements hook_menu_links_discovered_alter().
 */
function pardot_menu_links_discovered_alter(&$links) {
  $route_provider = \Drupal::service('router.route_provider');
  $bundles = \Drupal::entityTypeManager()
    ->getStorage('contact_form')
    ->loadMultiple();
  $base_plugin_definition = [
    'id' => 'admin_toolbar_tools.extra_links',
  ];
  foreach ($bundles as $machine_name => $bundle) {
    $content_entity_bundle_root = 'entity.contact_form.edit_form.' . $machine_name;

    // Normally, the edit form for the bundle would be its root link.
    $content_entity_bundle = 'contact_form';
    $i = $route_provider
      ->getRoutesByNames([
      'entity.' . $content_entity_bundle . '.pardot_form_mapping',
    ]);
    if (count($route_provider
      ->getRoutesByNames([
      'entity.' . $content_entity_bundle . '.pardot_form_mapping',
    ])) === 1) {
      $links['entity.' . $content_entity_bundle . '.pardot_form_mapping.' . $machine_name] = [
        'title' => t('Pardot Form Mapping'),
        'route_name' => 'entity.' . $content_entity_bundle . '.pardot_form_mapping',
        'parent' => $base_plugin_definition['id'] . ':' . $content_entity_bundle_root,
        'route_parameters' => [
          $content_entity_bundle => $machine_name,
        ],
        'weight' => 4,
      ] + $base_plugin_definition;
    }
  }
}

/**
 * Implements hook_entity_operation_alter().
 */
function pardot_entity_operation_alter(array &$operations, EntityInterface $entity) {
  $has_permission = \Drupal::currentUser()
    ->hasPermission('administer pardot form map');
  $has_link = $entity
    ->hasLinkTemplate('pardot-form-mapping');
  $is_contact_form = $entity
    ->getEntityTypeId() === 'contact_form';
  if ($is_contact_form && $has_link && $has_permission) {
    $operations['pardot-form-mapping'] = [
      'title' => t('Pardot Form Map'),
      'weight' => 100,
      'url' => $entity
        ->toUrl('pardot-form-mapping'),
    ];
  }
}

/**
 * Implements hook_page_attachments().
 *
 * Adds Pardot tracking script with configuration settings when appropriate.
 */
function pardot_page_attachments(array &$page) {

  // Get conditional state variable.
  // @see \Drupal\pardot\EventSubscriber\PardotEventSubscriber
  $include_tracking = (bool) \Drupal::state()
    ->get('pardot.include_tracking') ?: 0;
  $config = \Drupal::config('pardot.settings');
  if ($include_tracking && $config
    ->get('account_id') !== NULL) {

    // Use default campaign ID.
    $campaign_id = $config
      ->get('default_campaign_id');
    $page['#attached']['drupalSettings']['pardot']['accountId'] = $config
      ->get('account_id');
    $page['#attached']['drupalSettings']['pardot']['campaignId'] = $campaign_id;
    $page['#attached']['library'][] = 'pardot/pardot';
  }
}
function pardot_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {

  // Get conditional state variable.
  // @see \Drupal\pardot\EventSubscriber\PardotEventSubscriber
  $include_tracking = (bool) \Drupal::state()
    ->get('pardot.include_tracking') ?: 0;
  $config = \Drupal::config('pardot.settings');
  if (NULL !== $config
    ->get('account_id') && $include_tracking) {
    $bundle = FALSE;
    $form_object = $form_state
      ->getFormObject();
    if ($form_object instanceof WebformSubmissionForm) {
      $bundle = $form_object
        ->getEntity()
        ->bundle();

      /** @var \Drupal\webform\Element\Webform $entity */
      $entity = \Drupal::entityTypeManager()
        ->getStorage('webform')
        ->load($bundle);
      _set_pardot_form_submit($entity, $form, $form_state);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Add submit handler if the contact form has a Pardot mapping.
 */
function pardot_form_contact_message_form_alter(array &$form, FormStateInterface $form_state, $form_id) {

  // Get conditional state variable.
  // @see \Drupal\pardot\EventSubscriber\PardotEventSubscriber
  $include_tracking = (bool) \Drupal::state()
    ->get('pardot.include_tracking') ?: 0;
  $config = \Drupal::config('pardot.settings');
  if (NULL !== $config
    ->get('account_id') && $include_tracking) {
    $bundle = FALSE;
    $form_object = $form_state
      ->getFormObject();
    if ($form_object instanceof MessageForm) {

      /** @var \Drupal\contact\Entity\ContactForm $entity */
      $bundle = $form_object
        ->getEntity()
        ->bundle();
      $entity = \Drupal::entityTypeManager()
        ->getStorage('contact_form')
        ->load($bundle);
      _set_pardot_form_submit($entity, $form, $form_state);
    }
  }
}

/**
 * Set Pardot form submit.
 *
 * @param object $entity
 *   The entity (form) you want to attach the pardot form submit functionality.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   Form state interface.
 *
 * @see pardot_form_contact_message_form_alter()
 */
function _set_pardot_form_submit(object $entity, &$form, FormStateInterface $form_state) {
  $pardot_form_map_plugin = $entity
    ->getThirdPartySetting('pardot', 'pardot_form_mapping_plugin', FALSE);
  if ($pardot_form_map_plugin) {
    $pardot_form_map = new FormMap($pardot_form_map_plugin['settings']);
    if ($pardot_form_map) {
      $storage = $form_state
        ->getStorage();
      $storage['pardot_form_map'] = $pardot_form_map;

      // Add submit handler if we have an enabled contact form mapping.
      $form_state
        ->setStorage($storage);
      $form['actions']['submit']['#submit'][] = '_pardot_form_submit';
    }
  }
}

/**
 * Pardot contact form submit.
 *
 * @param array $form
 *   Form array.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   Form state interface.
 *
 * @see pardot_form_contact_message_form_alter()
 */
function _pardot_form_submit(array &$form, FormStateInterface $form_state) {

  // Retrieve storage, where pardot_mapping was set in
  // pardot_form_contact_message_form_alter().
  $storage = $form_state
    ->getStorage();
  if (isset($storage['pardot_form_map'])) {

    /** @var \Drupal\contact\MessageForm $contact_message */
    $contact_message = $form_state
      ->getFormObject()
      ->getEntity();

    /** @var \Drupal\pardot\Service\PardotClient $pardot_api_client */
    $pardot_api_client = \Drupal::service('pardot.api_client');

    /** @var \Drupal\pardot\FormMap $pardot_form_map */
    $pardot_form_map = $storage['pardot_form_map'];
    $post_url = $pardot_form_map
      ->getPostUrl();
    $field_map_collection = $pardot_form_map
      ->getMappedFieldCollection();
    $visitor_email = '';
    $visitor_id = $pardot_api_client
      ->getVisitorId();
    $query_params = [];
    foreach ($field_map_collection as $field_map) {
      $plugin = $field_map
        ->getPlugin();
      if ($plugin && $plugin
        ->getFormattedValue($form_state)) {
        $value = $plugin
          ->getFormattedValue($form_state);
        $query_params[] = [
          $field_map
            ->getPardotKey() => $value,
        ];
        if ($field_map instanceof MappedEmailField) {
          $visitor_email = $value;
        }
      }
    }

    // Unable to use \Drupal\Component\Utility\UrlHelper::buildQuery() b/c
    // Pardot accepts multiple values using the same parameter key.
    $query_string = '';
    foreach ($query_params as $param) {
      $keys = array_keys($param);
      $key = reset($keys);
      $query_string .= rawurlencode($key) . '=' . str_replace('%2F', '/', rawurlencode($param[$key])) . '&';
    }
    $request_data = [
      'timeout' => 5,
      'query' => $query_string,
    ];
    $result = $pardot_api_client
      ->executePardotOperation($post_url, $request_data);

    // Connect the visitor ID to a prospect ID using the submitted email.
    if ($visitor_email && $visitor_id) {

      // Look up the prospect ID.
      $prospect_id = $pardot_api_client
        ->getPardotProspect($visitor_email);

      // Use the visitor ID to update the prospect.
      $prospect_is_assigned = $pardot_api_client
        ->assignPardotProspect($visitor_id, $prospect_id);
      if (!$prospect_is_assigned) {
        \Drupal::logger('pardot')
          ->error('Unable to assign Pardot prospect. Failure returned from API request.');
      }
    }
  }
}