Split WP_Query output into chunks in Wordpress - php

I'm trying to extract an xml feed for about 30k products.
In the lower one, the output reaches the level of 7-8 thousand and does not continue. I need to include all products in the output.
Can I split the process or output files into parts, would something like this require a lot of code?
Or if anyone has any other ideas, I'm open to that, as this seems to be an important issue I need to resolve.
I get data from database with WP_Query() loop starts with foreach and outputs with XMLWriter().
<?php
add_action( 'wp_loaded', 'product_feeds_output_writer');
function product_feeds_output_writer() {
$args = array(
'post_type' => 'product', // Total product 30k.
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'instock',
'compare' => '='
)
)
);
$query = new WP_Query();
if (! $posts = $query->query( $args ) ) {
$error = new WP_Error( '003', 'No products found.' );
wp_send_json_error( $error );
}
$bloginfo = array(
'name' => get_bloginfo('name'),
'url' => get_bloginfo('url'),
'description' => get_bloginfo('description')
);
$xml = new XMLWriter();
$xml->openURI( $_SERVER['DOCUMENT_ROOT'] . '/wp-content/uploads/woo-products-feed-generator/XMLWriter.xml' );
$xml->startDocument('1.0','UTF-8');
$xml->setIndent( 4 );
$xml->startElement('rss');
$xml->writeAttribute('version', '2.0');
$xml->writeAttribute('xmlns:g', 'http://base.google.com/ns/1.0');
$xml->startElement('channel');
$xml->writeElement('title', $bloginfo['name']);
$xml->writeElement('link', $bloginfo['url']);
$xml->writeElement('description', $bloginfo['description']);
foreach ( $posts as $post ) {
$product = wc_get_product( $post->ID );
$bir = random_int( 0, 9 );
$on = random_int( 10, 99 );
$yuz = random_int( 100, 999 );
$bin = random_int( 1000, 9999 );
$mil = random_int( 1000000, 9999999 );
$id = $product->get_id();
$title = $product->get_title();
$link = $product->get_permalink();
$description = $product->get_description();
$price = $product->get_regular_price() ?: $product->get_price();
$sale_price = $product->get_sale_price() ?: '';
$availability = $product->get_stock_status() == 'instock' ? 'in_stock' : 'out_of_stock';
$brand = $product->get_attribute( 'pa_marka' );
$image_link = $product->get_meta('_product_image_thumbnail') ?: wp_get_attachment_url( $product->get_image_id() );
$type = implode( '', wp_get_post_terms( $product->id, 'product_cat', array('fields' => 'names') ) );
$xml->startElement('item');
$xml->writeElement( 'g:id', $id );
$xml->writeElement( 'g:title', $title );
$xml->writeElement( 'g:description', $description );
$xml->writeElement( 'g:link', $link );
$xml->writeElement( 'g:price', $price.' '.'TRY' );
if( $sale_price ) {
$xml->writeElement( 'g:sale_price', $sale_price.' '.'TRY' );
}
$xml->writeElement( 'g:availability', $availability );
$xml->writeElement( 'g:brand', $brand );
//$xml->writeElement( 'g:google_product_category', $track );
$xml->writeElement( 'g:product_type', $type );
$xml->writeElement( 'g:identifier_exists', 'yes' );
$xml->writeElement( 'g:gtin', $mil.'-'.'K'.$yuz.'DK' );
$xml->writeElement( 'g:mpn', $bin.'BS'.'-'.'L'.$on.$bir.'ZP' );
$xml->writeElement( 'g:condition', 'Yeni' );
//$xml->writeElement( 'g:shipping', $track );
$xml->writeElement( 'g:image_link', $image_link );
if( $attachment_images = $product->get_gallery_image_ids() ) {
$attachment_images = array_slice( $attachment_images, 0, 10 );
foreach( $attachment_images as $attachment_id ) {
$image_link = wp_get_attachment_url( $attachment_id );
$xml->writeElement( 'g:additional_image_link', $image_link );
}
}
$xml->writeElement( 'g:material', 'Polipropilen' );
if( $value = $product->get_attribute( 'pa_renk' ) ) {
$xml->startElement('g:product_detail');
$xml->writeElement('g:section_name', 'Additional information' );
$xml->writeElement('g:attribute_name', 'Renk' );
$xml->writeElement('g:attribute_value', $value );
$xml->endElement();
}
if( $value = $product->get_attribute( 'pa_beden' ) ) {
$xml->startElement('g:product_detail');
$xml->writeElement('g:section_name', 'Additional information' );
$xml->writeElement('g:attribute_name', 'Beden' );
$xml->writeElement('g:attribute_value', $value );
$xml->endElement();
}
$xml->endElement();
}
$xml->endElement();
$xml->endElement();
$xml->endDocument();
$xml->flush();
unset($xml);
}

