php and mysql dynamic breadcrumps - php

I have a website that list all food sources; In my db I've made a MySQL table named [foods]
In my page, when the user click the category he gets list of its all children. in my case
food
-- Plants
---- Vegetable
------ Aubergine
------ Broad_bean
------ Broccoli
------ Carrot
---- Fruits
------ Apple
------ Apricot
------ Banana
------ Cherry
------ Clementine
------ Guava
-- Animals
Now, I want to make a dynamic breadcrumbs navigation in the top of my page, something like
Food > Plants > Fruits > Banana
So the user can navigate through them.
I've tried several queries to get this but with no luck.
Every time I get only the first parent of the category only
So if I am in Banana page I only get the Fruits category, nothing deeper.
I know I have to use while loop where cat_parent_id != 0 but I couldn't figure-out how to implement it the right way!
here is a code snippet I've tried
$cat_parent_id = $_REQUEST['cat_id'];
$q = mysqli_query($link, "SELECT * FROM foods WHERE cat_id = $cat_parent_id");
while($r = mysqli_fetch_assoc($q))
{
echo $name = $r['cat_name'];
}
I really appreciate your help in this regards
Thanks in advance...

u have to use recursive function. means check
for ex:
function show_breadcumb($cat_id)
{
$q = mysqli_query($link, "SELECT * FROM foods WHERE cat_id = $cat_id");
while($r = mysqli_fetch_assoc($q))
{
$name = $r['cat_name'];
$string.= $name .">".$string
}
//check if this category has any parent again call this fucntion
if( has parent ) { show_breadcumb($cat_id) }
else return $string;
}
Means ur loop should continue find category up to first level.

Related

How to store data according to priority in database?

I want to store my category list in database with priority...like
cat_id cat_name cat_priority
---------------------------------
1 Test1 1
2 Test2 2
3 Test3 3
4 Test4 4
Now if i have to set Test1priority to 3..then there will be conflict on Test3 Now again if i want to set Test2 priority to 4 then how i can fetch data via php according to priority system..How it will work, and what i need to change in my table structure..
Each time you will want to change an item priority, you will have to re-assign priority for each of them. I assume you do not want duplicate priority.
//$category = ...
//get all categories
$categories = $this->db->order_by('cat_priority')->select('cat_id, cat_priority')->get();
$cat_to_change = $category['cat_id'];
$new_priority = 2;
$i_priority = 0;
$new_categories = array();
foreach($categories->result_array() as $row)
{
//this is the category we want to change, so change it
if($row['cat_id'] == $cat_to_change)
{
$row['cat_priority'] = $new_priority;
}
else
{
//increment the priority
$i_priority++;
//the new priority is owned by another cat
//so let it for the cat we want for him
if($row['cat_priority'] == $new_priority)
$i_priority++;
$row['cat_priority'] = $i_priority;
}
$new_categories[] = $row;
}
//save
$this->db->update_batch('categories', $new_categories, 'cat_id');
Didn't test it. Hope it help.

Data display on PHP (Select Query)

I have a table which contains:
transaction_id | the_pet | name_of_the_owners
1 dog shiela
2 dog ben
3 dog alice
4 cat jonathan
and on my query:
$query="select * from table ORDER BY name_of_the_owner limit 5";
$r=mysqli_query($query);
while ($row=mysqli_fetch_array($r)) {
echo "<tr>";
echo "<td><a href='../php/ownersname.php?the_pet=".$row['the_pet']."'>".$row['the_pet']."</a></td>";
echo "</tr>";
}
However, when I use the $query, it shows all the data from the table.
What I need is this:
the_pet
dog (hyperlink)
cat (hyperlink)
So whenever I click on the hyperlink, the name_of_the owners will be shown in another page
for the dog when clicked
name_of_the_owners
shiela
ben
alice
I already used
$query = "SELECT MAX(transaction_id) as transaction_id, the_pet GROUP BY the_pet, name_of_the_owners;
but when I clicked on the hyperlink, it doesn't show the owners. :(
so if I understand it right you dont want to show duplicates right ?
I think the best way to do this, is to change your select query to
$query = "SELECT DISTINCT the_pet FROM table";
and if you dont want to do that you could filter a array for duplicates
like so:
$arr = array('php','jsp','asp','php','asp');
$unique = array_unique($arr);
print_r($dups);
both will do the trick!

