Jump to content

Update product with reference


tarek.fellah

Recommended Posts

I have two shops that should have the same products but not always the same IDs, i'm creating a module to synchronize products with one direction; when i update a product in a shop => that should update the same product (with the same reference) in the other shop, my problem is when i'm making connection by reference, i get error 'id is required when modifying a resource',

this error disappear when making connection by id

This is my method code:

public function hookActionObjectProductUpdateAfter($params){

    define('DEBUG', true);
    define('PS_SHOP_PATH', Configuration::get('PS_SHOP_PATH'));
    define('PS_WS_AUTH_KEY', Configuration::get('PS_WS_AUTH_KEY'));
   
    // First : We always get the products's list or a specific one
    try
    {
            $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
            $opt = array('resource' => 'products');
            //var_dump($params['object']->id);
            if (isset($params['object']->id)){
              // $opt['id'] = $params['object']->id;
                $opt['display']  = 'full'; 
                $opt['filter']['reference'] = '['.$params['object']->reference.']';
                
                $xml = $webService->get($opt);
                $x = ($xml->products[0]->product->id);
                $this->id_product = (int)$x;
                //var_dump($x);
            }
            
            // Here we get the elements from children of customer markup which is children of prestashop root markup
            $resources = $xml->children()->children();
            
            //$id_product = $resources->id;
            //unset($resources->id);
            var_dump($resources->associations);
            //unset($resources->product->associations);
            
            unset($resources->manufacturer_name);
            unset($resources->quantity);
            unset($resources->id_shop_default);
            unset($resources->id_default_image);
            unset($resources->associations);
            unset($resources->id_default_combination);
            unset($resources->position_in_category);
            unset($resources->type);
            unset($resources->pack_stock_type);
            unset($resources->date_add);
            unset($resources->date_upd); 
            var_dump($resources);
    }
    catch (PrestaShopWebserviceException $e)
    {
            // Here we are dealing with errors
            $trace = $e->getTrace();
            if ($trace[0]['args'][0] == 404) echo 'Bad ID';
            else if ($trace[0]['args'][0] == 401) echo 'Bad auth key';
            else echo 'Other error<br />'.$e->getMessage();
    }
// Second : We update the data and send it to the web service
    if ($params['object']->id) // Here we check id cause in every resource there's an id
    {
            //print_r($params['product']->categories);exit;
            // get product categories
            $product = $params['object'];
            $categories = $product->getCategories();
            //var_dump($categories);
            
            $id_lang = Context::getContext()->language->id;
            $resources->product->associations->categories= '';
            foreach($categories as $catId){
              $categorie = new Category((int)$catId);
              $catName = $categorie->name[$id_lang];
              //var_dump($categorie->name);
              //get categorie id in remote shop
              $opt = array();
              $opt['resource'] = 'categories';
                // We set an id if we want to retrieve infos from a customer
              
              
              $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
              if(isset($catId) && $catName){
                $opt['filter[name]'] = '['.$catName.']' ; // cast string => int for security measures
                $opt['display']     = '[id]'; 
                // Call
                
                $xml1 = $webService->get($opt);
                $resources1 = $xml1->children()->children();
                //var_dump($resources1[0]);
                if($resources1->category->id[0]!=''){
                    $x = $resources->product->associations->categories->addChild('categorie');
                    $x->addChild('id', $resources1[0]->id);
                }else{
                    $xml3 = $webService->get(array('url' => PS_SHOP_PATH.'/api/categories?schema=blank'));
                    $resources3 = $xml3->children()->children();
                    unset($resources3->id);
                    unset($resources3->position);
                    unset($resources3->date_add);
                    unset($resources3->date_upd);
                    //unset($resources ->id_parent); //if unset category will be root. If set it must have id existing parent category!
                    unset($resources3->level_depth);
                    unset($resources3->nb_products_recursive);
                    $resources3 ->id_parent = '2';
                    $resources3->name->language[0][0] = $catName;
                    $resources3->link_rewrite->language[0][0] = Tools::link_rewrite($catName);
                    $resources3->active = 1;
                    $resources3->id_shop_default = 1;
                    $resources3->is_root_category = 0;

                    $opt = array('resource' => 'categories');

                    $opt['postXml'] = $xml3 -> asXML();

                    $xml4 = $webService -> add($opt);
                    
                    $resources1 = $xml4->children()->children();
                    //var_dump($resources1);
                    // Clean this object
                    $x = $resources->associations->categories->addChild('categorie');
                    $x->addChild('id', $resources1->id);
                    
                    }
                }
			
		
            }
            //update manufacturer
            //get id_manufacturer for current product
           $id_manufacturer = $params['object']->id_manufacturer;
            if($id_manufacturer and $id_manufacturer!=0){
           
            $manufacturer_name = Manufacturer::getNameById((int)$id_manufacturer);
            //var_dump($manufacturer_name);
            //get remote manufacturer name
            $opt = array();
            $opt['resource'] = 'manufacturers';
            $opt['filter[name]'] = '['.$manufacturer_name.']' ; // cast string => int for security measures
            $opt['display']     = '[id]'; 
                // Call
            $xml2 = $webService->get($opt);
            $resources2 = $xml2->children()->children();
            if($resources2->manufacturers->manufacturer[0]->id)
                $resources->product->id_manufacturer = $resources2->manufacturers->manufacturer[0]->id;
                else {
                    //create the manufacturer

                        $xml6 = $webService->get(array('resource' => 'manufacturers?schema=synopsis'));
                        $resources5 = $xml6->children()->children();
                        $resources5->name = $manufacturer_name;  
                        $resources5->active = 1; 
                        unset($resources5 -> link_rewrite);

                        $res = $webService->add(
                            array(
                            'resource' => 'manufacturers',
                            'active' => array(),
                            'postXml' => $xml6->asXML()
                            )
                        );
                       // var_dump($res);
                        $resources->product->id_manufacturer = $resources2->manufacturer->id;

                }
            }else
                unset($resources->product->id_manufacturer);
            // Here we have XML before update, lets update XML with new values
            foreach ($resources as $nodeKey => $node)

            {   
                //->{$nodeKey});
                    if(!$params['object']->{$nodeKey})
                        unset($node);
                    
                   // elseif($nodeKey == '')
            
                    elseif($nodeKey == 'link_rewrite' or 'name' ==$nodeKey or 'meta_description' == $nodeKey or 'meta_keywords' == $nodeKey or 'meta_title'  == $nodeKey or 'description' == $nodeKey or 'description_short'== $nodeKey  ){
                   
                        $link_rewrite = $params['object']->{$nodeKey};
                            foreach($params['object']->{$nodeKey} as $lang=>$link ){
                                  $resources->$nodeKey= '' ; // Clean this object
                                  $resources->$nodeKey->addChild('language' ,$link);
                                  $resources->$nodeKey->language->AddAttribute('id', $lang);
                            }
                    }elseif( $nodeKey ==  'id_category_default'){
                        $categorie = new Category((int)$params['object']->id_category_default);
                        $catName = $categorie->name[$id_lang];
                        //var_dump($catName);
                        //get categorie id in remote shop
                        $opt = array();
                        $opt['resource'] = 'categories';
                          // We set an id if we want to retrieve infos from a customer


                        $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
                        if (isset($resources->$nodeKey))
                          $opt['filter[name]'] = '['.$catName.']' ; // cast string => int for security measures
                          $opt['display']     = '[id]'; 
                          // Call
                          $xml1 = $webService->get($opt);
                          if($xml1){
                              $resources1 = $xml1->children()->children();
                              //echo '***************';
                              //var_dump($resources1);
                              $resources->$nodeKey = $resources1[0]->id;
                          }
                              

                    }
                         
                    
                    else
                    $resources->$nodeKey = $params['object']->{$nodeKey};
                    
                    
            }
            // And call the web service
            try
            {
                    $opt = array('resource' => 'products');
                    //First remove any indentations:
                    $opt['putXml'] = $xml->asXML();
                    //var_dump($this->id_product);
                    $opt['id'] = $this->id_product;
                    //$opt['filter[reference]'] = '['.$params['object']->reference.']';
                    $xml = $webService->edit($opt);
                    // if WebService don't throw an exception the action worked well and we don't show the following message
                    echo "Successfully updated.";
                    
                    exit;
            }
            catch (PrestaShopWebserviceException $ex)
            {
                    // Here we are dealing with errors
                    $trace = $ex->getTrace();
                    if ($trace[0]['args'][0] == 404) echo 'Bad ID';
                    else if ($trace[0]['args'][0] == 401) echo 'Bad auth key';
                    else echo 'Other error<br />'.$ex->getMessage();
            }
    }


        
}

