From e030da4b3c5def9775afd1835ab88970f0e8d5ae Mon Sep 17 00:00:00 2001 From: Majid Hajian Date: Sat, 1 Feb 2020 12:59:13 +0100 Subject: [PATCH] support for product attributes with terms --- README.md | 27 ++++++++++++++++- gatsby-node.js | 2 ++ helpers/index.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b17226..eefef3e 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ plugins:[ consumer_secret: , }, // Array of strings with fields you'd like to create nodes for... - fields: ['products', 'products/categories'], + fields: ['products', 'products/categories', 'products/attributes'], // Send the API keys as query string parameters instead of using the authorization header // OPTIONAL: defaults to false query_string_auth: false, @@ -70,6 +70,7 @@ plugins:[ Definitive: - Products +- Products Attributes - Customers - Orders - Reports @@ -105,6 +106,30 @@ For example, to get product categories: including 'products/categories' in field } ``` +### All products attributes with terms: +```graphql +{ + allWcProductsAttributes { + nodes { + name + wordpress_id + order_by + position + slug + type + has_archives + attribute_options { + count + description + menu_order + name + slug + } + } + } +} +``` + ### All product categories (with associated image): ```graphql { diff --git a/gatsby-node.js b/gatsby-node.js index 06c8694..32f7572 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -9,6 +9,7 @@ const { mapRelatedProducts, mapGroupedProducts, asyncGetProductVariations, + asyncGetProductAttributes, timeStampedLog, } = require("./helpers"); @@ -116,6 +117,7 @@ exports.sourceNodes = async ( } } nodes = await asyncGetProductVariations(nodes, WooCommerce, verbose); + nodes = await asyncGetProductAttributes(nodes, WooCommerce, verbose); nodes = await mapMediaToNodes({ nodes, store, diff --git a/helpers/index.js b/helpers/index.js index 0da02fa..302cc28 100644 --- a/helpers/index.js +++ b/helpers/index.js @@ -139,6 +139,81 @@ const asyncGetProductVariations = async (nodes, WooCommerce, verbose) => { return processedNodes; }; +/** + * Get product attributes terms. + * Asynchronous function. + * + * @param {array} nodes + * @param {object} WooCommerce + * + * @return {array} Processed nodes + */ +const asyncGetProductAttributes = async (nodes, WooCommerce, verbose) => { + if (verbose) { + timeStampedLog( + `gatsby-source-woocommerce: Fetching product attributes for ${nodes.length} nodes` + ); + } + const asyncGetProductAttributesStartTime = new Date().getTime(); + let asyncGetProductAttributesTimer = asyncGetProductAttributesStartTime; + const processedNodes = []; + const promises = nodes.map(async node => { + if (node.__type === 'wcProductsAttributes') { + let page = 1; + let pages = 1; + node.attribute_options = []; + const attributes_path = `products/attributes/${node.wordpress_id}/terms`; + do { + const args = { page, per_page: 100 }; + await WooCommerce.get(attributes_path, args) + .then(response => { + if (response.status === 200) { + node.attribute_options = [...node.attribute_options, ...response.data]; + pages = parseInt(response.headers['x-wp-totalpages']); + page++; + if (verbose) { + //print progress every 1500 ms + if (new Date().getTime() - asyncGetProductAttributesTimer > 1500) { + asyncGetProductAttributesTimer = new Date().getTime(); + timeStampedLog(`gatsby-source-woocommerce: Retrieved ${attributes_path}...`); + } + } + } else { + console.warn(` + Warning: error while fetching attributes terms for ${node.name}. + Error data: ${response.data}. + `); + pages = 0; + } + }) + .catch(error => { + console.warn(` + Warning: error while fetching attributes terms for ${node.name}. + Error: ${error}. + `); + pages = 0; + }); + } while (page <= pages); + } + return new Promise((res, rej) => { + res(node); + }); + }); + + await Promise.all(promises).then(results => { + results.forEach(async node => { + processedNodes.push(node); + }); + }); + + timeStampedLog( + `gatsby-source-woocommerce: ${promises.length} product attributes terms retrieved for ${ + nodes.length + } nodes in ${(new Date().getTime() - asyncGetProductAttributesStartTime) / 1000}s` + ); + return processedNodes; +}; + /** * Create links between products and categories (bi-directional) * @param {array} nodes @@ -474,5 +549,6 @@ module.exports = { mapRelatedProducts, mapGroupedProducts, asyncGetProductVariations, + asyncGetProductAttributes, timeStampedLog, };