Monday, 28 September 2015

How to make WooCommerce order itemmeta editable in Admin Pane

In WooCommerce the order itemmeta data are not editable

Open wp-admin/edit.php?post_type=shop_order
Click any order to edit it
In the 'Order Items' Section, the meta data are displayed but not editable
When looking at the source code of this section, a div '<div class="view">' can be found as well as a paralleled div '<div class="edit">', but the edit div is hidden. That's why the order itemmeta are not editable here

Tweak the template file to make it editable

Open the template file with the path of 'wp-content/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item.php'
Search 'div class="view"' and add 'style="display: none;' for the div
Search 'div class="edit"' and remove 'style="display: none;' from this div

Note: WooCommerce do have the logic implementation to process editing the order itemmeta, but the edit div is hidden for some reason and there is no documentation that indicate this trick which caused me a whole day to find it out. 

Monday, 4 May 2015

Traps of adding terms - wp set post terms

Usage of wp_set_post_terms

 <?php wp_set_post_terms( $post_id, $terms, $taxonomy, $append ) ?>
The usage is clearly demonstrated on codex.wordpress.org, but there are a couple of traps for the parameters of $tems and $append

How to add multiple terms for a specific post

There are two ways to do it. The first one is by setting $append true and passing a single term to the parameter of $terms, but the value of $append is set false by default. The alternative method is passing all the terms as a string or an array to the parameter of $terms and using the default value of $append.

The type of the parameter of $terms matters

When add a single term to a post, no matter the type is int or string it will work. Here is an example.
        $locationTerm = 'auckland';
        $locationTaxonomy = 'dealer-location';
        $termId = term_exists($locationTerm, $locationTaxonomy);//term_exists returns an array that contains values of string
        if(!$termId){
            $termId = wp_insert_term( $locationTerm, $locationTaxonomy);
        }
        $termId = $termId['term_id']; //the type of $termId is string
        return wp_set_post_terms( $post->ID, $termId, $locationTaxonomy);

However, the similar code doesn't work for adding multiple terms. Here is an example which doesn't work.
        $featureTerms = 'ABS, 4 Airbags';
        $featureTaxonomy = 'car-feature';
        $arrFeatureTerms = explode(',', $featureTerms);
        $arrTermIds = array();
        foreach ($arrFeatureTerms as $featureTerm){
            $featureTerm = trim($featureTerm);
            if(!empty($featureTerm)){
                $termId = term_exists($featureTerm, $featureTaxonomy);
                if(!$termId){
                    $termId = wp_insert_term( $featureTerm, $featureTaxonomy);
                }
                $termId = $termId['term_id'];
                $arrTermIds[] = $termId;
            }
        }
        wp_set_post_terms( $post->ID, $arrTermIds, $featureTaxonomy);

Since the type of $termId = $termId['term_id']; is string, WP will consider $termId as a term rather than an Id of the term. As a result, WP will create a new term using the value of $termId and attach the newly created integer term to the post which is against our expectation.

To make WP work as we expected, what we need to do is to convert the $termId to int type as below:
        $termId = (int)$termId['term_id'];
The full snippet should be like the following:
        $featureTerms = 'ABS, 4 Airbags';
        $featureTaxonomy = 'car-feature';
        $arrFeatureTerms = explode(',', $featureTerms);
        $arrTermIds = array();
        foreach ($arrFeatureTerms as $featureTerm){
            $featureTerm = trim($featureTerm);
            if(!empty($featureTerm)){
                $termId = term_exists($featureTerm, $featureTaxonomy);
                if(!$termId){
                    $termId = wp_insert_term( $featureTerm, $featureTaxonomy);
                }
                $termId = (int)$termId['term_id'];
                $arrTermIds[] = $termId;
            }
        }
        wp_set_post_terms( $post->ID, $arrTermIds, $featureTaxonomy);

A slight change make it work, but it might take a long time to figure it out.