Reputation: 6986
I am working on a project at the moment, that requires me to create a HTML view and then send it to DOMPDF to create a PDF of the view.
However the loop that builds my view is not very well written and when the tables and rows are created, there seems to be zero consistency as to whether an opening HTML tag actually gets closed or not, this is causing my problems with DOMPDF as it does not like tables or HTML elements for that matter that are not closed properly, below is the array I am working with and also the PHP loop.
The array
Array
(
[0] => Array
(
[credit_id] => 11
[credit_heading] => Testing another new entry
[credit_title] => Testing another new entry
[credit_role] => Testing another new entry
[credit_director] => Testing another new entry
[credit_type] => long
[credit_position] => 0
[date_created] => 2012-01-10 17:06:24
[candidates_candidate_id] => 54
[rel_id] => 8
[credits_candidate_id] => 54
[credits_credit_id] => 11
[category_title] => Feature Film
[category_position] => 0
)
[1] => Array
(
[credit_id] => 1
[credit_heading] => Test Heading 1
[credit_title] => Test Title 1
[credit_role] => Test Role 1
[credit_director] => Test Director 1
[credit_type] => long
[credit_position] => 1
[date_created] => 2012-01-06 17:23:41
[candidates_candidate_id] => 54
[rel_id] => 1
[credits_candidate_id] => 54
[credits_credit_id] => 1
[category_title] => Corporate
[category_position] => 3
)
[2] => Array
(
[credit_id] => 6
[credit_heading] => Test Heading 4
[credit_title] => Test Title 4
[credit_role] => Test Role 4
[credit_director] => Test Director 4
[credit_type] => long
[credit_position] => 2
[date_created] => 2012-01-06 17:20:40
[candidates_candidate_id] => 54
[rel_id] => 3
[credits_candidate_id] => 54
[credits_credit_id] => 6
[category_title] => Corporate
[category_position] => 3
)
)
The code
<?php if($credit['credit_type'] == "long") : ?>
<?php if($credit['category_title'] != $oldvalue) : ?>
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0px 0px 15px 0px;" class="long-entry">
<tbody>
<?php endif; ?>
<?php if($credit['category_title'] != $oldvalue) : ?>
<tr>
<td width="25%"><strong><?php echo trim($credit['category_title']); ?></strong></td>
<td width="25%"><strong>Title</strong></td>
<td width="25%"><strong>Role</strong></td>
<td width="25%"><strong>Director</strong></td>
</tr>
<?php else : ?>
<tr>
<td width="25%"><?php echo $credit['credit_heading'];?></td>
<td width="25%"><?php echo $credit['credit_title']; ?></td>
<td width="25%"><?php echo $credit['credit_role']; ?></td>
<td width="25%"><?php echo $credit['credit_director']; ?></td>
</tr>
<?php endif; ?>
</tbody>
</table>
<?php $oldvalue = $credit['category_title']; ?>
<?php endif; ?>
What the above code is trying to achieve is that while the $credit['category_title']
is new we create a new table, if on the next iteration it is still the same, we add a row to the table, and so on and so forth. What is in actual fact is that it creates a new table adds a new row and then does not close that row or the table.
Expected outcome
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td width="10%"><strong>Corporate</strong></td>
<td width="40%"><strong>Title</strong></td>
<td width="25%"><strong>Role</strong></td>
<td width="25%"><strong>Director</strong></td>
</tr>
<tr>
<td width="10%">Test Heading 1</td>
<td width="40%">Test Title 1</td>
<td width="25%">Test Role 1</td>
<td width="25%">Test Director 1</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td width="10%">Test Heading 4</td>
<td width="40%">Test Title 4</td>
<td width="25%">Test Role 4</td>
<td width="25%">Test Director 4</td>
</tr>
</tbody>
Actual outcome
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td width="10%"><strong>Corporate</strong></td>
<td width="40%"><strong>Title</strong></td>
<td width="25%"><strong>Role</strong></td>
<td width="25%"><strong>Director</strong></td>
</tr>
<tr>
<td width="10%">Test Heading 1</td>
<td width="40%">Test Title 1</td>
<td width="25%">Test Role 1</td>
<td width="25%">Test Director 1</td>
</tr>
<tr>
<td></td>
</tr>
Test Title 4 Test Role 4 Test Director 4
</tbody>
</table>
How should my loop look so that it create valid HTML and not the crap that I am at the moment?
Upvotes: 0
Views: 1204
Reputation: 13944
I stand by my answer when this question was asked previously. The code is ugly but I believe it will work.
However, this version of the question provides much more detail on what's going on. I think a better solution would be to update the data array to better reflect the nature of the data. So try something like this:
<?php
$credit_categories = array();
foreach ($records as $record) :
if (!array_key_exists($record['category_title'], $credit_categories)) :
$credit_categories[$record['category_title']] = array(
'category_title' => $record['category_title'],
'category_position' => $record['category_position'],
'credits' => array()
);
endif;
$credit_categories[$record['category_title']]['credits'][] = $record;
endforeach;
foreach ($credit_categories as $credit_category) : ?>
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:0px 0px 15px 0px;" class="long-entry">
<tbody>
<tr>
<td width="25%"><strong><?php echo trim($credit_category['category_title']); ?></strong></td>
<td width="25%"><strong>Title</strong></td>
<td width="25%"><strong>Role</strong></td>
<td width="25%"><strong>Director</strong></td>
</tr>
<?php foreach ($credit_category['credits'] as $credit) : ?>
<tr>
<td width="25%"><?php echo $credit['credit_heading'];?></td>
<td width="25%"><?php echo $credit['credit_title']; ?></td>
<td width="25%"><?php echo $credit['credit_role']; ?></td>
<td width="25%"><?php echo $credit['credit_director']; ?></td>
</tr>
<?php endforeach; // end $credit loop ?>
</tbody>
</table>
<?php endforeach; // end $credit_categories loop ?>
Some notes:
$records
to represent your initial data array, since you didn't specify the variable.$credit_categories
... just make sure it's unique for each category and represented in each record. I prefer to use IDs instead of text fields, I'm just working with what you've given us and I wasn't sure if category_position
would be unique.A special note on data structure:
I've modified your existing data structure, but you should strive to achieve a structure like this initially. Most MVC frameworks will supply a normalized data structure by default (if the database is normalized). If the database is not normalized, or if this is custom code, your first task should be to reformat the data array to better reflect a normalized data structure.
On the other hand data normalization isn't always necessary. Plus the code that normalizes the data can cause a lot of overhead depending on the number of records that need to be processed. So always determine ahead of time if normalization will make your job easier.
Upvotes: 1
Reputation: 3654
Something like this will probably do it, although I admit it isn't the most efficient solution.
You could speed it up slightly by using for loops instead of foreachs perhaps.
<?php
//where $creditArray is the array you're using
$tables = Array();
foreach ($creditArray as $row) {
$tables['category_title'][] = $row;
}
foreach ($tables as $table) {
echo '
<table>
<tr>
<td width="25%">
<strong>'.trim($table[0]['category_title']).'</strong>
</td>
<td width="25%"><strong>Title</strong></td>
<td width="25%"><strong>Role</strong></td>
<td width="25%"><strong>Director</strong></td>
</tr>';
foreach ($table as $row) {
echo'<tr>
<td width="25%">'.$row['credit_heading'].'</td>
<td width="25%">'.$row['credit_title'].'</td>
<td width="25%">'.$row['credit_role'].'</td>
<td width="25%">'.$row['credit_director'].'></td>
</tr>';
}
echo "</table>";
}
?>
Upvotes: 0
Reputation: 41080
category_title
in the third array is the same as the previous: "Corporate
", so the code acts different for the third case.
Upvotes: 1