如何通过 Soap/Java 在 Magento 中创建具有附加属性的产品

发布于 2024-12-28 02:44:40 字数 11856 浏览 1 评论 0原文

再会!

我想使用 Magento 的 SOAP API 来管理产品目录、属性等。我正在运行以下配置:-

  • Magento 1.6
  • Soap API WS-I 合规性
  • Mac OSX Lion
  • Mamp 2.0.5

如果有人想要创建新产品,有必要设置产品对象的一些属性。 以下代码将演示我的方法:

    public int createProduct(DatabaseProduct product) {

        ArrayOfString categories = new ArrayOfString();
                categories.getComplexObjectArray().add(categoryID);
        createEntity.setCategoryIds(categories);

        CatalogProductCreateEntity createEntity = populateCreateOrUpdateEntity(product);

        CatalogProductCreateRequestParam param = new CatalogProductCreateRequestParam();
        param.setSessionId(sessionId);
        param.setSet(setId);
        param.setSku(product.getSku());
        param.setType("simple");
        param.setStore(storeId);
        param.setProductData(createEntity);

        CatalogProductCreateResponseParam response = service.catalogProductCreate(param);
        return response.getResult();
    }

    private CatalogProductCreateEntity populateCreateOrUpdateEntity(DatabaseProduct product) {

        CatalogProductCreateEntity createEntity = new CatalogProductCreateEntity();
        createEntity.setShortDescription(product.getDescription().substring(0, 20) + "...");
        createEntity.setDescription(product.getDescription());
        createEntity.setName(product.getName());
        createEntity.setPrice(String.valueOf(product.getPrice()));
        createEntity.setStatus("1"); //active
        createEntity.setVisibility("4"); //visible in search/catalog
        createEntity.setWeight("70"); //some value 
        createEntity.setTaxClassId("2"); //standard

            AssociativeArray attributes = new AssociativeArray();            

            AssociativeEntity attr1 = new AssociativeEntity();
            attr1.("attribute1_key";
            attr1.("attribute1_value");
            attributes.getComplexObjectArray().add(attr1);

            AssociativeEntity attr2 = new AssociativeEntity();
            attr2.("attribute2_key");
            attr2.("attribute2_value");
            attributes.getComplexObjectArray().add(attr2);

        createEntity.setAdditionalAttributes(attributes);

        return createEntity;
    }

我意识到我在 Magento 的“system.log”中写入了一个错误。

2012-01-21T09:41:01+00:00 DEBUG (7): First parameter must either be an object or the name of an existing class/opt/website/magento/app/code/core/Mage/Catalog/Model/Product/Api/V2.php

我可以定位“V2.php”文件第 265 行中的错误。 根据 php.net 文档,“property_exists()”方法只能检查对象中的字段。 事实上,“$productData”变量拥有一个名为“additional_attributes”的数组类型属性。 因此,执行这段代码会导致错误。

此外,我不知道通过使用 Magento 的 SOAP API V2 来重现“$productData”对象的结构。

如果我检查第 270 行中的这段代码(“foreach”循环),它表明有一个对象(“$productData”)持有一个数组(“extra_attributes") 再次封装一组键/值对(如果我是对的)

253        protected function _prepareDataForSave ($product, $productData)
254     {
255         if (property_exists($productData, 'website_ids') && is_array($productData->website_ids)) {
256             $product->setWebsiteIds($productData->website_ids);
257         }
258 
259         Mage::log("debug1");
260         Mage::log(property_exists($productData, 'additional_attributes'));
261         
262         Mage::log($productData);
263         
264         if (property_exists($productData, 'additional_attributes')) {
265             if (property_exists($productData->additional_attributes, 'single_data')) {
266                 
267                 Mage::log("---> single");
268                 Mage::log($productData->additional_attributes);
269                 
270                 foreach ($productData->additional_attributes->single_data as $_attribute) {
271                     $_attrCode = $_attribute->key;
272                     $productData->$_attrCode = $_attribute->value;
273                 }
274             }
275             if (property_exists($productData->additional_attributes, 'multi_data')) {
276                 
277                 Mage::log("---> multi");
278                 Mage::log($productData->additional_attributes);
279                 
280                 foreach ($productData->additional_attributes->multi_data as $_attribute) {
281                     $_attrCode = $_attribute->key;
282                     $productData->$_attrCode = $_attribute->value;
283                 }
284             }   
285                 
286             Mage::log("debugXXX");
287             unset($productData->additional_attributes);
288         }
289         
290         Mage::log("debug2");
291         
292         foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $attribute) {
293             $_attrCode = $attribute->getAttributeCode();
294             if ($this->_isAllowedAttribute($attribute) && (isset($productData->$_attrCode))) {
295                 $product->setData(
296         ... etc ...

这似乎是一个错误。这是我的问题。

我是否可以将其称为应发布在错误库中的编程问题? 有办法解决这个问题吗? 我是否应该重写上面的 php.code 部分以满足我处理产品信息以正确创建产品的需要?

预先感谢

    $productData
    (
            [name] => testname
            [description] => testdescription
            [short_description] => shorttestdescription
            [weight] => 70
            [status] => 1
            [visibility] => 4
            [price] => 359.0
            [tax_class_id] => 2
            [additional_attributes] => Array
            (
                    [attribute1] => 999.0
                    [attribute2] => testcontent
            )
    )

SoapUI 生成的 WSDL 中的 CatalogProductCreate-Call:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:catalogProductCreateRequestParam>
         <sessionId>?</sessionId>
         <type>?</type>
         <set>?</set>
         <sku>?</sku>
         <productData>
            <!--Optional:-->
            <categories>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </categories>
            <!--Optional:-->
            <websites>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </websites>
            <!--Optional:-->
            <name>?</name>
            <!--Optional:-->
            <description>?</description>
            <!--Optional:-->
            <short_description>?</short_description>
            <!--Optional:-->
            <weight>?</weight>
            <!--Optional:-->
            <status>?</status>
            <!--Optional:-->
            <url_key>?</url_key>
            <!--Optional:-->
            <url_path>?</url_path>
            <!--Optional:-->
            <visibility>?</visibility>
            <!--Optional:-->
            <category_ids>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </category_ids>
            <!--Optional:-->
            <website_ids>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </website_ids>
            <!--Optional:-->
            <has_options>?</has_options>
            <!--Optional:-->
            <gift_message_available>?</gift_message_available>
            <!--Optional:-->
            <price>?</price>
            <!--Optional:-->
            <special_price>?</special_price>
            <!--Optional:-->
            <special_from_date>?</special_from_date>
            <!--Optional:-->
            <special_to_date>?</special_to_date>
            <!--Optional:-->
            <tax_class_id>?</tax_class_id>
            <!--Optional:-->
            <tier_price>
               <!--Zero or more repetitions:-->
               <complexObjectArray>
                  <!--Optional:-->
                  <customer_group_id>?</customer_group_id>
                  <!--Optional:-->
                  <website>?</website>
                  <!--Optional:-->
                  <qty>?</qty>
                  <!--Optional:-->
                  <price>?</price>
               </complexObjectArray>
            </tier_price>
            <!--Optional:-->
            <meta_title>?</meta_title>
            <!--Optional:-->
            <meta_keyword>?</meta_keyword>
            <!--Optional:-->
            <meta_description>?</meta_description>
            <!--Optional:-->
            <custom_design>?</custom_design>
            <!--Optional:-->
            <custom_layout_update>?</custom_layout_update>
            <!--Optional:-->
            <options_container>?</options_container>
            <!--Optional:-->
            <additional_attributes>
               <!--Zero or more repetitions:-->
               <complexObjectArray>
                  <key>?</key>
                  <value>?</value>
               </complexObjectArray>
            </additional_attributes>
            <!--Optional:-->
            <stock_data>
               <!--Optional:-->
               <qty>?</qty>
               <!--Optional:-->
               <is_in_stock>?</is_in_stock>
               <!--Optional:-->
               <manage_stock>?</manage_stock>
               <!--Optional:-->
               <use_config_manage_stock>?</use_config_manage_stock>
               <!--Optional:-->
               <min_qty>?</min_qty>
               <!--Optional:-->
               <use_config_min_qty>?</use_config_min_qty>
               <!--Optional:-->
               <min_sale_qty>?</min_sale_qty>
               <!--Optional:-->
               <use_config_min_sale_qty>?</use_config_min_sale_qty>
               <!--Optional:-->
               <max_sale_qty>?</max_sale_qty>
               <!--Optional:-->
               <use_config_max_sale_qty>?</use_config_max_sale_qty>
               <!--Optional:-->
               <is_qty_decimal>?</is_qty_decimal>
               <!--Optional:-->
               <backorders>?</backorders>
               <!--Optional:-->
               <use_config_backorders>?</use_config_backorders>
               <!--Optional:-->
               <notify_stock_qty>?</notify_stock_qty>
               <!--Optional:-->
               <use_config_notify_stock_qty>?</use_config_notify_stock_qty>
            </stock_data>
         </productData>
         <!--Optional:-->
         <store>?</store>
      </urn:catalogProductCreateRequestParam>
   </soapenv:Body>
</soapenv:Envelope>

Good day!

I would like to use the Magento’s SOAP API to manage the product catalog, attributes etc. I'm running following configuration:-

  • Magento 1.6
  • Soap API WS-I compliance
  • Mac OSX Lion
  • Mamp 2.0.5

In case someone wants to create a new product, it is necessary to set a few properties of the product object.
Following code will demonstrate my approach to do this :

    public int createProduct(DatabaseProduct product) {

        ArrayOfString categories = new ArrayOfString();
                categories.getComplexObjectArray().add(categoryID);
        createEntity.setCategoryIds(categories);

        CatalogProductCreateEntity createEntity = populateCreateOrUpdateEntity(product);

        CatalogProductCreateRequestParam param = new CatalogProductCreateRequestParam();
        param.setSessionId(sessionId);
        param.setSet(setId);
        param.setSku(product.getSku());
        param.setType("simple");
        param.setStore(storeId);
        param.setProductData(createEntity);

        CatalogProductCreateResponseParam response = service.catalogProductCreate(param);
        return response.getResult();
    }

    private CatalogProductCreateEntity populateCreateOrUpdateEntity(DatabaseProduct product) {

        CatalogProductCreateEntity createEntity = new CatalogProductCreateEntity();
        createEntity.setShortDescription(product.getDescription().substring(0, 20) + "...");
        createEntity.setDescription(product.getDescription());
        createEntity.setName(product.getName());
        createEntity.setPrice(String.valueOf(product.getPrice()));
        createEntity.setStatus("1"); //active
        createEntity.setVisibility("4"); //visible in search/catalog
        createEntity.setWeight("70"); //some value 
        createEntity.setTaxClassId("2"); //standard

            AssociativeArray attributes = new AssociativeArray();            

            AssociativeEntity attr1 = new AssociativeEntity();
            attr1.("attribute1_key";
            attr1.("attribute1_value");
            attributes.getComplexObjectArray().add(attr1);

            AssociativeEntity attr2 = new AssociativeEntity();
            attr2.("attribute2_key");
            attr2.("attribute2_value");
            attributes.getComplexObjectArray().add(attr2);

        createEntity.setAdditionalAttributes(attributes);

        return createEntity;
    }

I realized that I get an error written to the "system.log" of Magento.

2012-01-21T09:41:01+00:00 DEBUG (7): First parameter must either be an object or the name of an existing class/opt/website/magento/app/code/core/Mage/Catalog/Model/Product/Api/V2.php

I could localize the error in the "V2.php" file on line 265.
According to the php.net documentation the "property_exists()" method only can check for fields in objects.
As a matter of fact the "$productData" variable holds a property called "additional_attributes" which is of the type array.
Therefore the execution of this code will lead to an error.

Moreover I don’t know to reproduce the object the structure of the "$productData" object through the use of Magento’s SOAP API V2.

If I examine this code ("foreach" loop) in line 270, it indicates that there is an object ("$productData") holding an array ("additional_attributes") which again shall encapsulate a set of key/value pairs (if I am right)

253        protected function _prepareDataForSave ($product, $productData)
254     {
255         if (property_exists($productData, 'website_ids') && is_array($productData->website_ids)) {
256             $product->setWebsiteIds($productData->website_ids);
257         }
258 
259         Mage::log("debug1");
260         Mage::log(property_exists($productData, 'additional_attributes'));
261         
262         Mage::log($productData);
263         
264         if (property_exists($productData, 'additional_attributes')) {
265             if (property_exists($productData->additional_attributes, 'single_data')) {
266                 
267                 Mage::log("---> single");
268                 Mage::log($productData->additional_attributes);
269                 
270                 foreach ($productData->additional_attributes->single_data as $_attribute) {
271                     $_attrCode = $_attribute->key;
272                     $productData->$_attrCode = $_attribute->value;
273                 }
274             }
275             if (property_exists($productData->additional_attributes, 'multi_data')) {
276                 
277                 Mage::log("---> multi");
278                 Mage::log($productData->additional_attributes);
279                 
280                 foreach ($productData->additional_attributes->multi_data as $_attribute) {
281                     $_attrCode = $_attribute->key;
282                     $productData->$_attrCode = $_attribute->value;
283                 }
284             }   
285                 
286             Mage::log("debugXXX");
287             unset($productData->additional_attributes);
288         }
289         
290         Mage::log("debug2");
291         
292         foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $attribute) {
293             $_attrCode = $attribute->getAttributeCode();
294             if ($this->_isAllowedAttribute($attribute) && (isset($productData->$_attrCode))) {
295                 $product->setData(
296         ... etc ...

This seems to be a bug. So here is my question.

Am I going right to call this an programming issue which shall be posted in the bug base?
Is there a way to get over this issue?
Shall I rewrite parts of the php.code from above to satisfy my need to handle product information to create a product properly ?

Thanks in advance

    $productData
    (
            [name] => testname
            [description] => testdescription
            [short_description] => shorttestdescription
            [weight] => 70
            [status] => 1
            [visibility] => 4
            [price] => 359.0
            [tax_class_id] => 2
            [additional_attributes] => Array
            (
                    [attribute1] => 999.0
                    [attribute2] => testcontent
            )
    )

the CatalogProductCreate-Call from the WSDL generated by SoapUI:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:catalogProductCreateRequestParam>
         <sessionId>?</sessionId>
         <type>?</type>
         <set>?</set>
         <sku>?</sku>
         <productData>
            <!--Optional:-->
            <categories>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </categories>
            <!--Optional:-->
            <websites>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </websites>
            <!--Optional:-->
            <name>?</name>
            <!--Optional:-->
            <description>?</description>
            <!--Optional:-->
            <short_description>?</short_description>
            <!--Optional:-->
            <weight>?</weight>
            <!--Optional:-->
            <status>?</status>
            <!--Optional:-->
            <url_key>?</url_key>
            <!--Optional:-->
            <url_path>?</url_path>
            <!--Optional:-->
            <visibility>?</visibility>
            <!--Optional:-->
            <category_ids>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </category_ids>
            <!--Optional:-->
            <website_ids>
               <!--Zero or more repetitions:-->
               <complexObjectArray>?</complexObjectArray>
            </website_ids>
            <!--Optional:-->
            <has_options>?</has_options>
            <!--Optional:-->
            <gift_message_available>?</gift_message_available>
            <!--Optional:-->
            <price>?</price>
            <!--Optional:-->
            <special_price>?</special_price>
            <!--Optional:-->
            <special_from_date>?</special_from_date>
            <!--Optional:-->
            <special_to_date>?</special_to_date>
            <!--Optional:-->
            <tax_class_id>?</tax_class_id>
            <!--Optional:-->
            <tier_price>
               <!--Zero or more repetitions:-->
               <complexObjectArray>
                  <!--Optional:-->
                  <customer_group_id>?</customer_group_id>
                  <!--Optional:-->
                  <website>?</website>
                  <!--Optional:-->
                  <qty>?</qty>
                  <!--Optional:-->
                  <price>?</price>
               </complexObjectArray>
            </tier_price>
            <!--Optional:-->
            <meta_title>?</meta_title>
            <!--Optional:-->
            <meta_keyword>?</meta_keyword>
            <!--Optional:-->
            <meta_description>?</meta_description>
            <!--Optional:-->
            <custom_design>?</custom_design>
            <!--Optional:-->
            <custom_layout_update>?</custom_layout_update>
            <!--Optional:-->
            <options_container>?</options_container>
            <!--Optional:-->
            <additional_attributes>
               <!--Zero or more repetitions:-->
               <complexObjectArray>
                  <key>?</key>
                  <value>?</value>
               </complexObjectArray>
            </additional_attributes>
            <!--Optional:-->
            <stock_data>
               <!--Optional:-->
               <qty>?</qty>
               <!--Optional:-->
               <is_in_stock>?</is_in_stock>
               <!--Optional:-->
               <manage_stock>?</manage_stock>
               <!--Optional:-->
               <use_config_manage_stock>?</use_config_manage_stock>
               <!--Optional:-->
               <min_qty>?</min_qty>
               <!--Optional:-->
               <use_config_min_qty>?</use_config_min_qty>
               <!--Optional:-->
               <min_sale_qty>?</min_sale_qty>
               <!--Optional:-->
               <use_config_min_sale_qty>?</use_config_min_sale_qty>
               <!--Optional:-->
               <max_sale_qty>?</max_sale_qty>
               <!--Optional:-->
               <use_config_max_sale_qty>?</use_config_max_sale_qty>
               <!--Optional:-->
               <is_qty_decimal>?</is_qty_decimal>
               <!--Optional:-->
               <backorders>?</backorders>
               <!--Optional:-->
               <use_config_backorders>?</use_config_backorders>
               <!--Optional:-->
               <notify_stock_qty>?</notify_stock_qty>
               <!--Optional:-->
               <use_config_notify_stock_qty>?</use_config_notify_stock_qty>
            </stock_data>
         </productData>
         <!--Optional:-->
         <store>?</store>
      </urn:catalogProductCreateRequestParam>
   </soapenv:Body>
</soapenv:Envelope>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

谎言 2025-01-04 02:44:40

对于V2 SOAP API,我们似乎需要将additional_attributes 嵌套在multi_data 或single_data 层中?

看看 app/code/core/Mage/Catalog/Model/Product/Api/V2.php #256 我认为我们需要使用

$manufacturer = new stdClass();
$manufacturer->key = "manufacturer";
$manufacturer->value = "20";
$additionalAttrs['single_data'][] = $manufacturer;

或被

$manufacturer = new stdClass();
$manufacturer->key = "manufacturer";
$manufacturer->value = "20";
$additionalAttrs['multi_data'][] = $manufacturer;

使用如下:

    $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();
    }

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();
    }
辞旧 2025-01-04 02:44:40

实际上,我必须修补 app/code/core/Mage/Catalog/Model/Product/Api/V2.php 才能使此调用在版本 1.6.2.0 中工作。

现有代码检查“additional_attributes”属性下的“single_data”或“multi_data”属性,并尝试将这些属性作为关联数组进行迭代:

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;
            }
        }
}

我认为问题在于,因为我们正在传递关联数组结构:

<item>
  <key>...</key>
  <value>...</value>
</item>
<item>
  <key>...</key>
  <value>...</value>
</item>

直接在additional_attributes块下面,那么它实际上是必须迭代以拉取属性键/值的additional_attributes属性,所以我添加了第三个if块

 if (gettype($productData->additional_attributes) == 'array') {
            foreach ($productData->additional_attributes as $k => $v) {
                    $_attrCode = $k;
                    $productData->$_attrCode = $v;
            }
  }

:正在添加/更新我的自定义属性的代码。

这是一个示例请求:

 <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>

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>
向日葵 2025-01-04 02:44:40

这不是一个错误。我已经使用 Magento SOAP API V2 一年多了,Magento 团队在这里应用的概念是绝对正确的。

首先,每次使用 SOAP API V2 时,都必须完整检查相应 Magento 的 WSDL,以便他可以正确创建/调用消息。加载 SOAP API V2 的 WSDL 的 URL 为“/api/v2_soap/index/wsdl/1”。

现在回到你的问题,元素“additional_attributes”的类型是“associativeArray”,这意味着它的 XML 应该类似于:-

<additional_attributes>
  <!--
  This XML tag "item" can be anything;
  it's what I use, but can definitely be any other valid non-used literal.
  -->
  <item>
    <key>attribute_1_code</key>
    <value>attribute_1_value_as_defined_in_database</value>
  </item>
  <item>
    <key>attribute_2_code</key>
    <value>attribute_2_value_as_defined_in_database</value>
  </item>
</additional_attributes>

上述 XML 的一个示例格式将是:-

<additional_attributes>
  <item>
    <key>color</key>
    <!--
    I haven't provided the name / string "Blue",
    because Magento's EAV database structure will only hold the option value
    (which is a unique ID) and not the option literal string.
    -->
    <value>56</value> <!-- assuming this value for "Blue" color -->
  </item>
  <item>
    <key>manufacturer</key>
    <value>87</value> <!-- assuming this value for the manufacturer "Intel" -->
  </item>
</additional_attributes>

因此,您的“$productData”变量必须保存如下值:-

$productData
(
    [name] => testname
    [description] => testdescription
    [short_description] => shorttestdescription
    [weight] => 70
    [status] => 1
    [visibility] => 4
    [price] => 359.0
    [tax_class_id] => 2
    [additional_attributes] => Array
    (
        [0] => Array
        (
            [key] => attribute1
            [value] => 999.0
        )
        [1] => Array
        (
            [key] => attribute2
            [value] => testcontent
        )
    )
)

希望它有所帮助。

This is not a bug. I have been using this Magento SOAP API V2 for more than a year, and the concept which Magento team have applied here is absolutely correct.

First of all, every time any one using the SOAP API V2 must check the WSDL fully of that respective Magento, so that he can create / call messages correctly. The URL to load the WSDL of SOAP API V2 is "<your_magento_home_page_url>/api/v2_soap/index/wsdl/1".

Now coming back to your question, the type of the element "additional_attributes" is "associativeArray", which means its XML should look something like:-

<additional_attributes>
  <!--
  This XML tag "item" can be anything;
  it's what I use, but can definitely be any other valid non-used literal.
  -->
  <item>
    <key>attribute_1_code</key>
    <value>attribute_1_value_as_defined_in_database</value>
  </item>
  <item>
    <key>attribute_2_code</key>
    <value>attribute_2_value_as_defined_in_database</value>
  </item>
</additional_attributes>

One example of the above XML format will be:-

<additional_attributes>
  <item>
    <key>color</key>
    <!--
    I haven't provided the name / string "Blue",
    because Magento's EAV database structure will only hold the option value
    (which is a unique ID) and not the option literal string.
    -->
    <value>56</value> <!-- assuming this value for "Blue" color -->
  </item>
  <item>
    <key>manufacturer</key>
    <value>87</value> <!-- assuming this value for the manufacturer "Intel" -->
  </item>
</additional_attributes>

So, your "$productData" variable must hold the values like this:-

$productData
(
    [name] => testname
    [description] => testdescription
    [short_description] => shorttestdescription
    [weight] => 70
    [status] => 1
    [visibility] => 4
    [price] => 359.0
    [tax_class_id] => 2
    [additional_attributes] => Array
    (
        [0] => Array
        (
            [key] => attribute1
            [value] => 999.0
        )
        [1] => Array
        (
            [key] => attribute2
            [value] => testcontent
        )
    )
)

Hope it helps.

花海 2025-01-04 02:44:40

stroisi 几乎完全正确。该答案只有一个修复:
对于前两个条件,您添加的第三个条件也将计算为 true(因此,如果您在不符合 WSI 的模式下使用 SOAPv2,则添加这些属性两次)。

该条件链应如下所示:

    // ...
        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;
            }
        }
        else if (! property_exists($productData->additional_attributes, 'single_data')) {
            foreach ($productData->additional_attributes as $key => $value) {
                $productData->$key = $value;
            }
        }
    // ...

第三个条件断言 'single_data''multi_data'不是 additional_attributes 的属性


不过,在我看来,修复此错误的正确方法是编辑“wsi.xml”文件,使其与 wsdl.xml 一致(反之亦然)。

stroisi is almost completely correct. Just one fix to that answer:
the third condition you added will evaluate to true for the first two conditions too (thus adding those attributes twice in case you're using SOAPv2 in non-WSI-compliant mode).

That condition chain should look like this:

    // ...
        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;
            }
        }
        else if (! property_exists($productData->additional_attributes, 'single_data')) {
            foreach ($productData->additional_attributes as $key => $value) {
                $productData->$key = $value;
            }
        }
    // ...

The third condition asserts that both 'single_data' and 'multi_data' are not properties of additional_attributes.


Though, in my opinion, the correct way to fix this bug is to edit the "wsi.xml" file so it is consistent with wsdl.xml (or vice versa).

云之铃。 2025-01-04 02:44:40

我正在使用 SOAP API 在 magento 商店中输入产品。
完整代码

这是多选自定义属性情况下的

                $arrProductTime = explode(',', '136,139');

                $result = $client->catalogProductCreate($session, 'simple', $attributeSet->set_id, 'product_sku1234', array(

                    'categories' => array(36),
                    'websites' => array(1),
                    'name' => 'my_pdt1008',
                    'description' => 'my_pdt1',
                    'short_description' => 'my_pdt1000',
                    'weight' => '11',
                    'status' => '1',
                    'url_key' => 'product-url-key1',
                    'url_path' => 'product-url-path1',
                    'visibility' => '4',
                    'price' => '100',
                    'tax_class_id' => 1,
                    'meta_title' => 'Product meta title1',
                    'meta_keyword' => 'Product meta keyword1',
                    'meta_description' => 'Product meta description1',
                    'stock_data' => array('qty'=>'100','is_in_stock'=>1,'manage_stock'=>1),
                    'additional_attributes' => array('multi_data' => array(array('key' => 'product_time', 'value' => $arrProductTime)))
                ));

I am using SOAP API for entering products in magento shops.
here is the full code

In the case of multiselect custom attribute.

                $arrProductTime = explode(',', '136,139');

                $result = $client->catalogProductCreate($session, 'simple', $attributeSet->set_id, 'product_sku1234', array(

                    'categories' => array(36),
                    'websites' => array(1),
                    'name' => 'my_pdt1008',
                    'description' => 'my_pdt1',
                    'short_description' => 'my_pdt1000',
                    'weight' => '11',
                    'status' => '1',
                    'url_key' => 'product-url-key1',
                    'url_path' => 'product-url-path1',
                    'visibility' => '4',
                    'price' => '100',
                    'tax_class_id' => 1,
                    'meta_title' => 'Product meta title1',
                    'meta_keyword' => 'Product meta keyword1',
                    'meta_description' => 'Product meta description1',
                    'stock_data' => array('qty'=>'100','is_in_stock'=>1,'manage_stock'=>1),
                    'additional_attributes' => array('multi_data' => array(array('key' => 'product_time', 'value' => $arrProductTime)))
                ));
骄兵必败 2025-01-04 02:44:40

大家,我在创建具有 multi_data 附加属性的产品时花了很多时间。好吧,最后我成功地使用了以下数据包:

<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
    <x:Header/>
    <x:Body>
        <urn:catalogProductCreate>
            <urn:sessionId>fa6c91d36b1fbef209b3724cf0e3b188</urn:sessionId>
            <urn:type>simple</urn:type>
            <urn:set>4</urn:set>
            <urn:sku>147823691</urn:sku>
            <urn:productData>
                <urn:categories></urn:categories>
                <urn:websites></urn:websites>
                <urn:name>sample product-ntz-9May</urn:name>
                <urn:description>sample product-ntz-8May</urn:description>
                <urn:short_description>sample product-ntz-8May</urn:short_description>
                <urn:weight>?</urn:weight>
                <urn:status>1</urn:status>
                <urn:url_key>?</urn:url_key>
                <urn:url_path>?</urn:url_path>
                <urn:visibility>?</urn:visibility>
                <urn:category_ids></urn:category_ids>
                <urn:website_ids></urn:website_ids>
                <urn:has_options>?</urn:has_options>
                <urn:gift_message_available>?</urn:gift_message_available>
                <urn:price>?</urn:price>
                 <urn:tax_class_id>?</urn:tax_class_id>
                <urn:tier_price></urn:tier_price>
                <urn:meta_title>?</urn:meta_title>
                <urn:meta_keyword>?</urn:meta_keyword>
                <urn:meta_description>?</urn:meta_description>
                <urn:custom_design>?</urn:custom_design>
                <urn:custom_layout_update>?</urn:custom_layout_update>
                <urn:options_container>?</urn:options_container>
                <urn:additional_attributes>

                          ```<urn:multi_data>
                            <item>
                               <key>cert</key>
                               <value>
                                    <item>12300</item>//keys of multiselect dropdown
                                    <item>201690</item>
                                </value>
                             </item>
                           </urn:multi_data>```

                    <urn:single_data>
                        <item>
                            <key>finish</key>
                            <value>22534</value>
                        </item>
                    </urn:single_data>
                </urn:additional_attributes>
                <urn:stock_data>
                    <urn:qty>?</urn:qty>
                    <urn:is_in_stock>0</urn:is_in_stock>
                    <urn:manage_stock>0</urn:manage_stock>
                    <urn:use_config_manage_stock>0</urn:use_config_manage_stock>
                    <urn:min_qty>0</urn:min_qty>
                    <urn:use_config_min_qty>0</urn:use_config_min_qty>
                    <urn:min_sale_qty>0</urn:min_sale_qty>
                    <urn:use_config_min_sale_qty>0</urn:use_config_min_sale_qty>
                    <urn:max_sale_qty>0</urn:max_sale_qty>
                    <urn:use_config_max_sale_qty>0</urn:use_config_max_sale_qty>
                    <urn:is_qty_decimal>0</urn:is_qty_decimal>
                    <urn:backorders>0</urn:backorders>
                    <urn:use_config_backorders>0</urn:use_config_backorders>
                    <urn:notify_stock_qty>0</urn:notify_stock_qty>
                    <urn:use_config_notify_stock_qty>0</urn:use_config_notify_stock_qty>
                </urn:stock_data>
            </urn:productData>
            <urn:storeView>0</urn:storeView>
        </urn:catalogProductCreate>
    </x:Body>
</x:Envelope>

希望它能节省某人的时间。

Everyone, I spent a good amount of time while creating a product with multi_data additional attribute. Well finally I managed it to work with the following packet:

<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
    <x:Header/>
    <x:Body>
        <urn:catalogProductCreate>
            <urn:sessionId>fa6c91d36b1fbef209b3724cf0e3b188</urn:sessionId>
            <urn:type>simple</urn:type>
            <urn:set>4</urn:set>
            <urn:sku>147823691</urn:sku>
            <urn:productData>
                <urn:categories></urn:categories>
                <urn:websites></urn:websites>
                <urn:name>sample product-ntz-9May</urn:name>
                <urn:description>sample product-ntz-8May</urn:description>
                <urn:short_description>sample product-ntz-8May</urn:short_description>
                <urn:weight>?</urn:weight>
                <urn:status>1</urn:status>
                <urn:url_key>?</urn:url_key>
                <urn:url_path>?</urn:url_path>
                <urn:visibility>?</urn:visibility>
                <urn:category_ids></urn:category_ids>
                <urn:website_ids></urn:website_ids>
                <urn:has_options>?</urn:has_options>
                <urn:gift_message_available>?</urn:gift_message_available>
                <urn:price>?</urn:price>
                 <urn:tax_class_id>?</urn:tax_class_id>
                <urn:tier_price></urn:tier_price>
                <urn:meta_title>?</urn:meta_title>
                <urn:meta_keyword>?</urn:meta_keyword>
                <urn:meta_description>?</urn:meta_description>
                <urn:custom_design>?</urn:custom_design>
                <urn:custom_layout_update>?</urn:custom_layout_update>
                <urn:options_container>?</urn:options_container>
                <urn:additional_attributes>

                          ```<urn:multi_data>
                            <item>
                               <key>cert</key>
                               <value>
                                    <item>12300</item>//keys of multiselect dropdown
                                    <item>201690</item>
                                </value>
                             </item>
                           </urn:multi_data>```

                    <urn:single_data>
                        <item>
                            <key>finish</key>
                            <value>22534</value>
                        </item>
                    </urn:single_data>
                </urn:additional_attributes>
                <urn:stock_data>
                    <urn:qty>?</urn:qty>
                    <urn:is_in_stock>0</urn:is_in_stock>
                    <urn:manage_stock>0</urn:manage_stock>
                    <urn:use_config_manage_stock>0</urn:use_config_manage_stock>
                    <urn:min_qty>0</urn:min_qty>
                    <urn:use_config_min_qty>0</urn:use_config_min_qty>
                    <urn:min_sale_qty>0</urn:min_sale_qty>
                    <urn:use_config_min_sale_qty>0</urn:use_config_min_sale_qty>
                    <urn:max_sale_qty>0</urn:max_sale_qty>
                    <urn:use_config_max_sale_qty>0</urn:use_config_max_sale_qty>
                    <urn:is_qty_decimal>0</urn:is_qty_decimal>
                    <urn:backorders>0</urn:backorders>
                    <urn:use_config_backorders>0</urn:use_config_backorders>
                    <urn:notify_stock_qty>0</urn:notify_stock_qty>
                    <urn:use_config_notify_stock_qty>0</urn:use_config_notify_stock_qty>
                </urn:stock_data>
            </urn:productData>
            <urn:storeView>0</urn:storeView>
        </urn:catalogProductCreate>
    </x:Body>
</x:Envelope>

Hope it will save someone's time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文