Would going through the WooCommerce REST API not be a better approach?
I believe the endpoint for products is :
/wp-json/wc/v3/products
You should be able to page jump through the page= url parameter:
/wp-json/wc/v3/products?page=1&per_page=5000
Parameter
Description
page
(integer) Current page of the collection. Default is 1.
per_page
(integer) Maximum number of items to be returned in result set. Default is 10.
#See https://woocommerce.github.io/woocommerce-rest-api-docs/#list-all-products

Related

How do I show custom field in Sensei LMS Certificates plugin PDF

I am using "Sensei LMS" and "Sensei LMS Certificates" plugins.
Now , to enhance "Sensei LMS Certificates" plugin functionality , I have created a custom meta box and custom fields like this : https://prnt.sc/104s7oy
I am using this action hook sensei_certificates_before_pdf_output to show text in PDF
I have added the following code in my custom plugin :
<?php
add_action( 'sensei_certificates_before_pdf_output', 'action__sensei_certificates_before_pdf_output' , 20, 2 );
function action__sensei_certificates_before_pdf_output( $pdf_certificate, $fpdf ) {
global $woothemes_sensei_certificates;
$show_border = apply_filters( 'woothemes_sensei_certificates_show_border', 0 );
$start_position = 200;
$args = array(
'post_type' => 'certificate',
'meta_key' => 'certificate_hash',
'meta_value' => $pdf_certificate->hash,
);
$query = new WP_Query( $args );
$certificate_id = 0;
if ( $query->have_posts() ) {
$query->the_post();
$certificate_id = $query->posts[0]->ID;
}
wp_reset_query();
if ( 0 < intval( $certificate_id ) ) {
$user_id = get_post_meta( $certificate_id, 'learner_id', true );
$student = get_userdata( $user_id );
$student_name = $student->display_name;
$fname = $student->first_name;
$lname = $student->last_name;
if ( '' != $fname && '' != $lname ) {
$student_name = $fname . ' ' . $lname;
}
$course_id = get_post_meta( $certificate_id, 'course_id', true );
$course_title = get_post_field('post_title', $course_id);
$course_end = Sensei_Utils::sensei_check_for_activity(
array(
'post_id' => intval( $course_id ),
'user_id' => intval( $user_id ),
'type' => 'sensei_course_status',
),
true
);
$course_end_date = $course_end->comment_date;
$date = Woothemes_Sensei_Certificates_Utils::get_certificate_formatted_date( $course_end_date );
if ( isset( $woothemes_sensei_certificates->certificate_template_fields['certificate_custom_message']['text'] ) && '' != $woothemes_sensei_certificates->certificate_template_fields['certificate_custom_message']['text'] ) {
$certificate_custom_message = $woothemes_sensei_certificates->certificate_template_fields['certificate_custom_message']['text'];
$certificate_custom_message .= str_replace( array( '{{learner}}', '{{course_title}}', '{{completion_date}}', '{{course_place}}' ), array( $student_name, $course_title, $date, get_bloginfo( 'name' ) ), $certificate_custom_message );
}
$output_fields = array(
'certificate_custom_message' => 'textarea_field',
);
foreach ( $output_fields as $meta_key => $function_name ) {
if ( isset( $woothemes_sensei_certificates->certificate_template_fields[ $meta_key ]['position']['x1'] ) ) {
$font_settings = $woothemes_sensei_certificates->get_certificate_font_settings( $meta_key );
call_user_func_array( array( $pdf_certificate, $function_name ), array( $fpdf, $meta_key, $show_border, array( $woothemes_sensei_certificates->certificate_template_fields[ $meta_key ]['position']['x1'], $woothemes_sensei_certificates->certificate_template_fields[ $meta_key ]['position']['y1'], $woothemes_sensei_certificates->certificate_template_fields[ $meta_key ]['position']['width'], $woothemes_sensei_certificates->certificate_template_fields[ $meta_key ]['position']['height'] ), $font_settings ) );
}
}
} else {
wp_die( esc_html__( 'The certificate you are searching for does not exist.', '' ), esc_html__( 'Certificate Error', '' ) );
}
}
but this is how text showing inside PDF : https://prnt.sc/104sg3v
expected result is "Hello Test hii" instead of "certificate_custom_message"
How do I fix this ?

