Wordpress

Everything you should know about woocommerce/wordpress function/REST API for product attributes development

If you are doing any programing on top of wordpress/woocommerce, I believe that you will face some issues regarding product attributes. Here I will explain some of thing related to it, hope it will make you clear about how to deal with it.

Here I assume that you have basic knowledge of wordpress/ woocommerce development and REST API.

first of all, If we want to list all the global attributes configured in the system, what should we do ? we should use function wc_get_attribute_taxonomies(), for example:

$all_attributes = wc_get_attribute_taxonomies();

then you will get an object with structure like below.

{
	"id:2":{
		"attribute_id":"2",
		"attribute_name":"brand",
		"attribute_label":"Brand",
		"attribute_type":"select",
		"attribute_orderby":"menu_order",
		"attribute_public":0
	},
	"id:1":{
		"attribute_id":"1",
		"attribute_name":"color",
		"attribute_label":"Color",
		"attribute_type":"select",
		"attribute_orderby":"menu_order",
		"attribute_public":0
	},
	"id:3":{
		"attribute_id":"3",
		"attribute_name":"size",
		"attribute_label":"Size",
		"attribute_type":"select",
		"attribute_orderby":"menu_order",
		"attribute_public":0
	}
}

according to the result , you will get to know how many global attributes are there, and what is the id, name, label are they. (Please just notice that the “attribute_name” is the slug. but actually the slug stored in the system has a prefix “pa_”). for example, for the Brand attribute, the “attribute_name is “brand”, but the exact slug is “pa_brand”. so if you are going to use the plug for further purpose, please remember to add this “pa_” prefix in front it.

If we want to get all product attributes through REST API, then we can use the end point /wp-json/wc/v3/products/attributes whth GET method. then you can get the json response like below.

[
    {
        "id": 2,
        "name": "Brand",
        "slug": "pa_brand",
        "type": "select",
        "order_by": "menu_order",
        "has_archives": false,
        "_links": {
            "self": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/2"
                }
            ],
            "collection": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes"
                }
            ]
        }
    },
    {
        "id": 1,
        "name": "Color",
        "slug": "pa_color",
        "type": "select",
        "order_by": "menu_order",
        "has_archives": false,
        "_links": {
            "self": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/1"
                }
            ],
            "collection": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes"
                }
            ]
        }
    },
    {
        "id": 3,
        "name": "Size",
        "slug": "pa_size",
        "type": "select",
        "order_by": "menu_order",
        "has_archives": false,
        "_links": {
            "self": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/3"
                }
            ],
            "collection": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes"
                }
            ]
        }
    },
]

I believe that you will get some confusion here. because the “name” in the result from the REST API is not the same meaning as the “name” in the result from the function, but it is the “attribute_label” when you use function, and the “name” got from function add “pa_” as prefix will be the “slug” got from REST API. Hope it is clear for you.

Now let us talk about how to get the terms of an attribute. We can get all the terms of a specific attribute by using function get_terms() , you can provide a String parameter which should be the slug of the attribute you want to shearch, or you can provide a array of String of multiple slugs. I will show you the examples below.

if we run function below

$all_terms_of_brand = get_terms('pa_brand');

we will get a array like this

[
	{
		"term_id":31,
		"name":"Eva Solo",
		"slug":"eva-solo",
		"term_group":0,
		"term_taxonomy_id":31,
		"taxonomy":"pa_brand",
		"description":"[html_block id=\"228\"]",
		"parent":0,
		"count":5,
		"filter":"raw"
	},
	{
		"term_id":36,
		"name":"Hay",
		"slug":"hay",
		"term_group":0,
		"term_taxonomy_id":36,
		"taxonomy":"pa_brand",
		"description":"[html_block id=\"228\"]",
		"parent":0,
		"count":2,
		"filter":"raw"
	},
	{
		"term_id":38,
		"name":"Joseph Joseph",
		"slug":"joseph-joseph",
		"term_group":0,
		"term_taxonomy_id":38,
		"taxonomy":"pa_brand",
		"description":"[html_block id=\"228\"]",
		"parent":0,
		"count":2,
		"filter":"raw"
	}
]

If we run function below

$terms_of_multi_attr = get_terms( array(
    'taxonomy' => ['pa_brand','pa_color'],
));

we will get result like this, which contain all terms belong to ‘pa_brand’ and ‘pa_color’.

[
	{
		"term_id":24,
		"name":"Black",
		"slug":"black",
		"term_group":0,
		"term_taxonomy_id":24,
		"taxonomy":"pa_color",
		"description":"",
		"parent":0,
		"count":5,
		"filter":"raw"
	},
	{
		"term_id":25,
		"name":"Blue",
		"slug":"blue",
		"term_group":0,
		"term_taxonomy_id":25,
		"taxonomy":"pa_color",
		"description":"",
		"parent":0,
		"count":4,
		"filter":"raw"
	},
	{
		"term_id":26,
		"name":"Brown",
		"slug":"brown",
		"term_group":0,
		"term_taxonomy_id":26,
		"taxonomy":"pa_color",
		"description":"",
		"parent":0,
		"count":4,
		"filter":"raw"
	},
	{
		"term_id":31,
		"name":"Eva Solo",
		"slug":"eva-solo",
		"term_group":0,
		"term_taxonomy_id":31,
		"taxonomy":"pa_brand",
		"description":"[html_block id=\"228\"]",
		"parent":0,
		"count":5,
		"filter":"raw"
	},
	{
		"term_id":36,
		"name":"Hay",
		"slug":"hay",
		"term_group":0,
		"term_taxonomy_id":36,
		"taxonomy":"pa_brand",
		"description":"[html_block id=\"228\"]",
		"parent":0,
		"count":2,
		"filter":"raw"
	},
	{
		"term_id":38,
		"name":"Joseph Joseph",
		"slug":"joseph-joseph",
		"term_group":0,
		"term_taxonomy_id":38,
		"taxonomy":"pa_brand",
		"description":"[html_block id=\"228\"]",
		"parent":0,
		"count":2,
		"filter":"raw"
	}
]

