abstract class AcquiaLiftReportBase in Acquia Lift Connector 7
Base class providing report data loading functionality common to all Acquia Lift Reports.
Hierarchy
- class \AcquiaLiftReportBase implements \PersonalizeAgentReportInterface, AcquiaLiftReportInterface
Expanded class hierarchy of AcquiaLiftReportBase
File
- plugins/
agent_types/ AcquiaLiftAgent.inc, line 1156 - Provides an agent type for Acquia Lift
View source
abstract class AcquiaLiftReportBase implements PersonalizeAgentReportInterface, AcquiaLiftReportInterface {
/**
* The value to show when report data is not applicable.
*/
const DATA_NA = '—';
/**
* The value representing no features applied to an experiment.
*/
const NO_FEATURES = '(none)';
/**
* The Acquia Lift agent instance for reporting on.
*
* @var AcquiaLiftAgent
*/
protected $agent;
/**
* An instance of AcquiaLiftAPI.
*
* @var AcquiaLiftAPI
*/
protected $liftAPI;
/**
* The confidence measure for determining statistical significance.
*/
protected $confidence_measure = 95;
/**
* The extracted report data for each of the Acquia Lift API calls keyed
* by date/feature set requested.
*
* @var array;
*/
protected $report_data;
/**
* Constructs an AcquiaLiftReport object
*
* @param PersonalizeAgentInterface $agent
* The agent the report is for.
*
* @param AcquiaLiftReportDataSourceInterface $report_data_src
* The source for the report data.
*/
function __construct(PersonalizeAgentInterface $agent, AcquiaLiftReportDataSourceInterface $report_data_src) {
$this->agent = $agent;
$this->reportDataSrc = $report_data_src;
}
/**
* Implements AcquiaLiftReportInterface()::getConfidenceMeasure().
*/
public function getConfidenceMeasure() {
return $this->confidence_measure;
}
/**
* Implements AcquiaLiftReportInterface()::setConfidenceMeasure().
*/
public function setConfidenceMeasure($value) {
if ($value < 0) {
$value = 0;
}
if ($value > 100) {
$value = 100;
}
$this->confidence_measure = $value;
}
/**
* Implements AcquiaLiftReportInterface()::buildConversionReport().
*/
public function buildConversionReport($options) {
$report_data = $this
->generateReportConfiguration($options);
$report_name = t('All goals');
$report_options = array();
if (!empty($options['goal'])) {
// Get the summary data for the whole campaign in order to have overall
// statistics.
$this
->loadConversionReportHelper($report_data, FALSE, $options);
$report_options['goal'] = $options['goal'];
$actions = visitor_actions_get_actions();
// If the action still exists, use the label, otherwise just use the goal
// machine name.
if (isset($actions[$options['goal']])) {
$report_name = $actions[$options['goal']]['label'];
}
else {
$report_name = $options['goal'];
}
}
$this
->loadConversionReportHelper($report_data, TRUE, $report_options);
$this
->loadConversionReportHelper($report_data, FALSE, $report_options);
$reports = $this
->buildConversionReports(array(
'name' => $report_name,
'detail' => empty($options['goal']) ? $report_data['conversion_all']['detail'] : $report_data['conversion_goals'][$options['goal']]['detail'],
'summary' => empty($options['goal']) ? $report_data['conversion_all']['summary'] : $report_data['conversion_goals'][$options['goal']]['summary'],
), $report_data);
return $reports;
}
/**
* Generates a message to show when there is insufficient confidence in the
* test results.
*
* @return string
*/
protected function getLowConfidenceMessage() {
return t('There is not enough data to declare a winner with @confidence% confidence. Consider letting the test run longer before using the results.', array(
'@confidence' => $this
->getConfidenceMeasure(),
));
}
/**
* Generates the variation abbreviated label.
*
* @param $counter
* Indicates the number for the variation.
* @param $is_control
* True if this is the control option.
*/
protected function getVariationLabel($counter, $is_control) {
if ($is_control) {
return t('Control');
}
else {
return t('V@num', array(
'@num' => $counter,
));
}
}
/**
* Generates an internal raw report name for a confidence report based on
* the options.
*
* @param $options
* An array of options passed to the confidence report loader.
* @returns string
* The name of a report to reference within the raw reporting data.
*/
protected function getConfidenceReportRawName($options = array()) {
$report_name = 'confidence';
if (!empty($options['goal'])) {
$report_name .= '_' . $options['goal'];
}
if (isset($options['aggregated-over-dates']) && $options['aggregated-over-dates'] == FALSE) {
$report_name .= '_detail';
}
return $report_name;
}
/**
* Helper function to generate the report options necessary to get a detailed
* confidence report rather than a summary report.
*
* @returns array
* An array of confidence report options.
*/
protected function getConfidenceDetailReportOptions() {
$options['aggregated-over-dates'] = FALSE;
return $options;
}
/**
* Generates the general report configuration that is used to load any report.
*
* @param $options
* An array of options for the report.
* - decision: (Optional) decision point name to limit results.
* - start: (Optional) start date for report, defaults to agent start.
* - end: (Optional) end date for report, defaults to current date.
* - goal: (Optional) goal to show in report, defaults to all.
* - conversion_metric: (Optional) metric to show in report, defaults to
* 'rate'.
* @return array
* The basic reporting configuration.
*/
protected function generateReportConfiguration($options) {
$decision_name = empty($options['decision']) ? NULL : $options['decision'];
$date_from = empty($options['start']) ? NULL : $options['start'];
$date_to = empty($options['end']) ? NULL : $options['end'];
$machine_name = $this->agent
->getMachineName();
$today_only = $date_from === date('Y-m-d') && empty($date_to);
$date_from = empty($date_from) ? date('Y-m-d', $this->agent
->getStartTime()) : $date_from;
$date_to = empty($date_to) ? date('Y-m-d') : $date_to;
$key = 'S' . $date_from . 'E' . $date_to;
if (!isset($this->report_data[$key])) {
$confidence_measure = $this
->getConfidenceMeasure();
// Convert the confidence measure from a percentage to a value between
// 0 and 1 as expected by the Lift API.
$confidence_measure /= 100;
// Save basic report generation information with the data.
$this->report_data[$key]['today_only'] = $today_only;
$this->report_data[$key]['date_from'] = $date_from;
$this->report_data[$key]['date_to'] = $date_to;
$this->report_data[$key]['decision_name'] = $decision_name;
$this->report_data[$key]['machine_name'] = $machine_name;
$this->report_data[$key]['confidence_measure'] = $confidence_measure;
$this->report_data[$key]['features'] = array(
AcquiaLiftReportBase::NO_FEATURES,
);
$this->report_data[$key]['goal'] = empty($options['goal']) ? NULL : $options['goal'];
$this->report_data[$key]['conversion_metric'] = empty($options['conversion_metric']) ? 'rate' : $options['conversion_metric'];
}
return $this->report_data[$key];
}
/**
* Loads the context filter raw values into the report data.
*
* @param $report_data
* The current reporting array by reference.
* @return array
* The updated reporting data for chaining purposes. Note that the
* reporting data is updated by reference as well.
*/
protected function loadContextFilterData(&$report_data) {
// Check and see if it is already loaded.
if (isset($report_data['raw']['potential_context'])) {
return $report_data;
}
// Load it from the report source.
try {
$report_data['raw']['potential_context'] = $this->reportDataSrc
->getContextFilters($report_data['machine_name']);
} catch (Exception $e) {
$report_data['raw']['potential_context']['error'] = $e
->getMessage();
}
return $report_data;
}
/**
* Loads the agent status raw reporting data.
*
* @param $report_data
* The current reporting array by reference.
* @return array
* The updated reporting data for chaining purposes. Note that the
* reporting data is updated by reference as well.
*/
protected function loadAgentStatusData(&$report_data) {
// Check and see if it is already loaded.
if (isset($report_data['raw']['status'])) {
return $report_data;
}
try {
if ($report_data['today_only']) {
$num_days = 1;
}
else {
$interval = date_diff(date_create($report_data['date_from']), date_create($report_data['date_to']));
$num_days = $interval->days;
}
$report_data['raw']['status'] = $this->reportDataSrc
->getAgentStatusReport(array(
$report_data['machine_name'],
), $num_days);
} catch (Exception $e) {
$report_data['raw']['status']['error'] = $e
->getMessage();
}
return $report_data;
}
/**
* Loads the agent confidence raw reporting data.
*
* @param $report_data
* The current reporting array by reference.
* @param $options
* (Optional) An array of options to pass to the report source.
* @return array
* The updated reporting data for chaining purposes. Note that the
* reporting data is updated by reference as well.
*/
protected function loadConfidenceData(&$report_data, $options = array()) {
$report_name = $this
->getConfidenceReportRawName($options);
// Check and see if it is already loaded.
if (isset($report_data['raw'][$report_name])) {
return $report_data;
}
try {
$defaults = array(
'features' => 'all',
'confidence-measure' => $report_data['confidence_measure'],
);
$options = array_merge($defaults, $options);
$report_data['raw'][$report_name] = $this->reportDataSrc
->getConfidenceReport($report_data['machine_name'], $report_data['date_from'], $report_data['date_to'], $report_data['decision_name'], $options);
} catch (Exception $e) {
$report_data['raw'][$report_name]['error'] = $e
->getMessage();
}
return $report_data;
}
/**
* Loads the agent targeting raw reporting data.
*
* @param $report_data
* The current reporting array by reference.
* @return array
* The updated reporting data for chaining purposes. Note that the
* reporting data is updated by reference as well.
*/
protected function loadTargetingData(&$report_data) {
// Check and see if it is already loaded.
if (isset($report_data['raw']['targeting'])) {
return $report_data;
}
try {
$report_data['raw']['targeting'] = $this->reportDataSrc
->getTargetingImpactReport($report_data['machine_name'], $report_data['date_from'], $report_data['date_to'], $report_data['decision_name']);
} catch (Exception $e) {
$report_data['raw']['confidence']['error'] = $e
->getMessage();
}
return $report_data;
}
/**
* Formats a percentage value for use in reports.
*
* @param $value
* The number to show as a percentage.
* @param bool $include_sign
* True to include positive/negative sign indicators.
* @param $trim
* Boolean indicating whether the number should be trimmed of trailing 0s.
* @param $decimals
* The number of decimal places to display.
* @param $padding
* The total number of characters (including decimal) for padding of the
* final number. This allows numbers to align properly in column views.
* This will have no effect if trim is set to true.
* @return string
* The formatted number to display.
*/
protected function formatReportPercentage($value, $include_sign = FALSE, $trim = TRUE, $decimals = 2, $padding = 1) {
$percent = (double) $value * 100;
if ($percent > 0 && $include_sign) {
return '+' . $this
->formatReportNumber($percent, $trim, $decimals, $padding) . '%';
}
return $this
->formatReportNumber($percent, $trim, $decimals, $padding) . '%';
}
/**
* Formats a number value for use in reports.
*
* @param $value
* The number of format (or an empty value).
* @param $trim
* Boolean indicating whether the number should be trimmed of trailing 0s.
* @param $decimals
* The number of decimal places to display.
* @param $padding
* The total number of characters to pad to the left of the decimal point.
* @return string
* The formatted number to display.
*/
protected function formatReportNumber($value, $trim = TRUE, $decimals = 2, $padding = 1) {
if (is_numeric($value)) {
$value = number_format($value, $decimals);
if ($trim) {
$value = rtrim(rtrim($value, '0'), '.');
}
if ($padding > 0) {
$value = str_pad($value, $padding, '0', STR_PAD_LEFT);
}
}
if (empty($value)) {
$value = 0;
}
return $value;
}
/**
* Builds the conversion reports to show basic conversion metrics for report
* requested in the report_data.
*
* @param array $report_data
* The loaded report data for the selection decision and dates.
* @return array
* The render array for the report.
*/
protected function buildAllConversionReports($report_data) {
if (empty($report_data['goal'])) {
// Generate the conversion reports for all goals.
$reports = $this
->buildConversionReports(array(
'name' => t('All goals'),
'detail' => $report_data['conversion_all']['detail'],
'summary' => $report_data['conversion_all']['summary'],
), $report_data);
}
else {
// Generate the conversion reports for the specified goal.
$reports = $this
->buildConversionReports($report_data['conversion_goals'][$report_data['goal']], $report_data);
}
if ($reports == FALSE) {
drupal_set_message(t('There was a problem retrieving the report data. Please try again later.'), 'error');
}
$build['reports'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'lift-statistics',
),
),
'conversion' => $reports,
);
return $build;
}
/**
* Handles all of the logic to load and extract a conversion report.
*
* @param $report_data
* The array of existing report data.
* @param $detail
* True if the report should be a detailed report and false for summary.
* @param array $options
* An array of report options such as a goal for limiting.
*/
protected function loadConversionReportHelper(&$report_data, $detail, $options = array()) {
// Limit report results to the experimental group.
$options['policies'] = 'explore';
if ($detail) {
$options = array_merge($options, $this
->getConfidenceDetailReportOptions());
}
$new_report = array();
$report_name = $this
->getConfidenceReportRawName($options);
if (isset($options['goal'])) {
// Add the report name for this goal to track which goals are included.
$report_data['goal_reports'][] = $report_name;
// Determine the parent for reports added by this helper.
if (!isset($report_data['conversion_goals'])) {
$report_data['conversion_goals'][$options['goal']] = FALSE;
}
$detail_report =& $report_data['conversion_goals'][$options['goal']];
}
else {
// Determine the parent for reports added by this helper.
if (!isset($report_data['conversion_all'])) {
$report_data['conversion_all'] = FALSE;
}
$detail_report =& $report_data['conversion_all'];
}
// Check if the report is already loaded.
$subreport_name = $detail ? 'detail' : 'summary';
if (isset($detail_report[$subreport_name])) {
return;
}
// Load the raw report data.
if (!isset($report_data['raw'][$report_name])) {
$this
->loadConfidenceData($report_data, $options);
if (isset($report_data['raw'][$report_name]['error'])) {
return;
}
}
if (!isset($report_data['raw'][$report_name]['data'])) {
return;
}
// Extract the data into full report data from the raw data.
$detail_report[$subreport_name] = $detail ? $this
->extractConversionReportData($report_data['raw'][$report_name]['data']['items']) : $this
->extractConversionSummaryData($report_data['raw'][$report_name]['data']['items']);
}
/**
* Extracts the required overview data from the report data returned by
* Acquia Lift.
*
* @param $items
* An array of items as returned from Acquia Lift.
* @return array
* An associative array with information for today's and the total overview.
*/
protected function extractOverviewReportData($items) {
$agent_data = $this->agent
->getData();
$decision_style = $agent_data['decision_style'] === 'adaptive' ? t('Auto-personalize') : t('A/B');
$total_variations = isset($agent_data['decisions']) ? count($agent_data['decisions']) : 0;
// Create an array of data for each time option.
$report['today'] = array(
'unformatted' => array(
'total_lift' => $items['today']['liftOverDefaultUsingGoals'],
'total_shown' => $items['today']['sessionCount'],
'total_goals' => $items['today']['goalCount'],
),
'test_type' => $decision_style,
'total_shown' => $this
->formatReportNumber($items['today']['sessionCount']),
'total_goals' => $this
->formatReportNumber($items['today']['goalCount']),
'total_goals_positive' => $items['today']['goalCount'] > 0,
'total_lift' => $this
->formatReportPercentage($items['today']['liftOverDefaultUsingGoals']),
'total_variations' => $total_variations,
);
$report['all'] = array(
'unformatted' => array(
'total_shown' => $items['totals']['sessions']['count'],
'total_goals' => $items['totals']['goals']['count'],
'total_lift' => $items['today']['liftOverDefaultUsingGoalsToDate'],
),
'test_type' => $decision_style,
'total_shown' => $this
->formatReportNumber($items['totals']['sessions']['count']),
'total_goals' => $this
->formatReportNumber($items['totals']['goals']['count']),
'total_goals_positive' => $items['totals']['goals']['count'] > 0,
'total_lift' => $this
->formatReportPercentage($items['today']['liftOverDefaultUsingGoalsToDate']),
'total_variations' => $total_variations,
);
return $report;
}
/**
* Extracts data from the raw confidence detail report that is prepared for use
* within the conversion report rendering process.
*
* @param $items
* An array of items as return from Acquia Lift.
* @return array
* An associative array with information about the performance of each choice.
*/
protected function extractConversionReportData($items) {
if (empty($items)) {
return array();
}
$shown = array();
$counter = NAN;
$data = array();
$total_count = $total_goals = $total_val = array();
foreach ($items as $item) {
// Check to see if we are in a new grouping of choices.
$check = $item['choice'];
if (is_nan($counter) || isset($shown[$check])) {
$shown = array();
$counter = 0;
}
else {
$counter++;
}
$shown[$check] = $check;
$choice = $option_id = $item['choice'];
$choice_id = $choice;
if (strpos($choice, ':') !== FALSE) {
list($decision_name, $option_id) = explode(':', $choice);
}
if ($option_label = personalize_get_option_label_for_decision_and_choice($decision_name, $option_id)) {
$choice_id = $option_label;
}
$goals = $item['totals']['goals'];
$count = $item['totals']['count'];
$val = $item['totals']['val'];
$total_count[$counter] = isset($total_count[$counter]) ? $total_count[$counter] + $count : $count;
$total_goals[$counter] = isset($total_goals[$counter]) ? $total_goals[$counter] + $goals : $goals;
$total_val[$counter] = isset($total_val[$counter]) ? $total_val[$counter] + $val : $val;
$rate = $total_count[$counter] > 0 ? $total_goals[$counter] / $total_count[$counter] * 100 : 0;
$val_rate = $total_count[$counter] > 0 ? $total_val[$counter] / $total_count[$counter] : 0;
$margin = ($item['bHi'] - $item['bLo']) / 2;
$data[$item['feature']][] = array(
'choice_id' => $choice_id,
'raw_label' => $option_id,
'goals' => $total_goals[$counter],
'count' => $total_count[$counter],
'date' => $item['date'],
'timestamp' => strtotime($item['date']),
'conversion' => $this
->formatReportNumber($rate, TRUE, 4),
'conversion_value' => $this
->formatReportNumber($val_rate, TRUE, 4),
'estimated_value' => $this
->formatReportNumber($item['vMean'], TRUE, 4),
'margin_error' => $this
->formatReportNumber($margin, TRUE, 4),
'counter' => $counter,
'control' => $counter === 0,
);
}
return $data;
}
/**
* Loads and formats the necessary reporting data in order to generate a
* conversion metrics graph/report.
*
* @param array
* The report data object to load conversion report data into.
*/
protected function loadConversionReportData(&$report_data) {
// All goals - summary report is always loaded in order to get the overview
// data for the campaign.
if (!isset($report_data['conversion'])) {
$this
->loadConversionReportHelper($report_data, FALSE);
}
// All goals conversion report.
if (empty($report_data['goal'])) {
// All goals - detail report.
if (!isset($report_data['conversion_detail'])) {
$this
->loadConversionReportHelper($report_data, TRUE);
}
return;
}
// Load the detail and summary reports for the specified goal.
$actions = visitor_actions_get_actions();
$goal_id = $report_data['goal'];
if (!isset($report_data['conversion_goals'][$goal_id])) {
$report_data['conversion_goals'][$goal_id]['name'] = isset($actions[$goal_id]) ? $actions[$goal_id]['label'] : $goal_id;
$options['goal'] = $goal_id;
// Summary report.
$this
->loadConversionReportHelper($report_data, FALSE, $options);
// Detail report.
$this
->loadConversionReportHelper($report_data, TRUE, $options);
}
}
/**
* Extracts data from the raw aggregate confidence report that is prepared for
* use within the report rendering process.
*
* @param $items
* An array of items as return from Acquia Lift.
* @return array
* An associative array with information about the performance of each choice.
*/
protected function extractConversionSummaryData($items) {
if (empty($items)) {
return array();
}
$shown = array();
$counter = NAN;
$data = array();
$confidence = FALSE;
$winner = '';
$winning_value = NAN;
foreach ($items as $item) {
// Check to see if we are in a new grouping of choices.
$check = $item['choice'];
// First item in the loop so this is the control.
if (is_nan($counter) || isset($shown[$check])) {
$shown = array();
$counter = 0;
}
else {
$counter++;
}
$shown[$check] = $check;
$choice = $option_id = $item['choice'];
$choice_id = $choice;
if (strpos($choice, ':') !== FALSE) {
list($decision_name, $option_id) = explode(':', $choice);
}
if ($option_label = personalize_get_option_label_for_decision_and_choice($decision_name, $option_id)) {
$choice_id = $option_label;
}
$goals = $item['totals']['goals'];
$count = $item['totals']['count'];
// The format for percentages will already multiply by 100.
$rate = $count > 0 ? $goals / $count : 0;
$margin = ($item['bHi'] - $item['bLo']) / 2;
if ($item['signif']) {
if (is_nan($winning_value) || $item['confidence'] > $winning_value) {
$winning_value = $item['confidence'];
$winner = $counter;
$confidence = TRUE;
}
}
$data[$item['feature']][] = array(
'counter' => $counter,
'choice_id' => $choice_id,
'raw_label' => $option_id,
'goals' => $goals,
'count' => $count,
'date' => $item['date'],
'timestamp' => strtotime($item['date']),
'conversion' => $this
->formatReportPercentage($rate),
'estimated_value' => $this
->formatReportNumber($item['vMean'], TRUE, 4),
'estimated_higher' => $this
->formatReportNumber($item['bHi'], TRUE, 4),
'estimated_lower' => $this
->formatReportNumber($item['bLo'], TRUE, 4),
'margin_error' => $this
->formatReportNumber($margin, TRUE, 4),
'significant' => $item['signif'],
'control' => $counter === 0,
'confidence' => $counter === 0 ? self::DATA_NA : $this
->formatReportPercentage($item['confidence'] / 100),
'lift_default' => $counter === 0 ? self::DATA_NA : $this
->formatReportPercentage($item['lift']['default'] / 100, TRUE),
'lift_random' => $this
->formatReportPercentage($item['lift']['random'] / 100, TRUE),
);
}
$report = array(
'data' => $data,
'overview' => array(
'confidence' => $confidence,
'winner' => $winner,
),
);
return $report;
}
/**
* Builds the render array for the metrics portion of the report.
*
* @param array $report_data
* All of the reporting data for this AB report.
* @param array $all_report_data
* The report data for all reports to be build including overview data.
* @param array|bool
* A render array for the report or FALSE if it cannot be generated.
*/
protected function buildConversionDetailReport($report_data, $all_report_data) {
if ($report_data === FALSE) {
return FALSE;
}
$headers = array(
t('Date'),
t('Content variation'),
array(
'data' => t('Conversion rate (%)'),
'data-conversion-metric' => 'rate',
),
array(
'data' => t('Conversion value'),
'data-conversion-metric' => 'value',
),
t('Margin of error'),
);
$rows = array();
foreach ($report_data as $feature => $feature_data) {
if (!in_array($feature, $all_report_data['features'])) {
continue;
}
foreach ($feature_data as $data) {
$rows[] = array(
'data' => array(
array(
'data' => $data['timestamp'],
),
array(
'data' => $data['choice_id'],
'data-acquia-lift-variation-label' => $this
->getVariationLabel($data['counter'], $data['control']),
),
array(
'data' => $data['conversion'],
),
array(
'data' => $data['conversion_value'],
),
array(
'data' => $data['margin_error'],
),
),
'no_striping' => TRUE,
);
}
}
if (!empty($rows)) {
$build['metric_table'] = array(
'#theme' => 'table',
'#header' => $headers,
'#rows' => $rows,
'#sticky' => FALSE,
'#attributes' => array(
'data-lift-statistics' => '',
'data-liftGraph-columnName' => '2',
'data-liftGraph-columnX' => '1',
'data-liftGraph-renderer' => 'line',
'data-liftgraph-excluded' => '5',
'data-acquia-lift-campaign' => $all_report_data['machine_name'],
'data-acquia-lift-decision-name' => $all_report_data['decision_name'],
),
);
}
return $build;
}
/**
* Builds the render array for the summary portion of the report.
*
* @param array $report_data
* Reporting data for this summary report.
* @param array $all_report_data
* The report data for all reports to be build including overview data.
* @param array|bool
* A render array for the report or FALSE if it cannot be generated.
*/
protected function buildConversionSummaryReport($report_data, $all_report_data) {
if ($report_data === FALSE) {
return FALSE;
}
$confidence = !empty($all_report_data['conversion_all']['summary']['overview']['confidence']);
$winner = $all_report_data['conversion_all']['summary']['overview']['winner'];
$headers = array(
t('Variation'),
array(
'data' => t('Total goals met'),
'data-help-tooltip' => t('Number of times visitors completed a goal after viewing the variation.'),
),
array(
'data' => t('Total conversion rate'),
'data-help-tooltip' => t('Percentage of goals met for each display of the variation.'),
),
array(
'data' => t('Chance to beat control'),
'data-help-tooltip' => t('Likelihood visitors will complete goals for a variation compared to the control.'),
),
array(
'data' => t('Lift'),
'data-help-tooltip' => t('Likelihood visitors will complete goals for a variation compared to the control.'),
),
array(
'data' => t('Winner'),
'data-help-tooltip' => t('Most effective variation for visitors based on a @confidence% confidence level.', array(
'@confidence' => $this
->getConfidenceMeasure(),
)),
),
);
$confidence_message_shown = FALSE;
$rows = array();
foreach ($report_data['data'] as $feature => $feature_data) {
if (!in_array($feature, $all_report_data['features'])) {
continue;
}
foreach ($feature_data as $data) {
$row_data = array(
array(
'data' => $data['choice_id'],
'data-acquia-lift-variation-label' => $this
->getVariationLabel($data['counter'], $data['control']),
),
array(
'data' => $data['goals'],
),
array(
'data' => $data['conversion'],
),
array(
'data' => $data['confidence'],
),
array(
'data' => $data['lift_default'],
),
);
// Add the winner column data.
if (empty($rows) && !$confidence) {
// If there is low confidence then show the message throughout the
// winner column.
$row_data[] = array(
'data' => $this
->getLowConfidenceMessage(),
'rowspan' => count($feature_data),
'class' => array(
'acquia-lift-ab-winner',
),
);
$confidence_message_shown = TRUE;
}
else {
if (!$confidence_message_shown) {
// Show the winner indicator if this is the winning variation.
$row_data[] = $confidence && $winner === $data['counter'] ? '<span class="lift-winner">' . t('Winner') . '</span>' : '';
}
}
$rows[] = array(
'data' => $row_data,
'no_striping' => TRUE,
);
}
}
if (empty($rows)) {
return array();
}
$build['summary_holder'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'lift-graph-result',
),
),
);
$build['summary_holder']['summary_table'] = array(
'#theme' => 'table',
'#header' => $headers,
'#rows' => $rows,
'#sticky' => FALSE,
'#attributes' => array(
'class' => array(
'lift-graph-result-data',
),
'data-acquia-lift-campaign' => $all_report_data['machine_name'],
'data-acquia-lift-decision-name' => $all_report_data['decision_name'],
),
'#attached' => array(
'library' => array(
array(
'acquia_lift',
'acquia_lift.help',
),
),
),
);
return $build;
}
/**
* Build a set of confidence reports from the report data.
*
* @param array $report_data
* The extracted report data with the following keys:
* - name: The name of the section
* - detail: The detail report data
* - summary: The summary report data
* @param array $all_report_data
* The full report data for all reports including overview information.
* @return array|bool
* The render array for the reports or false if invalid data.
*/
protected function buildConversionReports($report_data, $all_report_data) {
if ($report_data['detail'] == FALSE || $report_data['summary'] == FALSE) {
return FALSE;
}
$build = array();
$build['reports']['title'] = array(
'#theme' => 'html_tag',
'#tag' => 'h3',
'#value' => $report_data['name'],
'#attributes' => array(
'class' => array(
'lift-statistic-category-name',
'element-invisible',
),
),
);
$build['reports']['detail'] = $this
->buildConversionDetailReport($report_data['detail'], $all_report_data);
$build['reports']['summary'] = $this
->buildConversionSummaryReport($report_data['summary'], $all_report_data);
$build['reports']['#theme_wrappers'] = array(
'container',
);
$build['reports']['#attributes'] = array(
'class' => array(
'lift-statistic-category',
),
);
return $build;
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AcquiaLiftReportBase:: |
protected | property | The Acquia Lift agent instance for reporting on. | |
AcquiaLiftReportBase:: |
protected | property | The confidence measure for determining statistical significance. | |
AcquiaLiftReportBase:: |
protected | property | An instance of AcquiaLiftAPI. | |
AcquiaLiftReportBase:: |
protected | property | The extracted report data for each of the Acquia Lift API calls keyed by date/feature set requested. | |
AcquiaLiftReportBase:: |
protected | function | Builds the conversion reports to show basic conversion metrics for report requested in the report_data. | |
AcquiaLiftReportBase:: |
protected | function | Builds the render array for the metrics portion of the report. | |
AcquiaLiftReportBase:: |
public | function |
Implements AcquiaLiftReportInterface()::buildConversionReport(). Overrides AcquiaLiftReportInterface:: |
|
AcquiaLiftReportBase:: |
protected | function | Build a set of confidence reports from the report data. | |
AcquiaLiftReportBase:: |
protected | function | Builds the render array for the summary portion of the report. | |
AcquiaLiftReportBase:: |
constant | The value to show when report data is not applicable. | ||
AcquiaLiftReportBase:: |
protected | function | Extracts data from the raw confidence detail report that is prepared for use within the conversion report rendering process. | |
AcquiaLiftReportBase:: |
protected | function | Extracts data from the raw aggregate confidence report that is prepared for use within the report rendering process. | |
AcquiaLiftReportBase:: |
protected | function | Extracts the required overview data from the report data returned by Acquia Lift. | |
AcquiaLiftReportBase:: |
protected | function | Formats a number value for use in reports. | |
AcquiaLiftReportBase:: |
protected | function | Formats a percentage value for use in reports. | |
AcquiaLiftReportBase:: |
protected | function | Generates the general report configuration that is used to load any report. | |
AcquiaLiftReportBase:: |
protected | function | Helper function to generate the report options necessary to get a detailed confidence report rather than a summary report. | |
AcquiaLiftReportBase:: |
public | function |
Implements AcquiaLiftReportInterface()::getConfidenceMeasure(). Overrides AcquiaLiftReportInterface:: |
|
AcquiaLiftReportBase:: |
protected | function | Generates an internal raw report name for a confidence report based on the options. | |
AcquiaLiftReportBase:: |
protected | function | Generates a message to show when there is insufficient confidence in the test results. | |
AcquiaLiftReportBase:: |
protected | function | Generates the variation abbreviated label. | |
AcquiaLiftReportBase:: |
protected | function | Loads the agent status raw reporting data. | |
AcquiaLiftReportBase:: |
protected | function | Loads the agent confidence raw reporting data. | |
AcquiaLiftReportBase:: |
protected | function | Loads the context filter raw values into the report data. | |
AcquiaLiftReportBase:: |
protected | function | Loads and formats the necessary reporting data in order to generate a conversion metrics graph/report. | |
AcquiaLiftReportBase:: |
protected | function | Handles all of the logic to load and extract a conversion report. | |
AcquiaLiftReportBase:: |
protected | function | Loads the agent targeting raw reporting data. | |
AcquiaLiftReportBase:: |
constant | The value representing no features applied to an experiment. | ||
AcquiaLiftReportBase:: |
public | function |
Implements AcquiaLiftReportInterface()::setConfidenceMeasure(). Overrides AcquiaLiftReportInterface:: |
|
AcquiaLiftReportBase:: |
function | Constructs an AcquiaLiftReport object |