Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
10582 lgm 1
<?php
2
/*
3
* 2007-2013 PrestaShop
4
*
5
* NOTICE OF LICENSE
6
*
7
* This source file is subject to the Open Software License (OSL 3.0)
8
* that is bundled with this package in the file LICENSE.txt.
9
* It is also available through the world-wide-web at this URL:
10
* http://opensource.org/licenses/osl-3.0.php
11
* If you did not receive a copy of the license and are unable to
12
* obtain it through the world-wide-web, please send an email
13
* to license@prestashop.com so we can send you a copy immediately.
14
*
15
* DISCLAIMER
16
*
17
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
18
* versions in the future. If you wish to customize PrestaShop for your
19
* needs please refer to http://www.prestashop.com for more information.
20
*
21
*  @author PrestaShop SA <contact@prestashop.com>
22
*  @copyright  2007-2013 PrestaShop SA
23
*  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
24
*  International Registered Trademark & Property of PrestaShop SA
25
* PrestaShop Webservice Library
26
* @package PrestaShopWebservice
27
*/
28
 
29
/**
30
 * @package PrestaShopWebservice
31
 */
32
class PrestaShopWebservice
33
{
34
 
35
	/** @var string Shop URL */
36
	protected $url;
37
 
38
	/** @var string Authentification key */
39
	protected $key;
40
 
41
	/** @var boolean is debug activated */
42
	protected $debug;
43
 
44
	/** @var array compatible versions of PrestaShop Webservice */
45
	const psCompatibleVersionsMin = '1.4.0.17';
46
	const psCompatibleVersionsMax = '1.5.4.1';
47
 
48
	/**
49
	 * PrestaShopWebservice constructor. Throw an exception when CURL is not installed/activated
50
	 * <code>
51
	 * <?php
52
	 * require_once('./PrestaShopWebservice.php');
53
	 * try
54
	 * {
55
	 * 	$ws = new PrestaShopWebservice('http://mystore.com/', 'ZQ88PRJX5VWQHCWE4EE7SQ7HPNX00RAJ', false);
56
	 * 	// Now we have a webservice object to play with
57
	 * }
58
	 * catch (PrestaShopWebserviceException $ex)
59
	 * {
60
	 * 	echo 'Error : '.$ex->getMessage();
61
	 * }
62
	 * ?>
63
	 * </code>
64
	 * @param string $url Root URL for the shop
65
	 * @param string $key Authentification key
66
	 * @param mixed $debug Debug mode Activated (true) or deactivated (false)
67
	*/
68
	function __construct($debug = false) {
69
		if (!extension_loaded('curl'))
70
		  throw new PrestaShopWebserviceException('Please activate the PHP extension \'curl\' to allow use of PrestaShop webservice library');
71
 
72
		$ci =& get_instance();
73
     	$ci->config->load('prestashop');
74
     	$this->url = str_replace('api/', '',$ci->config->item('curl_base_url'));
75
		$this->key = $ci->config->item('apikey');
76
		$this->debug = $debug;
77
	}
78
 
79
	/**
80
	 * Take the status code and throw an exception if the server didn't return 200 or 201 code
81
	 * @param int $status_code Status code of an HTTP return
82
	 */
83
	protected function checkStatusCode($status_code)
84
	{
85
		$error_label = 'This call to PrestaShop Web Services failed and returned an HTTP status of %d. That means: %s.';
86
		switch($status_code)
87
		{
88
			case 200:	case 201:	break;
89
			case 204: throw new PrestaShopWebserviceException(sprintf($error_label, $status_code, 'No content'));break;
90
			case 400: throw new PrestaShopWebserviceException(sprintf($error_label, $status_code, 'Bad Request'));break;
91
			case 401: throw new PrestaShopWebserviceException(sprintf($error_label, $status_code, 'Unauthorized'));break;
92
			case 404: throw new PrestaShopWebserviceException(sprintf($error_label, $status_code, 'Not Found'));break;
93
			case 405: throw new PrestaShopWebserviceException(sprintf($error_label, $status_code, 'Method Not Allowed'));break;
94
			case 500: throw new PrestaShopWebserviceException(sprintf($error_label, $status_code, 'Internal Server Error'));break;
95
			default: throw new PrestaShopWebserviceException('This call to PrestaShop Web Services returned an unexpected HTTP status of:' . $status_code);
96
		}
97
	}
98
	/**
99
	 * Handles a CURL request to PrestaShop Webservice. Can throw exception.
100
	 * @param string $url Resource name
101
	 * @param mixed $curl_params CURL parameters (sent to curl_set_opt)
102
	 * @return array status_code, response
103
	 */
104
	protected function executeRequest($url, $curl_params = array())
105
	{
106
		$defaultParams = array(
107
			CURLOPT_HEADER => TRUE,
108
			CURLOPT_RETURNTRANSFER => TRUE,
109
			CURLINFO_HEADER_OUT => TRUE,
110
			CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
111
			CURLOPT_USERPWD => $this->key.':',
112
			CURLOPT_HTTPHEADER => array( 'Expect:' )
113
		);
114
 
115
		$session = curl_init($url);
116
 
117
		$curl_options = array();
118
		foreach ($defaultParams as $defkey => $defval)
119
		{
120
			if (isset($curl_params[$defkey]))
121
				$curl_options[$defkey] = $curl_params[$defkey];
122
			else
123
				$curl_options[$defkey] = $defaultParams[$defkey];
124
		}
125
		foreach ($curl_params as $defkey => $defval)
126
			if (!isset($curl_options[$defkey]))
127
				$curl_options[$defkey] = $curl_params[$defkey];
128
 
129
		curl_setopt_array($session, $curl_options);
130
		$response = curl_exec($session);
131
 
132
		$index = strpos($response, "\r\n\r\n");
133
		if ($index === false && $curl_params[CURLOPT_CUSTOMREQUEST] != 'HEAD')
134
			throw new PrestaShopWebserviceException('Bad HTTP response');
135
 
136
		$header = substr($response, 0, $index);
137
		$body = substr($response, $index + 4);
138
 
139
		$headerArrayTmp = explode("\n", $header);
140
 
141
		$headerArray = array();
142
		foreach ($headerArrayTmp as &$headerItem)
143
		{
144
			$tmp = explode(':', $headerItem);
145
			$tmp = array_map('trim', $tmp);
146
			if (count($tmp) == 2)
147
				$headerArray[$tmp[0]] = $tmp[1];
148
		}
149
 
150
		if (array_key_exists('PSWS-Version', $headerArray))
151
		{
152
			if (
153
				version_compare(PrestaShopWebservice::psCompatibleVersionsMin, $headerArray['PSWS-Version']) == 1 ||
154
				version_compare(PrestaShopWebservice::psCompatibleVersionsMax, $headerArray['PSWS-Version']) == -1
155
			)
156
			throw new PrestaShopWebserviceException('This library is not compatible with this version of PrestaShop. Please upgrade/downgrade this library');
157
		}
158
 
159
		if ($this->debug)
160
		{
161
			$this->printDebug('HTTP REQUEST HEADER', curl_getinfo($session, CURLINFO_HEADER_OUT));
162
			$this->printDebug('HTTP RESPONSE HEADER', $header);
163
 
164
		}
165
		$status_code = curl_getinfo($session, CURLINFO_HTTP_CODE);
166
		if ($status_code === 0)
167
			throw new PrestaShopWebserviceException('CURL Error: '.curl_error($session));
168
		curl_close($session);
169
		if ($this->debug)
170
		{
171
			if ($curl_params[CURLOPT_CUSTOMREQUEST] == 'PUT' || $curl_params[CURLOPT_CUSTOMREQUEST] == 'POST')
172
				$this->printDebug('XML SENT', $curl_params[CURLOPT_POSTFIELDS]);
173
			if ($curl_params[CURLOPT_CUSTOMREQUEST] != 'DELETE' && $curl_params[CURLOPT_CUSTOMREQUEST] != 'HEAD')
174
				$this->printDebug('RETURN HTTP BODY', $body);
175
		}
176
		return array('status_code' => $status_code, 'response' => $body, 'header' => $header);
177
	}
178
	public function printDebug($title, $content)
179
	{
180
		echo '<div style="display:table;background:#CCC;font-size:8pt;padding:7px"><h6 style="font-size:9pt;margin:0">'.$title.'</h6><pre>'.htmlentities($content).'</pre></div>';
181
	}
182
	/**
183
	 * Load XML from string. Can throw exception
184
	 * @param string $response String from a CURL response
185
	 * @return SimpleXMLElement status_code, response
186
	 */
187
	protected function parseXML($response)
188
	{
189
		if ($response != '')
190
		{
191
			libxml_use_internal_errors(true);
192
			$xml = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
193
			if (libxml_get_errors())
194
				throw new PrestaShopWebserviceException('HTTP XML response is not parsable : '.var_export(libxml_get_errors(), true));
195
			return $xml;
196
		}
197
		else
198
			throw new PrestaShopWebserviceException('HTTP response is empty');
199
	}
200
 
201
	/**
202
	 * Add (POST) a resource
203
	 * <p>Unique parameter must take : <br><br>
204
	 * 'resource' => Resource name<br>
205
	 * 'postXml' => Full XML string to add resource<br><br>
206
	 * Examples are given in the tutorial</p>
207
	 * @param array $options
208
	 * @return SimpleXMLElement status_code, response
209
	 */
210
	public function add($options)
211
	{
212
		$xml = '';
213
 
214
		if (isset($options['resource'], $options['postXml']) || isset($options['url'], $options['postXml']))
215
		{
216
			$url = (isset($options['resource']) ? $this->url.'/api/'.$options['resource'] : $options['url']);
217
			$xml = $options['postXml'];
218
		}
219
		else
220
			throw new PrestaShopWebserviceException('Bad parameters given');
221
		$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => 'xml='.$xml));
