restrict children count till 6th level in a tree - php

the php function i made gets all the children of a the parent in tree form . The problem is that it gets all the children but i want to restrict it till level 6th of the tree . The code i made is
get_childs("2");
function get_childs($parent_id){
GLOBAL $con;
if ($result = mysqli_query($con,"SELECT * FROM user_profile WHERE referred_by='$parent_id'")) {
echo '<ul>';
while ($row = $result->fetch_assoc()) {
echo '<li>'.$row['user_id'].'';
//call again for each child. if the id dosen't have childs, then prints nothing and go on!
get_childs($row['user_id']);
echo '</li>';
}// end while
echo '</ul>';
}// end if select
}
The output it generates
I want to restrict it till 17 as in above output as the level 6th reaches there .

As per my comment, I'd suggest something like this:
get_childs("2", 0);
function get_childs($parent_id, $level){
GLOBAL $con;
if ($result = mysqli_query($con,"SELECT * FROM user_profile WHERE referred_by='$parent_id'")) {
echo '<ul>';
while ($row = $result->fetch_assoc()) {
echo '<li>'.$row['user_id'].'';
//call again for each child. if the id dosen't have childs, then prints nothing and go on!
if($level < 6)
get_childs($row['user_id'], $level + 1);
echo '</li>';
}// end while
echo '</ul>';
}// end if select
}
With this tiny alteration, your tree will stop as soon as the 6th level is reached. (You might have to tweak it a tiny bit)

get_childs("2", 6);
function get_childs($parent_id, $level){
if($level < 1) return false;
GLOBAL $con;
if ($result = mysqli_query($con,"SELECT * FROM user_profile WHERE referred_by='$parent_id'")) {
echo '<ul>';
while ($row = $result->fetch_assoc()) {
echo '<li>'.$row['user_id'].'';
//call again for each child. if the id dosen't have childs, then prints nothing and go on!
get_childs($row['user_id'], $level--);
echo '</li>';
}// end while
echo '</ul>';
}// end if select
}

Related

I am getting duplicate nodes on my family tree

My function is duplicating some nodes on the tree. When I am calling that function in a recursive way. I have a database table of all father, mother, wife, husband, child ids. I am taking all persons from their father id only. I don't know from where these extra nodes are coming and how should I handle ie it. Output image
<?php
function categoryTree($parent_id = 0,&$alreadyThereArr=array())
{
$ci =& get_instance();
//$query = $ci->db->query("SELECT * FROM tbl_user WHERE father_id = $parent_id ORDER BY id ASC");
$sql="SELECT * FROM `tbl_user` WHERE father_id = '$parent_id' ORDER BY id ASC";
$query=$ci->db->query($sql);
$result=$query->result();
if(count($result) > 0)
{
echo '<ul>';
foreach($result as $key)
{
if(!in_array($key->id,$alreadyThereArr))
{
//echo 'In';
if($key->wife_id != 0)
{
//echo 'wife';
$wife=$ci->Main_M->getSingleRow('tbl_user','id',$key->wife_id);
$start='<div>
<span class="male">'.$key->name.'</span>
<span class="spacer"></span>
<span class="female">'.$wife->name.'</span>
</div>';
}
else
{
$gender=($key->gender == 'M') ? 'male' : 'female';
$start='<div><span class="'.$gender.'">'.$key->name.'</span></div>';
}
$alreadyThereArr[]=&$key->id;
echo '<li>';
echo $start;
echo '<ul>';
categoryTree($key->id, $alreadyThereArr);
echo '</ul>';
echo '</li>';
}
}
echo '</ul>';
}
//print_r($alreadyThereArr);
}
?>

How to show specific menu items for specific user login in PHP using mysql

