doddsey_65 Posted March 6, 2011 Share Posted March 6, 2011 ive decided to go with a simpler version to the MPTT algorithm. I have 2 database table. Categories and forums. categories c_cid c_name 1 first category forums f_fid c_id p_id f_name 1 1 0 forum --- this is a forum within category 1 2 1 1 subforum --- this is a subforum of forum within category 1 i am trying to display the name of any subforums under the forum name they belong to but with this code its only showing the subforums under the last forum displayed(which has no subforums). i think its something to do with the foreach loop as when i stick a var dump in there of the subforum list the list is only built when it gets to the bottom. $s_list = $pids = $fids = array(); $template->has_child = false; $query = $link->query("SELECT c.*, f.* FROM ".TBL_PREFIX."categories c LEFT JOIN ".TBL_PREFIX."forums f ON (f.c_id = c.c_cid) ORDER BY f.p_id ASC"); $row = $query->fetchAll(); foreach($row as $key => $value) { $forum_id = $row[$key]['f_fid']; $parent_id = $row[$key]['p_id']; for($i=0; $i<count($row); $i++) { $fids[] = $row[$i]['f_fid']; $pids[] = $row[$i]['p_id']; } if($row[$key]['p_id'] != 0) { $s_list[] = $row[$key]['f_name']; $template->is_child = true; } if($row[$key]['p_id'] == 0) { if(in_array($forum_id, $pids)) { $template->has_child = true; } else { $template->has_child = false; } $template->f_name = $row[$key]['f_name']; $template->description = $row[$key]['f_description']; $template->children = implode(', ', $s_list); } $template->fid = $row[$key]['f_fid']; $template->cat_name = $row[$key]['c_name']; $template->render($template->template.'templates/forum_list_tpl.php'); } anyone know why it will only display this list at the bottom and not under the correct forum? Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/ Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 *a shameful bump* Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183875 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 i think it would be better to do one table for forums. when you are defining the id, cat id, forum id, child id, your node depth only goes down by three. a better way would use one table, and have the parent decided from a parent_id field. this way we can load the parents and children into different multi dem arrays. here is an example: <?php $categories = mysql_query("SELECT fid name, parent FROM forums"); while($row = mysql_fetch_assoc($categories)) { if($row['parent']=='0') { // these are root categories $cats[] = $row; } else { // these are all children, included sub-sub children, even sub-sub-sub children. $forums[$row['parent']][] = $row; } } if(is_array($cats)) { foreach($cats as $cat) { if(is_array($forums[$cat['fid']])) { foreach($forums[$cat['fid']] as $forum) { // all of your forums children are loaded here. // you can even loop the sub forums and find the 4th node children $forum['subforums'] = $forums[$forum['fid']]; // Need to store this into the classes variable to be used globally. // View will later be decided on if there is a forum id set. $this_forums[] = $forum; } } } if(!empty($this_forums)) { $nforums[] = array($cat,$this_forums); } $this_forums = array(); } ?> your $nforums will be your main array that has everything organised there for a basic three node forum thee, this has your basic root forum category which contains forums underneath, those forums can also have children that are the same type of forum, just made normally for organisation. anyway, your $nforums array will look like this with a root cat, parent, and child. <?php ['0'] => ( ['0'] => ( ['fid'] = "1" ['name'] = "Root" ['parent'] = "0" ) ['1'] => ( ['0'] => ( ['fid'] = "2" ['name'] = "Parent" ['parent'] = "1" ['subforums'] => ( ['0'] => ( ['fid'] = "3" ['name'] = "Child" ['parent'] = "2" ) ) ) ) ) ?> you'll need your basic foreach loops to handle this code, if you decided to go this way and need any help let me know. also, a demo of the actual forums that uses this can be found here. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183914 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 thanks for your reply. i have included your code but when i var dump $nforums it returns an empty array: $cats = $forums = $nforums = array(); $this_forums = array(); $query = $link->query("SELECT f_fid, f_name, p_id FROM ".TBL_PREFIX."forums"); while($row = $query->fetchAll()) { if($row['p_id'] == 0) { // these are root categories $cats[] = $row; } else { // these are all children, included sub-sub children, even sub-sub-sub children. $forums[$row['p_id']][] = $row; } } if(is_array($cats)) { foreach($cats as $cat) { if(is_array($forums[$cat['f_fid']])) { foreach($forums[$cat['f_fid']] as $forum) { // all of your forums children are loaded here. // you can even loop the sub forums and find the 4th node children $forum['subforums'] = $forums[$forum['fid']]; // Need to store this into the classes variable to be used globally. // View will later be decided on if there is a forum id set. $this_forums[] = $forum; } } } if(!empty($this_forums)) { $nforums[] = array($cat,$this_forums); } } var_dump($nforums); have i gone wrong somewhere? Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183917 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 for reference here is my database layout: [attachment deleted by admin] Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183924 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 try to dump $cats and $forums and tell me if the script has at least gotten that far. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183929 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 A dump of $cats: array(1) { [0]=> array(3) { [0]=> array(6) { ["f_fid"]=> string(1) "2" [0]=> string(1) "2" ["f_name"]=> string(10) "Discussion" [1]=> string(10) "Discussion" ["p_id"]=> string(1) "1" [2]=> string(1) "1" } [1]=> array(6) { ["f_fid"]=> string(1) "1" [0]=> string(1) "1" ["f_name"]=> string(7) "General" [1]=> string(7) "General" ["p_id"]=> string(1) "0" [2]=> string(1) "0" } [2]=> array(6) { ["f_fid"]=> string(1) "3" [0]=> string(1) "3" ["f_name"]=> string(9) "Sub Forum" [1]=> string(9) "Sub Forum" ["p_id"]=> string(1) "2" [2]=> string(1) "2" } } } but $forums returns empty Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183931 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 something is off with the array, maybe it has to do with the $cats = $forums = $nforums = array(); ? maybe it has to do with the query itself? it has these extra arrays that seem to be interferring with the rest of the code. [0]=> array(6) { ["f_fid"]=> string(1) "2" [0]=> string(1) "2" ["f_name"]=> string(10) "Discussion" [1]=> string(10) "Discussion" ["p_id"]=> string(1) "1" [2]=> string(1) "1" } which shoud look more like [0]=> array(6) { ["f_fid"]=> string(1) "2" ["f_name"]=> string(10) "Discussion" ["p_id"]=> string(1) "1" } so if you need to, check and see why the query returns that way, dump $row and see if that looks good, because you do have one parent and two forums so when $row['p_id'] doesn't equal 0, the $forums need to be filled, which it is not, so we need to debug some more. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183935 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 ok i assumed that i was using the wrong fetch method. I am using PDO for my connection and was using PDO::FETCH_ALL. Ive changed it to PDO::FETCH_ASSOC and the $row array appears normal(no added numeric keys). So now: $cats: array(1) { [0]=> array(3) { ["f_fid"]=> string(1) "1" ["f_name"]=> string(7) "General" ["p_id"]=> string(1) "0" } } $forums: array(2) { [1]=> array(1) { [0]=> array(3) { ["f_fid"]=> string(1) "2" ["f_name"]=> string(10) "Discussion" ["p_id"]=> string(1) "1" } } [2]=> array(1) { [0]=> array(3) { ["f_fid"]=> string(1) "3" ["f_name"]=> string(9) "Sub Forum" ["p_id"]=> string(1) "2" } } } but when i echo $nforums it shows that the forum "discussion" has no subforums. yet as you can see by the previous image it has 1 subforum array(1) { [0]=> array(2) { [0]=> array(3) { ["f_fid"]=> string(1) "1" ["f_name"]=> string(7) "General" ["p_id"]=> string(1) "0" } [1]=> array(1) { [0]=> array(4) { ["f_fid"]=> string(1) "2" ["f_name"]=> string(10) "Discussion" ["p_id"]=> string(1) "1" ["subforums"]=> NULL } } } } Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183942 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 You are correct, glad we got that fixed up. Also of course the subforums are not being displayed, you need to fix your code: $forum['subforums'] = $forums[$forum['fid']]; you need to make it $forum['subforums'] = $forums[$forum['f_fid']]; Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183945 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 thanks its working now. I just have to figure out how to display it in the correct way. eg: Category Forum Subforums - subforum forum2 forum3 Subforums - subforum2 Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183946 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 I'll be more than happy to help with that. <?php foreach($nforums as $cat) { // were going to have to imporant parts // $cat[0] which is the root forum // $cat[1] which are the sub forums echo '<h1>'.$cat[0]['name'].'</h1>'; if (is_array($cat[1])) { foreach($cat[1] as $forum) { echo '<h2>-'.$forum['name'].'</h2>'; if(is_array($forum['subforums'])) { foreach($forum['subforums'] as $sub) { echo '<h2>--'.$sub['name'].'</h2>'; } } } } } ?> The code is fairly simple and self explanatory, i'm sure you won't have a problem adding extra information to the code and making it suit your needs. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183949 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 thanks for the advice and code so far, youve been great. However it only displays one forum( i have 2 now to test). foreach($nforums as $cat) { $template->f_c_name = $cat[0]['f_name']; if(is_array($cat[1])) { foreach($cat[1] as $forum) { $template->f_name = $forum['f_name']; if(is_array($forum['subforums'])) { foreach($forum['subforums'] as $child) { $template->subforums = $child['f_name']; } } } } $template->render($template->template.'templates/forum_list_tpl.php'); } The render function basically sends the values defined using $template to a php tpl file which contains(simplified) <h3><?php echo $this->f_name; ?></h3> but like i said it only displays one forum(the last one). Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183952 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 Can you dump $cat for me and tell me how that shows up? if the proper categories show up then we determine it's not an issue with the array, but the rendering itself. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183955 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 it was an issue with the rendering. i moved the rendering into the foreach loop and problem solved. Thanks alot for your help. I have been trying to solve this for about a month now! thanks! Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183956 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 actually slight problem. I have a forum with a sunforum and a one without. For some reason it adds the sunforum of the first forum under the second one aswell. foreach($nforums as $cat) { $template->f_c_name = $cat[0]['f_name']; $template->is_cat = true; $template->render($template->template.'templates/forum_list_tpl.php'); if(is_array($cat[1])) { foreach($cat[1] as $forum) { $template->f_name = $forum['f_name']; $template->is_cat = false; if(is_array($forum['subforums'])) { foreach($forum['subforums'] as $child) { $template->subforums = $child['f_name']; } } $template->render($template->template.'templates/forum_list_tpl.php'); } } } Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183960 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 again this is a problem with the rendering, you need to mess around with where you place the template code a bit, i'm not sure how your tpl files are set up so i won't be too sure. as long as your array doesn't display the sub forums for that specific forum then we know it's not an issue with the array which is our foundation of the script. so like i said, make sure the array is correct, if it is the problem is with the rendering so check your template parsing class and your tpl files. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183961 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 i fixed it, just added an else statement to the is_array($forums['subforums']). also came across the problem of it only showing one subforum but i added $child['f_name'] to an array then imploded it. Again thanks alot for your help! Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183964 Share on other sites More sharing options...
Skepsis Posted March 7, 2011 Share Posted March 7, 2011 awesome, glad you got it working and i'm glad i was able to help. don't forget to mark the topic as solved and enjoy! Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183965 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 i would mark solved if the button was still there lol. Also noticed that when making a reply the bbcode button for php code is gone. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183966 Share on other sites More sharing options...
doddsey_65 Posted March 7, 2011 Author Share Posted March 7, 2011 sorry but i have another problem. this time with the categories. All forums are just displayed under one category with the second category left empty. i tired this but it hasnt worked. it displays about 6 categories all with a name which is a single letter(random letter). if(is_array($cat[0])) { foreach($cat[0] as $parent) { $template->f_c_name = $parent['f_name']; $template->c_url_name = create_url($template->f_c_name); $template->render($template->template.'templates/forum_header_tpl.php'); } } forum_header_tpl.php: </ul> <div class="category_header"> <?php echo $this->f_c_name; ?> </div> <ul class="forum_list"> Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1183979 Share on other sites More sharing options...
creata.physics Posted March 8, 2011 Share Posted March 8, 2011 This is Skepsis, it seems I broke my account yesterday when trying to change my email so i'm sorry for the delay in this reply. so i need to ask since it's been a while, are you still having the same issues or have you gotten it fixed yet? Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1184290 Share on other sites More sharing options...
doddsey_65 Posted March 8, 2011 Author Share Posted March 8, 2011 no i am still having the same problem Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1184341 Share on other sites More sharing options...
creata.physics Posted March 8, 2011 Share Posted March 8, 2011 sorry but i have another problem. this time with the categories. All forums are just displayed under one category with the second category left empty. i tired this but it hasnt worked. it displays about 6 categories all with a name which is a single letter(random letter). if(is_array($cat[0])) { foreach($cat[0] as $parent) { $template->f_c_name = $parent['f_name']; $template->c_url_name = create_url($template->f_c_name); $template->render($template->template.'templates/forum_header_tpl.php'); } } forum_header_tpl.php: </ul> <div class="category_header"> <?php echo $this->f_c_name; ?> </div> <ul class="forum_list"> change this to $cat[1]. $cat[1] are the subforums and their children, while $cat[0] are the root categories. Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1184348 Share on other sites More sharing options...
doddsey_65 Posted March 8, 2011 Author Share Posted March 8, 2011 i have the $cat[1] part in another section and removed the above code as it seemed to make things worse. Here is my code: $cats = $forums = $cat_list = $cat_name = $nforums = $subforums = $this_forums = array(); $query = $link->query("SELECT * FROM ".TBL_PREFIX."forums")or die(print_link_error()); while($row = $query->fetch(PDO::FETCH_ASSOC)) { if($row['p_id'] == 0) { // these are root categories $cats[] = $row; } else { // these are all children, included sub-sub children, even sub-sub-sub children. $forums[$row['p_id']][] = $row; } } if(is_array($cats)) { foreach($cats as $cat) { if(is_array($forums[$cat['f_fid']])) { foreach($forums[$cat['f_fid']] as $forum) { // all of your forums children are loaded here. // you can even loop the sub forums and find the 4th node children $forum['subforums'] = $forums[$forum['f_fid']]; // Need to store this into the classes variable to be used globally. // View will later be decided on if there is a forum id set. $this_forums[] = $forum; } } } if(!empty($this_forums)) { $nforums[] = array($cat,$this_forums); } } foreach($nforums as $cat) { $template->f_c_name = $cat[0]['f_name']; $template->c_url_name = create_url($template->f_c_name); $template->is_cat = true; $template->render($template->template.'templates/forum_list_tpl.php'); if(is_array($cat[1])) { foreach($cat[1] as $forum) { $template->is_cat = false; if(!empty($forum['f_last_post'])) { $template->f_icon = $template->template.'icons/forum.png'; $template->f_last_post = $forum['f_last_post']; $template->f_last_poster = profile_link($forum['f_last_poster']); $template->f_last_post_time = asf_date($forum['f_last_post_time'],'full'); } else { $template->f_empty = true; $template->no_posts = $lang->no_posts; $template->no_posts_sub = $lang->be_first; $template->f_icon = $template->template.'icons/forum_empty.png'; } $template->f_name = $forum['f_name']; $template->f_url_name = create_url($template->f_name); $template->description = $forum['f_description']; if(is_array($forum['subforums'])) { foreach($forum['subforums'] as $child) { $template->s_url_name = create_url($child['f_name']); $subforums[] = '<a href="category/'.$template->c_url_name.'/forum/'.$template->s_url_name.'">'.$child['f_name'].'</a>'; $template->subforums = implode(' ',$subforums); unset($subforums); } } else { $template->subforums = null; } $template->render($template->template.'templates/forum_list_tpl.php'); } } } it only displays one cateogry(the last one) and displays all forums within that cat rather than in the cat they belong to.( i have 2 cats ) EDIT: i can supply you with a dump of my database table if that would help (project is open source anyway) or i can update github so you can see it there Quote Link to comment https://forums.phpfreaks.com/topic/229754-subforums-again/#findComment-1184349 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.