222
 
223
		self::checkStatusCode($request['status_code']);
224
		return self::parseXML($request['response']);
225
	}
226
 
227
	/**
228
 	 * Retrieve (GET) a resource
229
	 * <p>Unique parameter must take : <br><br>
230
	 * 'url' => Full URL for a GET request of Webservice (ex: http://mystore.com/api/customers/1/)<br>
231
	 * OR<br>
232
	 * 'resource' => Resource name,<br>
233
	 * 'id' => ID of a resource you want to get<br><br>
234
	 * </p>
235
	 * <code>
236
	 * <?php
237
	 * require_once('./PrestaShopWebservice.php');
238
	 * try
239
	 * {
240
	 * $ws = new PrestaShopWebservice('http://mystore.com/', 'ZQ88PRJX5VWQHCWE4EE7SQ7HPNX00RAJ', false);
241
	 * $xml = $ws->get(array('resource' => 'orders', 'id' => 1));
242
	 *	// Here in $xml, a SimpleXMLElement object you can parse
243
	 * foreach ($xml->children()->children() as $attName => $attValue)
244
	 * 	echo $attName.' = '.$attValue.'<br />';
245
	 * }
246
	 * catch (PrestaShopWebserviceException $ex)
247
	 * {
248
	 * 	echo 'Error : '.$ex->getMessage();
249
	 * }
250
	 * ?>
251
	 * </code>
252
	 * @param array $options Array representing resource to get.
253
	 * @return SimpleXMLElement status_code, response
254
	 */