Setting the product type as a variable subscription in WooCommerce

I'm learning Woocommerce and I've managed to create a product programmatically. Currently, the product is being set as a variable product image
However, this needs to be a variable subscription. How should I do so? Tried looking in the wc_product class etc... Even though that replacing:
$product = new WC_Product_Variable( $product_id );
with
$product = new WC_Subscription_Variable( $product_id );
would work... It didn't obviously... So I'll try looking for an answer, but maybe if you knew what to do, then that would be amazing :)
My code:
create_product_variation( array(
'author' => '', // optional
'title' => $oVehicle['koeretoej']['titel'],
'excerpt' => 'The product short description…',
'regular_price' => '0', // product regular price
'sale_price' => '', // product sale price (optional)
'stock' => '1', // Set a minimal stock quantity
'image_id' => '', // optional
'gallery_ids' => array(), // optional
'sku' => '', // optional
'tax_class' => '', // optional
'weight' => '', // optional
// For NEW attributes/values use NAMES (not slugs)
'attributes' => array(
'Perioder' => array( '1 Uge', '2 Uger', '3 Uger', '4 Uger', '2 Måneder',),
// 'Attribute 2' => array( 'Value 1', 'Value 2', 'Value 3' ),
),
) );
}
}
$response['existingvehicles'] = $existingvehicles;
$response['$iProductID'] = $product;
$response['vehicles'] = $vehicles;
$response['aVehicles'] = $_POST['aVehicles'];
$response['bSucces'] = true;
echo json_encode($response);
wp_die();
}
function save_product_attribute_from_name( $name, $label='', $set=true ){
if( ! function_exists ('get_attribute_id_from_name') ) return;
global $wpdb;
$label = $label == '' ? ucfirst($name) : $label;
$attribute_id = get_attribute_id_from_name( $name );
if( empty($attribute_id) ){
$attribute_id = NULL;
} else {
$set = false;
}
$args = array(
'attribute_id' => $attribute_id,
'attribute_name' => $name,
'attribute_label' => $label,
'attribute_type' => 'select',
'attribute_orderby' => 'menu_order',
'attribute_public' => 0,
);
if( empty($attribute_id) ) {
$wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $args );
set_transient( 'wc_attribute_taxonomies', false );
}
if( $set ){
$attributes = wc_get_attribute_taxonomies();
$args['attribute_id'] = get_attribute_id_from_name( $name );
$attributes[] = (object) $args;
//print_r($attributes);
set_transient( 'wc_attribute_taxonomies', $attributes );
} else {
return;
}
}
/**
* Get the product attribute ID from the name.
*
* #since 3.0.0
* #param string $name | The name (slug).
*/
function get_attribute_id_from_name( $name ){
global $wpdb;
$attribute_id = $wpdb->get_col("SELECT attribute_id
FROM {$wpdb->prefix}woocommerce_attribute_taxonomies
WHERE attribute_name LIKE '$name'");
return reset($attribute_id);
}
/**
* Create a new variable product (with new attributes if they are).
* (Needed functions:
*
* #since 3.0.0
* #param array $data | The data to insert in the product.
*/
function create_product_variation( $data ){
if( ! function_exists ('save_product_attribute_from_name') ) return;
$postname = sanitize_title( $data['title'] );
$author = empty( $data['author'] ) ? '1' : $data['author'];
$post_data = array(
'post_author' => $author,
'post_name' => $postname,
'post_title' => $data['title'],
'post_content' => $data['content'],
'post_excerpt' => $data['excerpt'],
'post_status' => 'publish',
'ping_status' => 'closed',
'post_type' => 'product',
'guid' => home_url( '/product/'.$postname.'/' ),
);
// Creating the product (post data)
$product_id = wp_insert_post( $post_data );
// Get an instance of the WC_Product_Variable object and save it
$product = new WC_Product_Variable( $product_id );
$product->save();
## ---------------------- Other optional data ---------------------- ##
## (see WC_Product and WC_Product_Variable setters methods)
// THE PRICES (No prices yet as we need to create product variations)
// IMAGES GALLERY
if( ! empty( $data['gallery_ids'] ) && count( $data['gallery_ids'] ) > 0 )
$product->set_gallery_image_ids( $data['gallery_ids'] );
// SKU
if( ! empty( $data['sku'] ) )
$product->set_sku( $data['sku'] );
// STOCK (stock will be managed in variations)
$product->set_stock_quantity( $data['stock'] ); // Set a minimal stock quantity
$product->set_manage_stock(true);
$product->set_stock_status('');
// Tax class
if( empty( $data['tax_class'] ) )
$product->set_tax_class( $data['tax_class'] );
// WEIGHT
if( ! empty($data['weight']) )
$product->set_weight(''); // weight (reseting)
else
$product->set_weight($data['weight']);
$product->validate_props(); // Check validation
## ---------------------- VARIATION ATTRIBUTES ---------------------- ##
$product_attributes = array();
foreach( $data['attributes'] as $key => $terms ){
$taxonomy = wc_attribute_taxonomy_name($key); // The taxonomy slug
$attr_label = ucfirst($key); // attribute label name
$attr_name = ( wc_sanitize_taxonomy_name($key)); // attribute slug
// NEW Attributes: Register and save them
if( ! taxonomy_exists( $taxonomy ) )
save_product_attribute_from_name( $attr_name, $attr_label );
$product_attributes[$taxonomy] = array (
'name' => $taxonomy,
'value' => '',
'position' => '',
'is_visible' => 1,
'is_variation' => 1,
'is_taxonomy' => 1
);
foreach( $terms as $value ){
$term_name = ucfirst($value);
$term_slug = sanitize_title($value);
// Check if the Term name exist and if not we create it.
if( ! term_exists( $value, $taxonomy ) )
wp_insert_term( $term_name, $taxonomy, array('slug' => $term_slug ) ); // Create the term
// Set attribute values
wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
}
}
update_post_meta( $product_id, '_product_attributes', $product_attributes );
// $product->set_attributes(array( $taxonomy => $terms[0] ));
$product->save(); // Save the data
}
Replacing this:
$product = new WC_Product_Variable( $product_id );
with this
$product = new WC_Product_Variable_Subscription( $product_id );
did the job

How to programmatically set a term to a Woocommerce product variation?

I would like to set all variable products, when created, with the same six different variations using an already defined attribute ("bidragsstorlek"). The six variations should have different prices.
With my current code I succeded with all steps except the last one. I succefully added an attribute, six diffrent terms and six different variations. When I look in the back end panel the product variations have the prices I want, the only thing missing is to set the right term to each variation.
I know similar questions been asked before and been trying to implement those answers, but can't get it right.
$taxonomy = 'pa_bidragsstorlek';
$arrtermnames = array('50 kronor', '100 kronor', '250 kronor', '500 kronor', '1000 kronor', '5000 kronor');
$attr_data = Array(
$taxonomy=>Array(
'name' => $taxonomy,
'value' => '',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1'
)
);
$newproduct = new WC_Product($product_id);
update_post_meta( $product_id, '_product_attributes', array_merge($newproduct->get_attributes(), $attr_data) );
foreach ($arrtermnames as &$value) {
$term_name = $value; // The term "NAME"
$term_slug = sanitize_title($term_name); // The term "slug"
// Check if the term exist and if not it create it (and get the term ID).
if( ! term_exists( $term_name, $taxonomy ) ){
$term_data = wp_insert_term( $term_name, $taxonomy );
$term_id = $term_data['term_id'];
} else {
$term_id = get_term_by( 'name', $term_name, $taxonomy )->term_id;
}
// get an instance of the WC_Product Object
$product = wc_get_product( $product_id );
$attributes = (array) $product->get_attributes();
// 1. If the product attribute is set for the product
if( array_key_exists( $taxonomy, $attributes ) ) {
foreach( $attributes as $key => $attribute ){
if( $key == $taxonomy ){
$options = (array) $attribute->get_options();
$options[] = $term_id;
$attribute->set_options($options);
$attributes[$key] = $attribute;
break;
}
}
$product->set_attributes( $attributes );
}
// 2. The product attribute is not set for the product
else {
$attribute = new WC_Product_Attribute();
$attribute->set_id( sizeof( $attributes) + 1 );
$attribute->set_name( $taxonomy );
$attribute->set_options( array( $term_id ) );
$attribute->set_position( sizeof( $attributes) + 1 );
$attribute->set_visible( true );
$attribute->set_variation( false );
$attributes[] = $attribute;
$product->set_attributes( $attributes );
}
$product->save();
// Append the new term in the product
if( ! has_term( $term_name, $taxonomy, $product_id ))
wp_set_object_terms($product_id, $term_slug, $taxonomy, true );
}
unset($value);
$parent_id = $product_id;
$arrprice = array(50, 100, 250, 500, 1000, 5000);
for ($x = 0; $x <= 5; $x++) {
$variation = array(
'post_title' => 'Product #' . $parent_id. $arrprice[$x],
'post_content' => '',
'post_status' => 'publish',
'post_parent' => $parent_id,
'post_type' => 'product_variation'
);
// The variation id
$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_regular_price', $arrprice[$x] );
update_post_meta( $variation_id, '_price', $arrtermnames[$x] );
update_post_meta( $variation_id, '_virtual', '1' );
// Assign the size and color of this variation
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $arrtermnames[$x] );
WC_Product_Variable::sync( $parent_id );
}
Right now with this code, when checking in the panel, I have a drop-down at each variation with all the terms - but none is choosen. Any idea what is missing to make each variation to be set to the right term?

