You are here

mailchimp_signup.module in Mailchimp 7.4

Mailchimp Signup module. Allows creation of signup forms integrated with Mailchimp.

File

modules/mailchimp_signup/mailchimp_signup.module
View source
<?php

/**
 * @file
 * Mailchimp Signup module. Allows creation of signup forms integrated with
 * Mailchimp.
 */
define('MAILCHIMP_SIGNUP_BLOCK', 1);
define('MAILCHIMP_SIGNUP_PAGE', 2);
define('MAILCHIMP_SIGNUP_BOTH', 3);

/**
 * Implements hook_menu().
 */
function mailchimp_signup_menu() {
  $items = array();
  $items['admin/config/services/mailchimp/signup/%mailchimp_signup/edit'] = array(
    'title' => 'Edit a signup form',
    'description' => 'Edit a Signup form.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'mailchimp_signup_signup_form',
      5,
    ),
    'load arguments' => array(
      5,
    ),
    'access arguments' => array(
      'administer mailchimp',
    ),
    'file' => 'includes/mailchimp_signup.admin.inc',
    'type' => MENU_CALLBACK,
  );
  $items['admin/config/services/mailchimp/signup/%mailchimp_signup/delete'] = array(
    'title' => 'Delete Signup form',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'mailchimp_signup_signup_delete_form',
      5,
    ),
    'access arguments' => array(
      'administer mailchimp',
    ),
    'file' => 'includes/mailchimp_signup.admin.inc',
  );
  $signups = mailchimp_signup_load_multiple();
  foreach ($signups as $signup) {
    if (intval($signup->mode) == MAILCHIMP_SIGNUP_PAGE || intval($signup->mode) == MAILCHIMP_SIGNUP_BOTH) {
      $items[$signup->settings['path']] = array(
        'title' => $signup->title,
        'title callback' => 'mailchimp_signup_title',
        'title arguments' => array(
          $signup
            ->identifier(),
        ),
        'page callback' => 'mailchimp_signup_page',
        'page arguments' => array(
          $signup
            ->identifier(),
        ),
        'access callback' => 'user_access',
        'access arguments' => array(
          'access mailchimp signup pages',
        ),
        'type' => MENU_SUGGESTED_ITEM,
      );
    }
  }
  return $items;
}

/**
 * Implements hook_admin_menu_map().
 */
function mailchimp_signup_admin_menu_map() {
  if (!user_access('administer mailchimp signup entities')) {
    return;
  }
  $mailchimp_signups = mailchimp_signup_load_multiple();
  $path = 'admin/config/services/mailchimp/signup/manage/%mailchimp_signup_name';
  $mailchimp_signup_names = array();
  foreach ($mailchimp_signups as $mailchimp_signup) {
    $mailchimp_signup_names[] = $mailchimp_signup->name;
  }
  $map[$path] = array(
    'parent' => 'admin/config/services/mailchimp/signup',
    'arguments' => array(
      array(
        '%mailchimp_signup_name' => $mailchimp_signup_names,
      ),
    ),
  );
  return $map;
}

/**
 * callback function for translatable title
 */
function mailchimp_signup_title($signup_id) {
  $signup = mailchimp_signup_load($signup_id);
  return $signup
    ->getTranslation('title');
}

/**
 * Implements hook_permission().
 */
function mailchimp_signup_permission() {
  $return = array();
  $return['administer mailchimp signup entities'] = array(
    'title' => t('Administer Mailchimp Signup Entities.'),
  );
  $return['access mailchimp signup pages'] = array(
    'title' => t('Access all Mailchimp Signup Pages.'),
    'description' => t('This does not effect Signup Blocks: only Pages.'),
  );
  return $return;
}

/**
 * Implements hook_block_info().
 */
function mailchimp_signup_block_info() {
  $blocks = array();
  $signups = mailchimp_signup_load_multiple();
  foreach ($signups as $signup) {
    if (intval($signup->mode) == MAILCHIMP_SIGNUP_BLOCK || intval($signup->mode) == MAILCHIMP_SIGNUP_BOTH) {
      $blocks[$signup
        ->identifier()] = array(
        'info' => t('Mailchimp Subscription Form: @name', array(
          '@name' => $signup
            ->label(),
        )),
        'cache' => DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE,
      );
    }
  }
  return $blocks;
}

/**
 * Implements hook_block_view().
 *
 * Provides a block for each signup configured to add a block.
 */