255
	public function get($options)
256
	{
257
		if (isset($options['url']))
258
			$url = $options['url'];
259
		elseif (isset($options['resource']))
260
		{
261
			$url = $this->url.'/api/'.$options['resource'];
262
			$url_params = array();
263
			if (isset($options['id']))
264
				$url .= '/'.$options['id'];
265
 
266
			$params = array('filter', 'display', 'sort', 'limit');
267
			foreach ($params as $p)
268
				foreach ($options as $k => $o)
269
					if (strpos($k, $p) !== false)
270
						$url_params[$k] = $options[$k];
271
			if (count($url_params) > 0)
272
				$url .= '?'.http_build_query($url_params);
273
		}
274
		else
275
			throw new PrestaShopWebserviceException('Bad parameters given');
276
 
277
		$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'GET'));
278
 
279
		self::checkStatusCode($request['status_code']);// check the response validity
280
		return self::parseXML($request['response']);
281
	}
282
 
283
	/**
284
 	 * Head method (HEAD) a resource
285
	 *
286
	 * @param array $options Array representing resource for head request.
287
	 * @return SimpleXMLElement status_code, response
288
	 */
289
	public function head($options)
290
	{
291
		if (isset($options['url']))
292
			$url = $options['url'];
293
		elseif (isset($options['resource']))
294
		{
295
			$url = $this->url.'/api/'.$options['resource'];
296
			$url_params = array();
297
			if (isset($options['id']))
298
				$url .= '/'.$options['id'];
299
 
300
			$params = array('filter', 'display', 'sort', 'limit');
301
			foreach ($params as $p)
302
				foreach ($options as $k => $o)
303
					if (strpos($k, $p) !== false)
304
						$url_params[$k] = $options[$k];
305
			if (count($url_params) > 0)
306
				$url .= '?'.http_build_query($url_params);
307
		}
308
		else
309
			throw new PrestaShopWebserviceException('Bad parameters given');
310
		$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'HEAD', CURLOPT_NOBODY => true));
