showing products after categories php - php

I have the following markup which shows a list of categories and subcategories:
<table border="0" width="100%" cellspacing="0" cellpadding="2">
<tr class="dataTableHeadingRow">
<td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
<td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?> </td>
</tr>
<?php
function category_list( $category_parent_id = 0 )
{
$sql = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id AND c.parent_id='.$category_parent_id;
$res = tep_db_query( $sql );
$cats = array();
while ( $cat = tep_db_fetch_array( $res ) )
{
$cats[] = $cat;
}
if (count($cats) == 0)
{
return '';
}
$list_items = array();
foreach ( $cats as $cat )
{
$list_items[] = '<tr class="dataTableRow"><td class="dataTableContent">';
if($category_parent_id != 0) $list_items[] = ' ';
if($category_parent_id == 0 )$list_items[] = '<b>';
$list_items[] = $cat['categories_name'];
if($category_parent_id == 0) $list_items[] = '</b>';
$list_items[] = '</td><td class="dataTableContent">';
$list_items[] = category_list( $cat['categories_id'] );
$list_items[] = '</td></tr>';
}
$list_items[] = '';
return implode( '', $list_items );
}
echo category_list();
?>
</table>
Each category is show in bold and the sub category is shown slightly indented to the right. I need to show the products available in each of the subcategory's. I tried adding the needed product fields to the sql query, but it didn't respond. The fields I need to add to search for the products are: products_id, products_name, these are from the table TABLE_PRODUCTS_DESCRIPTION, and to sort it their categories, there is another table called TABLE_PRODUCTS_TO_CATEGORIES, which has the fields products_id and categories_id.
How would I go about doing this?

It looks like you are using osCommerce or one of its forks and you want to display the amount of products for each category.
If you have only two levels of categories that's ok to do, if your category tree goes deeper, be warned that this is a real performance killer as building the category-tree in osCommerce is done, let's say, not really performance optimized, especially for complex tree structures.
The straight forward way is, to count the entries of the TABLE_PRODUCTS_TO_CATEGORIES table where the column categories_id holds the current category id:
$query = 'SELECT COUNT(*) FROM `'.TABLE_PRODUCTS_TO_CATEGORIES.'` WHERE `categories_id` = "'.$cat['categories_id'].'"';
Fetch the result and you have the count.
With this approach though you will only get the count of products directly in tnis category, not the count of products which reside in children categories.
You might also have a look on includes/boxes/categories.php as this is already built in in osC - the methods tep_show_category() and the herein called tep_count_products_in_category() might be usable for your purpose so no need to write it yourself.

I don't really like the from thing in the query for joining 2 tables. I have changed the query the way I prefer. You can change it to the from way if you wish.
$sql = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order, pd.products_id, pd.products_name
from ' . TABLE_CATEGORIES . ' c
inner join ' . TABLE_CATEGORIES_DESCRIPTION . ' cd on c.categories_id = cd.categories_id
inner join '. TABLE_PRODUCTS_TO_CATEGORIES .' pc on pc.categories_id=c.categories_id
inner join ' . TABLE_PRODUCTS_DESCRIPTION . ' pd on pd.products_id=pc.products_id
where c.parent_id='.$category_parent_id;

Related

Php output for categories