Woocommerce newProduct() Taxonomy is Not Working

Can you show me what I'm doing wrong?
My code to add a new product to Woocommerce looks like this right now:
function newProduct( $idERP, $titulo, $conteudo, $preco, $precoDesconto, $sku, $peso, $comprimento, $largura, $altura, $estoque, $variacoes, $categorias ){
global $woocommerce;
$titulo = utf8_encode($titulo);
$conteudo = utf8_encode($conteudo);
$my_post = array(
'post_title' => $titulo,
'post_content' => $conteudo,
'post_status' => 'pending',
'post_author' => 6,
'post_type' =>'product'
);
$product_ID = wp_insert_post( $my_post );
if ( $product_ID ){
if( $preco == $precoDesconto){
add_post_meta($product_ID, '_price', $precoDesconto );
}else{
add_post_meta($product_ID, '_regular_price', $preco );
add_post_meta($product_ID, '_price', $precoDesconto );
add_post_meta($product_ID, '_sale_price', $precoDesconto );
}
add_post_meta($product_ID, '_sku', $sku );
add_post_meta($product_ID, '_weight', $peso );
add_post_meta($product_ID, '_length', $comprimento );
add_post_meta($product_ID, '_width', $largura );
add_post_meta($product_ID, '_height', $altura );
add_post_meta($product_ID, '_stock', $this->estoque($estoque) );
add_post_meta($product_ID, '_idERP', $idERP ); //ID from erp
wp_set_object_terms( $product_ID, 'variable', 'product_type' );
//wp_set_object_terms( $product_ID, $categorias, 'product_cat');
$guardaVariacoes = array();$i = 1;
foreach($variacoes as $v){
$vid = wp_insert_post(
array(
'post_title' => 'Variacao #' . $i,
'post_name' => 'product-' . $product_ID . '-variation-' . $i,
'post_status' => 'publish',
'post_parent' => $product_ID,
'post_type' => 'product_variation',
'guid' => home_url() . '/?product_variation=product-' . $product_ID . '-variation-' . $i
)
);
if( $v[1] == $v[2] ){
update_post_meta( $vid, '_regular_price', $v[1]);
}else{
update_post_meta( $vid, '_price', $v[2] );
update_post_meta( $vid, '_regular_price', $v[1]);
update_post_meta( $vid, '_sale_price', $v[2] );
}
update_post_meta( $vid, '_stock', $this->estoque($v[0]) );
update_post_meta( $vid, '_weight', $v[3]);
update_post_meta( $vid, '_width', $v[4]);
update_post_meta( $vid, '_height', $v[5]);
update_post_meta( $vid, '_length', $v[6]);
update_post_meta( $vid, '_sku', $v[8]);
update_post_meta( $vid, '_idERP', $v[9]);
foreach($v[7] as $nAtr=>$vAtr){
$nomeAtributo = strtolower(trim($nAtr));
$tt = $nomeAtributo;
if(strtolower($tt) == 'tamanho')$tt = 'pa_tamanho';
if(strtolower($tt) == 'cor')$tt = 'pa_cor';
update_post_meta( $vid, 'attribute_'.$tt, trim($vAtr));
$temp = $tt.'|'.$nAtr;
if( !array_key_exists($temp,$guardaVariacoes) ) $guardaVariacoes[$temp] = array();
$guardaVariacoes[$temp][] = $vAtr;
}
$i++;
}
$product_attributes = array();
foreach($guardaVariacoes as $r=>$s){
$r = explode('|',$r);
$temp = array();
foreach($s as $w){
$w = trim($w);
if( strtoupper($w) == 'UNICA' ){
$w = 'Única';
}
if( strtoupper($w) == 'UNICO' ){
$w = 'Único';
}
if( array_search( $w,$temp)===false){
if( strtoupper(trim($r[1])) == 'COR'){
$temp[] = ucfirst(strtolower($w));
}else{
$temp[] = $w;
}
}
}
$s = array_unique($temp);
$tt = $r[1];
if(strtolower($tt) == 'tamanho')$tt = 'pa_tamanho';
if(strtolower($tt) == 'cor')$tt = 'pa_cor';
$product_attributes[$r[0]] = array(
'name' => $tt,
'value' => implode(' | ', $s ),
'position' => 1,
'is_visible' => 1,
'is_variation' => 1,
'is_taxonomy' => 1 //MY PROBLEM IS HERE
);
}
update_post_meta($product_ID, '_product_attributes', $product_attributes);
}
return $product_ID;
}
When I change the code like so...
'is_taxonomy' => 1
...it works, but it doesn't work for "search layered filters", which means I have to use taxonomy.
How do I do that without losing the "attributes" inside my product?
Sounds to me like you are trying to set Categories for products, and correct me if I'm wrong please. If this is the case, you don't want to use taxonomies. First, you are missing a ton of meta_keys for the product and all of it's variations. I suggest you install a fresh copy of WooCommerce plugin on a Fresh copy of Wordpress. Create a product manually in the back-end with 2 variations, and take a look at the wp_posts and wp_postmeta (post_id, meta_key, and meta_values). For variations, there are more values for the actual product id in the wp_postmeta table than that of the variations. _max_variation_sale_price_id, _max_variation_sale_price, _min_variation_sale_price_id, _min_variation_sale_price, etc. etc. etc. There is also another serialized array, _default_attributes, that you can just make an empty array and serialize it, for the product so that it has it's defaults set.
So, if you are referring to Categories and want to assign products to categories so that you can click on a category and see that product in there... than do the following:
Keep is_taxonomy set to 0
is_visible doesn't matter, if you want to see it under Additional Info, than set to 1, otherwise, it should still show all different variations, but I suppose it depends on your theme's way of handling this.
position needs to start at 1 and be incremented each time, so use a variable for this, example:
$position = 1;
foreach($guardaVariacoes as $r=>$s) {
// your top code... down to where the _product_attributes array begins...
$product_attributes[$r[0]] = array(
'name' => $tt,
'value' => implode(' | ', $s),
'position' => $position,
'is_visible' => count($s) > 1 ? 0 : 1,
'is_variation' => count($s) > 1 ? 1 : 0,
'is_taxonomy' => 0
);
$position++;
}
To create and assign categories on the fly for products you use: term_exists (will return 0 or NULL if term doesn't exist, you can check with empty()), wp_insert_term (if the term doesn't exist), insert it so that you can assign the category to the product. Example below if you want to insert a sub-brand category into a parent brand category, just an example of how I add categories to products (wp_term_relationships table assigns the categories to each product, via the products/posts ID value):
// Check if Brand exists or not...
$brand = term_exists('brand', 'product_cat', 0);
$category = 'new category';
$cat_name = addslashes(ucwords(strtolower($category)));
$cats['brand'] = array(
'name' => $cat_name,
'slug' => sanitize_title_with_dashes($category)
);
if (!empty($brand))
{
$subbrand = term_exists($cats['brand']['slug'], 'product_cat', $brand['term_id']);
if (empty($subbrand))
{
$subbrand = wp_insert_term(
$cats['brand']['name'],
'product_cat',
array(
'slug' => $cats['brand']['slug'],
'parent'=> $brand['term_id']
)
);
}
} else {
$brand = wp_insert_term(
'Brand',
'product_cat',
array(
'slug' => 'brand',
'parent'=> 0 // This means it will be at the first level!
)
);
$subbrand = term_exists($cats['brand']['slug'], 'product_cat', $brand['term_id']);
if (empty($subbrand))
{
$subbrand = wp_insert_term(
$cats['brand']['name'],
'product_cat',
array(
'slug' => $cats['brand']['slug'],
'parent'=> $brand['term_id']
)
);
}
}
$categories = array(
'product_id' => // put the product id value in here!
'terms' => array()
);
if (!empty($subbrand))
{
$categories['terms']['subbrands'] = $subbrand;
}
// Now insert into term_relationships table for that product and that's all folks...
foreach($categories['terms'] as $type => $nfo)
{
$wpdb->insert(
$wpdb->prefix . "term_relationships",
array(
'object_id' => $categories['product_id'],
'term_taxonomy_id' => intval($nfo['term_taxonomy_id']),
'term_order' => 0
),
array('%d', '%d', '%d')
);
}
So, hopefully this helps you to build categories for your products, while still keeping your product attributes in tact in the search filter. Good Luck.