function mailchimp_signup_block_view($delta = '') {
  $signup = mailchimp_signup_load($delta);
  if ($signup) {
    $block = array(
      'subject' => check_plain($signup
        ->getTranslation('title')),
      'content' => drupal_get_form('mailchimp_signup_subscribe_block_' . $signup->name . '_form', $signup, 'mailchimp_signup_block'),
    );
  }
  else {
    $block = FALSE;
  }
  return $block;
}

/**
 * Wrapper around mailchimp_signup_load_multiple to load a single signup entity.
 */
function mailchimp_signup_load($signup_id) {
  $signups = mailchimp_signup_load_multiple(array(
    $signup_id,
  ));
  if ($signups) {
    return reset($signups);
  }
  else {
    return FALSE;
  }
}

/**
 * Loads multiple signup forms.
 */
function mailchimp_signup_load_multiple($signup_ids = array(), $conditions = array(), $reset = FALSE) {
  if (empty($signup_ids)) {
    $signup_ids = FALSE;
  }
  return entity_load('mailchimp_signup', $signup_ids, $conditions, $reset);
}

/**
 * Deletes multiple signups by ID.
 *
 * @param array $signup_ids
 *   An array of signup IDs to delete.
 *
 * @return bool
 *   TRUE on success, FALSE otherwise.
 */
function mailchimp_signup_delete_multiple($signup_ids) {
  return entity_get_controller('mailchimp_signup')
    ->delete($signup_ids);
}

/**
 * Gets a single Signup.
 *
 * @param string $name
 *   The Mailchimp signup machine name.
 *
 * @return \MailchimpSignup
 *   A single mailchimp signup object.
 */
function mailchimp_signup_name_load($name) {
  return mailchimp_signup_load_multiple_by_name($name);
}

/**
 * Gets an array of all Signups, keyed by the list name.
 *
 * @param string $name
 *   If set, the signup with the given name is returned.
 *
 * @return MailchimpSignup[]
 *   Depending whether $name isset, an array of signups or a single one.
 */
function mailchimp_signup_load_multiple_by_name($name = NULL) {
  $signups = entity_load_multiple_by_name('mailchimp_signup', isset($name) ? array(
    $name,
  ) : FALSE);
  return isset($name) ? reset($signups) : $signups;
}

/**
 * Implements hook_entity_info().
 */
function mailchimp_signup_entity_info() {
  $entities = array(
    'mailchimp_signup' => array(
      'label' => t('Mailchimp Signup'),
      'plural label' => t('Mailchimp Signups'),
      'entity class' => 'MailchimpSignup',
      'controller class' => 'EntityAPIControllerExportable',
      'base table' => 'mailchimp_signup',
      'uri callback' => 'entity_class_uri',
      'fieldable' => FALSE,
      'exportable' => TRUE,
      'label callback' => 'mailchimp_signup_entity_info_label',
      'module' => 'mailchimp_signup',
      'entity keys' => array(
        'id' => 'mcs_id',
        'name' => 'name',
      ),
      'bundles' => array(
        'mailchimp_signup' => array(
          'label' => t('Mailchimp Signup'),
        ),
      ),
      'view modes' => array(
        'full' => array(
          'label' => t('Full'),
          'custom settings' => FALSE,
        ),
      ),
      // Enable the entity API's admin UI.
      'admin ui' => array(
        'menu wildcard' => '%mailchimp_signup_name',
        'path' => 'admin/config/services/mailchimp/signup',
        'file' => 'includes/mailchimp_signup.admin.inc',
        'controller class' => 'MailChimpSignupUIController',
      ),
      'access callback' => 'mailchimp_signup_entity_access',
    ),
  );
  return $entities;
}

/**
 * Entity label callback.
 */
function mailchimp_signup_entity_info_label($entity, $entity_type) {
  return empty($entity) ? t('New Mailchimp Signup') : $entity
    ->getTranslation('title');
}

/**
 * Access callback for mailchimp_activity_entity.
 */
function mailchimp_signup_entity_access() {
  return mailchimp_apikey_ready_access('administer mailchimp signup entities');
}

/**
 * Menu callback for Signup pages.
 */
function mailchimp_signup_page($signup_id) {
  $signup = mailchimp_signup_load($signup_id);
  return drupal_get_form('mailchimp_signup_subscribe_page_' . $signup_id . '_form', $signup, 'mailchimp_signup_page');
}

/**
 * Implements hook_forms().
 *
 * This allows each subscription form rendering to have a unique form
 * ID. If this weren't the case, multiple forms getting rendered on a single
 * page display would have submit button conflicts.
 */
