dolibarr 19.0.3
dolistore.class.php
1<?php
2/*
3 * Copyright (C) 2017 Oscss-Shop <support@oscss-shop.fr>.
4 *
5 * This program is free software; you can redistribute it and/or modifyion 2.0 (the "License");
6 * it under the terms of the GNU General Public License as published bypliance with the License.
7 * the Free Software Foundation; either version 3 of the License, or
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 * or see https://www.gnu.org/
17 */
18
19include_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
20if (!class_exists('PrestaShopWebservice')) { // We keep this because some modules add this lib too into a different path. This is to avoid "Cannot declare class PrestaShopWebservice" errors.
21 include_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/PSWebServiceLibrary.class.php';
22}
23
24
29{
34 public $start;
35
40 public $end;
41
42 public $per_page; // pagination: display per page
43 public $categorie; // the current categorie
44 public $categories; // an array of categories
45 public $search; // the search keywords
46
47 // setups
48 public $url; // the url of this page
49 public $shop_url; // the url of the shop
50 public $lang; // the integer representing the lang in the store
51 public $debug_api; // usefull if no dialog
52
53 public $api;
54 public $products;
55
61 public function __construct($debug = false)
62 {
63 global $langs;
64
65 $this->url = DOL_URL_ROOT.'/admin/modules.php?mode=marketplace';
66 $this->shop_url = 'https://www.dolistore.com/index.php?controller=product&id_product=';
67 $this->debug_api = $debug;
68
69 $langtmp = explode('_', $langs->defaultlang);
70 $lang = $langtmp[0];
71 $lang_array = array('en'=>1, 'fr'=>2, 'es'=>3, 'it'=>4, 'de'=>5); // Into table ps_lang of Prestashop - 1
72 if (!in_array($lang, array_keys($lang_array))) {
73 $lang = 'en';
74 }
75 $this->lang = $lang_array[$lang];
76 }
77
84 public function getRemoteCategories()
85 {
86 global $conf;
87
88 try {
89 $this->api = new PrestaShopWebservice($conf->global->MAIN_MODULE_DOLISTORE_API_SRV, $conf->global->MAIN_MODULE_DOLISTORE_API_KEY, $this->debug_api);
90 dol_syslog("Call API with MAIN_MODULE_DOLISTORE_API_SRV = ".getDolGlobalString('MAIN_MODULE_DOLISTORE_API_SRV'));
91 // $conf->global->MAIN_MODULE_DOLISTORE_API_KEY is for the login of basic auth. There is no password as it is public data.
92
93 // Here we set the option array for the Webservice : we want categories resources
94 $opt = array();
95 $opt['resource'] = 'categories';
96 $opt['display'] = '[id,id_parent,nb_products_recursive,active,is_root_category,name,description]';
97 $opt['sort'] = 'id_asc';
98
99 // Call
100 dol_syslog("Call API with opt = ".var_export($opt, true));
101 $xml = $this->api->get($opt);
102 $this->categories = $xml->categories->children();
103 } catch (PrestaShopWebserviceException $e) {
104 // Here we are dealing with errors
105 $trace = $e->getTrace();
106 if ($trace[0]['args'][0] == 404) {
107 die('Bad ID');
108 } elseif ($trace[0]['args'][0] == 401) {
109 die('Bad auth key');
110 } else {
111 print 'Can not access to ' . getDolGlobalString('MAIN_MODULE_DOLISTORE_API_SRV').'<br>';
112 print $e->getMessage();
113 }
114 }
115 }
116
124 public function getRemoteProducts($options = array('start' => 0, 'end' => 10, 'per_page' => 50, 'categorie' => 0, 'search' => ''))
125 {
126 global $conf;
127
128 $this->start = $options['start'];
129 $this->end = $options['end'];
130 $this->per_page = $options['per_page'];
131 $this->categorie = $options['categorie'];
132 $this->search = $options['search'];
133
134 if ($this->end == 0) {
135 $this->end = $this->per_page;
136 }
137
138 try {
139 $this->api = new PrestaShopWebservice($conf->global->MAIN_MODULE_DOLISTORE_API_SRV, $conf->global->MAIN_MODULE_DOLISTORE_API_KEY, $this->debug_api);
140 dol_syslog("Call API with MAIN_MODULE_DOLISTORE_API_SRV = ".getDolGlobalString('MAIN_MODULE_DOLISTORE_API_SRV'));
141 // $conf->global->MAIN_MODULE_DOLISTORE_API_KEY is for the login of basic auth. There is no password as it is public data.
142
143 // Here we set the option array for the Webservice : we want products resources
144 $opt = array();
145 $opt['resource'] = 'products';
146 $opt2 = array();
147
148 // make a search to limit the id returned.
149 if ($this->search != '') {
150 $opt2['url'] = getDolGlobalString('MAIN_MODULE_DOLISTORE_API_SRV') . '/api/search?query='.$this->search.'&language='.$this->lang; // It seems for search, key start with
151
152 // Call
153 dol_syslog("Call API with opt2 = ".var_export($opt2, true));
154 $xml = $this->api->get($opt2);
155
156 $products = array();
157 foreach ($xml->products->children() as $product) {
158 $products[] = (int) $product['id'];
159 }
160 $opt['filter[id]'] = '['.implode('|', $products).']';
161 } elseif ($this->categorie != 0) { // We filter on category, so we first get list of product id in this category
162 // $opt2['url'] is set by default to $this->url.'/api/'.$options['resource'];
163 $opt2['resource'] = 'categories';
164 $opt2['id'] = $this->categorie;
165
166 // Call
167 dol_syslog("Call API with opt2 = ".var_export($opt2, true));
168 $xml = $this->api->get($opt2);
169
170 $products = array();
171 foreach ($xml->category->associations->products->children() as $product) {
172 $products[] = (int) $product->id;
173 }
174 $opt['filter[id]'] = '['.implode('|', $products).']';
175 }
176 $opt['display'] = '[id,name,id_default_image,id_category_default,reference,price,condition,show_price,date_add,date_upd,description_short,description,module_version,dolibarr_min,dolibarr_max]';
177 $opt['sort'] = 'id_desc';
178 $opt['filter[active]'] = '[1]';
179 $opt['limit'] = "$this->start,$this->end";
180 // $opt['filter[id]'] contais list of product id that are result of search
181
182 // Call API to get the detail
183 dol_syslog("Call API with opt = ".var_export($opt, true));
184 $xml = $this->api->get($opt);
185 $this->products = $xml->products->children();
186 } catch (PrestaShopWebserviceException $e) {
187 // Here we are dealing with errors
188 $trace = $e->getTrace();
189 if ($trace[0]['args'][0] == 404) {
190 die('Bad ID');
191 } elseif ($trace[0]['args'][0] == 401) {
192 die('Bad auth key');
193 } else {
194 print 'Can not access to ' . getDolGlobalString('MAIN_MODULE_DOLISTORE_API_SRV').'<br>';
195 print $e->getMessage();
196 }
197 }
198 }
199
200 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
207 public function get_categories($parent = 0)
208 {
209 // phpcs:enable
210 if (!isset($this->categories)) {
211 die('not possible');
212 }
213 if ($parent != 0) {
214 $html = '<ul>';
215 } else {
216 $html = '';
217 }
218
219 $nbofcateg = count($this->categories);
220 for ($i = 0; $i < $nbofcateg; $i++) {
221 $cat = $this->categories[$i];
222 if ($cat->is_root_category == 1 && $parent == 0) {
223 $html .= '<li class="root"><h3 class="nomargesupinf"><a class="nomargesupinf link2cat" href="?mode=marketplace&categorie='.((int) $cat->id).'" ';
224 $html .= 'title="'.dol_escape_htmltag(strip_tags($cat->description->language[$this->lang - 1])).'">'.dol_escape_htmltag($cat->name->language[$this->lang - 1]).' <sup>'.dol_escape_htmltag($cat->nb_products_recursive).'</sup></a></h3>';
225 $html .= self::get_categories($cat->id);
226 $html .= "</li>\n";
227 } elseif (trim($cat->id_parent) == $parent && $cat->active == 1 && trim($cat->id_parent) != 0) { // si cat est de ce niveau
228 $select = ($cat->id == $this->categorie) ? ' selected' : '';
229 $html .= '<li><a class="link2cat'.$select.'" href="?mode=marketplace&categorie='.((int) $cat->id).'"';
230 $html .= ' title="'.dol_escape_htmltag(strip_tags($cat->description->language[$this->lang - 1])).'" ';
231 $html .= '>'.dol_escape_htmltag($cat->name->language[$this->lang - 1]).' <sup>'.dol_escape_htmltag($cat->nb_products_recursive).'</sup></a>';
232 $html .= self::get_categories($cat->id);
233 $html .= "</li>\n";
234 }
235 }
236
237 if ($html == '<ul>') {
238 return '';
239 }
240 if ($parent != 0) {
241 return $html.'</ul>';
242 } else {
243 return $html;
244 }
245 }
246
247 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
253 public function get_products()
254 {
255 // phpcs:enable
256 global $langs, $conf;
257 $html = "";
258 $last_month = time() - (30 * 24 * 60 * 60);
259 foreach ($this->products as $product) {
260 // check new product ?
261 $newapp = '';
262 if ($last_month < strtotime($product->date_add)) {
263 $newapp .= '<span class="newApp">'.$langs->trans('New').'</span> ';
264 }
265
266 // check updated ?
267 if ($last_month < strtotime($product->date_upd) && $newapp == '') {
268 $newapp .= '<span class="updatedApp">'.$langs->trans('Updated').'</span> ';
269 }
270
271 // add image or default ?
272 if ($product->id_default_image != '') {
273 $image_url = DOL_URL_ROOT.'/admin/dolistore/ajax/image.php?id_product='.urlencode(((int) $product->id)).'&id_image='.urlencode(((int) $product->id_default_image));
274 $images = '<a href="'.$image_url.'" class="documentpreview" target="_blank" rel="noopener noreferrer" mime="image/png" title="'.dol_escape_htmltag($product->name->language[$this->lang - 1].', '.$langs->trans('Version').' '.$product->module_version).'">';
275 $images .= '<img src="'.$image_url.'&quality=home_default" style="max-height:250px;max-width: 210px;" alt="" /></a>';
276 } else {
277 $images = '<img src="'.DOL_URL_ROOT.'/admin/dolistore/img/NoImageAvailable.png" />';
278 }
279
280 // free or pay ?
281 if ($product->price > 0) {
282 $price = '<h3>'.price(price2num($product->price, 'MT'), 0, $langs, 1, -1, -1, 'EUR').' '.$langs->trans("HT").'</h3>';
283 $download_link = '<a target="_blank" href="'.$this->shop_url.urlencode($product->id).'"><img width="32" src="'.DOL_URL_ROOT.'/admin/dolistore/img/follow.png" /></a>';
284 } else {
285 $price = '<h3>'.$langs->trans('Free').'</h3>';
286 $download_link = '<a target="_blank" rel="noopener noreferrer" href="'.$this->shop_url.urlencode($product->id).'"><img width="32" src="'.DOL_URL_ROOT.'/admin/dolistore/img/Download-128.png" /></a>';
287 $download_link .= '<br><br><a target="_blank" href="'.$this->shop_url.urlencode($product->id).'"><img width="32" src="'.DOL_URL_ROOT.'/admin/dolistore/img/follow.png" /></a>';
288 }
289
290 // Set and check version
291 $version = '';
292 if ($this->version_compare($product->dolibarr_min, DOL_VERSION) <= 0) {
293 if ($this->version_compare($product->dolibarr_max, DOL_VERSION) >= 0) {
294 //compatible
295 $version = '<span class="compatible">'.$langs->trans(
296 'CompatibleUpTo',
297 $product->dolibarr_max,
298 $product->dolibarr_min,
299 $product->dolibarr_max
300 ).'</span>';
301 $compatible = '';
302 } else {
303 //never compatible, module expired
304 $version = '<span class="notcompatible">'.$langs->trans(
305 'NotCompatible',
306 DOL_VERSION,
307 $product->dolibarr_min,
308 $product->dolibarr_max
309 ).'</span>';
310 $compatible = 'NotCompatible';
311 }
312 } else {
313 //need update
314 $version = '<span class="compatibleafterupdate">'.$langs->trans(
315 'CompatibleAfterUpdate',
316 DOL_VERSION,
317 $product->dolibarr_min,
318 $product->dolibarr_max
319 ).'</span>';
320 $compatible = 'NotCompatible';
321 }
322
323 //output template
324 $html .= '<tr class="app oddeven '.dol_escape_htmltag($compatible).'">';
325 $html .= '<td class="center" width="210"><div class="newAppParent">';
326 $html .= $newapp.$images; // No dol_escape_htmltag, it is already escape html
327 $html .= '</div></td>';
328 $html .= '<td class="margeCote"><h2 class="appTitle">';
329 $html .= dol_escape_htmltag($product->name->language[$this->lang - 1]);
330 $html .= '<br><small>';
331 $html .= $version; // No dol_escape_htmltag, it is already escape html
332 $html .= '</small></h2>';
333 $html .= '<small> '.dol_print_date(dol_stringtotime($product->date_upd), 'dayhour').' - '.$langs->trans('Ref').': '.dol_escape_htmltag($product->reference).' - '.dol_escape_htmltag($langs->trans('Id')).': '.((int) $product->id).'</small><br><br>'.dol_escape_htmltag($product->description_short->language[$this->lang - 1]).'</td>';
334 // do not load if display none
335 $html .= '<td class="margeCote center">';
336 $html .= $price;
337 $html .= '</td>';
338 $html .= '<td class="margeCote">'.$download_link.'</td>';
339 $html .= '</tr>';
340 }
341 return $html;
342 }
343
344 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
351 public function get_previous_link($text = '<<')
352 {
353 // phpcs:enable
354 return '<a href="'.$this->get_previous_url().'" class="button">'.dol_escape_htmltag($text).'</a>';
355 }
356
357 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
364 public function get_next_link($text = '>>')
365 {
366 // phpcs:enable
367 return '<a href="'.$this->get_next_url().'" class="button">'.dol_escape_htmltag($text).'</a>';
368 }
369
370 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
376 public function get_previous_url()
377 {
378 // phpcs:enable
379 $param_array = array();
380 if ($this->start < $this->per_page) {
381 $sub = 0;
382 } else {
383 $sub = $this->per_page;
384 }
385 $param_array['start'] = $this->start - $sub;
386 $param_array['end'] = $this->end - $sub;
387 if ($this->categorie != 0) {
388 $param_array['categorie'] = $this->categorie;
389 }
390 $param = http_build_query($param_array);
391 return $this->url."&".$param;
392 }
393
394 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
400 public function get_next_url()
401 {
402 // phpcs:enable
403 $param_array = array();
404 if (count($this->products) < $this->per_page) {
405 $add = 0;
406 } else {
407 $add = $this->per_page;
408 }
409 $param_array['start'] = $this->start + $add;
410 $param_array['end'] = $this->end + $add;
411 if ($this->categorie != 0) {
412 $param_array['categorie'] = $this->categorie;
413 }
414 $param = http_build_query($param_array);
415 return $this->url."&".$param;
416 }
417
418 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
426 public function version_compare($v1, $v2)
427 {
428 // phpcs:enable
429 $v1 = explode('.', $v1);
430 $v2 = explode('.', $v2);
431 $ret = 0;
432 $level = 0;
433 $count1 = count($v1);
434 $count2 = count($v2);
435 $maxcount = max($count1, $count2);
436 while ($level < $maxcount) {
437 $operande1 = isset($v1[$level]) ? $v1[$level] : 'x';
438 $operande2 = isset($v2[$level]) ? $v2[$level] : 'x';
439 $level++;
440 if (strtoupper($operande1) == 'X' || strtoupper($operande2) == 'X' || $operande1 == '*' || $operande2 == '*') {
441 break;
442 }
443 if ($operande1 < $operande2) {
444 $ret = -$level;
445 break;
446 }
447 if ($operande1 > $operande2) {
448 $ret = $level;
449 break;
450 }
451 }
452 //print join('.',$versionarray1).'('.count($versionarray1).') / '.join('.',$versionarray2).'('.count($versionarray2).') => '.$ret.'<br>'."\n";
453 return $ret;
454 }
455}
Class Dolistore.
get_products()
Return list of product formated for output.
getRemoteCategories()
Load data from remote Dolistore market place.
get_next_url()
get next url
__construct($debug=false)
Constructor.
get_categories($parent=0)
Return tree of Dolistore categories.
get_next_link($text='> >')
get next link
version_compare($v1, $v2)
version compare
get_previous_url()
get previous url
get_previous_link($text='<<')
get previous link
getRemoteProducts($options=array('start'=> 0, 'end'=> 10, 'per_page'=> 50, 'categorie'=> 0, 'search'=> ''))
Load data from remote Dolistore market place.
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:426
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...