Filter categories in wordpress

I want to add a filter to get_categories function.
I tried this:
function wpr_cat_filter($args) {
$args['include'] = '37';
return $args;
}
add_filter('get_categories','wpr_cat_filter');
but it doesn't seem to be working. Any ides of what is wrong?
The filter doesn't actually seems to be applied.
If you check the "get_categories" function (in wp-includes/category.php), there's no "get_categories" filter applied:
function &get_categories( $args = '' ) {
$defaults = array( 'taxonomy' => 'category' );
$args = wp_parse_args( $args, $defaults );
$taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );
// Back compat
if ( isset($args['type']) && 'link' == $args['type'] ) {
_deprecated_argument( __FUNCTION__, '3.0', '' );
$taxonomy = $args['taxonomy'] = 'link_category';
}
$categories = (array) get_terms( $taxonomy, $args );
foreach ( array_keys( $categories ) as $k )
_make_cat_compat( $categories[$k] );
return $categories;
}
Also, if you check the source:
wordpress$ grep -Ri "apply_filters" * | grep get_categories
wp-includes/default-widgets.php: wp_dropdown_categories(apply_filters('widget_categories_dropdown_args', $cat_args));
wp-includes/default-widgets.php: wp_list_categories(apply_filters('widget_categories_args', $cat_args));
wp-includes/category.php: $taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );
Perhaps it is just a placeholder for a filter that you can add yourself or might be added later.
If you want that filter, change the get_category function:
function &get_categories( $args = '' ) {
$defaults = array( 'taxonomy' => 'category' );
$args = wp_parse_args( $args, $defaults );
$args = apply_filters( 'get_categories', $args );
$taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );
// Back compat
if ( isset($args['type']) && 'link' == $args['type'] ) {
_deprecated_argument( __FUNCTION__, '3.0', '' );
$taxonomy = $args['taxonomy'] = 'link_category';
}
$categories = (array) get_terms( $taxonomy, $args );
foreach ( array_keys( $categories ) as $k )
_make_cat_compat( $categories[$k] );
return $categories;
}
You might want to file a bug with wordpress or ask on their mailing list to find out why this filter isn't being applied!

Categories