function mailchimp_signup_forms($form_id, $args) {
  $forms = array();
  if (strpos($form_id, 'mailchimp_') === 0 && isset($args[1])) {
    if ($args[1] == 'mailchimp_signup_page') {
      $forms['mailchimp_signup_subscribe_page_' . $args[0]->name . '_form'] = array(
        'callback' => 'mailchimp_signup_subscribe_form',
      );
    }
    if ($args[1] == 'mailchimp_signup_block') {
      $forms['mailchimp_signup_subscribe_block_' . $args[0]->name . '_form'] = array(
        'callback' => 'mailchimp_signup_subscribe_form',
      );
    }
  }
  return $forms;
}

/**
 * Returns a subscription form for mailchimp lists.
 *
 * If there are multiple lists, this generates a single form for all of them.
 */
function mailchimp_signup_subscribe_form($form, &$form_state, $signup, $type) {
  $form['#attributes'] = array(
    'class' => array(
      'mailchimp-signup-subscribe-form',
    ),
  );
  $form['description'] = array(
    '#markup' => mailchimp_signup_tt("mailchimp_signup:mailchimp_signup:{$signup->name}:description", filter_xss($signup->settings['description'])),
    '#prefix' => '<div class="mailchimp-signup-subscribe-form-description">',
    '#suffix' => '</div>',
  );
  $form['mailchimp_lists'] = array(
    '#tree' => TRUE,
  );
  $use_interest_groups = $signup->settings['include_interest_groups'];
  $lists = mailchimp_get_lists($signup->mc_lists, $use_interest_groups);
  $lists_count = !empty($lists) ? count($lists) : 0;
  if (empty($lists)) {
    drupal_set_message('The subscription service is currently unavailable. Please try again later.', 'warning');
  }
  $list = array();
  if ($lists_count > 1) {
    foreach ($lists as $list) {

      // Wrap in a div:
      $wrapper_key = 'mailchimp_' . $list->id;
      $form['mailchimp_lists'][$wrapper_key] = array(
        '#prefix' => '<div id="mailchimp-newsletter-' . $list->id . '" class="mailchimp-newsletter-wrapper">',
        '#suffix' => '</div>',
      );
      $form['mailchimp_lists'][$wrapper_key]['subscribe'] = array(
        '#type' => 'checkbox',
        '#title' => $list->name,
        '#return_value' => $list->id,
        '#default_value' => 0,
      );
      if ($signup->settings['include_interest_groups'] && isset($list->intgroups)) {
        $form['mailchimp_lists'][$wrapper_key]['interest_groups'] = array(
          '#type' => 'fieldset',
          '#title' => t('Interest Groups for %label', array(
            '%label' => $list->name,
          )),
          '#states' => array(
            'invisible' => array(
              ':input[name="mailchimp_lists[' . $wrapper_key . '][subscribe]"]' => array(
                'checked' => FALSE,
              ),
            ),
          ),
        );
        $form['mailchimp_lists'][$wrapper_key]['interest_groups'] += mailchimp_interest_groups_form_elements($list);
        foreach ($form['mailchimp_lists'][$wrapper_key]['interest_groups'] as $group_id => $group) {
          $form['mailchimp_lists'][$wrapper_key]['interest_groups'][$group_id]['#title'] = mailchimp_signup_tt("mailchimp_signup:mailchimp_signup:{$signup->name}:intgroup_{$group_id}", $group['#title']);
          foreach ($group['#options'] as $interest_id => $interest_name) {
            $form['mailchimp_lists'][$wrapper_key]['interest_groups'][$group_id]['#options'][$interest_id] = mailchimp_signup_tt('mailchimp_signup:mailchimp_signup:' . $signup->name . ':intgroup_' . $group_id . '_interest_' . $interest_id, $interest_name);
          }
        }
      }
    }
  }
  else {
    $list = reset($lists);
    if ($use_interest_groups && isset($list->intgroups)) {
      $form['mailchimp_lists']['#weight'] = 9;
      $form['mailchimp_lists']['interest_groups'] = mailchimp_interest_groups_form_elements($list);
      foreach ($form['mailchimp_lists']['interest_groups'] as $group_id => $group) {
        $form['mailchimp_lists']['interest_groups'][$group_id]['#title'] = mailchimp_signup_tt("mailchimp_signup:mailchimp_signup:{$signup->name}:intgroup_{$group_id}", $group['#title']);
        foreach ($group['#options'] as $interest_id => $interest_name) {
          $form['mailchimp_lists']['interest_groups'][$group_id]['#options'][$interest_id] = mailchimp_signup_tt('mailchimp_signup:mailchimp_signup:' . $signup->name . ':intgroup_' . $group_id . '_interest_' . $interest_id, $interest_name);
        }
      }
    }
  }
  $form['mergevars'] = array(
    '#prefix' => '<div id="mailchimp-newsletter-' . $list->id . '-mergefields" class="mailchimp-newsletter-mergefields">',
    '#suffix' => '</div>',
    '#tree' => TRUE,
  );
  foreach ($signup->settings['mergefields'] as $tag => $mergevar) {
    if (!empty($mergevar)) {
      $mergevar->name = mailchimp_signup_tt("mailchimp_signup:mailchimp_signup:{$signup->name}:mergefield:{$tag}", $mergevar->name);
      $placeholder = isset($signup->settings['placeholder']) ? $signup->settings['placeholder'] : NULL;
      $form['mergevars'][$tag] = mailchimp_insert_drupal_form_tag($mergevar, $placeholder);
      if (empty($lists)) {
        $form['mergevars'][$tag]['#disabled'] = TRUE;
      }
    }
  }
  $form['actions']['#type'] = 'actions';
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#weight' => 10,
    '#value' => mailchimp_signup_tt("mailchimp_signup:mailchimp_signup:{$signup->name}:submit_button", $signup->settings['submit_button']),
    '#disabled' => empty($lists),
  );
  return $form;
}