I have a shop with more than 30k categories in it and it's almost impossible to edit products in admin because the way it handles categories selection in products edit page it's not designed for that amount of categories. It loads very long and sometimes even crashes. It's a simple select box and I wonder what can be done?
Do I need ajax for this to work?
Here's the code:
<?php function custom_catalog_tree($category_id=0, $depth=1, $count=0) {
$output = '';
if ($category_id == 0) {
$output .= '<div class="checkbox" id="category-id-'. $category_id .'"><label>'. functions::form_draw_checkbox('categories[]', '0', (isset($_POST['categories']) && in_array('0', $_POST['categories'], true)) ? '0' : false, 'data-name="'. htmlspecialchars(language::translate('title_root', 'Root')) .'" data-priority="0"') .' '. functions::draw_fonticon('fa-folder', 'title="'. language::translate('title_root', 'Root') .'" style="color: #cccc66;"') .' ['. language::translate('title_root', 'Root') .']</label></div>' . PHP_EOL;
}
// Output categories
$categories_query = database::query(
"select c.id, ci.name
from ". DB_TABLE_CATEGORIES ." c
left join ". DB_TABLE_CATEGORIES_INFO ." ci on (ci.category_id = c.id and ci.language_code = '". language::$selected['code'] ."')
where c.parent_id = '". (int)$category_id ."'
order by c.priority asc, ci.name asc;"
);
while ($category = database::fetch($categories_query)) {
$count++;
$output .= ' <div class="checkbox"><label>'. functions::form_draw_checkbox('categories[]', $category['id'], true, 'data-name="'. htmlspecialchars($category['name']) .'" data-priority="'. $count .'"') .' '. functions::draw_fonticon('fa-folder fa-lg', 'style="color: #cccc66; margin-left: '. ($depth*1) .'em;"') .' '. $category['name'] .'</label></div>' . PHP_EOL;
if (database::num_rows(database::query("select * from ". DB_TABLE_CATEGORIES ." where parent_id = '". $category['id'] ."' limit 1;")) > 0) {
$output .= custom_catalog_tree($category['id'], $depth+1, $count);
}
}
database::free($categories_query);
return $output;
}
echo custom_catalog_tree();
?>
I would suggest you to make a search box instead of a select box. Write down a query to search the product category with ajax if you can. Make a search query with select * from table_name where category like %your_value%
You can easily handle this using Select2 plugin.
It provides a suggestion dropdown, where users can type and filter through dropdown values.
On server side you have to create web service to fetch categories by name.
Go through section Loading remote data,
https://select2.github.io/examples.html#data-ajax

How to pass an alias from a database query into a loop for output in Wordpress

I am querying the database in Wordpress to retrieve comment_content in the wp_comments table as well as the meta_value of 2 meta_keys in the wp_commentmeta table. My aim is to take every comment in the database and output it within a list, with each list item displaying the comment, as well as my 2 commentmeta items (name and country).
I am using an alias for each meta_key as so:
$querystr = " SELECT * FROM $wpdb->comments, $wpdb->commentmeta AS commentmeta1, $wpdb->commentmeta AS commentmeta2
WHERE $wpdb->comments.comment_ID = commentmeta1.comment_id
AND $wpdb->comments.comment_ID = commentmeta2.comment_id
AND commentmeta1.meta_key = 'comment_name'
AND commentmeta2.meta_key = 'comment_country' ORDER BY $wpdb->comments.comment_date DESC";
$comment_info = $wpdb->get_results($querystr, OBJECT);
I then run run my loop to display my results:
echo '<ul>';
// display the results
foreach($comment_info as $info) {
echo '<li class="commentBox"><p>' . $info->comment_content . '</p>
<h6>' . $info->meta_value['commentmeta1'] . ', ' . $info->meta_value['commentmeta2'] . '</h6></li>';
}
echo '</ul>';
What I need to do is pass the alias I defined for each meta_key into my loop so I can display it's respective meta_value. I tried using $info->comment_content and $info->meta_value['commentmeta2'] but it doesn't work. Using $info->meta_value only displays commentmeta2. Can anybody help?
Thanks to MatBailie's suggestion, the final working code is as follows:
$querystr = " SELECT comment_content, commentmeta1.meta_value AS comment_name, commentmeta2.meta_value AS comment_country
FROM $wpdb->comments, $wpdb->commentmeta AS commentmeta1, $wpdb->commentmeta AS commentmeta2
WHERE $wpdb->comments.comment_ID = commentmeta1.comment_id
AND $wpdb->comments.comment_ID = commentmeta2.comment_id
AND commentmeta1.meta_key = 'comment_name'
AND commentmeta2.meta_key = 'comment_country' ORDER BY $wpdb->comments.comment_date DESC";
$comment_info = $wpdb->get_results($querystr, OBJECT);
echo '<ul>';
// display the results
foreach($comment_info as $info) {
echo '<li class="commentBox"><p>' . $info->comment_content . '</p>
<h6>' . $info->comment_name . ', ' . $info->comment_country . '</h6></li>';
}
echo '</ul>';