This is the xml sent

<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<products>
<product>
	<id>1</id>
	<id_manufacturer xlink:href="http://www.website.com/api/manufacturers/1">116</id_manufacturer>
	<id_supplier>0</id_supplier>
	<id_category_default xlink:href="http://www.website.com/api/categories/2">2</id_category_default>
	<new/>
	<cache_default_attribute>0</cache_default_attribute>
	<id_default_image xlink:href="http://www.website.com/api/images/products/1/61" notFilterable="true">61</id_default_image>
	<id_default_combination notFilterable="true"/>
	<id_tax_rules_group xlink:href="http://www.website.com/api/tax_rule_groups/8">8</id_tax_rules_group>
	<position_in_category notFilterable="true">0</position_in_category>
	<manufacturer_name notFilterable="true">Abac</manufacturer_name>
	<quantity notFilterable="true">0</quantity>
	<type notFilterable="true">simple</type>
	<id_shop_default>1</id_shop_default>
	<reference>VIPCARD</reference>
	<supplier_reference/>
	<location/>
	<width>0.000000</width>
	<height>0.000000</height>
	<depth>0.000000</depth>
	<weight>0.000000</weight>
	<quantity_discount>0</quantity_discount>
	<ean13/>
	<upc/>
	<cache_is_pack>0</cache_is_pack>
	<cache_has_attachments>0</cache_has_attachments>
	<is_virtual>0</is_virtual>
	<on_sale>0</on_sale>
	<online_only>0</online_only>
	<ecotax>0.000000</ecotax>
	<minimal_quantity>1</minimal_quantity>
	<price>99.170000</price>
	<wholesale_price>0.000000</wholesale_price>
	<unity/>
	<unit_price_ratio>0.000000</unit_price_ratio>
	<additional_shipping_cost>0.00</additional_shipping_cost>
	<customizable>0</customizable>
	<text_fields>0</text_fields>
	<uploadable_files>0</uploadable_files>
	<active>1</active>
	<redirect_type>404</redirect_type>
	<id_product_redirected>0</id_product_redirected>
	<available_for_order>1</available_for_order>
	<available_date>0215-09-01</available_date>
	<condition>new</condition>
	<show_price>1</show_price>
	<indexed>1</indexed>
	<visibility>both</visibility>
	<advanced_stock_management>0</advanced_stock_management>
	<date_add>2016-04-21 12:19:16</date_add>
	<date_upd>2016-04-21 12:19:16</date_upd>
	<pack_stock_type>0</pack_stock_type>
	<meta_description><language id="1" xlink:href="http://www.website.com/api/languages/1"></language></meta_description>
	<meta_keywords><language id="1" xlink:href="http://www.website.com/api/languages/1"></language></meta_keywords>
	<meta_title><language id="1" xlink:href="http://www.website.com/api/languages/1">Carte VIP</language></meta_title>
	<link_rewrite><language id="1" xlink:href="http://www.website.com/api/languages/1">carte-vip</language></link_rewrite>
	<name><language id="1" xlink:href="http://www.website.com/api/languages/1">Carte VIP</language></name>
	<description><language id="1" xlink:href="http://www.website.com/api/languages/1"><p>Cette carte virtuelle vous permet de bénéficier d’une réduction systématique de 5% sur tous vos achats. Elle coûte seulement 99€ et reste valable à vie. Elle peut également ouvrir droit à certaines opérations et promotions spéciales.</p></language></description>
	<description_short><language id="1" xlink:href="http://www.website.com/api/languages/1"></language></description_short>
	<available_now><language id="1" xlink:href="http://www.website.com/api/languages/1"></language></available_now>
	<available_later><language id="1" xlink:href="http://www.website.com/api/languages/1"></language></available_later>
