Skip to content

Variation attribute value silently lost when a custom attribute shares its name with a taxonomy #11

Description

@Pichinov-Jose

Repository: SplashSync/Wordpress
Plugin version: 2.1.0 (code identical at current master HEAD)
WooCommerce: 11.0.1 · WordPress: PHP 8.1 · Target node: Dolibarr module 2.23.3

Summary

A variation attribute entered as a custom product attribute (attribute_xxx) is exported with an
empty value whenever a global attribute taxonomy named pa_xxx also exists. The receiving node
rejects the attribute and drops it — without failing the object, so the sync reports success.

Evidence

Read through the connector itself (no Splash server involved), on a variation whose meta is
attribute_foyer = "Imposable", attribute_membre = "1er membre":

Splash::object("Product")->get("57595", ["code@attributes","name@attributes","value@attributes"]);
'attributes' => [
    'foyer'  => ['code' => 'foyer',  'name' => 'Foyer',  'value' => ''],   // <-- lost
    'membre' => ['code' => 'membre', 'name' => 'Membre', 'value' => ''],   // <-- lost
]

The same read on a variation using a real taxonomy attribute works:

'pa_adhesion' => ['code' => 'adhesion', 'name' => 'Adhésion', 'value' => 'Inscription']   // OK

On the Dolibarr side this surfaces as:

[Splash Client] Product Attribute Value Name is Not Valid.

Root cause

src/Objects/Product/Variants/AttributesTrait.php:225-236

private function getVariantsAttributesField(string $fieldId, string $code, string $name)
{
    $group = Manager::getGroupByCode($code);
    if (!$group) {
        return $this->getVariantsCustomAttributesField($fieldId, $code, $name);   // custom path
    }
    $attribute = Manager::getValueByCode($code, $name);
    $attributeName = $attribute->name ?? "";        // <-- "" when $name is not a term
    ...
    case 'name':  return $this->encodeMultiLang($group->name, $isoCode);      // resolves
    case 'value': return $this->encodeMultiLang($attributeName, $isoCode);    // empty
}

The custom-attribute fallback exists and works, but it is only reached when no group matches the
code. When a taxonomy pa_xxx exists while the variation stores a plain custom value, the group
resolves, the term does not, and value silently becomes "".

Note this is not about the taxonomy being empty: it also happens with a well-populated taxonomy
(pa_creneau-lacroix, 25 terms) as soon as the variation stores the attribute as custom.

Why it stays invisible

On the Dolibarr side, setVariantsAttributesFields() skips an invalid attribute with continue.
The rest of the product writes normally, so the object write succeeds and the UI is all green while
the attributes are dropped. See the companion issue on error message context.

Scale on one real install

Scanning attribute_% meta across all variations:

variations
taxonomy attributes (attribute_pa_*) — exported correctly ~575
custom attributes with a homonymous pa_* taxonomy — value lost 852

13 distinct attributes affected. The largest were ticket (404), taille (144), couleur (144).

Suggested fix

Fall back to the raw variation value when the term cannot be resolved:

 $attribute = Manager::getValueByCode($code, $name);
 $attributeName = $attribute->name ?? "";
+//====================================================================//
+// Attribute group exists but the value is not a taxonomy term:
+// this is a custom product attribute, use the raw variation value.
+if (!$attribute) {
+    $attributeName = $name;
+}

Deliberately minimal: it leaves code and name untouched, so the taxonomy path that already works
is unaffected. Routing to getVariantsCustomAttributesField() instead would also change name,
which resolves through getGroupNameFromParent($this->baseProduct, …) and returns null when
baseProduct is not loaded — that would break a field that currently works.

Verified on the affected install: value goes from '' to 'Imposable' / '1er membre', and a
control read on a taxonomy-based variation is unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions