skip to Main Content

I get all my products from an API and those who are variations to each other all share a custom meta key called “api_product_family“. The products with the same api_product_family are variants to each other, so on the single page I have a hook where I display the other variants with image and anchor to it’s variants.

My code:

function mv_variations() {
  global $post;
  global $wpdb;

  $product_id = $post->ID;

  $product_family = get_post_meta( $post->ID, 'api_product_family', true );

  if(!empty($product_family)) {
    $query = "
      SELECT post_id
      FROM " . $wpdb->prefix . "postmeta
      WHERE meta_value = '" . $product_family . "'
    ";

    $products = $wpdb->get_col($query);

    if(count($products) > 0) {
      for($i=0; $i<count($products); $i++) {
        if($products[$i] == $product_id) {
          unset($products[$i]);
        }
     }

      if(count($products) > 0) {
        print '<h3>Choose other variants: </h3>';
        foreach($products as $product) {
          $image = wp_get_attachment_image_src(get_post_thumbnail_id($product));
          print '<a href="' . get_permalink($product) . '"><img src="' . $image[0] . '" alt="img"/> </a>';
        }
      }
    }
  }
}

add_action( 'woocommerce_single_product_summary', 'mv_variations' );

The problem:
I have a LOT of posts, and a lot of post_meta’s, so it’s taking an eternity to load so I was thinking to move this whole function inside and AJAX call so it’s doesn’t slow down the initial load. The problem is that I have no idea how to do that with wordpress

2

Answers


  1. So I think you might get better performance using WP_Query. Below I converted what you have into a custom WP_Query. May need some slight adjustment but should be the right direction.

    function mv_variations() {
      global $post_id;
    
      // get current post "product family"
      $product_family = get_post_meta( $post_id, 'api_product_family', true );
    
      // build related "product family" products query
      $products_query_args = array(
        'post_type' => 'product', // may need to update this for your case
        'posts_per_page' => -1, // return all found
        'post__not_in' => array($post_id), // exclude current post
        'post_status' => 'publish',
    
        // use a meta query to pull only posts with same "product family" as current post
        'meta_query' => array(
          array(
            'key' => 'api_product_family',
            'value' => $product_family,
            'compare' => '='
          )
        )
      );
    
      $products_query = new WP_Query($products_query);
    
      // use "the loop" to display your products
      if ( $products_query->have_posts() ) :
        print '<h3>Choose other variants: </h3>';
        while ( $products_query->have_posts() ) : $products_query->the_post();
          print '<a href="' . get_permalink() . '">'. wp_get_attachment_image() .'</a>';
        endwhile;
        // restore global post
        wp_reset_postdata();
      endif;
    }
    add_action( 'woocommerce_single_product_summary', 'mv_variations' );
    
    
    Login or Signup to reply.
  2. Are you simply looking to run a WP function via AJAX?

    1) Add ajax actions

    This needs to run inside the main plugin file. If you run this only on the public code, it will not work. WP is a little weird and all ajax uses admin-ajax.php

    if ( wp_doing_ajax() ){
        add_action( 'wp_ajax_yourcustomfunction', array($this, 'yourcustomfunction') );
        add_action( 'wp_ajax_nopriv_yourcustomfunction', array($this, 'yourcustomfunction') );
    }
    
    function yourcustomfunction(){
    
    
        echo 'success';
        exit();
    
    }
    

    2) In JavaScript
    in the backend, you have the global: ajaxurl for the ajax url
    BUT in the front end you need to pass this as a variable via wp_localize_script

    $datatoBePassed = array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
    );
    
    wp_localize_script( 'your_javascript_script', 'plugin_display_settings', $datatoBePassed );
    

    In JS:

    var datavar = {
         action: 'yourcustomfunction',
    };
    
    $.post(plugin_display_settings.ajaxurl, datavar, function(response){
     //response received here. It will be 'success' which is echoed in PHP
    });
    

    3)
    If you also want to run a security nonce check (to check the request truly originates from the WP website, prevents some attacks), it gets a little more complicated:

    $datatoBePassed should also include 'security' => wp_create_nonce( 'yourplugin_security_nonce' ),
    datavar in JS includes security: plugin_display_settings.security,

    Finally, your PHP custom function begins with:

    // Check security nonce. 
        if ( ! check_ajax_referer( 'yourplugin_security_nonce', 'security' ) ) {
            wp_send_json_error( 'Invalid security token sent.' );
            wp_die();
        }
    // If security check passed, run further 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search