php recursive function not working correctly - php

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}'";

Related

PHP code calling the field in db that does not exist [resulting no display on webpage]

We have a website that has having trouble accessing Shipping info on all of our product page. The information is pulled from the database called shipping_info
What I see from php code below is it calls parent_id to access the shipping info for a particular product but the parent_id does not exist in the shipping_info table but exist in awt_prod table.
$parent_id = $_GET['id'];
if (is_numeric($parent_id)) {
$parent_id = mysql_escape_string($parent_id);
} else {
die("<p> Error: Invalid Product ID <br> </p>");
function()
function()
$primary_shipping_query = "SELECT name, wt, length, width, height FROM awt_prods WHERE (p_c_flag ='P' OR p_c_flag ='C') AND parent_id = '$parent_id'";
$sorted_rows = fetchAllRows(mysql_query($primary_shipping_query));
usort($sorted_rows, 'rowCodeNatCmp');
> //Table HTML Header
</table>
$shipping_options_id_query = "SELECT id, name FROM awt_prods WHERE (p_c_flag ='P' OR p_c_flag ='C') AND parent_id = '$parent_id'";
$shipping_ids = mysql_query($shipping_options_id_query);
$shipping_info_array = array();
$table_id = 0;
while ($part_id = mysql_fetch_assoc($shipping_ids)) {
$part_skey = $part_id['id'];
$part_skey_query = "SELECT * FROM prods_shipping_options WHERE part_skey = '$part_skey'";
$shipping_info = mysql_query($part_skey_query);
while ($ship_row = mysql_fetch_assoc($shipping_info)) {
$table_group_name = table_group($ship_row['title']);
$shipping_info_array[$table_id] = array('table' => $table_group_name, 'name' => $part_id['name'], 'memo' => $ship_row['memo']);
$table_id++;
}
}
$unique_title_array = array();
//print_r($shipping_info_array);
foreach ($shipping_info_array as $unique) {
$unique_title_array[] = $unique['table'];
}
$unique_title = array_unique($unique_title_array);
foreach ($unique_title as $shipping_table_name) {
>Some <html><css>
?>
My possible solution is to join both shipping_info table and awt_prod table using a Key but I dont know what the key should be or how to approach this possible solution.

stop update parent if he has child

I have list like this
John
Jack
Husam
Koko
Rami
Loay
And I have this function that allow me to change father of child, in my case I can change Koko to make him child of Loay.
I want to stop this because he has child, how can I validate this case to check if he has child then can't change it, and if he does not has child then I can change his father ?
This is my function
public function updateParentId($parentId, $childId)
{
$statment = $this->db->prepare("UPDATE person SET parent = $parentId WHERE id = $childId");
$statment->execute();
$result = $statment->rowCount();
if($result == "1")
{
$message = '<label>successfully</label>';
}
else
{
$message = '<label>Wrong</label>';
}
echo $message;
}
}
Following query will return all children below Koko(Rami, Loay) in hierarchy.
$statment = $this->db->prepare('SELECT id, parent FROM (SELECT * FROM person ORDER BY parent, id) sorted, (SELECT #id:=:id) temp WHERE (FIND_IN_SET(parent, #id) > 0 || id = "Loay") AND #id:=CONCAT(#id, ",", id)');
$statment->execute();
$parents = $statment->fetchAll();
foreach ($parents as $value) {
if ($value['id'] == "Loay") {
throw new \Exception('Person can not be moved to its children.');
}
}
Note: Here I'm not aware of table structure completely. So just given a general example.
Update Query
$statment = $this->db->prepare("UPDATE person SET parent = :parentId WHERE id = :childId");
$statment->execute([":parentId" => $parentId, ":childId" => $childId]);
$result = $statment->rowCount();

Get Parent Category of Product in Sub-Category Open Cart

If I am trying to add a php statement on my product page template that looks like this:
<?php if (Product Has Parent Category = 146) {
// Do this
} elseif (Product Has Parent Category = 130) {
// Do this
} else {
// Do this } ?>
Ofcourse this isnt the code, but how would I do this? Im basically trying to get the parent category that the subcategory is in. Any help would be greatly appreciated. Thanks!
UPDATE:
Each product is placed in multiple categories.. So I should have an array of Parent categories. Here is the database structure that I found for this.
product_to_category
product_id | category_id
category
category_id | parent_id | ...
In catalog/controller/product/product.php find
$this->load->model('catalog/product');
//this will load product model
add after
$cat_info = $this->model_catalog_product->getCategories($this->request->get['product_id']);
// this will give all the category of product
foreach($cat_info as $cat_id){
$cat = $this->model_catalog_category->getParentCategories($cat_id['category_id']);
//this will give the parent category
if(!empty($cat)){
foreach($cat as $ids){
$this->data['path_id'][] = $ids['path_id'];
}
}
}
In catalog/model/catalog/category.php add
public function getParentCategories($category_id) {
$query = $this->db->query("SELECT path_id FROM " . DB_PREFIX . "category_path WHERE category_id = '" . (int)$category_id . "' AND '" . (int)$category_id . "'!=path_id");
return $query->rows;
}
now in product.tpl
<?php
if(in_array(20,$path_id)){
echo 'exists';
}else{
echo 'not exists';
}
?>
I was able to figure it out. I wrote this code and am using it on my product.tpl.
<?php
$current_product_id = "SELECT `product_id`,`category_id` FROM `oc_product_to_category` WHERE `product_id`='$product_id' ";
$current_product_ids = mysql_query($current_product_id);
$current_product_cat_ids='';
while($current_product_cat_id = mysql_fetch_array($current_product_ids)){
$current_product_cat_ids.=$current_product_cat_id['category_id'].',';
}
$parent_cat_path = mysql_query("SELECT `category_id`,`path_id` FROM `oc_category_path` WHERE `category_id` IN (" . rtrim($current_product_cat_ids, ',') . ")");
$parent_cat_id_array='';
while ($parent_cat_paths = mysql_fetch_array($parent_cat_path)) {
$parent_cat_id_array.=$parent_cat_paths['path_id'].',';
}
$parent_cat_id_array_str = implode(',',array_unique(explode(',', $parent_cat_id_array)));
if (strpos($parent_cat_id_array_str,'132') !== false) {
// Do This Here
} else {
//Do This Here
} ?>

Most effective way of data collection?

Let's first get to an important note about my situation:
I have 1 table in my MySQL database with approx 10 thousand entries
Currently, when collecting information from table #1. I collect a total of 20 - 24 rows per page.
Example being:
Q1 : SELECT * FROM table WHERE cat = 1 LIMIT 0,25
R1: id: 1, name: something, info: 12
The PHP file that does these queries, is called by the jquery ajax function, and creates an XML file that that jquery function reads and shows to the user.
My question here is. How do i improve the speed & stability of this process. I can have up to 10 thousand visitors picking up information at the same time, which makes my server go extremely sluggish and in some cases even crash.
I'm pretty much out of idea's, so i'm asking for help here. Here's an actual presentation of my current data collection (:
public function collectItems($type, $genre, $page = 0, $search = 0)
{
// Call Core (Necessary for Database Interaction
global $plusTG;
// If Search
if($search)
{
$searchString = ' AND (name LIKE "%'.$search.'%")';
}
else
{
$searchString = '';
}
// Validate Query
$search = $plusTG->validateQuery($search);
$type = $plusTG->validateQuery($type);
$genre = $plusTG->validateQuery($genre);
// Check Numeric
if((!is_numeric($genre)))
{
return false;
}
else
{
if(!is_numeric($type))
{
if($type != 0)
{
$typeSelect = '';
$split = explode(',',$type);
foreach($split as $oneType)
{
if($typeSelect == '')
{
$typeSelect .= 'type = '.$oneType.' ';
}
else
{
$typeSelect .= 'OR type = '.$oneType.' ';
}
}
}
}
else
{
$typeSelect = 'type = ' . $type . ' ';
}
//echo $typeSelect;
$limit = ($page - 1) * 20;
if(($type != 0) && ($genre != 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND genre = '.$genre.' AND ('.$typeSelect.')'.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND genre = '.$genre.' AND ('.$typeSelect.')'.$searchString);
}
elseif(($type == 0) && ($genre != 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND genre = '.$genre.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND genre = '.$genre.$searchString);
}
elseif(($type != 0) && ($genre == 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1 AND ('.$typeSelect.')'.$searchString.'ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1 AND ('.$typeSelect.')'.$searchString);
}
elseif(($type == 0) && ($genre == 0))
{
$items = $plusTG->db->query('SELECT * FROM dream_items WHERE active = 1'.$searchString.' ORDER BY name LIMIT '.$limit.',20');
$total = $plusTG->db->query('SELECT COUNT(*) as items FROM dream_items WHERE active = 1'.$searchString);
}
$this->buildInfo($items->num_rows, $total->fetch_assoc());
while($singleItem = $items->fetch_assoc())
{
$this->addItem($singleItem);
}
}
return true;
}
The build info call & add item call are adding the items to the DOMXML.
This is my javascript (domain and filename filtered):
function itemRequest(type,genre,page, search)
{
if(ajaxReady != 0)
{
ajaxReady = 0;
$('#item_container').text('');
var searchUrl = '';
var searchLink;
var ajaxURL;
if(search != 0)
{
searchUrl = '&search=' + search;
searchLink = search;
ajaxURL = "/////file.php";
}
else
{
searchLink = 0;
ajaxURL = "////file.php";
}
$.ajax({
type: "GET",
url: ajaxURL,
data: "spec=1&type="+type+"&genre="+genre+"&page="+page+searchUrl,
success: function(itemListing){
$(itemListing).find('info').each(function()
{
var total = $(this).find('total').text();
updatePaging(total, page, type, genre, searchLink);
});
var items = $(itemListing).find('items');
$(items).find('item').each(function()
{
var itemId = $(this).find('id').text();
var itemType = $(this).find('type').text();
var itemGenre = $(this).find('genre').text();
var itemTmId = $(this).find('tm').text();
var itemName = $(this).find('name').text();
buildItem(itemId, itemType, itemGenre, itemTmId, itemName);
});
$('.item_one img[title]').tooltip();
},
complete: function(){
ajaxReady = 1;
}
});
}
Build item calls this:
function buildItem(itemId, itemType, itemGenre, itemTmId, itemName)
{
// Pick up Misc. Data
var typeName = nameOfType(itemType);
// Create Core Object
var anItem = $('<div/>', {
'class':'item_one'
});
// Create Item Image
$('<img/>', {
'src':'///'+typeName+'_'+itemTmId+'_abc.png',
'alt':itemName,
'title':itemName,
click:function(){
eval(typeName + 'Type = ' + itemTmId);
$('.equipped_item[name='+typeName+']').attr('src','//'+typeName+'_'+itemTmId+'_abc.png');
$('.equipped_item[name='+typeName+']').attr('alt',itemName);
$('.equipped_item[name='+typeName+']').attr('title',itemName);
$('.equipped_item[title]').tooltip();
recentEquipped(typeName, itemTmId, itemName);
updateSelfy();
}
}).appendTo(anItem);
// Favs
var arrayHack = false;
$(favEquips).each(function(){
if(arrayHack == false)
{
if(in_array(itemTmId, this))
{
arrayHack = true;
}
}
});
var itemFaved = '';
if(arrayHack == true)
{
itemFaved = 'activated';
}
$('<div/>',{
'class':'fav',
'id':itemFaved,
click:function(){
if($(this).attr('id') != 'activated')
{
$(this).attr('id','activated');
}
else
{
$(this).removeAttr('id');
}
itemFav(itemTmId, typeName, itemName);
}
}).appendTo(anItem);
$(anItem).appendTo('#item_container');
}
If anyone could help me improve this code, it'd be very much appreciated.
add an index to your table for cat column
figure out what the bottleneck is, if it is your XML then try json,
if it is your network, try enabling gzip compression
I agree with Zepplock, it is important to find out where the bottleneck is - if not, you're only guessing. Zepplock's list is good but I would also add caching:
Find out where the bottleneck is.
Use indexes in your db table.
Cache your query results
Find the Bottleneck.
There are number opinions and ways to do this... Basically when your site is under load, get the time it takes to complete each step in the process: The DB queries, the server-side processes, the client side processes.
Use Indexes.
If your DB is slow chances are you can get a lot of improvement by optimizing your queries. A table index may be in order... Use 'EXPLAIN' to help identify where indexes should be placed to optimize your queries:
EXPLAIN SELECT * FROM dream_items WHERE active = 1 AND (name LIKE "%foo%") ORDER BY name LIMIT 0,20;
(I bet an index on active and name would do the trick)
ALTER TABLE `dream_items` ADD INDEX `active_name` (`active` , `name`);
Also try to avoid using the wildcard '*'. Instead only ask for the columns you need. Something like:
SELECT `id`, `type`, `genre`, `tm`, `name` FROM `dream_items` WHERE...
Cache Your Results.
If the records in the DB have not changed then there is no reason to try an re-query the results. Use some sort of caching to reduce the load on your DB (memcached, flat file, etc..). Depending on the database class / utilities you're using it may already be capable of caching results.

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