Recursive reading of flat file -> hierarchical menu?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Sinemacula
Forum Contributor
Posts: 110
Joined: Sat Feb 08, 2003 2:36 am
Location: San Jose, CA

Recursive reading of flat file -> hierarchical menu?

Post by Sinemacula »

I've managed to create a hierarchical tree-style menu based on recursively pulling data from a mysql database... but I've now discovered I may have to use a flat file rather than a database to hold the data that will create the menu - and I'm not sure how to approach that, having never used a flat text file as a data source before.

So, I'm just wondering what the best approach is, and if I could get some pointers what I should be looking at?

What I'm going to have is a list of courses, which I will divide into groups, with books assigned to each course. So, the data for each record will be:
Course Group
Course
Book Title
ISBN #

There will be one ISBN for each book, multiple books for each course, and multiple courses for each course group.

The menu is in the format of:

Course Group
- Course
- Book, ISBN
- Course
- Book, ISBN
- Book, ISBN
Course Group
- Course
- Book, ISBN

and so on. You can see the one that's based on the mysql database here: http://store.multipleangles.com/indexwmenu.php -- it's the ITP Course Books menu on the right.

I want have it set up in a way similar to how I've done it with the database, where the menu module is already coded and the data just needs to be loaded in, this time from a text file I can replace when the list is updated by the school.

Here's the code I'm using with the mysql database to create the menu (neither elegant nor efficient, I suspect, but it works):

Code: Select all

<?php			
$db = mysql_connect($db_host, $db_user, $db_pass);
mysql_select_db($db_name,$db);
$result = mysql_query("SELECT coursegroup FROM itpgroups",$db);

echo "<ul id=\"treemenu1\" class=\"treeview\">";

while ($myrow = mysql_fetch_array($result))
{

	echo "<li>".$myrow['coursegroup']."";

	$grouping=$myrow['coursegroup'];
	$result2 = mysql_query("SELECT coursenum FROM itpcourses WHERE coursegroup = '$grouping'",$db);

	echo "<ul>";

	while ($myrow2 = mysql_fetch_array($result2))
	{

		echo "<li>".$myrow2['coursenum']."";
		
		$course=$myrow2['coursenum'];
		$result3 = mysql_query("SELECT * FROM itpbooks WHERE coursenum = '$course'",$db);

		echo "<ul>";

		while ($myrow3 = mysql_fetch_array($result3))
		{

			$book=$myrow3['title'];
			
			echo "<li><a href=\"http://astore.amazon.com/itp-ma4cs-20/detail/".$myrow3['isbn']."\" target=\"iframe\" title=\"".$book."\">".truncate_long_string($book, 22)."</a></li>";
		}

		echo "</li></ul>";
	}

	echo "</li></ul>";
}

echo "</li></ul>";

?>
So what I need to do now is get from a text file with the data, through something like this:

Code: Select all

<ul id="treemenu1" class="treeview">
<li>$CourseGroup
     <ul>
           <li>$CourseName
                 <ul>
                      <li><a href="http://url/$ISBN" target="iframe" title="$Title">truncate_long_string($Title, 20)</a></li>
                  </ul>
            </li>
      </ul>
</li>
</ul>
...recursively going through the text file to end up with something like this:

Code: Select all

<ul id="treemenu1" class="treeview">
  <li>Course Group 1
    <ul>
      <li>Course 1
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
      <li>Course 2
        <ul>
            <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]</a></li>
            <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Courses Group 2
    <ul>
      <li>Course 3
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
      <li>Course 4
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
      <li>Course 5
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Course Group 3
    <ul>
      <li>Course 6
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
So, I assume this is possible, but I don't know where to begin.

I guess I need to know:
-- what's the best way to have the text file set up? should it be an xml file? or would there be a way to read the data from a more basic text file?
-- what should I be looking for in terms of available functions and areas in manuals?
-- any specific hints that will make this easier? :wink:

Thanks,
Scott
lanasa
Forum Newbie
Posts: 14
Joined: Mon Mar 26, 2007 7:49 am
Location: Buffalo, NY

Re: Recursive reading of flat file -> hierarchical menu?

Post by lanasa »

Sure, an xml file would be nice, but why not use a CSV file like:

coursegroup, 1
course, 2
book, isbn, 3
course, 2
book, isbn, 3
book, isbn, 3

Where the numbers are the levels in the menu. I'll admit, not elegant, but probably easier than parsing a CSV.


Course Group
- Course
- Book, ISBN
- Course
- Book, ISBN
- Book, ISBN
Course Group
- Course
- Book, ISBN

and so on. You can see the one that's based on the mysql database here: http://store.multipleangles.com/indexwmenu.php -- it's the ITP Course Books menu on the right.

I want have it set up in a way similar to how I've done it with the database, where the menu module is already coded and the data just needs to be loaded in, this time from a text file I can replace when the list is updated by the school.

Here's the code I'm using with the mysql database to create the menu (neither elegant nor efficient, I suspect, but it works):

Code: Select all

<?php			
$db = mysql_connect($db_host, $db_user, $db_pass);
mysql_select_db($db_name,$db);
$result = mysql_query("SELECT coursegroup FROM itpgroups",$db);

echo "<ul id=\"treemenu1\" class=\"treeview\">";

while ($myrow = mysql_fetch_array($result))
{

	echo "<li>".$myrow['coursegroup']."";

	$grouping=$myrow['coursegroup'];
	$result2 = mysql_query("SELECT coursenum FROM itpcourses WHERE coursegroup = '$grouping'",$db);

	echo "<ul>";

	while ($myrow2 = mysql_fetch_array($result2))
	{

		echo "<li>".$myrow2['coursenum']."";
		
		$course=$myrow2['coursenum'];
		$result3 = mysql_query("SELECT * FROM itpbooks WHERE coursenum = '$course'",$db);

		echo "<ul>";

		while ($myrow3 = mysql_fetch_array($result3))
		{

			$book=$myrow3['title'];
			
			echo "<li><a href=\"http://astore.amazon.com/itp-ma4cs-20/detail/".$myrow3['isbn']."\" target=\"iframe\" title=\"".$book."\">".truncate_long_string($book, 22)."</a></li>";
		}

		echo "</li></ul>";
	}

	echo "</li></ul>";
}

echo "</li></ul>";

?>
So what I need to do now is get from a text file with the data, through something like this:

Code: Select all

<ul id="treemenu1" class="treeview">
<li>$CourseGroup
     <ul>
           <li>$CourseName
                 <ul>
                      <li><a href="http://url/$ISBN" target="iframe" title="$Title">truncate_long_string($Title, 20)</a></li>
                  </ul>
            </li>
      </ul>
</li>
</ul>
...recursively going through the text file to end up with something like this:

Code: Select all

<ul id="treemenu1" class="treeview">
  <li>Course Group 1
    <ul>
      <li>Course 1
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
      <li>Course 2
        <ul>
            <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]</a></li>
            <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Courses Group 2
    <ul>
      <li>Course 3
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
      <li>Course 4
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
      <li>Course 5
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Course Group 3
    <ul>
      <li>Course 6
        <ul>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
          <li><a href="http://url/[ISBN]" target="iframe" title="[Title]">[shortened Title]...</a></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
So, I assume this is possible, but I don't know where to begin.

I guess I need to know:
-- what's the best way to have the text file set up? should it be an xml file? or would there be a way to read the data from a more basic text file?
-- what should I be looking for in terms of available functions and areas in manuals?
-- any specific hints that will make this easier? :wink:

Thanks,
Scott[/quote]
Sinemacula
Forum Contributor
Posts: 110
Joined: Sat Feb 08, 2003 2:36 am
Location: San Jose, CA

Re: Recursive reading of flat file -> hierarchical menu?

Post by Sinemacula »

lanasa wrote:Sure, an xml file would be nice, but why not use a CSV file like:

coursegroup, 1
course, 2
book, isbn, 3
course, 2
book, isbn, 3
book, isbn, 3

Where the numbers are the levels in the menu. I'll admit, not elegant, but probably easier than parsing a CSV.
Thanks for the idea, lanasa; it would probably be easier to get the document from the school in a CSV file, or something easily converted to CSV than it would an xml file (therefore meaning less work for me on reformatting!! :D ).

What might be more likely in terms of what the school would give me than the format you laid out would be something like:

course, book, isbn
course, book, isbn
course, book, isbn

Then I would have to add the coursegroup field to each... and then have the CSV parsed to get the data into the page.

So, I guess my next step is to look up info on parsing CSV files and how to do so recursively. (and I'm open to accepting hints :wink: )

Thanks!

Scott
Sinemacula
Forum Contributor
Posts: 110
Joined: Sat Feb 08, 2003 2:36 am
Location: San Jose, CA

Post by Sinemacula »

Okay, I got it!! :D 8)

I don't know if it's pretty, or the best way to do it, but this does exactly what I want:

Code: Select all

<?php	
echo "<ul id=\"treemenu1\" class=\"treeview\">";

$filedata = file('books.csv');

$currentGroup = '' ; 
$currentCourse = '' ; 
$g = 0;
$c = 0;

foreach ($filedata as $line_num => $line) {

$books = explode(',',$line);
				
	if ($currentGroup != $books[0] ) 
	{

		if($g > 0)
		{
			echo "</ul></li></ul></li>";
		 }
		
	$g++;	
	$c=0;		
		
	$currentGroup = $books[0] ; 
	echo "<li>".$currentGroup."<ul>" ; 
	} 

			
  	if ($currentCourse != $books[1]) 
	{ 
			
		 if($c > 0)
		 {
			echo "</ul></li>";
		  }
		
	$c++;
			
  	$currentCourse = $books[1] ; 
	echo "<li>".$currentCourse."<ul>" ; 

	} 

	echo "<li><a href=\"http://astore.amazon.com/itp-ma4cs-20/detail/".$books[3]."\" target=\"iframe\" title=\"".$books[3]."\">".truncate_long_string($books[2], 22)."...</a></li>";

}

echo "</ul>";
?>
If there's a better, or more efficient way, I'm open to it... but I'm also very happy to have this working!

Thanks!
Scott
Post Reply