• hi guys,

    been searching for quite some time. found 2 code examples, none working. on a standard product archive page i try to sort products by products attribute.

    few questions for that:

    • woocommerce products attributes are not the same as post metas, right?
    • on products category pages i can output the volume of the product with the code echo $product->get_attribute( ‘pa_Volumen’ );
    • i can also output the post meta by print_r(get_post_meta($product->get_id()));
    • but the post meta outputs product attributes as serialized data like `[_product_attributes] => Array
      (
      [0] => a:35:{s:13:”Artikelnummer”;a:6:{s:4:”name”;s:13:”Artikelnummer”;s:5:”value”;s:11:”SBPA1250RWB”;s:8:”position”;s:1:”1″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”0″;}s:32:”pa_max_betriebsdruck_typenschild”;a:6:{s:4:”name”;s:32:”pa_max_betriebsdruck_typenschild”;s:5:”value”;s:0:””;s:8:”position”;s:1:”1″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:18:”pa_produktberuehrt”;a:6:{s:4:”name”;s:18:”pa_produktberuehrt”;s:5:”value”;s:0:””;s:8:”position”;s:1:”1″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:16:”pa_hat_ruehrwerk”;a:6:{s:4:”name”;s:16:”pa_hat_ruehrwerk”;s:5:”value”;s:0:””;s:8:”position”;s:1:”1″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:14:”pa_ausfuehrung”;a:6:{s:4:”name”;s:14:”pa_ausfuehrung”;s:5:”value”;s:0:””;s:8:”position”;s:1:”1″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:10:”pa_bauform”;a:6:{s:4:”name”;s:10:”pa_bauform”;s:5:”value”;s:0:””;s:8:”position”;s:1:”1″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:17:”pa_sonstige_teile”;a:6:{s:4:”name”;s:17:”pa_sonstige_teile”;s:5:”value”;s:0:””;s:8:”position”;s:1:”2″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:19:”pa_ruehrwerk_anzahl”;a:6:{s:4:”name”;s:19:”pa_ruehrwerk_anzahl”;s:5:”value”;s:0:””;s:8:”position”;s:1:”2″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:11:”pa_isoliert”;a:6:{s:4:”name”;s:11:”pa_isoliert”;s:5:”value”;s:0:””;s:8:”position”;s:1:”2″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:25:”pa_anzahl_der_fixierungen”;a:6:{s:4:”name”;s:25:”pa_anzahl_der_fixierungen”;s:5:”value”;s:0:””;s:8:”position”;s:1:”2″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:19:”pa_art_des_artikels”;a:6:{s:4:”name”;s:19:”pa_art_des_artikels”;s:5:”value”;s:0:””;s:8:”position”;s:1:”2″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:25:”pa_max_betriebstemperatur”;a:6:{s:4:”name”;s:25:”pa_max_betriebstemperatur”;s:5:”value”;s:0:””;s:8:”position”;s:1:”2″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:17:”pa_druckbehaelter”;a:6:{s:4:”name”;s:17:”pa_druckbehaelter”;s:5:”value”;s:0:””;s:8:”position”;s:1:”3″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:26:”pa_werkstoff_fuesse_rollen”;a:6:{s:4:”name”;s:26:”pa_werkstoff_fuesse_rollen”;s:5:”value”;s:0:””;s:8:”position”;s:1:”3″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:20:”pa_durchmesser_innen”;a:6:{s:4:”name”;s:20:”pa_durchmesser_innen”;s:5:”value”;s:0:””;s:8:”position”;s:1:”3″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:27:”pa_ruehrwerk_positionierung”;a:6:{s:4:”name”;s:27:”pa_ruehrwerk_positionierung”;s:5:”value”;s:0:””;s:8:”position”;s:1:”3″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:6:”Extras”;a:6:{s:4:”name”;s:6:”Extras”;s:5:”value”;s:11:”Klappdeckel”;s:8:”position”;s:1:”4″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”0″;}s:21:”pa_durchmesser_aussen”;a:6:{s:4:”name”;s:21:”pa_durchmesser_aussen”;s:5:”value”;s:0:””;s:8:”position”;s:1:”4″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:21:”pa_ruehrwerk_leistung”;a:6:{s:4:”name”;s:21:”pa_ruehrwerk_leistung”;s:5:”value”;s:0:””;s:8:”position”;s:1:”4″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:17:”pa_spruehkopf_cip”;a:6:{s:4:”name”;s:17:”pa_spruehkopf_cip”;s:5:”value”;s:0:””;s:8:”position”;s:1:”4″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:8:”Drehzahl”;a:6:{s:4:”name”;s:8:”Drehzahl”;s:5:”value”;s:6:”190UPM”;s:8:”position”;s:1:”5″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”0″;}s:10:”pa_zustand”;a:6:{s:4:”name”;s:10:”pa_zustand”;s:5:”value”;s:0:””;s:8:”position”;s:1:”5″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:32:”pa_4f-technische_zeichung_unterl”;a:6:{s:4:”name”;s:32:”pa_4f-technische_zeichung_unterl”;s:5:”value”;s:0:””;s:8:”position”;s:1:”5″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:21:”pa_zylindrische_hoehe”;a:6:{s:4:”name”;s:21:”pa_zylindrische_hoehe”;s:5:”value”;s:0:””;s:8:”position”;s:1:”5″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:14:”pa_typenschild”;a:6:{s:4:”name”;s:14:”pa_typenschild”;s:5:”value”;s:0:””;s:8:”position”;s:1:”6″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:10:”pa_volumen”;a:6:{s:4:”name”;s:10:”pa_volumen”;s:5:”value”;s:0:””;s:8:”position”;s:1:”6″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:23:”pa_ruehrwerk_ruehrorgan”;a:6:{s:4:”name”;s:23:”pa_ruehrwerk_ruehrorgan”;s:5:”value”;s:0:””;s:8:”position”;s:1:”6″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:7:”Auslauf”;a:6:{s:4:”name”;s:7:”Auslauf”;s:5:”value”;s:13:”DN50 DIN11851″;s:8:”position”;s:1:”7″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”0″;}s:14:”pa_gesamthoehe”;a:6:{s:4:”name”;s:14:”pa_gesamthoehe”;s:5:”value”;s:0:””;s:8:”position”;s:1:”7″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:22:”pa_ruehrwerk_sonstiges”;a:6:{s:4:”name”;s:22:”pa_ruehrwerk_sonstiges”;s:5:”value”;s:0:””;s:8:”position”;s:1:”7″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:15:”Maximale Dichte”;a:6:{s:4:”name”;s:15:”Maximale Dichte”;s:5:”value”;s:10:”1,6Kg/dm3”;s:8:”position”;s:1:”7″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”0″;}s:12:”Gesamtbreite”;a:6:{s:4:”name”;s:12:”Gesamtbreite”;s:5:”value”;s:11:”1150x1200mm”;s:8:”position”;s:1:”8″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”0″;}s:16:”pa_auslaufventil”;a:6:{s:4:”name”;s:16:”pa_auslaufventil”;s:5:”value”;s:0:””;s:8:”position”;s:1:”8″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:13:”pa_lieferzeit”;a:6:{s:4:”name”;s:13:”pa_lieferzeit”;s:5:”value”;s:0:””;s:8:”position”;s:1:”9″;s:10:”is_visible”;s:1:”1″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}s:13:”pa_is_feature”;a:6:{s:4:”name”;s:13:”pa_is_feature”;s:5:”value”;s:0:””;s:8:”position”;s:2:”21″;s:10:”is_visible”;s:1:”0″;s:12:”is_variation”;s:1:”0″;s:11:”is_taxonomy”;s:1:”1″;}}
      )`

    however, with the code

    
    
    dd_filter('woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args');
     
    function custom_woocommerce_get_catalog_ordering_args( $args ) {
        global $wp_query;
            // Changed the $_SESSION to $_GET
        if (isset($_GET['orderby'])) {
            switch ($_GET['orderby']) :
                case 'pa_Volumen' :
                    $args['order'] = 'ASC';
                    $args['meta_key'] = 'pa_Volumen';
                    $args['orderby'] = 'meta_value_num';
                break;
            endswitch;
        }
        return $args;
    }
     
    /**
     *  Adds the sorting options to dropdown list .. The logic/criteria is in the method above
     */
    add_filter('woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby');
     
    function custom_woocommerce_catalog_orderby( $sortby ) {
        $sortby['pa_Volumen'] = 'Volumen aufsteigend';
        return $sortby;
    }
     
    /**
     *  Save custom attributes as post's meta data as well so that we can use in sorting and searching
     */
    add_action( 'save_post', 'save_woocommerce_attr_to_meta' );
    function save_woocommerce_attr_to_meta( $post_id ) {
            // Get the attribute_names .. For each element get the index and the name of the attribute
            // Then use the index to get the corresponding submitted value from the attribute_values array.
        foreach( $_REQUEST['attribute_names'] as $index => $value ) {
            update_post_meta( $post_id, $value, $_REQUEST['attribute_values'][$index] );
        }
    }
    /************ End of Sorting ***************************/
    

    sorting just outputs regular order. i guess because there is nor rela post meta key pa_Volumen, just serialized data for attributes. right?

    i guess the reason is because with that code i’d have to save each products > attributes > post meta. right? if possible anyhow i’d like to sort straight by products attribute, not by a duplicated post meta. the latter would add megabytes of unneccessary data to the db as we got thousands of products with dozens of attributes.`

    • This topic was modified 3 years, 5 months ago by ffwebdesigner.
Viewing 5 replies - 1 through 5 (of 5 total)
  • Hey @ffwebdesigner,

    Could I get a bit more detail from you about what you’re wanting to achieve? That would help us know which way to point you.

    Custom fields (meta) are different from attributes. Each attribute is a taxonomy with terms assigned to it. Custom meta is data that’s saved in the _postmeta table for each product/post.

    Thanks

    Thread Starter ffwebdesigner

    (@ffwebdesigner)

    hi 3 sons,

    i’m trying to do a new standard sorting of all products on any category page.
    value to be sorted by is $product->get_attribute( ‘pa_Volumen’ ); pa_Volumen is numerical.

    the above code doesn’t work as i already guessed because attributes are not post metas. the standard sorting of posts can only be changed to post metas.

    maybe one idea: how about converting just pa_Volumen attribute of each product to post meta – for ALL products? couldn’t find a working code to do that…

    Gotcha. You could programmatically add post meta for each product that’s based on the attributes if you wanted to go that route. Finding some example code to follow may be difficult because the search terms will probably push you to term meta or how to duplicate posts.

    I’ll leave this open for a while and see if anyone can chime in with a suggested snippet.

    Thread Starter ffwebdesigner

    (@ffwebdesigner)

    as this might be helpful: the complete solution for others:

    copy archive-product.php from woocommerce plugin theme folder to your theme_folder/woocommerce/single_product/archive-product.php

    after do_action( ‘woocommerce_before_shop_loop’ ); insert the following code:

    $args = array(
            'post_type'      => 'product',
            'posts_per_page' => -1
        );
        $loop = new WP_Query( $args );
        while ( $loop->have_posts() ) : $loop->the_post();
            global $product;
            $volumen = $product->get_attribute( 'pa_Volumen' );
            if ( ! add_post_meta( $product->get_id(), 'Volumen', $volumen, true ) ) { 
               update_post_meta ( $product->get_id(), 'Volumen', $volumen );
            }
        endwhile;
        wp_reset_query();

    then load a frontend product category one. it should copy the products attribute volumen to the post meta volumen for all products in your shop. i’m doing this on the archive page as i found it quite hard to get alle products objects / functions to work in functions.php. check the result for some products on the edit page. you should see new custom meta volume. DISABLE THE CODE WHEN EVERYTHING HAS BEEN COPIED THE RIGHT WAY.

    next, extend your functions.php inside theme folder:

    
    // new sorting criteria
    add_filter('woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args');
     
    function custom_woocommerce_get_catalog_ordering_args( $args ) {
        global $wp_query;
        if (isset($_GET['orderby'])) {
            switch ($_GET['orderby']) :
                case 'Volumen_asc' :
                    $args['order'] = 'ASC';
                    $args['meta_key'] = 'Volumen';
                    $args['orderby'] = 'meta_value_num';
                break;
            endswitch;
        }
        return $args;
    }
    
    // define new standard sorting option for all category archives
    
    add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
    function am_woocommerce_catalog_orderby( $args ) {
        $args['meta_key'] = 'Volumen';
        $args['orderby'] = 'meta_value_num';
        $args['order'] = 'ASC'; 
        return $args;
    }
     
    /**
     *  Adds the sorting options to dropdown list .. The logic/criteria is in the method above
     */
    add_filter('woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby');
     
    function custom_woocommerce_catalog_orderby( $sortby ) {
        $sortby['Volumen_asc'] = 'Volumen aufsteigend';
        return $sortby;
    }

    works like a charme. only thing i still have to fix: the plugin “woocommerce product filters” is bitting this piece of code in the ass… still working on a fix. without that plugin this solution should work like charme. you might want to integrate the copying of attribute > meta into a on save_post hook.

    enjoy your wp shop!

    Thread Starter ffwebdesigner

    (@ffwebdesigner)

    one more problem: the newly define standard sorting by volume works like a charme on any category products page:

    add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
    function am_woocommerce_catalog_orderby( $args ) {
        $args['meta_key'] = 'Volumen';
        $args['orderby'] = 'meta_value_num';
        $args['order'] = 'ASC'; 
        return $args;
    }

    but the custom sorting options “volumen_desc” doesn’t work, output is always the same as ASC. any idea why?

    add_filter('woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args');
     
    function custom_woocommerce_get_catalog_ordering_args( $args ) {
        global $wp_query;
        if (isset($_GET['orderby'])) {
            switch ($_GET['orderby']) :
                case 'volumen' :
                    $args['order'] = 'ASC';
                    $args['meta_key'] = 'Volumen';
                    $args['orderby'] = 'meta_value_num';
                break;
                case 'volumen_desc' :
                    $args['order'] = 'DESC';
                    $args['meta_key'] = 'Volumen';
                    $args['orderby'] = 'meta_value_num';
                break;
            endswitch;
        }
        return $args;
    }
    add_filter('woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby');
     
    function custom_woocommerce_catalog_orderby( $sortby ) {
        $sortby['volumen'] = 'Volumen aufsteigend';
        $sortby['volumen_desc'] = 'Volumen absteigend';
        return $sortby;
    }
Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘sort products by attribute’ is closed to new replies.