For function get_terms(), if we us an array as the parameter, there are many way wen can use, check this link https://developer.wordpress.org/reference/functions/get_terms/ for detail.

We can also get terms of an attribute through REST API by using end point /wp-json/wc/v3/products/attributes/<attribute_id>/terms with GET method. Let us assume the <attribute_id> is 2, which is brand, then we will get something like this.

[
    {
        "id": 23,
        "name": "Apple",
        "slug": "apple",
        "description": "",
        "menu_order": 0,
        "count": 3,
        "_links": {
            "self": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/2/terms/23"
                }
            ],
            "collection": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/2/terms"
                }
            ]
        }
    },
    {
        "id": 24,
        "name": "Asus",
        "slug": "asus",
        "description": "",
        "menu_order": 0,
        "count": 4,
        "_links": {
            "self": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/2/terms/24"
                }
            ],
            "collection": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/2/terms"
                }
            ]
        }
    },
    {
        "id": 25,
        "name": "Canon",
        "slug": "canon",
        "description": "",
        "menu_order": 0,
        "count": 4,
        "_links": {
            "self": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/2/terms/25"
                }
            ],
            "collection": [
                {
                    "href": "https://tikamall.com/wp-json/wc/v3/products/attributes/2/terms"
                }
            ]
        }
    },
]

After we understand how to get global attributes and their terms, let us talk about how to get the same of a specific product which is very useful when we want to do something on a product.

to get the terms of a product , we can use function get_the_terms() which has two parameters, 1st one can be the product id, second on is the slug of attribute, for exampe, if we run the below function

$product_attr_terms = get_the_terms($product->id, 'pa_brand');

We will get result like this.

[
	{
		"term_id":31,
		"name":"Eva Solo",
		"slug":"eva-solo",
		"term_group":0,
		"term_taxonomy_id":31,
		"taxonomy":"pa_brand",
		"description":"[html_block id=\"228\"]",
		"parent":0,
		"count":5,
		"filter":"raw"
	},
]

If you want to get all attributes and their terms information of a product, we have a function which is $product->get_attributes(), but unforturnatly, this function only return a list with attributes ‘slug’. if we execute below function

$product_attributes = $product->get_attributes();

The result will look like this.

{
	"custom-attributes":{},
	"pa_brand":{}
}

I don’t know why they make a function like this , but that is it. what we can do is base on this result get more information about the terms by other functions. We are luck that we have another function $product->get_attribute(); there is only one “s” less than the previous function, it also need a parameter which should be the “slug” of the attribute we want to search.

if we use below function

$product_attr_value  = $product->get_attribute("pa_brand");

We will get result like this,. be notice that this result is a String, if there are multi value of this attribute, the values will be seperated with comma.

Eva Solo

use the same function , we can also get the value of a product private attribute. as the previous example, there are two attribute in the result, one of them is “custom-attributes”. then by using $product->get_attribute() function ,we can get the value of this private attribute. if we use the below functon.

$product_attr_value = $product->get_attribute(“custom-attributes”);

we will get result like this.

aaa | bbb

the result is also a String, In this example, there are two values under the attribute “custom-attributes”, they are seperated by “|” which is difference as the value of the global attribute.

We done ? not yet, what about if we want to create a product through REST API with attributes and values ? in the Json body, how should we mention the attrbutes and values ? I will show you the Json structure first, And then I will explain in detail.

{
  "name": "Ship Your Idea",
  "type": "simple",
  "description": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",
  "short_description": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",
  "categories": [
    {
      "id": 9
    },
    {
      "id": 14
    }
  ],
  "images": [
    {
      "src": "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_4_front.jpg"
    },
    {
      "src": "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_front.jpg"
    },
  ],
  "attributes": [
    {
      "id": 1, 
      "position": 0,
      "visible": true,
      "variation": true,
      "options": [
        "black",
        "green"
      ]
    },
    {
      "name": "Size",
      "position": 0,
      "visible": true,
      "variation": true,
      "options": [
        "S",
        "M"
      ]
    }
  ],
}

if you look at the above json in detail, you will find out that this product has two attributes, first on , the Json passed a id, and the second on , passed a name, that is because the first one is a global attribute in the target system, and second one will be a private attribue. For the global attribute, this product has two values(options), if in the targeting system, there are terms with the same name under this attribute, then the product will be created using the exist term as its value., otherwise, new term will be created under this attribute. when the system compare the name of value and the name of term, case will be ignored.

That is all here, hope it is helpful.

Leave a Reply

Your email address will not be published. Required fields are marked *