You are here

function acquia_lift_implement_targeting in Acquia Lift Connector 7.2

Takes whatever is in the 'lift_targeting' data property and converts it into the required campaign structure (including nested tests where needed).

Parameters

stdClass $agent: The agent to create the targeting structure for.

11 calls to acquia_lift_implement_targeting()
AcquiaLiftWebTestBase::createTargetingAgentWithNestedTest in tests/acquia_lift.test
AcquiaLiftWebTestReports::testAudienceReportLogic in tests/acquia_lift.test
AcquiaLiftWebTestReports::testReportEndDate in tests/acquia_lift.test
AcquiaLiftWebTestReports::testReportPage in tests/acquia_lift.test
AcquiaLiftWebTestTarget::testAudienceChanges in tests/acquia_lift.test

... See full list

File

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

Code

function acquia_lift_implement_targeting($agent) {
  if (empty($agent->data['lift_targeting'])) {

    // Just update the test options for any embedded tests and return an empty
    // array.
    acquia_lift_save_nested_test_options($agent);
    return;
  }
  $all_option_sets = personalize_option_set_load_by_agent($agent->machine_name);

  // Bail if not all option sets have an equal number of options.
  $num_decisions = $decision_name = NULL;
  foreach ($all_option_sets as $os) {
    if ($num_decisions == NULL) {
      $num_decisions = count($os->options);
    }
    elseif (count($os->options) !== $num_decisions) {
      throw new AcquiaLiftException('Variation sets do not have equal numbers of options');
    }
  }

  // First we need to figure out what existing tests we have running as nested
  // tests for this agent.
  $targeting_option_set = acquia_lift_get_option_set_for_targeting($agent->machine_name);

  // Make sure we only have one reference to the targeting option set.
  $all_option_sets[$targeting_option_set->osid] = $targeting_option_set;
  $existing_structure = acquia_lift_get_structure_from_targeting($targeting_option_set, FALSE);

  // Any target audience that has multiple variations in it has a test running.
  $existing_tests = $existing_options = array();
  foreach ($existing_structure as $audience => $variations) {
    if (count($variations) > 1) {
      $existing_tests[$audience] = $variations;
    }
    else {
      $existing_options[$audience] = reset($variations);
    }
  }

  // Now look at the tests and options required by the new structure.
  $rules = $new_tests = $new_options = $remove_audiences = array();
  foreach ($agent->data['lift_targeting'] as $new_audience => $variations) {
    $audience_name = $new_audience;
    if (count($variations) == 1) {
      if (isset($existing_structure[$audience_name]) && count($existing_structure[$audience_name]) > 1) {

        // This used to be a test - create a new audience so that the new
        // reporting data won't interfere with the reporting data for the test.
        $new_name = acquia_lift_target_audience_copy($targeting_option_set, $audience_name);

        // Reload the option set.
        $targeting_option_set = personalize_option_set_load($targeting_option_set->osid, TRUE);

        // Mark the old audience for removal
        $remove_audiences[] = $audience_name;
        $audience_name = $new_name;
      }
      $new_options[$audience_name] = reset($variations);
      continue;
    }
    if (isset($existing_structure[$audience_name])) {
      if ($existing_structure[$audience_name] != $variations) {

        // This audience is getting a different test from what it had before -
        // change its name so that the old test report will still make sense.
        $new_name = acquia_lift_target_audience_copy($targeting_option_set, $audience_name);

        // Reload the option set.
        $targeting_option_set = personalize_option_set_load($targeting_option_set->osid, TRUE);

        // Mark the original audience for removal.
        $remove_audiences[] = $audience_name;
        $audience_name = $new_name;
      }
      else {
        $rules[$audience_name] = $audience_name;
      }
    }

    // If we didn't find an existing test corresponding to this combination,
    // we'll need to create a new one.
    if (!isset($rules[$audience_name])) {
      $new_tests[$audience_name] = $variations;
    }
  }

  // Keep track of nested agents that get deleted.
  foreach (array_keys($existing_tests) as $audience) {
    if (!in_array($audience, $rules)) {

      // Delete the old test if it's no longer being used.
      acquia_lift_remove_nested_test($targeting_option_set, $audience, $agent);
    }
  }
  foreach ($existing_options as $audience => $option) {
    if (!isset($agent->data['lift_targeting'][$audience])) {
      acquia_lift_remove_option_for_audience($targeting_option_set, $audience);
    }
  }

  // Now create any new tests required by the new structure.
  foreach ($new_tests as $audience => $variations) {
    acquia_lift_add_new_test_for_audience($targeting_option_set, $audience, $agent, $variations);
  }
  foreach ($new_options as $audience => $option) {
    acquia_lift_set_option_for_audience($targeting_option_set, $option, $audience);
  }

  // Remove any audiences that are now defunct.
  foreach ($remove_audiences as $audience_name) {
    unset($targeting_option_set->targeting[$audience_name]);
  }

  // Refresh the reference to teh targeting option set, in case it got reloaed.
  $all_option_sets[$targeting_option_set->osid] = $targeting_option_set;

  // Go through any other option sets for this personalization, assign the same
  // decision name and option IDs to each of them, and copy the targeting infor-
  // mation to them.
  $targeting_option_set->options = array_values($targeting_option_set->options);
  foreach ($all_option_sets as $os) {
    if ($os->osid != $targeting_option_set->osid) {
      $os->targeting = $targeting_option_set->targeting;
      $os->options = array_values($os->options);
      foreach ($os->options as $i => &$option) {
        $option['option_id'] = $targeting_option_set->options[$i]['option_id'];
      }
    }
    $os->decision_name = $agent->machine_name;
    personalize_option_set_save($os);
  }

  // Update the test options for any embedded tests.
  acquia_lift_save_nested_test_options($agent);

  // Now clobber the "lift_targeting" data as we only use that to store *changes*
  // to the running targeting.
  $agent->data['lift_targeting'] = array();
  personalize_agent_save($agent);
}