/**
 * Validation handler for mailchimp_signup_subscribe_form.
 */
function mailchimp_signup_subscribe_form_validate($form, &$form_state) {
  $signup = reset($form_state['build_info']['args']);
  if (count($signup->mc_lists) > 1) {
    foreach ($form_state['values']['mailchimp_lists'] as $list) {
      if ($list['subscribe']) {
        return;
      }
    }
    form_set_error('mailchimp_lists', t("Please select at least one list to subscribe to."));
  }
}

/**
 * Submit handler to add users to lists on subscription form submission.
 */
function mailchimp_signup_subscribe_form_submit($form, &$form_state) {
  $signup = reset($form_state['build_info']['args']);
  $list_details = mailchimp_get_lists($signup->mc_lists);
  $subscribe_lists = array();

  // Filter out blank fields so we don't erase values on the Mailchimp side.
  $mergevars = array_filter($form_state['values']['mergevars']);

  // Format mergevar values.
  foreach ($mergevars as $mergevar_key => $mergevar_value) {
    if (isset($form['mergevars'][$mergevar_key]['#attributes']['type']) && $form['mergevars'][$mergevar_key]['#attributes']['type'] == 'tel') {
      $mergevars[$mergevar_key] = mailchimp_format_phone_number($mergevar_value);
    }
  }
  $email = $mergevars['EMAIL'];

  // If we only have one list we won't have checkbox values to investigate:
  if (count($signup->mc_lists) == 1) {
    $subscribe_lists[0] = array(
      'subscribe' => reset($signup->mc_lists),
      'interest_groups' => isset($form_state['values']['mailchimp_lists']['interest_groups']) ? $form_state['values']['mailchimp_lists']['interest_groups'] : NULL,
    );
  }
  else {

    // We can look at the checkbox values now:
    foreach ($form_state['values']['mailchimp_lists'] as $list) {
      if ($list['subscribe']) {
        $subscribe_lists[] = $list;
      }
    }
  }
  $successes = array();

  // Loop through the selected lists and try to subscribe:
  foreach ($subscribe_lists as $list_choices) {
    $list_id = $list_choices['subscribe'];
    $interest_groups = isset($list_choices['interest_groups']) ? $list_choices['interest_groups'] : array();

    // Parse interests from interest groups.
    $interests = array();
    foreach ($interest_groups as $interest_group) {

      // Check if interest group is an array. Checkbox options will appear in an
      // array, and unset options will be an empty array.
      if (is_array($interest_group)) {
        foreach ($interest_group as $interest_id => $interest_status) {
          $interests[$interest_id] = $interest_status !== 0;
        }
      }
      else {
        if ($interest_group != 0) {
          $interests[$interest_group] = TRUE;
        }
      }
    }
    $result = mailchimp_subscribe($list_id, $email, $mergevars, $interests, $signup->settings['doublein']);

    // Let other modules act on the results in hook_form_alter.
    $form_state['mailchimp_results'][$list_id] = $result;
    if (empty($result) || isset($result->success) && $result->success === FALSE) {
      drupal_set_message(t('There was a problem with your newsletter signup to %list.', array(
        '%list' => $list_details[$list_id]->name,
      )), 'warning');
    }
    else {
      $successes[] = $list_details[$list_id]->name;
    }
  }
  if (count($successes) && !empty($signup->settings['confirmation_message'])) {
    $message = mailchimp_signup_tt("mailchimp_signup:mailchimp_signup:{$signup->name}:confirmation_message", check_plain($signup->settings['confirmation_message']));
    drupal_set_message($message, 'status');
  }
  if (!empty($signup->settings['destination'])) {
    $form_state['redirect'] = $signup->settings['destination'];
  }
}