I have a tables in MySQL one is test table columns like this
id refid name userdefined
1 0 A
2 0 B
3 0 C
4 1 A1 abc
5 1 A2 cde
6 2 B1
7 2 B2
8 3 C3
9 3 c4
10 3 c5
11 2 C7
12 2 C8 lmn
13 11 c9
14 11 c10
Using the above table I am creating the dynamic menu using a PHP function.
I have one more table, it has the login fields and data like this:
id username password field3
1 john john 1,3,4,5,6,7,8,9
What i want is if John is logged in, how do I only show the menu items in field3.
I am new to PHP. I am showing all menu items using a function in
PHP please help me, thanks in advance.
<?php
//this is php function for creating menu
$sql2 = mysqli_query($conn, 'select * from login');
$row = mysqli_fetch_array($sql2);
$menu_items = explode(',', $row['field3']);
function submenu($parentid = 0)
{
global $conn;
$sql = mysqli_query($conn, "SELECT * FROM test WHERE refid=" . $parentid . " AND id IN " . ($menu_items));
{
$rowcount = mysqli_num_rows($sql);
if ($rowcount > 0) {
echo '<ul>';
}
while ($row = mysqli_fetch_array($sql, MYSQLI_ASSOC)) {
if ($row['refid'] == 0) {
echo '<li class="limain">' . $row['name'];
submenu($row['id']);
echo '</li>';
} else {
if ($row['userdefined']) {
echo '<li class="lichild">' . $row['name'] . '';
} else {
echo '<li class="lichild">' . $row['name'];
}
submenu($row['id']);
echo '</li>';
}
}
if ($rowcount > 0) {
echo '</ul>';
}
}
}
?>
$sql2=mysqli_query($conn,'select * from login');
$row = mysqli_fetch_array($sql2);
//storing the field values in menuitems variables
$menu_items = $row['field3'];
//pass the menuitem variables to query
function submenu($parentid=0){
global $conn;
$sql=mysqli_query($conn,"SELECT * FROM test WHERE refid=".$parentid ." AND
id in ($menu_items)");
{
$rowcount=mysqli_num_rows($sql);
if($rowcount>0){
echo '<ul>';
}
while($row=mysqli_fetch_array($sql,MYSQLI_ASSOC))
{
if($row['refid']==0)
{
echo '<li class="limain">'.$row['name'];
submenu($row['id']);
echo '</li>';
}
else{
if($row['userdefined']){
echo '<li class="lichild">'.$row['name'].'';
}else{
echo '<li class="lichild">'.$row['name'];
}
submenu($row['id']);
echo '</li>';
}
}
if($rowcount>0){
echo '</ul>';
}
}
}
Your function is mostly correct in principle, I had a bit of trouble following your function so I changed a few things to improve readability, but this should work.
The only issue I found that would prevent this from working was your if($refid), which is checking for any data not == to null.
0 == null //true 0 === null //false
If I understood your table correctly, entries with a refid of 0 are parent items. In that case they're the only menu items passing into that part of the function, so I changed it from if ($refid) to if ($refid === 0)
With regards to you wanting to you only wanting to show specific menu items, you'll need to run a separate query outside of the function to get the list you made. And then add a check in you submenu() function.
I didn't have a way to test this, but it should work.
//Query to get list of menu items
$menu_items = explode(',', $row['menus']);
function submenu($parentid=0, $menu_items=null) {
global $conn;
$sql=mysqli_query($conn,"SELECT * FROM test WHERE refid=".$parentid);
$rowcount=mysqli_num_rows($sql);
if($rowcount > 0) {
echo '<ul>';
}
while($row=mysqli_fetch_array($sql,MYSQLI_ASSOC)) {
if($menu_items !== null || !in_array($id, $menu_items)) {
continue;
}
$id = $row['id'];
$refid = $row['refid'];
$userdefined = $row['userdefined'];
$name = $row['name'];
if($refid === 0) {
echo "<li class='limain'>{$name}";
submenu($id, $menu_items);
echo '</li>';
} else if ($refid > 0) {
if($userdefined) {
echo "<li class='lichild'><a href='{$userdefined}'>{$name}</a>";
} else {
echo "<li class='lichild'>{$name}";
}
submenu($id, $menu_items);
echo '</li>';
}
}
if($rowcount > 0) {
echo '</ul>';
}
}
You must protect the php files too, not only the menu items. If the user know the php filename, can access with a direct link to protected area.

How Would I Turn Mysqli Table Results into a menu with drop down

Here Is my question: What I am wanting To do is Take Results from a mysql table and turn them into a menu and a drop down menu
HERE IS A QUICK EXAMPLE:
if you see in my mysql table i have page_name and parent, So the example is:
page_name and if i have row 1 the page_name is 'Home' now it's parent is 'none' right but on id number 39 the page_name is 'Contact Us' and the Parent Is 'Far Far Away 123' so if the parent is equal to 'none' then it will show at the top of the menu not the drop down if it has a parent it will show under that parent like this:
Home | the ben page | The Brock Page | Far Far Away 123 | dsfk
Contact Us
You see Contact Us is under Far Far Away Because the parent Is Far Far Away 123
here is my table:
Here is my code That I am trying but it is not working for some reason:
<ul>
<?php
$sql = "SELECT * FROM pages ORDER by item_order";
$result = mysqli_query($db, $sql);
confirm_query($result);
while ($links = mysqli_fetch_assoc($result)) {
if($links['parent'] !== "none") {
?>
<li id = "<?php echo $links['id']; ?>"><a href="
<?php
echo "page.php?id=" . $links['id'] . "\" title=\"" . $links['page_title'] . "\"";
?>>
<?php
echo $links['page_name'];
?>
</a>
<?php
if($links['parent'] !== "none") {
$child = "";
$sql = "SELECT * FROM pages";
$result = mysqli_query($db, $sql);
while($row = mysqli_fetch_assoc($result)) {
if($row['parent'] !== "none") {
$child = $row['page_name'];
}
}
echo "<ul id=\"sub_menu\" class=\"sub_navagation" . $links['id'] . "\">";
echo "<li>";
echo $child;
echo "<li>";
echo "</ul>";
}
?>
</li>
<?php
}
}
?>
</ul>
CSS:
#sub_menu {
display: none;
}
#sub_menu:hover {
display: block;
}
Ok if as you can see i have the parent row in the MYSQL table and on id number 39 i want the 'Far Far Away123' to be the parent of Contact Us and i want to show it when i hover over 'Far Far Away123'
My suggestion is to build out an array of all the results. Then run through that array (instead of multiple database queries).
I added a function build_dropdown() that will take the page name and run through the array of pages to see if there are any items with a parent matching. If so, we make an array of those items and run through them to build the dropdown menu. If not, it does nothing and moves on to the next menu item.
<?php
function build_dropdown ($parent, $pages){
foreach($pages as $page){
if($page['parent'] == $parent){
$items = $page;
} // END if
} // END foreach
if(is_array($items)){ // If a sub
echo '<ul id="sub_menu" class="sub_navagation'. $item['id'] .'">';
foreach($items as $item){
echo '<li>'.$item['name'].'<li>';
} // END foreach
echo '</ul>';
} // END if
}
$sql = "SELECT * FROM pages ORDER by item_order";
$result = mysqli_query($db, $sql);
confirm_query($result);
while ($row = mysqli_fetch_assoc($result)) {
$pages[] = $row; // Add each row to $pages array to use later
}
foreach($pages as $key => $page){
if($page['parent'] == 'none'){ ?>
<li id = "<?php echo $page['id']; ?>">
<a href="page.php?id=<?php echo $page['id']; ?>" title="<?php echo $page['page_title']; ?>">
<?php echo $page['page_name']; ?>
</a>
<?php
build_dropdown($page['page_name'], $pages); // If there are child items then build them out
?>
</li>
<?php
} // END if
} // END foreach
?>
I suggest you will need to JOIN your table to basically query it again to get the parent value, and add that to your markup.
SELECT *
FROM Pages
LEFT JOIN Pages p2 on page_name = p2.parent
(note: the syntax above may not be right, but I wanted to give you an idea of where I would start).

