WooCommerce Get All Products as ID name pair - wordpress

I am using this function to get all products as ID name pairs to populate data into a select box.
function get_product_list_as_key_name(){
$args = array( 'post_type' => 'product','posts_per_page' => -1);
$products = get_posts( $args );
$products_list = array();
if(!empty($products)){
$i = 0;
foreach ($products as $value) {
$products_list[$i]['id'] = $value->ID;
$products_list[$i]['name'] = strlen($value->post_title) > 25 ? substr(strip_tags($value->post_title), 0, 25) . "..." : $value->post_title;
$i++;
}
}
return $products_list;
}
Is there any better way to do this?(Any default function ?)

No you have to do this manually. or you can do this with custom query
function get_product_list_as_key_name(){
global $wpdb;
$query = "SELECT ID,post_title FROM {$wpdb->prefix}posts where post_type='product' AND post_status='publish'";
$products_array = $wpdb->get_results( $wpdb->prepare( $query ) );
return $products_array;
}
this is more fast then yours.

Related

Exclude grouped products children in woocommerce, without exclude simple products

THis code is working but I need to include single product without a parent grouped product associated
add_action( 'woocommerce_product_query', 'remove_grouped_children' );
function remove_grouped_children( $q ) {
//get current loop query
$taxonomy_query = $q->get('tax_query') ;
//appends the grouped products condition
$taxonomy_query['relation'] = 'AND';
$taxonomy_query[] = array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => array('grouped','variable')
);
$q->set( 'tax_query', $taxonomy_query );
}
This a walk-around, but finally work.
function wr_convert_array_to_ids(){
$products = wr_get_grouped_product_children();
$post_ids = array();
foreach ($products as $product){
foreach ($product as $id){
array_push($post_ids,$id);
}
}
return $post_ids;
}
function wr_get_grouped_product_children(){
global $wpdb;
$products = $wpdb->get_results(
$wpdb->prepare("SELECT * FROM $wpdb->prefix" . "postmeta WHERE meta_key = %s", '_children'),ARRAY_A
);
$products_id = array();
foreach($products as $product){
array_push($products_id, unserialize($product['meta_value']));
}
return $products_id;
}
function wr_custom_get_posts( $query ) {
if ( is_admin() || ! $query->is_main_query() )
return;
if ( $query->is_archive() || $query->is_shop()) {
$query->set( 'post__not_in', wr_convert_array_to_ids() );
}
}
add_action( 'pre_get_posts', 'wr_custom_get_posts', 1 );
Because the children of grouped products live in the post-meta table below the meta_key _children that is saved as a serialized array, the first thing is to get all the children, then save them in an array and call the 'pre_get_posts' action to exclude those identifiers.

How to convert existing code into WooCommerce Plugin

