Adding products to PrestaShop 1.6.0.9 with WebService

16,470

Solution 1

I found the bug in PSWebServiceLibrary.php in public function add($options). The problem was with request:

$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => 'xml='.urlencode($xml)));

Notice, that CURLOPT_POSTFIELDS => 'xml='.urlencode($xml). This sends XML as string with prepending 'xml=' string to the beginning of file and url encoding the whole XML, but PS expects XML, so it should be this way:

$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => $xml));

Solution 2

Try this Solution. It works for me

<html><head><title>Add Product</title></head><body>
<?php

define('DEBUG', true);
define('PS_SHOP_PATH', 'http://myshop.com');
define('PS_WS_AUTH_KEY', 'E6R9IDPK2R519WB9QAJ45MUACZ9GANC2');
require_once('PSWebServiceLibrary.php');


try
{
    $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
    $opt = array('resource' => 'products');
    if (isset($_GET['Create']))
        $xml = $webService->get(array('url' => PS_SHOP_PATH.'/api/products?schema=blank'));
    else
        $xml = $webService->get($opt);
    $resources = $xml->children()->children();
}
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';
}

if (count($_POST) > 0)
{
// Here we have XML before update, lets update XML
    foreach ($resources as $nodeKey => $node)
    {
        $resources->$nodeKey = $_POST[$nodeKey];
    }
    try
    {
        $opt = array('resource' => 'products');
        if ($_GET['Create'] == 'Creating')
        {
            $opt['postXml'] = $xml->asXML();
            $xml = $webService->add($opt);
            echo "Successfully added.";
        }
    }
    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();
    }
}

// Title
echo '<h1>Product\'s ';
if (isset($_GET['Create'])) echo 'Creation';
else echo 'List';
echo '</h1>';

// We set a link to go back to list if we are in creation
if (isset($_GET['Create']))
    echo '<a href="?">Return to the list</a>';

if (!isset($_GET['Create']))
    echo '<input type="button" onClick="document.location.href=\'?Create\'" value="Create">';
else
    echo '<form method="POST" action="?Create=Creating">';

echo '<table border="5">';
if (isset($resources))
{

echo '<tr>';
if (count($_GET) == 0)
{
    echo '<th>Id</th></tr>';

    foreach ($resources as $resource)
    {
        echo '<tr><td>'.$resource->attributes().'</td></tr>';
    }
}
else
{
    echo '</tr>';
    foreach ($resources as $key => $resource)
    {
        echo '<tr><th>'.$key.'</th><td>';
        if (isset($_GET['Create']))
            echo '<input type="text" name="'.$key.'" value=""/>';
        echo '</td></tr>';
    }
}

}
echo '</table><br/>';

if (isset($_GET['Create']))
    echo '<input type="submit" value="Create"></form>';


?>
</body></html>

Solution 3

You can use a simpler way just using direct XML input and the product schema, adding values directly with $vars value like $myID etc. Note that I am using 2 languages in PS.

$ps_product = <<<XML
<prestashop>
<product>
    <id></id>
    <id_manufacturer></id_manufacturer>
    <id_supplier></id_supplier>
    <id_category_default></id_category_default>
    <new></new>
    <cache_default_attribute></cache_default_attribute>
    <id_default_image></id_default_image>
    <id_default_combination></id_default_combination>
    <id_tax_rules_group></id_tax_rules_group>
    <position_in_category></position_in_category>
    <type></type>
    <id_shop_default></id_shop_default>
    <reference></reference>
    <supplier_reference></supplier_reference>
    <location></location>
    <width></width>
    <height></height>
    <depth></depth>
    <weight></weight>
    <quantity_discount></quantity_discount>
    <ean13></ean13>
    <upc></upc>
    <cache_is_pack></cache_is_pack>
    <cache_has_attachments></cache_has_attachments>
    <is_virtual></is_virtual>
    <on_sale></on_sale>
    <online_only></online_only>
    <ecotax></ecotax>
    <minimal_quantity></minimal_quantity>
    <price></price>
    <wholesale_price></wholesale_price>
    <unity></unity>
    <unit_price_ratio></unit_price_ratio>
    <additional_shipping_cost></additional_shipping_cost>
    <customizable></customizable>
    <text_fields></text_fields>
    <uploadable_files></uploadable_files>
    <active></active>
    <redirect_type></redirect_type>
    <id_product_redirected></id_product_redirected>
    <available_for_order></available_for_order>
    <available_date></available_date>
    <condition></condition>
    <show_price></show_price>
    <indexed></indexed>
    <visibility></visibility>
    <advanced_stock_management></advanced_stock_management>
    <date_add></date_add>
    <date_upd></date_upd>
    <meta_description><language id='1'></language><language id='2'></language></meta_description>
    <meta_keywords><language id='1'></language><language id='2'></language></meta_keywords>
    <meta_title><language id='1'></language><language id='2'></language></meta_title>
    <link_rewrite><language id='1'></language><language id='2'></language></link_rewrite>
    <name><language id='1'></language><language id='2'></language></name>
    <description><language id='1'></language><language id='2'></language></description>
    <description_short><language id='1'></language><language id='2'></language></description_short>
    <available_now><language id='1'></language><language id='2'></language></available_now>
    <available_later><language id='1'></language><language id='2'></language></available_later>
