Skip to content

Attribute Mapping Feature

Miguel Pérez Pellicer edited this page Mar 6, 2024 · 4 revisions

1. Routes for CRUD Attribute Mapping rules

It's done with a new Controller Route Collection (Located under AttributeMappingRulesController.php):

Get all the rules

GET /wc/gla/mc/mapping/rules

  • per_page and page query params are both available in this endpoint

Create a rule

POST /wc/gla/mc/mapping/rules

Body params:
id: {integer} The Id for the rule
attribute: {string} The attribute value for the rule
source: {string} The source value for the rule
category_condition_type:{ALL|ONLY|EXCEPT} The category condition type to apply for this rule
categories: {string} List of category IDs, separated by commas.

Update a rule

POST /wc/gla/mc/mapping/rules/{rule_id}

Body params:
id: {integer} The Id for the rule
attribute: {string} The attribute value for the rule
source: {string} The source value for the rule
category_condition_type:{ALL|ONLY|EXCEPT} The category condition type to apply for this rule
categories: {string} List of category IDs, separated by commas.

Delete a rule

DELETE /wc/gla/mc/mapping/rules/{rule_id}

2. Routes for Getting Attribute sources and fields

A new controller was created in AttributeMappingDataController.php

Get available attributes

GET /wc/gla/mc/mapping/attributes

Get available sources per attribute

GET /wc/gla/mc/mapping/sources?attribute={attribute_id}

3. Routes for Getting the sync status

A new controller was created in AttributeMappingSyncerController.php

Get current sync status

GET /wc/gla/mc/mapping/sync

This controller depends on ProductSyncStats.php

4. Routes for getting the categories

This is handled in a new controller AttributeMappingCategoriesController.php

Get the store categories

GET /wc/gla/mc/mapping/categories

It returns all the store categories with the id, name and parent (id)

It doesn't have any dependency since it uses get_categories built-in function.

5. Frontend logic

All the frontend logic is located in the attribute-mapping folder.

It's basically a table with the rules and the pagination, a button to create a new rule and the sync information.

When the user clicks on create a new rule (or updates a rule). A new modal is loaded in order to show some controls to define the rule. This is located in the AttributeMappingRuleModal component.

For getting the attributes available as well as the sources available for that attribute, we use two hooks: useMappingAttributes and useMappingAttributesSources. This two hooks both perform API request to the routes explained in "2. Routes for Getting Attribute sources and fields" section.

We have also a new section in the store reducer in mc/mapping holding this information:

attributes: [],
sources: {},
rules: {
   items: [],
   total: null,
   pages: null,
},

The rule modal consist on different controls depending on the type of attribute:

If the attribute is type ENUM, then it loads a select control with the enum values.

If he attribute is type field, it loads select control with the available sources and another control for setting a fixed value. This two sources are handled in AttributeMappingSourceTypeSelector component and the sources selector is handled in AttributeMappingFieldSourcesControl.

The category selector, present in all the target types, is handled in AttributeMappingCategoryControl component.

The categories are cached in the store as well using a new reducer section in store_categories and handled via API in a hook named useCategories which also formats the categories.

Once the rule is saved we use updateMappingRule and createMappingRule dispatch actions to perform the action via CRUD Rules API.

When the user want to delete a rule, this is handled in AttributeMappingDeleteRuleModal and it uses deleteMappingRule dispatch to perform the action via CURD Rules API

The sync status is handled in AttributeMappingSync component and uses a new hook usePolling to poll the Sync API for getting sync status.

6. Rule update and sync workflow

When the user enters in the Attribute page we fetch all the rules available using the CURD Rules API, we save the rules in the store so future navigations over the same page wont require new requests. The user can then navigate over the different pages , create, delete or update a rule.

When the user creates or updates a Rule a new modal is open and via request the available attributes via Attribute Data API. The we load them in the selector. When the user selects one of them we perform another request to Attribute Data API for that attribute and we load the sources in the selector. We save this response in the store state so future choices over this type of target wont require extra requests. We perform also a request to the Categories API to get the store categories.

Once the user click save, we perform an API action again to CURD Rules API updating the state and the rules listed. On each rule change we call a hook woocommerce_gla_mapping_rules_change

This hook is in charge checking the current sync status. In case there is a syncing products job running we don't do nothing, otherwise we schedule a new product sync job after 30 minutes. Also we update the sync status in the frontend. The event in charge of handling the Product Sync Job is the StartProductSync event. The job is being handled in UpdateAllProducts::schedule_delayed method.

For the syncing we rely on WCProductAdapter. In mapTypes method we call map_attribute_mapping_rules method. This method will check for each the rules if they are matching the category selection. If so it will apply override the attribute based on the selected source.

7. Useful hooks

woocommerce_gla_product_attribute_value_{$attribute_id}

Allows to filter the attribute source value.

woocommerce_gla_attribute_mapping_sources

Allows to filter the sources for an attribute (useful to integrate extensions like YOAST)

woocommerce_gla_attribute_mapping_sources_global_attributes

Allows to filter product global attributes

woocommerce_gla_attribute_mapping_sources_taxonomies

Allows to filter product taxonomies

woocommerce_gla_attribute_mapping_sources_product_fields

Allows to filter product fields

woocommerce_gla_attribute_mapping_sources_custom_attributes

Allows to filter custom meta attributes. Example:

User created a field at product level named ISBN, and wants to use that field as GTIN.

add_filter(
	'woocommerce_gla_attribute_mapping_sources_custom_attributes',
	function ( $attributes ) {
		return [
			...$attributes,
			'isbn',
		];
	}
);