While inside while php

We're trying to put a while inside a while loop.
The first while is run through and the results are displayed in a list (139, 140, 141).
The list for the second while only displays one value (1ste troop).
These are the results:
139
1ste troop
140
141
So it seems that the second while is only executed once.
What can I do to fix this?
echo "<ul>";
while($user = $allUsersintroops->fetch_assoc())
{
if($user['userid'] == $_SESSION['userid'])
{
echo "<li>" . $user['troopid']. " </li>";
while ($mytroops = $alltroops->fetch_assoc())
{
if($user['troopid'] == $mytroops['troopid'])
{
echo "<li>" . $mytroops['description']. " </li>";
}
}
}
}
echo "</ul>";
The inner loop stops once fetch_assoc returns false... but that indicates the end of all found results and it doesn't have any rows left for the next iteration.
You should collect all the rows from $alltroops into an array once, then iterate over that:
echo "<ul>";
$allTroopsList = array();
while ($mytroops = $alltroops->fetch_assoc()) {
$allTroopsList []= $mytroops;
}
while($user = $allUsersintroops->fetch_assoc()) {
if($user['userid'] == $_SESSION['userid']) {
echo "<li>" . $user['troopid']. " </li>";
foreach($allTroopsList as $mytroops) {
if($user['troopid'] == $mytroops['troopid']) {
echo "<li>" . $mytroops['description']. " </li>";
}
}
}
}
echo "</ul>";
Additionally, you should consider adding some filtering to your $allUsersintroops query, because you are only using a part of the the returned rows, which means the rest of the rows are sent from the DB to your code for no reason, wasting time and bandwidth.

