Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.61% covered (warning)
82.61%
19 / 23
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Index_Based_Merge_Strategy
86.36% covered (warning)
86.36%
19 / 22
50.00% covered (danger)
50.00%
1 / 2
13.43
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 merge
85.71% covered (warning)
85.71%
18 / 21
0.00% covered (danger)
0.00%
0 / 1
12.42
1<?php
2/**
3 * Index-Based Merge Strategy
4 *
5 * Merges comparison data by array position for time-series reports.
6 *
7 * @package Automattic\Jetpack\PremiumAnalytics\Reports\Export\MergeStrategy
8 */
9
10declare( strict_types=1 );
11
12namespace Automattic\Jetpack\PremiumAnalytics\Reports\Export\MergeStrategy;
13
14defined( 'ABSPATH' ) || exit;
15
16use Automattic\Jetpack\PremiumAnalytics\Reports\Export\Csv_Report_Controller_Interface;
17use Automattic\Jetpack\PremiumAnalytics\Reports\Export\Logging\Logger_Interface;
18use Automattic\Jetpack\PremiumAnalytics\Reports\Export\Support\Logger_Trait;
19
20/**
21 * Index-based merge strategy for time-series reports.
22 *
23 * This strategy merges data by array position (row 0 with row 0, row 1 with row 1, etc.).
24 * It's appropriate for time-series reports where dates align between periods.
25 *
26 * Empty value handling: Uses empty strings for missing data, which signals
27 * "no data for this date" when period lengths don't match.
28 *
29 * @since $$next-version$$
30 */
31class Index_Based_Merge_Strategy extends Abstract_Merge_Strategy {
32
33    use Logger_Trait;
34
35    /**
36     * Constructor.
37     *
38     * @param Logger_Interface $logger Logger instance.
39     */
40    public function __construct( Logger_Interface $logger ) {
41        $this->logger = $logger;
42    }
43
44    /**
45     * Merge original and comparison data by array index.
46     *
47     * @param array                           $original_items   Items from original period.
48     * @param array                           $comparison_items Items from comparison period.
49     * @param string                          $prefix           Prefix for comparison field names.
50     * @param Csv_Report_Controller_Interface $controller       Controller (not used for index-based).
51     * @return array Merged items with comparison data.
52     */
53    public function merge( array $original_items, array $comparison_items, string $prefix, Csv_Report_Controller_Interface $controller ): array { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Signature required by the merge strategy interface; index-based merging aligns by position, not by controller.
54        // Get template items for creating empty rows.
55        $original_template   = ! empty( $original_items ) ? $original_items[0] : array();
56        $comparison_template = ! empty( $comparison_items ) ? $comparison_items[0] : array();
57
58        // Use a copy of a template if the other template is empty (i.e., no data in that set).
59        if ( empty( $comparison_template ) && ! empty( $original_template ) ) {
60            $comparison_template = $original_template;
61        }
62        if ( empty( $original_template ) && ! empty( $comparison_template ) ) {
63            $original_template = $comparison_template;
64        }
65
66        $max_length   = max( count( $original_items ), count( $comparison_items ) );
67        $merged_items = array();
68
69        for ( $i = 0; $i < $max_length; $i++ ) {
70            $merged_item = array();
71
72            // Add original data (or empty marker).
73            if ( isset( $original_items[ $i ] ) ) {
74                $merged_item = $original_items[ $i ];
75            } else {
76                // Use null for controller to ensure empty strings instead of default values (e.g., 0).
77                $merged_item = $this->create_empty_item( $original_template, null );
78            }
79
80            // Add comparison data with prefix (or empty marker).
81            if ( isset( $comparison_items[ $i ] ) ) {
82                foreach ( $comparison_items[ $i ] as $key => $value ) {
83                    $merged_item[ $prefix . $key ] = $value;
84                }
85            } else {
86                // Use null for controller to ensure empty strings instead of default values (e.g., 0).
87                $empty_comparison = $this->create_empty_item( $comparison_template, null );
88                foreach ( $empty_comparison as $key => $value ) {
89                    $merged_item[ $prefix . $key ] = $value;
90                }
91            }
92
93            $merged_items[] = $merged_item;
94        }
95
96        return $merged_items;
97    }
98}