Reputation: 9702
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.
Upvotes: 3
Views: 16831
Reputation: 217
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.
Upvotes: 1
Reputation: 51
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>
Upvotes: 2
Reputation: 9702
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));
Upvotes: 2