RiotAct
RiotAct

Reputation: 773

Using For inside of Foreach

This will probably be easy for someone, but I'm not getting this through my head correctly. I am building a invoice PDF using fpdf and want a certain number of rows to display even if some are empty. Here is what I have so far in the relevant portion:

$rows = 12;
$repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
    if ( $repeatable_fields ) {
        foreach ( $repeatable_fields as $field ) {
            $pdf->Cell(96, 15, esc_attr( $field['order_sku'] ), 'L,R,B', 0, 'L');
            $pdf->Cell(258, 15, esc_attr( $field['order_item'] ), 'R,B', 0, 'L');
            $pdf->Cell(30, 15, esc_attr( $field['order_qty'] ), 'R,B', 0, 'C');
            $pdf->Cell(96, 15, esc_attr( $field['order_price'] ), 'R,B', 0, 'R');
            $pdf->Cell(96, 15, esc_attr( $field['order_subtotal'] ), 'R,B', 1, 'R');
            $counter++;     
        }
        for ($counter = 0 ; $counter < $rows; $counter++){
            $pdf->Cell(96, 15, '', 'L,R,B', 0, 'L');
            $pdf->Cell(258, 15, '', 'R,B', 0, 'L');
            $pdf->Cell(30, 15, '', 'R,B', 0, 'C');
            $pdf->Cell(96, 15, '', 'R,B', 0, 'R');
            $pdf->Cell(96, 15, '', 'R,B', 1, 'R');
        }
    }

This is working (somewhat). It creates 12 new rows below the loop. I want a total of 12 including the looped response. I've tried a few different variations but can't get the code to produce the right number of rows.

Upvotes: 1

Views: 42

Answers (2)

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41810

The reason this isn't working the way you are expecting is that you are resetting $counter to zero in the definition for your for loop. It should work with one slight change. Instead of incrementing $counter, decrement $rows. Then when you get to the for loop, it will just count up to however many rows are left.

$rows = 12;
$repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
    if ( $repeatable_fields ) {
        foreach ( $repeatable_fields as $field ) {
            $pdf->Cell(96, 15, esc_attr( $field['order_sku'] ), 'L,R,B', 0, 'L');
            $pdf->Cell(258, 15, esc_attr( $field['order_item'] ), 'R,B', 0, 'L');
            $pdf->Cell(30, 15, esc_attr( $field['order_qty'] ), 'R,B', 0, 'C');
            $pdf->Cell(96, 15, esc_attr( $field['order_price'] ), 'R,B', 0, 'R');
            $pdf->Cell(96, 15, esc_attr( $field['order_subtotal'] ), 'R,B', 1, 'R');

            $rows--; // <-------- change this

        }
        for ($counter = 0 ; $counter < $rows; $counter++){
            $pdf->Cell(96, 15, '', 'L,R,B', 0, 'L');
            $pdf->Cell(258, 15, '', 'R,B', 0, 'L');
            $pdf->Cell(30, 15, '', 'R,B', 0, 'C');
            $pdf->Cell(96, 15, '', 'R,B', 0, 'R');
            $pdf->Cell(96, 15, '', 'R,B', 1, 'R');
        }
    }

Upvotes: 1

stratedge
stratedge

Reputation: 2820

If the goal is to have 12 rows, even if you have less than 12 data points, I think this might do it:

$repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);

$rows = 12;

//Loop 12 times
for ($i = 0; $i < $rows; $i++) {
    if (!empty($repeatable_fields[$i])) {
        //Since we have an entry for this row number, we'll use it
        $pdf->Cell(96, 15, esc_attr($repeatable_fields[$i]['order_sku']), 'L,R,B', 0, 'L');
        $pdf->Cell(258, 15, esc_attr($repeatable_fields[$i]['order_item']), 'R,B', 0, 'L');
        $pdf->Cell(30, 15, esc_attr($repeatable_fields[$i]['order_qty']), 'R,B', 0, 'C');
        $pdf->Cell(96, 15, esc_attr($repeatable_fields[$i]['order_price']), 'R,B', 0, 'R');
        $pdf->Cell(96, 15, esc_attr($repeatable_fields[$i]['order_subtotal']), 'R,B', 1, 'R');
    } else {
        //No entry for this row number, print a blank row
        $pdf->Cell(96, 15, '', 'L,R,B', 0, 'L');
        $pdf->Cell(258, 15, '', 'R,B', 0, 'L');
        $pdf->Cell(30, 15, '', 'R,B', 0, 'C');
        $pdf->Cell(96, 15, '', 'R,B', 0, 'R');
        $pdf->Cell(96, 15, '', 'R,B', 1, 'R');
    }
}

This is untested, but assuming $repeatable_fields is indexed numerically starting at 0 with no breaks, it should do what I think you're looking for.

Edit 1

If my assumption that $repeatable_fields is numerically indexed starting at zero is wrong, you can use array_values to convert it to that format.

Upvotes: 0

Related Questions