Get all products from english version - WooCommerce & WPML

I'm developing a web application that works with WordPress database. In my website,(which works with WooCommerce and WPML) I have products in two languages - english (1st), serbian(2nd). I wrote an SQL code that get the products from database, with their regular and sale prices and etc., but I want to get ONLY products where lang = en (the products from english version). The problem is I don't know how to get them.
Simple SQL:
$sql = 'SELECT * from `wp_posts` WHERE post_type = product';
This is the method that SELECT from database:
// SELECT
public function select (
$table_1 = ' wp_posts ',
$table_2 = ' wp_postmeta ',
$rows = ' t1.id, t1.post_title, guid, post_type ',
$where = ' t1.post_status = "publish" AND t1.post_type = "product" OR t1.post_type = "product_variation" ',
$groupby = ' t1.ID, t1.post_title '
) {
// Connect to database and set charset
$this->connect();
$this->conn->set_charset('utf8');
// Published products
$sql = "SELECT $rows,
max(case when meta_key = '_regular_price' then t2.meta_value end) AS price,
max(case when meta_key = '_sale_price' then t2.meta_value end) AS sale,
max(case when meta_key = 'attribute_colors' then t2.meta_value end) AS colors,
max(case when meta_key = 'attribute_number' then t2.meta_value end)
FROM $table_1 AS t1
INNER JOIN $table_2 AS t2 ON ( t1.ID = t2.post_id )
WHERE $where
GROUP BY $groupby";
$result = mysqli_query($this->conn, $sql);
$published_products_count = mysqli_num_rows($result);
// Trashed products
$trashed_sql = "SELECT post_status FROM `wp_posts`
WHERE post_status = 'trash'";
$trashed_result = mysqli_query($this->conn, $trashed_sql);
$trashed_products_count = mysqli_num_rows($trashed_result);
// If results -> show them
if ($result) {
printf( "\t\t" . "<p>There are <strong>%d published</strong> products and <strong>%d trashed</strong>.</p>", $published_products_count, $trashed_products_count);
$table = '
<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th>Row. №</th>
<th>ID</th>
<th>Product</th>
<th>Regular price</th>
<th>Sale price</th>
<th>Type</th>
<th>Edit</th>
</tr>
</thead>';
$row_number = 1;
while ($row = $result->fetch_assoc()) {
$table .= '
<tr>
<td>' . $row_number++ . '</td>
<td>' . $row["id"] . '</td>
<td>' . $row["post_title"] . '</td>
<td class="price">' . $row["price"] . '</td>
<td class="sale">' . $row["sale"] . '</td>
<td>' . $row["post_type"] . '</td>
<td>Edit</td>
</tr>';
}
$table .= '
</table>';
echo $table;
}
// If no results
else {
echo 'There isn't any products';
}
}
I hope somebody help me!
Thanks in advance! :)
P.S. The application is not based on WordPress!
WPML plugin creates several new tables to manage multilang, not affecting the standard WP posts tables. Specifically, it creates the wp_icl_translations table, where it stores relations between posts and languages.
You need to add two new JOIN statements to your query:
JOIN wp_icl_translations t ON wp_posts.ID = t.element_id AND t.element_type = 'post_product' JOIN wp_icl_languages l ON t.language_code=l.code AND l.active=1
Then, you can add a new condition to your WHERE statement like this:
AND t.language_code='en'
Hope this helps.
Regards.

How can I add categories and subcategories to an array?

