Create a nested list - php

How would I create a nested list, I currently have this
public function getNav($cat,$subcat){
//gets all sub categories for a specific category
if(!$this->checkValue($cat)) return false; //checks data
$query = false;
if($cat=='NULL'){
$sql = "SELECT itemID, title, parent, url, description, image
FROM p_cat
WHERE deleted = 0
AND parent is NULL
ORDER BY position;";
$query = $this->db->query($sql) or die($this->db->error);
}else{
//die($cat);
$sql = "SET #parent = (SELECT c.itemID FROM p_cat c WHERE url = '".$this->sql($cat)."' AND deleted = 0);
SELECT c1.itemID, c1.title, c1.parent, c1.url, c1.description, c1.image, (SELECT c2.url FROM p_cat c2 WHERE c2.itemID = c1.parent LIMIT 1) as parentUrl
FROM p_cat c1
WHERE c1.deleted = 0
AND c1.parent = #parent
ORDER BY c1.position;";
$query = $this->db->multi_query($sql) or die($this->db->error);
$this->db->store_result(); $this->db->next_result();
$query = $this->db->store_result();
}
return $query;
}
public function getNav($cat=false, $subcat=false){
//gets a list of all categories form this level, if $cat is false it returns top level nav
if($cat==false || strtolower($cat)=='all-products') $cat='NULL';
$ds = $this->data->getNav($cat, $subcat);
$nav = $ds ? $ds : false;
$html = '';
//create html
if($nav){
$html = '<ul>';
//var_dump($nav->fetch_assoc());
while($row = $nav->fetch_assoc()){
$url = isset($row['parentUrl']) ? $row['parentUrl'].'/'.$row['url'] : $row['url'];
$current = $subcat==$row['url'] ? ' class="current"' : '';
$html .= '<li'.$current.'>'.$row['title'].'</li>';
}
$html .='</ul>';
}
return $html;
}
The sql returns parents and children, for each parent I need the child to nest in a list.

It's been a while since I've done any PHP but wondering if this will work. Inside your while loop, could you just recurse and add the output of getNav($cat = $row['url']) again in a new <li>, kind of like:
while($row = $nav->fetch_assoc()){
$url = isset($row['parentUrl']) ? $row['parentUrl'].'/'.$row['url'] : $row['url'];
$current = $subcat==$row['url'] ? ' class="current"' : '';
$html .= '<li'.$current.'>'.$row['title'].'';
/* Add subNav HTML */
$html .= $this->getNav($row['url']);
$html .= '</li>';
}
It seems that "getNav" refers to both the function to get the SQL as well as the function that renders the nav HTML - maybe change the HTML getNav function name to getNavHtml just for clarity.
Also seems like the $subcat argument may be able to be removed from the SQL getNav function since it is never used.

Related

How can I do this sql filter results