<associations>
<categories>
    <category>
    <id></id>
    </category>
</categories>
<images>
    <image>
    <id></id>
    </image>
</images>
<combinations>
    <combination>
    <id></id>
    </combination>
</combinations>
<product_option_values>
    <product_option_value>
    <id></id>
    </product_option_value>
</product_option_values>
<product_features>
    <product_feature>
    <id></id>
    <id_feature_value></id_feature_value>
    </product_feature>
</product_features>
<tags>
    <tag>
    <id></id>
    </tag>
</tags>
<stock_availables>
    <stock_available>
    <id></id>
    <id_product_attribute></id_product_attribute>
    </stock_available>
</stock_availables>
<accessories>
    <product>
    <id></id>
    </product>
</accessories>
<product_bundle>
    <product>
    <id></id>
    <quantity></quantity>
    </product>
</product_bundle>
</associations>
</product>
</prestashop>
XML;

$xml = new SimpleXMLElement($psXML);
$opt = array( 'resource' => 'products' );
$opt['postXml'] = $xml->asXML();
$xml = $webService->add( $opt );

I'm using this way in order to add carts directly in PS. If you don't have values for some node (you can pass data only for required fields) just use the following schema (for example id_default_image):

<id_default_image/>

instead of

<id_default_image></id_default_image>

Hope this will help you.

Share:
16,470
torayeff
Author by

torayeff

Updated on June 05, 2022

Comments

  • torayeff
    torayeff almost 2 years

    I am trying to add products to my shop powered by PrestaShop 1.6.0.9. Here is my code:

    <?php
        ini_set('display_errors',1);
        ini_set('display_startup_errors',1);
        error_reporting(-1);
        define('DEBUG', true);
        define('_PS_DEBUG_SQL', true);
        define('PS_SHOP_PATH', 'http://myshop.com');
        define('PS_WS_AUTH_KEY', 'E6R9IDPK2R519WB9QAJ45MUACZ9GANC2');
    
        require_once('PSWebServiceLibrary.php');
    
        try {
                $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
                $opt = array('resource' => 'products');
    
                $xml = $webService->get(array('url' => PS_SHOP_PATH.'/api/products?schema=synopsis'));
                $resources = $xml->children()->children();
    
                unset($resources->position_in_category);
                unset($resources->manufacturer_name);
    
                $resources->price = '1000';
                $resources->active = '1';
                $resources->quantity = '50';
                $resources->link_rewrite = 'blabla';
                $resources->name->language[0][0] = 'blabla';
                $resources->description->language[0][0] = '<p>blabla</p>';
                $resources->description_short->language[0][0] = 'blabla';
                $resources->associations = '';
    
                $opt = array('resource' => 'products');
                $opt['postXml'] = $xml->asXML();
                $xml = $webService->add($opt); 
        }
        catch (PrestaShopWebserviceException $ex) {
            echo 'Other error: <br/>'.$ex->getMessage();
        }
    ?>
    

    But I receive this error as XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
    <errors>
    <error>
    <code><![CDATA[127]]></code>
    <message><![CDATA[XML error : String could not be parsed as XML
    XML length : 7891
    Original XML : %3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%0A%3Cprestashop+xmlns%3Axlink%3D...................
    </error>
    </errors>
    </prestashop>
    

    I receive error for every update or insert. What can be the problem? And how can I fix this? My PrestaShop version is 1.6.0.9.

  • baao
    baao over 9 years
    Would be great to explain your changes