I want to list Main categories and subcategories but dont know how ?
What I want to do is like this
Main cat 1
-subcat 1
-subcat 2
-subcat others
Main cat 2
-subcat 1
-subcat 2
-subcat others
I have two part codes which is printing only main categories like this,
Main cat1
Main cat2
Main cat3
Here is the total codes Trying separate ways but cant do it.
$sql_select_cats_list = $db->query("SELECT category_id, items_counter, hover_title FROM " . DB_PREFIX . "categories WHERE parent_id=0 AND hidden=0 AND user_id=0 AND enable_auctions=1 ORDER BY order_id ASC, name ASC");
$cats = array();
while($row=$db->fetch_array($sql_select_cats_list)) {
$cats[$row['category_id']] = $row;
}
$cat_ids = implode(', ', array_keys($cats));
$sql_select_subcats_list = $db->query("SELECT sub.category_id, sub.items_counter, sub.hover_title, parent.order_id FROM " . DB_PREFIX . "categories sub LEFT JOIN " . DB_PREFIX . "categories parent ON (parent.category_id=sub.parent_id) WHERE parent.category_id IN (" . $cat_ids . ") AND sub.hidden=0 AND sub.user_id=0 AND sub.enable_auctions=1 ORDER BY parent.order_id ASC, sub.order_id ASC, sub.name ASC");
while($row=$db->fetch_array($sql_select_subcats_list)) {
if(!isset($subs[$row['parent_id']])) {
$subs[$row['parent_id']] = array();
}
$subs[$row['parent_id']][] = $row;
}
$template->set('cats_list', $cats);
$template->set('subs_list', $subs);
$category_box_content = $template->process('categories_box.tpl.php');
$template->set('category_box_content', $category_box_content);
I am trying to list categories and sub categories with this code:
<?php
foreach($cats as $parent_id => $cats_header_details) {
$category_link = process_link('categories', array('category' => $category_lang[$cats_header_details['category_id']], 'parent_id' => $cats_header_details['category_id']));
// subcategory links:
if(isset($subs_list[$parent_id])) {
foreach($subs_list[$parent_id]) as $sub) {
// do something with your subcategory
}
}
?>
<li><a style="font-size: 11px; font-weight: normal;" href="<?=$category_link;?>"
<?=((!empty($cats_header_details['hover_title'])) ? 'title="' . $cats_header_details['hover_title'] . '"' : '');?> alt="">
<img src="themes/<?=$setts['default_theme'];?>/img/arrow.gif" border="0" hspace="4"><?=$category_lang[$cats_header_details['category_id']];?>
<?=(($setts['enable_cat_counters']) ? (($cats_header_details['items_counter']) ? '(<strong>' . $cats_header_details['items_counter'] . '</strong>)' : '') : '');?></a> </li> <?
}
?>
I get this Warning: Think foreach is returning empty ! cant find the way how to solve it.
Warning: Invalid argument supplied for foreach() in C:\AppServ\www\site\themes\temamiz\templates\categories_box.tpl.php on line 14
And print Main categories on the page with the code below.
<?=$category_box_content;?>
Basically change your pre-template code to first get all category_ids from your categories. Then get a list of subcats which matches that list.
Now process the subs, ordering them to easily be found by their parent id (2nd loop).
Then instead of passing an sql resource to your template (bad form), you hand out the 2 arrays (cats and subcats).
In your template, you then loop through the categories, then within that loop, you have a 2nd loop which loops only over the subcats for that specific category (if any).
In code, like this:
$sql_cats_list = $db->query("SELECT category_id, items_counter, hover_title FROM " . DB_PREFIX . "categories WHERE parent_id=0 AND hidden=0 AND user_id=0 AND enable_auctions=1 ORDER BY order_id ASC, name ASC");
$cats = array();
while($row=$db->fetch_array($sql_cats_list)) {
$cats[$row['category_id']] = $row;
}
$cat_ids = implode(', ', array_keys($cats));
$sql_subcats_list = $db->query("SELECT sub.category_id, sub.items_counter, sub.hover_title, parent.order_id FROM " . DB_PREFIX . "categories sub LEFT JOIN " . DB_PREFIX . "categories parent ON (parent.category_id=sub.parent_id) WHERE parent.category_id IN (" . $cat_ids . ") AND sub.hidden=0 AND sub.user_id=0 AND sub.enable_auctions=1 ORDER BY parent.order_id ASC, sub.order_id ASC, name ASC");
while($row=$db->fetch_array($sql_subcats_list)) {
if(!isset($subs[$row['parent_id']])) {
$subs[$row['parent_id']] = array();
}
$subs[$row['parent_id']][] = $row;
}
$template->set('cats_list', $cats);
$template->set('subs_list', $subs);
$category_box_content = $template->process('categories_box.tpl.php');
$template->set('category_box_content', $category_box_content);
I assume this was your categories_box.tpl.php file (?)
<?php
foreach($cats as $parent_id => $cats_header_details) {
$category_link = process_link('categories', array('category' => $category_lang[$cats_header_details['category_id']], 'parent_id' => $cats_header_details['category_id']));
// subcategory links:
if(isset($subs_list[$parent_id])) {
foreach($subs_list[$parent_id] as $sub) {
// do something with your subcategory
}
}
?>
<li><a style="font-size: 11px; font-weight: normal;" href="<?=$category_link;?>"
<?=((!empty($cats_header_details['hover_title'])) ? 'title="' . $cats_header_details['hover_title'] . '"' : '');?> alt=""><img src="themes/<?=$setts['default_theme'];?>/img/arrow.gif" border="0" hspace="4"><?=$category_lang[$cats_header_details['category_id']];?> <?=(($setts['enable_cat_counters']) ? (($cats_header_details['items_counter']) ? '(<strong>' . $cats_header_details['items_counter'] . '</strong>)' : '') : '');?></a> </li> <?
}
?>
And print Main categories on the page with the code below.
<?=$category_box_content;?>