How to create a nested menu from MySQL with PHP?

I need to create a menu with PHP from a MySQL database.
Table called categories has id, name, parent_id, shortdesc, etc.
The output need to have parent list and children list under the partent list as follows.
If you can show me codes or website, I will appreciate it.
<ul id="catmenu">
<li class="menulist">Cars
<ul>
<li>Ford</li>
<li>Honda</li>
<li>Toyota</li>
</ul>
</li>
<li class="menulist">Food
<ul>
<li>Pasta</li>
<li>Pizza</li>
...
</ul>
</li>
...
...
</ul>
This is specifically for two levels deep. Recommended approach should it be more is to use an optimized table structure for traversal, like http://articles.sitepoint.com/article/hierarchical-data-database/2 (pointed out elsewhere) or to pull the data you need and push it into a dictionary (associative array) and query it that way.
<?php
$query = <<<EOT
SELECT
parent.name as parent_name,
child.name as child_name,
FROM
items child
INNER JOIN
items parent
ON
child.parent_id = parent.id
ORDER BY
parent.name
EOT;
$result = mysql_query($query) or die('Failure!');
echo "<ul id=\"catmenu\">";
$last_parent = '';
while($row = mysql_fetch_array($result)){
// If this is a new category, start a new one
if($last_parent != $row['parent_name']){
// Unless this is the first item, close the last category
if($last_parent != ''){
echo "</ul></li>";
}
$last_parent = $row['parent_name'];
echo "<li class=\"menulist\">{$row['parent_name']}<ul>";
}
echo "<li>{$row['child_name']}</li>";
}
// If we actually had items, close the "category"
if($last_parent != ''){
echo "</ul></li>";
}
echo "</ul>";
?>
If you have only two levels then, you could just display them :
echo '<ul id="catmenu">';
foreach($menu as $element) {
echo '<li><ul class="menulist">';
foreach($element['submenu'] as $submenu) {
echo '<li>' . $submenu['name'] . '</li>';
}
echo '</ul></li>';
}
echo '</ul>
If you have an undefined number of submenus however you should use a Recursive Function.
function menu($item) {
$ret = '<li>' . $item['name'];
if (!empty($item['submenu'])) {
foreach($item['submenu'] as $submenu) {
$ret .= menu($submenu);
}
}
return $ret;
}
echo menu($menu);
So every of your subcategories, whatever their number is will be displayed.
You make database like this.
ID NAME PARENT
0 Cars -1
1 Foods -1
2 Ford 0
3 Honda 0
4 Toyota 0
5 Pasta 1
6 Pizza 1
...
You query them all up and put it in an array.
$Menus = array();
// In a read MySQL loop
$Menus[$i]['ID']
$Menus[$i]['NAME']
$Menus[$i]['PARENT']
// Sorry, lazy to write. I think you know what I mean.
Then you loop all menu looking for PARENT == -1. Generate all UL and IL then sub it with another nested menu.
You can simply create a function like this.
var $MenuLevelClass = array("menulist");
function CreateMenu($Menus, $Tab = 0, $Parent = -1, $Level = 0) {
global $MenuLevelClass;
$CatClass = ($Level != 0) ? '' : ' class="catmenu"';
$MenuClass = $MenuLevelClass[$Level];
if ($MenuClass != '')
$MenuClass = ' class="'.$MenuClass.'"';
$TabCount = $Level + $Tab;
$TabUL = "";
for ($t = 0; $t < $TabCount; $t++)
$TabUL = $TabUL."\t";
$TabLI = $TabUL."\t";
?>
<?=$TabUL?><ul<?=$CatClass?>>
<?php
$MenuCount = count($Menus);
for ($m = 0; $m < $MenuCount; $m++) {
$Menu = $Menu[$m];
$ID = $Menu['ID'];
if ($ID != $Parent)
continue;
?>
<?=$TabLI?><li<?=$MenuClass?>><?=$Menu['Name']?><?=CreateMenu($Menus, $Tab + 1, $ID, $Level + 1)?></li>
<?php
?>
<?=$TabUL?></ul>
<?php
}
}
And to use it just run 'CreateMenu($Menus);' or 'CreateMenu($Menus, $PrefixTabCount);'.
CreateMenu will recursively create the nested menu for you.
I have not test it so you may have to adjust it.
Hope this helps.

Categories