How to numerate a Hierachical Table of Contents in PHP out of a parent-child (adjacency) table

I'm trying to numerate/create or generate a Table of contents in PHP out of a MySQL database in an adjacency tree model (id, parent_id). So far this is what I have achieved when echoing the output.
1. Category 1
1 Subcategory 1
2 Subcategory 2
3 Subcategory 3
2. Category 2
1. Subcategory 1
1. Subcategory Subcategory 1
2. Subcategory Subcategory 2
2 Subcategory 2
1 Subcategory 1
2 Subcategory 2
I'm very close, but what the output I want is:
1. Category 1
1.1 Subcategory 1
1.2 Subcategory 2
1.3 Subcategory 3
2. Category 2
2.1. Subcategory 1
2.1.1. Subcategory Subcategory 1
2.1.2. Subcategory Subcategory 2
2.2 Subcategory 2
2.2.1 Subcategory 1
2.2.2 Subcategory 2
In other words, I want to use the Table of contents format in a multilevel hierarchical structure as follows: Chapter.Subchapter.Subchapter.Subchapter TITLE.
I have tried by using a recursive array that keeps the current index and concatenates to the previous index but what it ends up adding a weird long number before each item, such,
0.11.2..11.2.3.4.5.6.7..11..11.2.3.4.5.6 Computers,
when instead it should be just:
2.7.6 Computers.
(The other numbers are the numbers of the other items)
This is the code I've been working on
renumber(0,0,1,0);
function renumber($parent_id,$level=0,$counter=1) {
// Counter level keeps track of the current index number
$counterlevel[$level]=$counter;
$query = "SELECT defaultTitle, id, pid FROM defaultChapters WHERE pid=".$parent_id;
$res = mysql_query($query) or die(mysql_error());
// Exit if there are no tree leafs
if(mysql_num_rows($res) == 0) {return;}
while (list ($title, $id) = mysql_fetch_row($res))
{
$leveltext[$level][$counterlevel[$level]] = $section.".".$counterlevel[$level];
echo str_repeat("......",$level)." ".$counterlevel[$level]." ".$section." ".$title."<BR>";
// Increase the counter of the current level
$counterlevel[$level]++;
// Initialize the level counter
if(!$counterlevel[$level+1]) {
$counterlevel[$level+1] = 1;
}
// Start the function again to find children
renumber($id,$level+1,$counterlevel[$level+1]);
} // End While
}
I have browsed all the technical support forums, including this one and it seems nobody has ever published an algorithm for this, simply there is no sample code for this anywhere to be found. There are hundreds of tutorials and codes to get a hierarchical tree in php out of a mysql database without numbering but nothing about numerating a hierarchical Table of Contents in php.
Is it possible to do it with a SQL query too?
I would refactor it a little bit and pass along the numbering up to the current invocation:
function renumber($parent_id = 0, $level = 0, $prefix = '')
{
// we don't need pid in the results
$query = "SELECT defaultTitle, id
FROM defaultChapters
WHERE pid=$parent_id";
$res = mysql_query($query) or die(mysql_error());
// Exit if there are no tree leafs
if (mysql_num_rows($res) == 0) {
return;
}
// start numbering at 1
$nr = 1;
while (list($title, $id) = mysql_fetch_row($res)) {
// dropped section, not sure where it was used
echo str_repeat("......", $level) . " $prefix.$nr $title<BR>";
// Start the function again to find children
renumber($id, $level + 1, strlen($prefix) ? "$prefix.$nr." : "$nr.");
// advance list numbering
++$nr;
}
}
renumber();

How can I use recursion to retrieve parent nodes?