displaying subcategories under the categories in oscommerce

Here is the markup of what I have so far:
<?php
$categories_query = tep_db_query("select c.categories_id, cd.categories_name, c.categories_image, c.parent_id, c.sort_order, c.date_added, c.last_modified from " . TABLE_CATEGORIES . " c, " . TABLE_CATEGORIES_DESCRIPTION . " cd where c.categories_id = cd.categories_id order by c.sort_order ASC");
while ($categories = tep_db_fetch_array($categories_query)){
echo '<tr class="dataTableRow">
<td class="dataTableContent">' . $categories ['categories_name'] . '</td>';
?>
<td class="dataTableContent"></td>
<?php
echo '</tr>';
}
?>
This displays all the categories and subcategories all on a page, but in no order, what i need is for the subcategories to be displayed under the main category. I have some clue as to how i would do it, a link between the sort_order field and the parent_id field. The main categories use the sort_order field as id, and the subccat's use the parent_id field to sort the category they belong to. Any ideas?
I'm not sure how to do display category tree with single MySQL query, so I'm suggesting to use recursive PHP function:
<?php
function showChildCategories($parent) {
$parent = intval($parent);
// Select only categories with parent_id = $parent
$categories_query = tep_db_query("select
cd.categories_name,
c.categories_id
from " . TABLE_CATEGORIES . " c, " .
TABLE_CATEGORIES_DESCRIPTION . " cd
where c.categories_id = cd.categories_id
and c.parent_id = $parent
order by c.sort_order ASC");
// Go through all query result rows
while ($categories = tep_db_fetch_array($categories_query)){
// Show category name
echo '<tr class="dataTableRow"><td class="dataTableContent">' .
$categories ['categories_name'] . '</td></tr>';
// Show child categories for current row
showChildCategories($categories ['categories_id']);
} // while
} // function showChildCategories
// Show top-level categories and all their children recursively
showChildCategories(0);
?>

Categories