Im extremely new to WordPress and WooCommerce code. I've been provided with some working code that resides in the plugins/woocommerce/templates/archive-product.php
The function is pretty simple, it simply fetches for an array of data from a remote site and makes use of the JSON returned to find the matching SKUs and inject them as items in the product list.
Works quite nicely, however, as I'm new to Woo & WP, I'm hoping someone might be able to show me how I can transform this code into the proper way of it being defined as a plugin?
I'm hoping its just a case of wrapping some additional code around the function, but I'm unsure as to where to start
any tips greatly appreciated
if ( wc_get_loop_prop( 'total' ) ) {
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$cat = explode('/', $actual_link);
if ($cat[4] == 'my-product-list') {
global $current_user;
get_currentuserinfo();
$data = array( 'email' => $current_user->user_email);
$response = wp_remote_post( 'https://www.shop.com/remote-data/', array( 'data' => $data ) );
$curl = 'https://www.shop.com/remote-data/';
$response = wp_remote_get( $curl );
$rows = wp_remote_retrieve_body( $response ) ;
$decode = json_decode(stripslashes($rows), true);
global $wpdb;
$product_id = array();
$i = 0;
foreach ($decode as $single_data) {
foreach ($single_data['items'] as $data) {
$result = $wpdb->get_results ( "SELECT post_id FROM wp_postmeta WHERE meta_key = '_sku' AND meta_value = '".$data."'" );
$product_id[$i] = $result[0]->post_id;
$i++;
}
}
$product_id = array_filter(array_unique($product_id));
$args = array(
'post_type' => 'product',
'post__in' => $product_id
);
//The Query
$the_query = new WP_Query( $args );
while ( $the_query->have_posts() ) {
$the_query->the_post();
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
You could try to hook it into woocommerce_before_main_content
Like so:
function fetch_shop_data() {
// your code
}
add_action('woocommerce_before_main_content', 'fetch_shop_data');

Updating mate values by meta key for all posts

I want to update a meta value with a specific meta key out of wordpress page. What I want is that, multiplying a meta value with a variable then write the result to another meta value.
for example;
$var=5
meta_key|meta_value
key-1 |10
key-2 |20
the meta_value for the key-1 = 100 (key-2 * $var). I have tried below code to retrieve key-1 but it returns nothing.
require_once("wp-load.php");
function wp_update_value( ) {
global $wpdb;
$mylink = $wpdb->get_results("
SELECT $wpdb->postmeta.meta_value
FROM $wpdb->postmeta
WHERE $wpdb->postmeta.meta_key = 'key-1'",
ARRAY_A);
$array = unserialize($mylink);
return $array;
}
How can I get two meta values by meta keys and update them for all posts?
You can do it inside a loop, something like:
<?php
header('Response: HTTP/1.1 200 OK');
define('WP_USE_THEMES', false);
require('../../../../wp-load.php');
$args = array(
'posts_per_page' => '-1',
);
$the_query = new WP_Query( $args );
$var = 5;
if ( $the_query->have_posts() ){
while ( $the_query->have_posts() ) : $the_query->the_post();
$value = 100 * (get_post_meta(get_the_ID(),'key-2',true) * $var);
update_post_meta(get_the_ID(), 'key-1', $value);
endwhile;
}
?>

Return Number of published posts in a custom post type

<?php
$counter=1;
$counter_new=0;
$args = array('posts_per_page' =>-1,'orderby' => 'post_date','order' =>'DESC','post_type' => 'interview','post_status' => 'publish',
'suppress_filters' => true );query_posts( $args );while (have_posts($args)) : the_post();
if($counter < 8)
{
$counter++;
}
else
{
$counter_new++;
$counter=1;
}
endwhile;
?>
I saw someone else code to find the number of post, as record increase it is not efficient. What is the right way to do? It looks stupid now.
In case you use WPML wp_count_post() will not show correct count of posts for given language. Use this instead:
$posts = get_posts('post_type=yourcustomposttype&suppress_filters=0&posts_per_page=-1');
$count = count($posts);
echo $count;
Take a look at the wp_count_posts() function.
For your example:
$count_posts = wp_count_posts('interview');
$published_posts = $count_posts->publish;
$published_posts will return the number of published posts in your 'interview' custom post type.
One of the other answers won't work if you have WMPL and translations. The other one will work, but will be very inefficient.
With WPML, try this instead:
function my_count_posts( string $post_type = 'post', string $language_code = '', string $post_status = 'publish' ): int {
global $wpdb;
$default_language_code = apply_filters( 'wpml_default_language', null );
$language_code = $language_code !== '' ? $language_code : $default_language_code;
$translation_param = $default_language_code == $language_code ? "IS NULL" : "= '{$default_language_code}'";
$query = <<<SQL
SELECT COUNT( {$wpdb->prefix}posts.ID )
FROM {$wpdb->prefix}posts
LEFT JOIN {$wpdb->prefix}icl_translations ON {$wpdb->prefix}posts.ID = {$wpdb->prefix}icl_translations.element_id
WHERE {$wpdb->prefix}icl_translations.language_code = '{$language_code}'
AND {$wpdb->prefix}icl_translations.source_language_code $translation_param
AND {$wpdb->prefix}icl_translations.element_type = 'post_{$post_type}'
AND {$wpdb->prefix}posts.post_status = '$post_status'
SQL;
return $wpdb->get_var( $query );
}
You'd use it like this:
// counts published "posts" in the default language
$count = my_count_posts();
// counts posts of `post_type=custom_post_type` in the current language
$count = my_count_posts('custom_post_type', apply_filters( 'wpml_current_language', '' ));

get_categories for Custom Post Type

I have a Custom Post Type, 'ioni_codex'
I am using built-in Wordpress category as taxonomy
I want to list all categories used by 'ioni_codex'.
I assume that this code will do the trick:
$myargs = array (
'type' => 'ioni_codex'
);
$categories = get_categories( $myargs );
However instead I see the list of all categories not the categories assigned to by 'ioni_codex'.
What Am I doing wrong?
get_categories() does not accept post_type as an argument, use taxonomy instead and refer to the taxonomy by the name you gave it when registering it. Here is a link to the codex which can explain it in more detail - http://codex.wordpress.org/Function_Reference/get_categories.
Instead of type you have to set post_type , by default get_categories try to hide empty categories , if you want display it all add hide_empty property set to false
get_categories(array(
'post_type' => 'ioni_codex',
'hide_empty' => false,
) );
I have an answer at a sister project:
Bainternet♦ has re-written get_terms() function to provide for the post_type
Please refer to his solution here or just copy and past from below:
/* get terms limited to post type
# $taxonomies - (string|array) (required) The taxonomies to retrieve terms from.
# $args - (string|array) all Possible Arguments of get_terms http://codex.wordpress.org/Function_Reference/get_terms
# $post_type - (string|array) of post types to limit the terms to
# $fields - (string) What to return (default all) accepts ID,name,all,get_terms.
if you want to use get_terms arguments then $fields must be set to 'get_terms'
*/
function get_terms_by_post_type($taxonomies,$args,$post_type,$fields = 'all'){
$args = array(
'post_type' => (array)$post_type,
'posts_per_page' => -1
);
$the_query = new WP_Query( $args );
$terms = array();
while ($the_query->have_posts()){
$the_query->the_post();
$curent_terms = wp_get_object_terms( $post->ID, $taxonomy);
foreach ($curent_terms as $t){
//avoid duplicates
if (!in_array($t,$terms)){
$terms[] = $c;
}
}
}
wp_reset_query();
//return array of term objects
if ($fields == "all")
return $terms;
//return array of term ID's
if ($fields == "ID"){
foreach ($terms as $t){
$re[] = $t->term_id;
}
return $re;
}
//return array of term names
if ($fields == "name"){
foreach ($terms as $t){
$re[] = $t->name;
}
return $re;
}
// get terms with get_terms arguments
if ($fields == "get_terms"){
$terms2 = get_terms( $taxonomies, $args );
foreach ($terms as $t){
if (in_array($t,$terms2)){
$re[] = $t;
}
}
return $re;
}
}
While quick reading #ioni's answer; it looks like it would give you a proper result it will most likely be pretty slow as it goes through every post and then looks for all terms that belong to each post individually. This will easily result in thousands of SQL queries.
My recommendation is to use a single query to get the IDs of all terms that belong to a post type. Then use those ids to filter get_terms().
MySQL query:
SELECT
wp_term_taxonomy.term_id
FROM
wp_term_relationships
LEFT JOIN wp_posts ON wp_term_relationships.object_id = wp_posts.ID
LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE
wp_term_taxonomy.taxonomy = 'category'
AND wp_posts.post_type = 'ioni_codex'
GROUP BY
term_id
PHP function:
<?php
function ioni_get_terms_by_post_type( $taxonomy = 'category', $post_type = 'post', $args = array() ) {
global $wpdb;
$sql = $wpdb->prepare(
"
SELECT
{$wpdb->prefix}term_taxonomy.term_id
FROM
{$wpdb->prefix}term_relationships
LEFT JOIN {$wpdb->prefix}posts ON {$wpdb->prefix}term_relationships.object_id = {$wpdb->prefix}posts.ID
LEFT JOIN {$wpdb->prefix}term_taxonomy ON {$wpdb->prefix}term_relationships.term_taxonomy_id = {$wpdb->prefix}term_taxonomy.term_taxonomy_id
WHERE
{$wpdb->prefix}term_taxonomy.taxonomy = '%s'
AND {$wpdb->prefix}posts.post_type = '%s'
GROUP BY
term_id
",
$taxonomy,
$post_type,
);
$term_ids = $wpdb->get_col( $sql );
if ( empty( $term_ids ) ) {
return array();
}
// custom code to allow for exclude to work
if ( ! empty( $args['exclude'] ) ) {
// allow exclude to be either a string or array
$exclude = is_string( $args['exclude'] ) ? (array) $args['exclude'] : $args['exclude'];
// filter $term_ids with array from $args['exclude']
$term_ids = array_filter( $term_ids, function( $term_id ) use ( $exclude ) {
return ! in_array( $term_id, $exclude );
} );
}
$args = wp_parse_args(
$args,
array(
'taxonomy' => $taxonomy,
'include' => $term_ids,
),
);
return get_terms( $args );
}
Usage:
<?php
$categories = ioni_get_terms_by_post_type( 'category', 'ioni_codex' );

Resources