/**
 * Implements hook_entity_delete().
 */
function mailchimp_signup_entity_delete($entity, $type) {
  if ($type == 'mailchimp_signup') {
    if ($entity->mode & MAILCHIMP_SIGNUP_PAGE) {
      menu_rebuild();
    }
  }
}

/**
 * Wrapper function for i18n_string() if i18nstrings enabled.
 */
function mailchimp_signup_tt($name, $string, $langcode = NULL, $update = FALSE) {
  if (function_exists('i18n_string')) {
    $options = array(
      'langcode' => $langcode,
      'update' => $update,
    );
    return i18n_string($name, $string, $options);
  }
  else {
    return $string;
  }
}

/**
 * Implements hook_feeds_node_processor_targets_alter().
 */
function mailchimp_signup_feeds_processor_targets_alter(&$targets, $type, $bundle) {

  // Create target for all Mailchimp list subscription fields.
  $field_info = field_info_field_types('mailchimp_lists_subscription');
  $field_instances = field_info_instances($type, $bundle);
  foreach ($field_instances as $field_name => $field) {
    if ($field['widget']['type'] == $field_info['default_widget']) {
      $targets[$field_name . ':subscribe'] = array(
        'name' => t($field['label']),
        'description' => t('Mailchimp subscription field.'),
        'callback' => 'mailchimp_signup_set_target',
      );
    }
  }
}

/**
 * Mapping callback.
 */
function mailchimp_signup_set_target($source, $entity, $target, $value, $mapping) {
  list($field_name, $option) = explode(':', $target . ':value');
  $field = isset($entity->{$field_name}) ? $entity->{$field_name} : array(
    'und' => array(),
  );
  $delta = 0;
  if (is_array($value)) {
    foreach ($value as $each_value) {
      if (is_object($each_value) && $each_value instanceof FeedsElement) {
        $each_value = $value
          ->getValue();
        $field['und'][$delta] = array(
          $option => $each_value,
        );
      }
      $delta++;
    }
  }
  else {
    $field['und'][$delta] = array(
      $option => $value,
    );
  }
  $entity->{$field_name} = $field;
}

Functions

Namesort descending Description
mailchimp_signup_admin_menu_map Implements hook_admin_menu_map().
mailchimp_signup_block_info Implements hook_block_info().
mailchimp_signup_block_view Implements hook_block_view().
mailchimp_signup_delete_multiple Deletes multiple signups by ID.
mailchimp_signup_entity_access Access callback for mailchimp_activity_entity.
mailchimp_signup_entity_delete Implements hook_entity_delete().
mailchimp_signup_entity_info Implements hook_entity_info().
mailchimp_signup_entity_info_label Entity label callback.
mailchimp_signup_feeds_processor_targets_alter Implements hook_feeds_node_processor_targets_alter().
mailchimp_signup_forms Implements hook_forms().
mailchimp_signup_load Wrapper around mailchimp_signup_load_multiple to load a single signup entity.
mailchimp_signup_load_multiple Loads multiple signup forms.
mailchimp_signup_load_multiple_by_name Gets an array of all Signups, keyed by the list name.
mailchimp_signup_menu Implements hook_menu().
mailchimp_signup_name_load Gets a single Signup.
mailchimp_signup_page Menu callback for Signup pages.
mailchimp_signup_permission Implements hook_permission().
mailchimp_signup_set_target Mapping callback.
mailchimp_signup_subscribe_form Returns a subscription form for mailchimp lists.
mailchimp_signup_subscribe_form_submit Submit handler to add users to lists on subscription form submission.
mailchimp_signup_subscribe_form_validate Validation handler for mailchimp_signup_subscribe_form.
mailchimp_signup_title callback function for translatable title
mailchimp_signup_tt Wrapper function for i18n_string() if i18nstrings enabled.

Constants

Namesort descending Description
MAILCHIMP_SIGNUP_BLOCK @file Mailchimp Signup module. Allows creation of signup forms integrated with Mailchimp.
MAILCHIMP_SIGNUP_BOTH
MAILCHIMP_SIGNUP_PAGE