How do I create a product with additional attributes in Magento via Soap/Java
I actually had to patch app/code/core/Mage/Catalog/Model/Product/Api/V2.php to get this call to work in version 1.6.2.0.
The existing code checks for either a "single_data" or "multi_data" attribute under the 'additional_attributes' property and tries to iterate over the those as an associative array:
if (property_exists($productData, 'additional_attributes')) {
if (property_exists($productData->additional_attributes, 'single_data')) {
foreach ($productData->additional_attributes->single_data as $_attribute) {
$_attrCode = $_attribute->key;
$productData->$_attrCode = $_attribute->value;
}
}
if (property_exists($productData->additional_attributes, 'multi_data')) {
foreach ($productData->additional_attributes->multi_data as $_attribute) {
$_attrCode = $_attribute->key;
$productData->$_attrCode = $_attribute->value;
}
}
}
I think that the issue is that since we're passing the associative array structure:
<item>
<key>...</key>
<value>...</value>
</item>
<item>
<key>...</key>
<value>...</value>
</item>
directly under the additional_attribtutes block then it's really the additional_attributes property that must be iterated over to pull the attribute key/values, so I added third if block:
if (gettype($productData->additional_attributes) == 'array') {
foreach ($productData->additional_attributes as $k => $v) {
$_attrCode = $k;
$productData->$_attrCode = $v;
}
}
With that code in place my custom attributes are being added/updated.
Here's a sample request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
<soapenv:Header/>
<soapenv:Body>
<urn:catalogProductUpdateRequestParam>
<sessionId>100fe1f9d0518b0fd0ed49cc460c1fa6</sessionId>
<productId>1</productId>
<productData>
<name>product 3</name>
<!-- the custom attributes to updated....
-->
<additional_attributes>
<complexObjectArray>
<key>feed_id</key>
<value>56920</value>
</complexObjectArray>
<complexObjectArray>
<key>feed_active</key>
<value>1</value>
</complexObjectArray>
</additional_attributes>
</productData>
</urn:catalogProductUpdateRequestParam>
</soapenv:Body>
</soapenv:Envelope>
For the V2 SOAP API it appears that we need to nest the additional_attributes in a multi_data or single_data layer?
Looking at app/code/core/Mage/Catalog/Model/Product/Api/V2.php #256 I think we need to use
$manufacturer = new stdClass();
$manufacturer->key = "manufacturer";
$manufacturer->value = "20";
$additionalAttrs['single_data'][] = $manufacturer;
or
$manufacturer = new stdClass();
$manufacturer->key = "manufacturer";
$manufacturer->value = "20";
$additionalAttrs['multi_data'][] = $manufacturer;
to be used like:
$productData = new stdClass();
$additionalAttrs = array();
// manufacturer from one of the two above ^
$productData->name = $data['name'];
$productData->description = $data['description'];
$productData->short_description = $data['short_description'];
$productData->weight = 0;
$productData->status = 2; // 1 = active
$productData->visibility = 4; //visible in search/catalog
$productData->category_ids = $data['categories'];
$productData->price = $data['price'];
$productData->tax_class_id = 2; // 2=standard
$productData->additional_attributes = $additionalAttrs;
// Create new product
try {
$proxy->catalogProductCreate($sessionId, 'virtual', 9, $sku, $productData); // 9 is courses
} catch (SoapFault $e) {
print $e->getMessage(); //Internal Error. Please see log for details.
exit();
}