I have created a recursive function to get parent products of a product. I'm almost sure I'm nearly there, but need help snapping out of recursion.
The result I am looking for is something like:
Product 1 (id:1, parent:none)
Product 2 (id:2, parent:1)
--- --- Product 3 (id:3, parent:2)
--- --- Product 4 (id:4, parent:2)
--- Product 5 (id:5, parent:1)
--- --- Product 6 (id:6, parent:5)
--- --- Product 7 (id:7, parent:5)
My updated function is as follows:
function get_parents ($pid, $found = array()) {
array_push ($found, $pid);
$sql = "SELECT * FROM products WHERE child_id = '$pid'";
$result = mysql_query($sql) or die ($sql);
if(mysql_num_rows($result)){
while($row = mysql_fetch_assoc($result)){
$found[] = get_parents($row['pid'], $found);
}
}
return $found;
}
I call it using a simple:
$parents = get_parents($pid);
The problem I am having is that when I run it, it creates an infinite loop, which doesn't break.
I don't want to get done for spamming so I have saved the result of my array to a text file, which can be seen here http://vasa.co/array.txt
Any help would be seriously appreciated :-)
Hmm.. judging by your structure of your DB, it would seem that something is amiss unless I'm missing something
The statement
$sql = "SELECT * FROM products WHERE child_id = '$pid'";
Tells me that for each product, you are storing the ID of the child. Typically, in a tree based structure, it's the reverse, you store the parent ID not the child - unless you want a child node to have many parents. If that is the case, then the function could easily run into problems. Consider the following:
| ID | Child_ID |
+----+----------+
| 1 | 2 |
| 2 | 1 |
This would cause an infinite loop. If you store the parent_id, then by that nature, you are encoding the graph to be hierarchical. Since every product has A parent, then the logic can be written recursively.
The could then be written as such?
function get_parents ($pid, $found = array()) {
array_push ($found, $pid);
$sql = "SELECT * FROM products WHERE id = '$pid'";
$result = mysql_query($sql) or die ($sql);
if(mysql_num_rows($result)){
while($row = mysql_fetch_assoc($result)){
$found[] = get_parents($row['parent_id'], $found);
}
}
return $found;
}

Build category - sub category html list from mysql table

i have a table with categoryId, name and parentId. I would like to build a html list with parent and child tree like structure
my table looks like this
------------------------------------------------------------------
id categoryId parentId categoryName SortSeq
------------------------------------------------------------------
1 438044691 NULL test 1
2 438044692 438044691 test item one 2
3 438044693 438044691 test item two 3
1 438044701 NULL testOne 4
2 438044702 438044701 testOne item one 5
3 438044703 438044701 testOne item two 6
1 438044709 NULL testTwo 7
2 438044710 438044709 testTwo item one 8
3 438044711 438044709 testTwo item two 9
the structure can have sub-sub category item as well. but its just one in this example.
i'll be more than happy to give you more information if you think the question is incomplete.
thank you very much.
I use "Modified Preorder Tree Traversal", which is also called "Nested Sets". This Sitepoint article provides a good summary of how it works. Hector Virgen has written a Zend_Db_Table enhancement to support it that I am using because my app is built on the Zend Framework. I've also used the code written by Nick Pack to build the tree in PHP.
function categorylist($parent=NULL, $level = 0) {
$sql = "SELECT `id`,`name` FROM `categories` WHERE `parentId`";
if($parent === NULL) {
$sql .= " IS NULL";
else {
$sql .= " = '".$parent."'";
}
$sql .= " ORDER BY `SortSeq`";
$res = mysql_query($sql);
while ($cat = mysql_fetch_object($res)) {
echo '<li class="level'.$level.'">'.$line['name'].'</li>';
$new_level = $level + 1;
categorylist($line['id'], $new_level);
}
}
echo '<ul>';
categorylist();
echo '</ul>';
You can then style the list how you want with each each class level1, level2 etc..
You're probably looking at a recursive function as being the simplest solution to this. A really simple example is something like this, there are various techniques you could use to make this a proper tree structure. Really depends what you want to do tbh
function showlist($parent=NULL) {
$q = ($parent !== NULL) ? "SELECT `id`,`name` FROM `categories` WHERE `parentId` ='".$parent."'" : "SELECT `id`,`name` FROM `categories` WHERE `parentId` IS NULL";
$result = mysql_query($q)or die(mysql_error());
while ($cat = mysql_fetch_assoc($result)) {
echo $line['name'];
showlist($line['id']);
}
}
Theres some really good info on the MySQL site about managing hierarchical data but the most elegant solutions would mean you changing your Schema which i'm not sure if you're able to do or not?

Categories