You are here

function acquia_lift_new_target_audience_form in Acquia Lift Connector 7

Form for adding a targeting audience to an agent.

1 string reference to 'acquia_lift_new_target_audience_form'
acquia_lift_menu in ./acquia_lift.module
Implements hook_menu().

File

./acquia_lift.admin.inc, line 913
acquia_lift.admin.inc Provides functions needed for the admin UI.

Code

function acquia_lift_new_target_audience_form($form, &$form_state, $agent) {

  // Build up a list of available context values for targeting.
  module_load_include('inc', 'personalize', 'personalize.admin');
  $targeting_values = personalize_get_targeting_values_for_agent($agent);
  $attributes = array(
    'class' => array(
      'personalize-variation-row',
    ),
  );
  $form = array(
    '#tree' => TRUE,
    '#type' => 'container',
    '#attributes' => $attributes,
  );
  $form['#attached']['css'][] = drupal_get_path('module', 'personalize') . '/css/personalize.admin.css';
  $form['agent'] = array(
    '#type' => 'value',
    '#value' => $agent->machine_name,
  );
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Audience name'),
    '#required' => TRUE,
  );
  $context_options = array(
    '' => '-- ' . t('Select a context') . ' --',
  );
  $value_types = array();
  $operator_options = array(
    'string' => array(
      'equals' => t('equals'),
      'contains' => t('contains'),
      'starts' => t('starts with'),
      'ends' => t('ends with'),
    ),
    'number' => array(
      'equals' => t('equals'),
      'numgt' => t('greater than'),
      'numlt' => t('less than'),
    ),
  );
  foreach ($targeting_values as $key => $info) {
    $option_key = $info['visitor_context'] . PERSONALIZE_TARGETING_ADMIN_SEPARATOR . $key;
    $key_label = isset($info['friendly name']) ? $info['friendly name'] : $key;
    $context_options[$option_key] = $key_label;
    $value_types[$option_key] = $info['value type'];
  }

  // This is the portion of the form that will be replace when the "add new" or "remove
  // context" links are clicked.
  $main_wrapper_id = 'acquia-lift-targeting';
  $form['mapping'] = array(
    '#tree' => TRUE,
    '#theme_wrappers' => array(
      'container',
    ),
    '#attributes' => $attributes,
  );
  $form['mapping']['contexts'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'id' => $main_wrapper_id,
    ),
  );

  // Load from the existing form if passed first, otherwise, load from option
  // set.
  $mappings = array();
  if (isset($form_state['values']['mapping']['contexts'])) {
    foreach ($form_state['values']['mapping']['contexts'] as $delta => $context) {
      list($plugin_name, $context_option) = explode(PERSONALIZE_TARGETING_ADMIN_SEPARATOR, $context['context']);

      // Important: preserve the delta passed through the form as it is used
      // to determine the item to delete when "remove" is clicked.
      $mappings[$delta] = array(
        'plugin' => $plugin_name,
        'context' => $context_option,
        'operator' => $context['value']['operator'],
        'match' => $context['value']['match'],
      );
    }
  }

  // If the "Remove" button was clicked for a context, we need to remove that context
  // from the form.
  if (isset($form_state['to_remove'])) {
    unset($mappings[$form_state['to_remove']]);
    unset($form_state['to_remove']);
    $form_state['num_contexts']--;
  }

  // Make sure there is at least an empty context.
  if (empty($mappings)) {
    $mappings[] = array(
      'context' => '',
      'operator' => 'equals',
      'match' => '',
      'plugin' => '',
    );
  }

  // If the "Add another" button was clicked, we need to add contexts to get up
  // to the number indicated.
  $num_contexts = count($mappings);
  if (isset($form_state['num_contexts']) && $form_state['num_contexts'] > $num_contexts) {
    while ($num_contexts < $form_state['num_contexts']) {
      $mappings[] = array(
        'context' => '',
        'operator' => 'equals',
        'match' => '',
        'plugin' => '',
      );
      $num_contexts++;
    }
  }
  $form_state['num_contexts'] = count($mappings);
  foreach ($mappings as $delta => $mapping) {
    $wrapper_id = 'operator-dropdown-replace-' . $delta;
    $selected_plugin_context = $mapping['plugin'] . PERSONALIZE_TARGETING_ADMIN_SEPARATOR . $mapping['context'];
    $selected_context = $mapping['context'];
    $selected_operator = $mapping['operator'];
    $selected_match = $mapping['match'];
    $form['mapping']['contexts'][$delta] = array(
      '#prefix' => '<div class="personalize-target-wrapper">',
      '#suffix' => '</div>',
      'context' => array(
        '#type' => 'select',
        '#title' => t('Context'),
        '#options' => $context_options,
        '#default_value' => empty($selected_plugin_context) ? '' : $selected_plugin_context,
        '#ajax' => array(
          'event' => 'change',
          'callback' => 'personalize_explicit_targeting_context_callback',
          'wrapper' => $wrapper_id,
        ),
        '#attributes' => array(
          'class' => array(
            'acquia-lift-targeting-context',
          ),
        ),
      ),
    );
    $form['mapping']['contexts'][$delta]['value'] = array(
      '#tree' => TRUE,
      '#prefix' => '<div id="' . $wrapper_id . '">',
      '#suffix' => '</div>',
    );
    $value_type = isset($value_types[$selected_plugin_context]) ? $value_types[$selected_plugin_context] : 'string';

    // We use different form elements depending on whether there is a predefined list
    // of possible values or not.
    switch ($value_type) {
      case 'predefined':
        $form['mapping']['contexts'][$delta]['value']['operator'] = array(
          '#type' => 'value',
          '#value' => 'equals',
        );
        $form['mapping']['contexts'][$delta]['value']['match'] = array(
          '#type' => 'select',
          '#options' => $targeting_values[$selected_context]['values'],
          '#title' => 'Value',
          '#default_value' => $selected_match,
        );
        break;
      case 'boolean':
        $form['mapping']['contexts'][$delta]['value']['operator'] = array(
          '#type' => 'value',
          '#value' => 'equals',
        );
        $off_label = isset($targeting_values[$selected_context]['off_label']) ? $targeting_values[$selected_context]['off_label'] : 'No';
        $on_label = isset($targeting_values[$selected_context]['on_label']) ? $targeting_values[$selected_context]['on_label'] : 'Yes';
        $form['mapping']['contexts'][$delta]['value']['match'] = array(
          '#type' => 'select',
          '#options' => array(
            0 => $off_label,
            1 => $on_label,
          ),
          '#title' => 'Value',
          '#default_value' => $selected_match,
        );
        break;
      default:
        $form['mapping']['contexts'][$delta]['value']['operator'] = array(
          '#type' => 'select',
          '#title' => t('Operator'),
          '#options' => $operator_options[$value_type],
          '#default_value' => $selected_operator,
        );
        $form['mapping']['contexts'][$delta]['value']['match'] = array(
          '#type' => 'textfield',
          '#title' => 'Value',
          '#size' => $value_type == 'number' ? 6 : 30,
          '#default_value' => $selected_match,
        );
        break;
    }

    // Add a "remove" button for this context.
    // NOTE: ajax.js expects the ID of the element to match the element's name
    // even when a different selector is passed.
    $form['mapping']['contexts'][$delta]['remove'] = array(
      '#prefix' => '<div class="acquia-lift-remove-context">',
      '#suffix' => '</div>',
      '#type' => 'submit',
      '#tag' => 'button',
      '#text' => t('Remove'),
      '#value' => 'remove_' . $delta,
      '#theme_wrappers' => array(
        'personalize_html_tag',
      ),
      '#attributes' => array(
        'class' => array(
          'personalize-delete-context',
          'form-submit',
        ),
        'title' => t('Delete this context.'),
        'id' => 'edit-targeting-mapping-contexts-' . $delta . '-remove',
      ),
      '#submit' => array(
        'acquia_lift_targeting_remove_context_submit',
      ),
      '#ajax' => array(
        'callback' => 'acquia_lift_targeting_context_ajax_callback',
        'wrapper' => $main_wrapper_id,
        'effect' => 'fade',
      ),
    );
  }

  // Create an "add new context" link.
  $form['add_new'] = array(
    '#prefix' => '<span class="personalize-add-link-prefix"></span>',
    '#type' => 'submit',
    '#value' => t('Add context'),
    '#submit' => array(
      'acquia_lift_targeting_add_context_submit',
    ),
    '#ajax' => array(
      'callback' => 'acquia_lift_targeting_context_ajax_callback',
      'wrapper' => $main_wrapper_id,
      'effect' => 'fade',
    ),
  );
  $form['strategies'] = array(
    '#type' => 'container',
    '#attributes' => $attributes,
  );

  // Add radio buttons so the user can select how multiple features for an option
  // should be treated.
  $default_strategy = 'OR';
  $form['strategy'] = array(
    '#type' => 'select',
    '#multiple' => FALSE,
    '#field_prefix' => t('Visitor must have '),
    '#field_suffix' => t(' of the specified contexts'),
    '#description' => t('Choose how multiple contexts should be applied to options. Choose "any" if the rule should apply if the user has any of the contexts. Choose "all" if the rule should apply only if the user has all of the contexts.'),
    '#options' => array(
      'OR' => 'any',
      'AND' => 'all',
    ),
    '#default_value' => $default_strategy,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Create new audience'),
  );
  return $form;
}