I have an website there are 5 categories, i only want to show the 1-4 category only in the new posts..how can I edit the code to do this job? thanks
Here is my code, and I do that in my sql by using following code:
SELECT * FROM `ff_se` WHERE Wid in ('1','2','3','4')"
but i dont know how to do that in php code. following is my part of php code:
$this->TableSe = 'ff_se';
$this->TableSeWord = 'ff_se_word';
$this->TableSeSupport = 'ff_se_support';
$this->TableSePost = 'ff_se_post';
$this->TableSePostTableId = 'ff_se_post_tableid';
public function GetAjaxList($Get){
$Results = array();
$Get = $this->StrToGBK($Get);
$Page = $Get['page'] ? intval($Get['page']):0;
$Where = '';
$Order = 'S.updateline';
if($Get['type'] == 'New'){
$Order = 'S.dateline';
}else if($Get['type'] == 'Hot'){
$Order = 'S.updateline';
if($this->Config['PluginVar']['ListHotVal']){
$Where .= ' and (S.support_count >= '.$this->Config['PluginVar']['ListHotVal'].' OR S.comment_count >= '.$this->Config['PluginVar']['ListHotVal'].')';
}
if($this->Config['PluginVar']['ListHotDataline']){
$Where .= ' and S.dateline >= '.strtotime("-".$this->Config['PluginVar']['ListHotDataline']." hours",time());
}
}else if($Get['type'] == 'Nearby'){//
$Order = 'S.updateline';
if($Get['lng'] && $Get['lat']){
$SquarePoint = $this->GetReturnSquarePoint($Get['lng'],$Get['lat'],$this->Config['PluginVar']['Distance']);
$Where .= ' and S.lat <> 0 and S.lat > '.$SquarePoint['right-bottom']['lat'].' and S.lat < '.$SquarePoint['left-top']['lat'].' and S.lng > '.$SquarePoint['left-top']['lng'].' and S.lng < '.$SquarePoint['right-bottom']['lng'];
}else{
return $Results;
}
}
if($_GET['wid']){
$Where .= ' and S.wid = '.intval($_GET['wid']);
}
$Where .= ' and S.display = 1 and S.fast_add_display = 1';
$Where = preg_replace('/and/','where',$Where,1);
$this->Config['PluginVar']['ListNum'] = $this->Config['PluginVar']['ListNum'] ? $this->Config['PluginVar']['ListNum'] : 10;
$Limit = 'LIMIT '.($Page * $this->Config['PluginVar']['ListNum']).','.$this->Config['PluginVar']['ListNum'];
$FetchSql = 'SELECT W.title as Ttitle,S.* FROM '.DB::table($this->Tablese).' S LEFT JOIN '.DB::table($this->TableSeWord).' W on W.id = S.wid '.$Where .' order by topdateline > '.time().' desc,'.$Order.' desc,S.dateline desc '.$Limit;
$Results = $this->ListFormat(DB::fetch_all($FetchSql));
return $Results;
}
I think you should try and understand the code first before you modify it ... but anyway:
You would only need to append the condition to the where clause generated in the PHP code.
You could do that by adding THE LINE MARKED "THIS LINE IS NEW" after this line:
$Where = '';
And this is the relevant part of the code:
$Where = '';
$Order = 'S.updateline';
if($Get['type'] == 'New'){
$Where .= ' and S.wid in (1,2,3,4)'; //THIS LINE IS NEW
$Order = 'S.dateline';
}else .......
As you can see any redundant initial "and"s are replaced with "where" here:
$Where = preg_replace('/and/','where',$Where,1);
so this should work - assuming that $Get['type'] == 'New' means that this is a new post which I can only guess.

php recursive function not working correctly

i have a categories table
(id=1 , name=Hand made, parent=0)
(id=2 , name=Factory made, parent=0)
(id=3 , name=chairs, parent=1)
(id=4 , name=tabels, parent=1)
(id=5 , name=old chairs, parent=3)
at the menu if visitor clicked on category OLD CHAIRS , will go to page
products.php?category_id = 5
then at this page i need to know what is the main category_id , which should be HAND MADE with category_id=1
so at this page i want to say
if isset($_REQUEST['category_id']){
do the function till find the main parent,
$mainparentid = main parent category_id
}else { $mainparentid = '';
} echo $mainparentid;
here is my PHP Code
if (isset($_REQUEST['category_id'])) {
function getParent($id) {
global $connection;
$query_rsCategoryId = "SELECT * FROM categories
WHERE category_id = '".$_REQUEST['category_id']."'";
$rsCategoryId = mysql_query($query_rsCategoryId, $connection);
$row_rsCategoryId = mysql_fetch_assoc($rsCategoryId);
$parent = $row_rsCategoryId['category_parent'];
if (mysql_num_rows($rsCategoryId) < 1) {
// Error handling, entry with id $id not found
return null;
}
if ($parent == 0) {
return $id;
} else {
return getParent($parent);
}
}
$mainparentid = getParent($id);
}else {
$mainparentid ='none';
}
echo $mainparentid ;
You always input ID of the category from $_REQUEST. Change line:
WHERE category_id = '".$_REQUEST['category_id']."'";
to:
WHERE category_id = '".$id."'";
You are using parent id from request instead of given via function parameter
// notice $id instead of $_REQUEST['category_id']
$query_rsCategoryId = "SELECT * FROM categories WHERE category_id = '{$id}'";