<associations>
<categories nodeType="category" api="categories"><categorie><id>2</id></categorie></categories>
<images nodeType="image" api="images">
	<image xlink:href="http://www.website.com/api/images/products/1/61">
	<id>61</id>
	</image>
</images>
<combinations nodeType="combination" api="combinations"/>
<product_option_values nodeType="product_option_value" api="product_option_values"/>
<product_features nodeType="product_feature" api="product_features"/>
<tags nodeType="tag" api="tags"/>
<stock_availables nodeType="stock_available" api="stock_availables">
	<stock_available xlink:href="http://www.website.com/api/stock_availables/1">
	<id>1</id>
	<id_product_attribute>0</id_product_attribute>
	</stock_available>
</stock_availables>
<accessories nodeType="product" api="products"/>
<product_bundle nodeType="product" api="products"/>
</associations>
</product>
</products>
</prestashop>
Link to comment
Share on other sites

  • 1 month later...

To solve it, i used this code in the update 

 $opt = array('resource' => 'products');
                    $opt['putXml'] = $xml->products[0]->asXML();
               
                    $opt['id'] = $id_product;
                    
                    $xml = $webService->edit($opt);
                    // if WebService don't throw an exception the action worked well and we don't show the following message
                    echo "Successfully updated.";

I got the product id like this 

 if (isset($params['object']->id)){
               // $opt['id'] = $params['object']->id;
                $opt['filter[reference]'] = '['.$params['object']->reference.']';
                $opt['display']='full';
                 $opt['limit']   = '1';
                $xml = $webService->get($opt);
            }
            
            // Here we get the elements from children of customer markup which is children of prestashop root markup
            $resources = $xml->children()->children();
            unset($resources->product->manufacturer_name);
            $id_product = (int)$resources->product->id;

Hope this helps someone else :)

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...