311
		self::checkStatusCode($request['status_code']);// check the response validity
312
		return $request['header'];
313
	}
314
	/**
315
	 * Edit (PUT) a resource
316
	 * <p>Unique parameter must take : <br><br>
317
	 * 'resource' => Resource name ,<br>
318
	 * 'id' => ID of a resource you want to edit,<br>
319
	 * 'putXml' => Modified XML string of a resource<br><br>
320
	 * Examples are given in the tutorial</p>
321
	 * @param array $options Array representing resource to edit.
322
	 */
323
	public function edit($options)
324
	{
325
		$xml = '';
326
		if (isset($options['url']))
327
			$url = $options['url'];
328
		elseif ((isset($options['resource'], $options['id']) || isset($options['url'])) && $options['putXml'])
329
		{
330
			$url = (isset($options['url']) ? $options['url'] : $this->url.'/api/'.$options['resource'].'/'.$options['id']);
331
			$xml = $options['putXml'];
332
		}
333
		else
334
			throw new PrestaShopWebserviceException('Bad parameters given');
335
 
336
		$request = self::executeRequest($url,  array(CURLOPT_CUSTOMREQUEST => 'PUT', CURLOPT_POSTFIELDS => $xml));
337
		self::checkStatusCode($request['status_code']);// check the response validity
338
		return self::parseXML($request['response']);
339
	}
340
 
341
	/**
342
	 * Delete (DELETE) a resource.
343
	 * Unique parameter must take : <br><br>
344
	 * 'resource' => Resource name<br>
345
	 * 'id' => ID or array which contains IDs of a resource(s) you want to delete<br><br>
346
	 * <code>
347
	 * <?php
348
	 * require_once('./PrestaShopWebservice.php');
349
	 * try
350
	 * {
351
	 * $ws = new PrestaShopWebservice('http://mystore.com/', 'ZQ88PRJX5VWQHCWE4EE7SQ7HPNX00RAJ', false);
352
	 * $xml = $ws->delete(array('resource' => 'orders', 'id' => 1));
353
	 *	// Following code will not be executed if an exception is thrown.
354
	 * 	echo 'Successfully deleted.';
355
	 * }
356
	 * catch (PrestaShopWebserviceException $ex)
357
	 * {
358
	 * 	echo 'Error : '.$ex->getMessage();
359
	 * }
360
	 * ?>
361
	 * </code>
362
	 * @param array $options Array representing resource to delete.
363
	 */
364
	public function delete($options)
365
	{
366
		if (isset($options['url']))
367
			$url = $options['url'];
368
		elseif (isset($options['resource']) && isset($options['id']))
369
			if (is_array($options['id']))
370
				$url = $this->url.'/api/'.$options['resource'].'/?id=['.implode(',', $options['id']).']';
371
			else
372
				$url = $this->url.'/api/'.$options['resource'].'/'.$options['id'];
373
		$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'DELETE'));
374
		self::checkStatusCode($request['status_code']);// check the response validity
375
		return true;
376
	}
377
 
378
 
379
}
380
 
381
/**
382
 * @package PrestaShopWebservice
383
 */
384
class PrestaShopWebserviceException extends Exception { }