Php Dynamic Menubar code error

I am having a problem with making the links in my bar work properly the database is setup like so my db http://bloodkittens.com/resources/upload/db.png
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
mysql_connect("localhost", "dbuser", "******");
mysql_select_db("guild");
// prepare special array with parent-child relations
$menuData = array(
'items' => array(),
'parents' => array()
);
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name FROM main_menu` ORDER BY parentID_menu");
while ($menuItem = mysql_fetch_assoc($result))
{
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
}
// menu builder function, parentId 0 is the root
function buildMenu($parentId, $menuData)
{
$html = '';
$parent='';
if (isset($menuData['parents'][$parentId]))
{
$menuClass= ($parentId==0) ? ' class="navbar" id="navbar"' : '';
$parent= ($parentId==0) ? 0 : 1;
$html = "<ul{$menuClass}>\n";
foreach ($menuData['parents'][$parentId] as $itemId)
{
//subment
$result=mysql_query("select * from main_menu where parentID_menu='$itemId'");
if (mysql_num_rows($result)>(int)0 && $parentId!=0) {
$subm =' class="navbar"';
}else{
$subm ='';
}
//end
$menu = $parentId == 0 ? ' class="menulink"' : ''; //class of main menu
$html .= '<li>' . "<a{$subm}{$menu} href=\"#\" >{$menuData['items'][$itemId]['name']}</a>";
// find childitems recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
?>
How would i make it so that the value link_menu would be the href in the code for each separate entry in the db? rather then \'#\' because the code works completely and i'm very happy how it looks after i apply my css to it but the links aren't working
For work the menu sorting
must be add a new field in the table,
and change this query from
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name, link_menu link FROM main_menu ORDER BY parentID_menu");
to :
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name, link_menu link FROM main_menu ORDER BY menu_sort");
you never seem to select it
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu, link_menu, name FROM main_menu ORDER BY parentID_menu");
and then..
$html .= '<li>' . "<a{$subm}{$menu} href=\"{$menuData['items'][$itemId]['link_menu']}\" >{$menuData['items'][$itemId]['name']}</a>";
Instead of href=\"#\" >, use this:
href=\"{$menuData['items'][$itemId]['link_menu']}\" >
the code that i used was in the end like this i think i got it to work by pure luck but regardless i win : )
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
mysql_connect("localhost", "BloodKittens", "Zangoshi1");
mysql_select_db("bloodkittens");
// prepare special array with parent-child relations
$menuData = array(
'items' => array(),
'parents' => array(),
'links' => array()
);
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name, link_menu link FROM main_menu ORDER BY parentID_menu");
while ($menuItem = mysql_fetch_assoc($result))
{
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
$menuData['links'] = $menuItem['link'];
}
// menu builder function, parentId 0 is the root
function buildMenu($parentId, $menuData)
{
$html = '';
$parent='';
if (isset($menuData['parents'][$parentId]))
{
$menuClass= ($parentId==0) ? ' class="navbar" id="navbar"' : '';
$parent= ($parentId==0) ? 0 : 1;
$html = "<ul{$menuClass}>\n";
foreach ($menuData['parents'][$parentId] as $itemId)
{
//subment
$result=mysql_query("select * from main_menu where parentID_menu='$itemId'");
if (mysql_num_rows($result)>(int)0 && $parentId!=0) {
$subm =' class="navbar"';
}else{
$subm ='';
}
//end
$menu = $parentId == 0 ? ' class="menulink"' : ''; //class of main menu
$html .= '<li>' . "<a{$subm}{$menu} href=\"{$menuData['items'][$itemId]['link']}\" >{$menuData['items'][$itemId]['name']}</a>";
// find childitems recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
?>

How can I load the title of parent item in Drupal

I want to extend Nodes with the title of the parentnode so I can display a hierarchy link.
I have a solution that sometimes works:
function modulename_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL)
{
switch ($op)
{
case 'view':
loadParentTitle($node);
break;
}
}
function loadParentTitle(&$node)
{
$title = $node->title;
$query = "SELECT mlid, p1, p2,p4,p5,p6,p7,p8,p9 FROM menu_links WHERE link_title like '%%%s%%'";
$data = db_fetch_array(db_query($query, $title));
$mlid = $data["mlid"];
$i = 9;
while (($data["p". $i] == 0 || $data["p". $i] == $mlid) && $i >= 0)
{
$i--;
}
if ($i > 0)
{
$query = "SELECT `link_title` as parentTitle from `menu_links` WHERE mlid = " . $data["p" . $i];
$data = db_fetch_array(db_query($query));
$parentTitle = ($data["parentTitle"]);
}
else
{
$parentTitle = $title;
}
$node->content['#parentTitle'] = $parentTitle;
}
This works as long as the title of the item is the same as the Menu Title. However i'm looking for a solution that will work all the time. Any ideas?
You did not specify really what do you mean by 'parent node' but the mlid of the parent of a menu link is stored in menu_links.plid. Now, the link_path is going to be node/nid and you can fetch the title from there.
$mlid = db_result(db_query("SELECT plid FROM {menu_links} WHERE link_path = 'node/%d'", $node->nid));
$link_path = db_result(db_query("SELECT link_path FROM {menu_links} WHERE mlid = %d", $mlid));
$title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", substr($link_path, 5));
The first two queries can be unified by a JOIN but I strongly recommend against getting the third in there too (you can with CONCAT('node/', nid) = parent.link_path) because that is not going to be indexable. These three queries should be practically instant.
P.S. You won't forget to check_plain($title) before printing, would you? :)

Printing the Categories and Sub Categories Alone

function build_list($id=0,$collapsed="") //return an array with the categories ordered by position
{
$RootPos = "";
$this->c_list = array();
if($id != 0){
$this_category = $this->fetch($id);
$positions = explode(">",$this_category['position']);
$RootPos = $positions[0];
}
// lets fetch the root categories
$sql = "SELECT *
FROM ".$this->table_name."
WHERE position RLIKE '^([0-9]+>){1,1}$' AND c_group = '".$this->Group."'
ORDER BY c_name";
$res = mysql_query($sql) or die(trigger_error("<br><storng><u>MySQL Error:</u></strong><br>".mysql_error()."<br><br><storng><u>Query Used:</u></strong><br>".$sql."<br><br><storng><u>Info:</u></strong><br>",E_USER_ERROR));
while($root = mysql_fetch_array($res)){
$root["prefix"] = $this->get_prefix($root['position']);
$this->c_list[$root['id']] = $root;
if($RootPos == $root['id'] AND $id != 0 AND $collapsed != ""){
$this->list_by_id($id);
continue;
}else{
// lets check if there is sub-categories
if($collapsed == "" AND $id==0){
$has_children = $this->has_children($root['position']);
if($has_children == TRUE) $this->get_children($root['position'],0);
}}}
return $this->c_list;
}
// He is the Author of the code...
Categories Class
Author: Shadi Ali
Now I want to just return the Categories and Sub Categories from the above code.
function browse() {
$categories = new categories;
$categories_list = $categories->build_list();
foreach($categories_list as $c)
{
return $c->$id;
}
}
The above code is not working.... can anyone help me out.
Here are two problems with the browse() function:
The return statement is inside the foreach loop. The statement will return one value for one of the items in the $categories-list (at most), and not continue to loop over the rest of the $categories-list.
The $id variable is never declared or initialised in return $c->$id, perhaps you meant to use $c['id'] or $c->id

Categories