I have a follow-up to a previous thread/question that I hope can be solved by relatively small updates to this existing code. In the other thread/question, I pretty much solved a need for a nested unordered list. I needed the nested unordered list to be broken up into columns based on the number of topics.
For example, if a database query resulted in 6 topics and a user specified 2 columns for the layout, each column would have 3 topics (and the related news items below it).
For example, if a database query resulted in 24 topics and a user specified 4 columns for the layout, each column would have 6 topics (and the related news items below it).
The previous question is called PHP - Simple Nested Unordered List (UL) Array. The provided solution works pretty well, but it doesn't always divide correctly. For example, when $columns = 4, it only divides the columns into 3 groups. The code is below.
Another issue that I'd like to solve was brought to my attention by the gentleman who answered the question. Rather than putting everything into memory, and then iterating a second time to print it out, I would like to run two queries: one to find the number of unique TopicNames and one to find the number of total items in the list.
One last thing I'd like to solve is to have a duplicate set of code with an update that breaks the nested unordered list into columns based on the number of news items (rather than categories). So, this would probably involve just swapping a few variables for this second set of code.
So, I was hoping to solve three issues:
1.) Fix the division problem when relying on the number of categories (unordered list broken up into columns based on number of topics)
2.) Reshape the PHP code to run two queries: one to find the number of unique TopicNames and one to find the number of total items in the list
3.) Create a duplicate set of PHP code that works to rely on the number of news items rather than the categories (unordered list broken up into columns based on number of news items)
Could anyone provide an update or point me in the right direction? Much appreciated!
$columns = // user specified;
$result = mysql_query("SELECT * FROM News");
$num_articles = 0;
// $dataset will contain array( 'Topic1' => array('News 1', 'News2'), ... )
$dataset = array();
while($row = mysql_fetch_array($result)) {
if (!$row['TopicID']) {
$row['TopicName'] = 'Sort Me';
}
$dataset[$row['TopicName']][] = $row['NewsID'];
$num_articles++;
}
$num_topics = count($dataset);
// naive topics to column allocation
$topics_per_column = ceil($num_topics / $columns);
$i = 0; // keeps track of number of topics printed
$c = 1; // keeps track of columns printed
foreach($dataset as $topic => $items){
if($i % $topics_per_columnn == 0){
if($i > 0){
echo '</ul></div>';
}
echo '<div class="Columns' . $columns . 'Group' . $c . '"><ul>';
$c++;
}
echo '<li>' . $topic . '</li>';
// this lists the articles under this topic
echo '<ul>';
foreach($items as $article){
echo '<li>' . $article . '</li>';
}
echo '</ul>';
$i++;
}
if($i > 0){
// saw at least one topic, need to close the list.
echo '</ul></div>';
}
UPDATE 12/19/2011: Separating Data Handling from Output Logic (for the "The X topics per column variant"):
Hi Hakre: I've sketched out the structure of my output, but am struggling with weaving the two new functions with the old data handling. Should the code below work?
/* Data Handling */
$columns = // user specified;
$result = mysql_query("SELECT * FROM News LEFT JOIN Topics on Topics.TopicID = New.FK_TopicID WHERE News.FK_UserID = $_SESSION[user_id] ORDER BY TopicSort, TopicName ASC, TopicSort, NewsTitle");
$num_articles = 0;
// $dataset will contain array( 'Topic1' => array('News 1', 'News2'), ... )
$dataset = array();
while($row = mysql_fetch_array($result)) {
if (!$row['TopicID']) {
$row['TopicName'] = 'Sort Me';
}
$dataset[$row['TopicName']][] = $row['NewsID'];
$num_articles++;
}
/* Output Logic */
function render_list($title, array $entries)
{
echo '<ul><li>', $title, '<ul>';
foreach($entries as $entry)
{
echo '<li>', $entry['NewsID'], '</li>';
}
echo '</ul></li></ul>;
}
function render_column(array $topics)
{
echo '<div class="column">';
foreach($topics as $topic)
{
render_list($topic['title'], $topic['entries']);
}
echo '</div>';
}