Issues (608)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/ProductsHandler.php (22 issues)

1
<?php
2
3
namespace XoopsModules\Oledrion;
4
5
/*
6
 You may not change or alter any portion of this comment or credits
7
 of supporting developers from this source code or any supporting source code
8
 which is considered copyrighted (c) material of the original comment or credit authors.
9
10
 This program is distributed in the hope that it will be useful,
11
 but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
*/
14
15
/**
16
 * oledrion
17
 *
18
 * @copyright   {@link https://xoops.org/ XOOPS Project}
19
 * @license     {@link http://www.fsf.org/copyleft/gpl.html GNU public license}
20
 * @author      Hervé Thouzard (http://www.herve-thouzard.com/)
21
 */
22
23
/**
24
 * Gestion des produits mis en vente
25
 */
26
27
use XoopsModules\Oledrion;
28
29
/**
30
 * Class ProductsHandler
31
 */
32
class ProductsHandler extends OledrionPersistableObjectHandler
33
{
34
    /**
35
     * ProductsHandler constructor.
36
     * @param \XoopsDatabase|null $db
37
     */
38
    public function __construct(\XoopsDatabase $db = null)
39
    {
40
        //                            Table               Classe              Id          Libellé
41
        parent::__construct($db, 'oledrion_products', Products::class, 'product_id', 'product_title');
0 ignored issues
show
It seems like $db can also be of type null; however, parameter $db of XoopsModules\Oledrion\Ol...tHandler::__construct() does only seem to accept XoopsDatabase, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

41
        parent::__construct(/** @scrutinizer ignore-type */ $db, 'oledrion_products', Products::class, 'product_id', 'product_title');
Loading history...
42
    }
43
44
    /**
45
     * Retourne la liste des x produits les plus vus par les visiteurs
46
     *
47
     * @param  Parameters $parameters
48
     * @return array               Tableau de produits (sous la forme d'objets)
49
     * @internal param int $start Début des données
50
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
51
     * @internal param int $category Identifiant de la catégorie (évenutellement)
52
     * @internal param string $sort Champ sur lequel trier
53
     * @internal param string $order Sens du tri
54
     */
55
    public function getMostViewedProducts(Parameters $parameters)
56
    {
57
        $parameters = $parameters->extend(new Oledrion\Parameters([
58
                                                                      'start'    => 0,
59
                                                                      'limit'    => 0,
60
                                                                      'category' => 0,
61
                                                                      'sort'     => 'product_hits',
62
                                                                      'order'    => 'DESC',
63
                                                                  ]));
64
        $data       = [];
0 ignored issues
show
The assignment to $data is dead and can be removed.
Loading history...
65
        $criteria   = new \CriteriaCompo();
66
        $criteria->add(new \Criteria('product_online', 1, '='));
67
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
68
            // Ne pas afficher les produits qui ne sont pas publiés
69
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
70
        }
71
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
72
            // Se limiter aux seuls produits encore en stock
73
            $criteria->add(new \Criteria('product_stock', 0, '>'));
74
        }
75
        if (is_array($parameters['category']) && count($parameters['category']) > 0) {
76
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
77
        } elseif (0 != $parameters['category']) {
78
            $criteria->add(new \Criteria('product_cid', (int)$parameters['category'], '='));
79
        }
80
        $criteria->add(new \Criteria('product_hits', 0, '>'));
81
82
        $criteria->setLimit($parameters['limit']);
83
        $criteria->setStart($parameters['start']);
84
        $criteria->setSort($parameters['sort']);
85
        $criteria->setOrder($parameters['order']);
86
        $data = $this->getObjects($criteria, true);
87
88
        return $data;
89
    }
90
91
    /**
92
     * Retourne la liste des x produits les mieux notés par les visiteurs
93
     *
94
     * @param  Parameters $parameters
95
     * @return array               Tableau de produits (sous la forme d'objets)
96
     * @internal param int $start Début des données
97
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
98
     * @internal param int $category Identifiant de la catégorie (évenutellement)
99
     */
100
    public function getBestRatedProducts(Parameters $parameters)
101
    {
102
        $parameters = $parameters->extend(new Oledrion\Parameters([
103
                                                                      'start'    => 0,
104
                                                                      'limit'    => 0,
105
                                                                      'category' => 0,
106
                                                                      'sort'     => 'product_rating',
107
                                                                      'order'    => 'DESC',
108
                                                                  ]));
109
        $data       = [];
0 ignored issues
show
The assignment to $data is dead and can be removed.
Loading history...
110
        $criteria   = new \CriteriaCompo();
111
        $criteria->add(new \Criteria('product_online', 1, '='));
112
        $criteria->add(new \Criteria('product_rating', 0, '>')); // Se limiter aux seuls produits qui ont été vraiment notés
113
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
114
            // Ne pas afficher les produits qui ne sont pas publiés
115
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
116
        }
117
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
118
            // Se limiter aux seuls produits encore en stock
119
            $criteria->add(new \Criteria('product_stock', 0, '>'));
120
        }
121
        if (is_array($parameters['category']) && count($parameters['category']) > 0) {
122
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
123
        } elseif (0 != $parameters['category']) {
124
            $criteria->add(new \Criteria('product_cid', (int)$parameters['category'], '='));
125
        }
126
        $criteria->setLimit($parameters['limit']);
127
        $criteria->setStart($parameters['start']);
128
        $criteria->setSort($parameters['sort']);
129
        $criteria->setOrder($parameters['order']);
130
        $data = $this->getObjects($criteria, true);
131
132
        return $data;
133
    }
134
135
    /**
136
     * Retourne la liste des x derniers produits recommandés
137
     *
138
     * @param  Parameters $parameters
139
     * @return array               Tableau de produits (sous la forme d'objets)
140
     * @internal param int $start Indice de départ
141
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
142
     * @internal param int $category Identifiant de la catégorie (évenutellement)
143
     */
144
    public function getRecentRecommended(Parameters $parameters)
145
    {
146
        $parameters = $parameters->extend(new Oledrion\Parameters([
147
                                                                      'start'    => 0,
148
                                                                      'limit'    => 0,
149
                                                                      'category' => 0,
150
                                                                      'sort'     => 'product_recommended',
151
                                                                      'order'    => 'DESC',
152
                                                                  ]));
153
        $data       = [];
0 ignored issues
show
The assignment to $data is dead and can be removed.
Loading history...
154
        $criteria   = new \CriteriaCompo();
155
        $criteria->add(new \Criteria('product_online', 1, '='));
156
        $criteria->add(new \Criteria('product_recommended', '0000-00-00', '<>'));
157
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
158
            // Ne pas afficher les produits qui ne sont pas publiés
159
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
160
        }
161
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
162
            // Se limiter aux seuls produits encore en stock
163
            $criteria->add(new \Criteria('product_stock', 0, '>'));
164
        }
165
        if (is_array($parameters['category'])) {
166
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
167
        } elseif (0 != $parameters['category']) {
168
            $criteria->add(new \Criteria('product_cid', (int)$parameters['category'], '='));
169
        }
170
        $criteria->setLimit($parameters['limit']);
171
        $criteria->setStart($parameters['start']);
172
        $criteria->setSort($parameters['sort']);
173
        $criteria->setOrder($parameters['order']);
174
        $data = $this->getObjects($criteria, true);
175
176
        return $data;
177
    }
178
179
    /**
180
     * Retourne le nombre total de produits recommandés
181
     *
182
     * @return int Le nombre total de produits recommandés
183
     */
184
    public function getRecommendedCount()
185
    {
186
        $criteria = new \CriteriaCompo();
187
        $criteria->add(new \Criteria('product_online', 1, '='));
188
        $criteria->add(new \Criteria('product_recommended', '0000-00-00', '<>'));
189
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
190
            // Ne pas afficher les produits qui ne sont pas publiés
191
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
192
        }
193
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
194
            // Se limiter aux seuls produits encore en stock
195
            $criteria->add(new \Criteria('product_stock', 0, '>'));
196
        }
197
198
        return $this->getCount($criteria);
199
    }
200
201
    /**
202
     * Retourne la liste des x derniers produits parus toutes catégories confondues ou dans une catégorie spécifique
203
     *
204
     * @param  Parameters $parameters
205
     * @return array               Tableau de produits (sous la forme d'objets)
206
     * @internal param int $start Début des données
207
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
208
     * @internal param mixed $category Identifiant de la catégorie (évenutellement) ou tableau d'ID ou rien du tout
209
     * @internal param string $sort Champ(s) à utiliser pour le tri
210
     * @internal param string $order Ordre de tri
211
     * @internal param int $excluded Produit à exclure de la liste (éventuellement)
212
     * @internal param bool $thisMonthOnly Indique s'il ne faut prendre que les produits du mois
213
     */
214
    public function getRecentProducts(Parameters $parameters)
215
    {
216
        $parameters = $parameters->extend(new Oledrion\Parameters([
217
                                                                      'start'         => 0,
218
                                                                      'limit'         => 0,
219
                                                                      'category'      => 0,
220
                                                                      'sort'          => 'product_submitted DESC, product_title',
221
                                                                      'order'         => '',
222
                                                                      'excluded'      => 0,
223
                                                                      'thisMonthOnly' => false,
224
                                                                  ]));
225
        $data       = [];
0 ignored issues
show
The assignment to $data is dead and can be removed.
Loading history...
226
        $criteria   = new \CriteriaCompo();
227
        $criteria->add(new \Criteria('product_online', 1, '='));
228
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
229
            // Ne pas afficher les produits qui ne sont pas publiés
230
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
231
        }
232
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
233
            // Se limiter aux seuls produits encore en stock
234
            $criteria->add(new \Criteria('product_stock', 0, '>'));
235
        }
236
        if (is_array($parameters['category']) && count($parameters['category']) > 0) {
237
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
238
        } elseif ($parameters['category'] > 0) {
239
            $criteria->add(new \Criteria('product_cid', (int)$parameters['category'], '='));
240
        }
241
        if ($parameters['excluded'] > 0) {
242
            $criteria->add(new \Criteria('product_id', $parameters['excluded'], '<>'));
243
        }
244
245
        if ($parameters['thisMonthOnly']) {
246
            $criteria->add(Oledrion\Utility::getThisMonthCriteria());
247
        }
248
249
        $criteria->setLimit($parameters['limit']);
250
        $criteria->setStart($parameters['start']);
251
        $criteria->setSort($parameters['sort']);
252
        if ('' !== xoops_trim($parameters['order'])) {
253
            $criteria->setOrder($parameters['order']);
254
        }
255
        $data = $this->getObjects($criteria, true);
256
257
        return $data;
258
    }
259
260
    /**
261
     * Retourne le nombre total de produits récents (éventuellement dans une catégorie)
262
     *
263
     * @param  mixed $category        Array ou Integer
264
     * @param int    $excludedProduct ID d'un produit à exclure
265
     * @return int
266
     */
267
    public function getRecentProductsCount($category = 0, $excludedProduct = 0)
268
    {
269
        $criteria = new \CriteriaCompo();
270
        $criteria->add(new \Criteria('product_online', 1, '='));
271
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
272
            // Ne pas afficher les produits qui ne sont pas publiés
273
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
274
        }
275
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
276
            // Se limiter aux seuls produits encore en stock
277
            $criteria->add(new \Criteria('product_stock', 0, '>'));
278
        }
279
        if (is_array($category)) {
280
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $category) . ')', 'IN'));
281
        } elseif ($category > 0) {
282
            $criteria->add(new \Criteria('product_cid', (int)$category, '='));
283
        }
284
        if ($excludedProduct > 0) {
285
            $criteria->add(new \Criteria('product_id', $excludedProduct, '<>'));
286
        }
287
288
        return $this->getCount($criteria);
289
    }
290
291
    /**
292
     * Retourne la liste des produits qui correspondent à des "critères" de manière à les utiliser pour la newsletter
293
     *
294
     * @param  Parameters $parameters
295
     * @return array               Des objects de type produits
296
     * @internal param int $startingDate Date de soumission du produit à prendre comme borne inférieure
297
     * @internal param int $endingDate Date de soumission du produit à prendre comme borne supérieure
298
     * @internal param mixed $category Soit un tableau d'ID de catégories soit un ID unique de catégorie
299
     * @internal param int $start Position de départ
300
     * @internal param int $limit Nombre d'enregistrements à retourner
301
     */
302
    public function getProductsForNewsletter(Parameters $parameters)
303
    {
304
        $parameters = $parameters->extend(new Oledrion\Parameters([
305
                                                                      'startingDate' => 0,
306
                                                                      'endingDate'   => 0,
307
                                                                      'category'     => 0,
308
                                                                      'start'        => 0,
309
                                                                      'limit'        => 0,
310
                                                                  ]));
311
        $data       = [];
0 ignored issues
show
The assignment to $data is dead and can be removed.
Loading history...
312
        $criteria   = new \CriteriaCompo();
313
        $criteria->add(new \Criteria('product_online', 1, '='));
314
        $criteria->add(new \Criteria('product_submitted', $parameters['startingDate'], '>='));
315
        $criteria->add(new \Criteria('product_submitted', $parameters['endingDate'], '<='));
316
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
317
            // Ne pas afficher les produits qui ne sont pas publiés
318
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
319
        }
320
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
321
            // Se limiter aux seuls produits encore en stock
322
            $criteria->add(new \Criteria('product_stock', 0, '>'));
323
        }
324
        if (is_array($parameters['category'])) {
325
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
326
        } elseif ($parameters['category'] > 0) {
327
            $criteria->add(new \Criteria('product_cid', (int)$parameters['category'], '='));
328
        }
329
        $criteria->setLimit($parameters['limit']);
330
        $criteria->setStart($parameters['start']);
331
        $criteria->setSort('product_title');
332
        $data = $this->getObjects($criteria, true);
333
334
        return $data;
335
    }
336
337
    /**
338
     * Retourne le nombre total de produits publiés dans la base en tenant compte des préférences du module
339
     *
340
     * @param  int|int $product_cid Catégorie du produit
341
     * @return int         Le nombre de produits publiés
342
     */
343
    public function getTotalPublishedProductsCount($product_cid = 0)
344
    {
345
        $criteria = new \CriteriaCompo();
346
        $criteria->add(new \Criteria('product_online', 1, '='));
347
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
348
            // Ne pas afficher les produits qui ne sont pas publiés
349
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
350
        }
351
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
352
            // Se limiter aux seuls produits encore en stock
353
            $criteria->add(new \Criteria('product_stock', 0, '>'));
354
        }
355
        if ($product_cid > 0) {
356
            $criteria->add(new \Criteria('product_cid', (int)$product_cid, '='));
357
        }
358
359
        return $this->getCount($criteria);
360
    }
361
362
    /**
363
     * Récupération de l'ID et du titre d'une série de produits répondants à un critère
364
     *
365
     * @param  null|\CriteriaElement|\CriteriaCompo $criteria critère de sélection
366
     * @return array  Tableau dont la clé = ID produit et la valeur le titre du produit
367
     */
368
    public function getIdTitle($criteria = null)
369
    {
370
        global $myts;
371
        $ret = [];
372
        $sql = 'SELECT product_id, product_title FROM ' . $this->table;
373
        if (null !== $criteria && $criteria instanceof \CriteriaElement) {
374
            $sql .= ' ' . $criteria->renderWhere();
0 ignored issues
show
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

374
            $sql .= ' ' . $criteria->/** @scrutinizer ignore-call */ renderWhere();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
375
            if ('' !== $criteria->getSort()) {
376
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
377
            }
378
            $limit = $criteria->getLimit();
379
            $start = $criteria->getStart();
380
        }
381
        $result = $this->db->query($sql, $limit, $start);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $limit does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $start does not seem to be defined for all execution paths leading up to this point.
Loading history...
382
        if (!$result) {
383
            return $ret;
384
        }
385
        while (false !== ($myrow = $this->db->fetchArray($result))) {
386
            $ret[$myrow['product_id']] = $myts->htmlSpecialChars($myrow['product_title']);
387
        }
388
389
        return $ret;
390
    }
391
392
    /**
393
     * Mise à jour du compteur de lectures du produit
394
     *
395
     * @param int $product_id L'identifiant du produit dont il faut mettre à jour le compteur de lectures
396
     * @return bool Le résultat de la mise à jour
397
     */
398
    public function addCounter($product_id)
399
    {
400
        $sql = 'UPDATE ' . $this->table . ' SET product_hits = product_hits + 1 WHERE product_id= ' . (int)$product_id;
401
402
        // Note, pas de mise à jour du cache !
403
        return $this->db->queryF($sql);
404
    }
405
406
    /**
407
     * Mise à jour de la notation d'un produit
408
     *
409
     * @param int    $product_id Identifiant du produit
410
     * @param  float $rating     la notation
411
     * @param int    $votes      Le nombre de votes du produit
412
     * @return bool Le résultat de la mise à jour
413
     */
414
    public function updateRating($product_id, $rating, $votes)
415
    {
416
        $sql = 'UPDATE ' . $this->table . ' SET product_rating = ' . (int)$rating . ', product_votes = ' . (int)$votes . ' WHERE product_id = ' . (int)$product_id;
417
418
        return $this->db->queryF($sql);
419
    }
420
421
    /**
422
     * Mise à jour du nombre de commentaires d'un produit
423
     *
424
     * @param int $product_id    Identifiant du produit
425
     * @param int $commentsCount Nombre total de commentaires
426
     */
427
    public function updateCommentsCount($product_id, $commentsCount)
428
    {
429
        $product = null;
0 ignored issues
show
The assignment to $product is dead and can be removed.
Loading history...
430
        $product = $this->get($product_id);
431
        if (is_object($product)) {
432
            $criteria = new \Criteria('product_id', $product_id, '=');
433
            $this->updateAll('product_comments', $commentsCount, $criteria, true);
434
        }
435
    }
436
437
    /**
438
     * Retourne x produits au hasard
439
     *
440
     * @param  Parameters $parameters
441
     * @return array               Tableau de produits (sous la forme d'objets)
442
     * @internal param int $start Début des données
443
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
444
     * @internal param int $category Identifiant de la catégorie (évenutellement)
445
     * @internal param string $sort Zone sur laquelle faire le tri
446
     * @internal param string $order Ordre de tri
447
     * @internal param bool $thisMonthOnly Uniquement les produits du mois en cours ?
448
     */
449
    public function getRandomProducts(Parameters $parameters)
450
    {
451
        $parameters = $parameters->extend(new Oledrion\Parameters([
452
                                                                      'start'         => 0,
453
                                                                      'limit'         => 0,
454
                                                                      'category'      => 0,
455
                                                                      'sort'          => 'RAND()',
456
                                                                      'order'         => 'ASC',
457
                                                                      'thisMonthOnly' => false,
458
                                                                  ]));
459
        $data       = [];
0 ignored issues
show
The assignment to $data is dead and can be removed.
Loading history...
460
        $criteria   = new \CriteriaCompo();
461
        $criteria->add(new \Criteria('product_online', 1, '='));
462
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
463
            // Ne pas afficher les produits qui ne sont pas publiés
464
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
465
        }
466
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
467
            // Se limiter aux seuls produits encore en stock
468
            $criteria->add(new \Criteria('product_stock', 0, '>'));
469
        }
470
        if (is_array($parameters['category'])) {
471
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
472
        } elseif (0 != $parameters['category']) {
473
            $criteria->add(new \Criteria('product_cid', (int)$parameters['category'], '='));
474
        }
475
476
        if ($parameters['thisMonthOnly']) {
477
            $criteria->add(Oledrion\Utility::getThisMonthCriteria());
478
        }
479
480
        $criteria->setLimit($parameters['limit']);
481
        $criteria->setStart($parameters['start']);
482
        $criteria->setSort($parameters['sort']);
483
        $criteria->setOrder($parameters['order']);
484
        $data = $this->getObjects($criteria, true);
485
486
        return $data;
487
    }
488
489
    /**
490
     * Retourne x produits en promo
491
     *
492
     * @param  Parameters $parameters
493
     * @return array               Tableau de produits (sous la forme d'objets)
494
     * @internal param int $start Début des données
495
     * @internal param int $limit Nombre maximum d'enregistrements à renvoyer
496
     * @internal param int $category Identifiant de la catégorie (évenutellement)
497
     */
498
    public function getPromotionalProducts(Parameters $parameters)
499
    {
500
        $parameters = $parameters->extend(new Oledrion\Parameters([
501
                                                                      'start'    => 0,
502
                                                                      'limit'    => 0,
503
                                                                      'category' => 0,
504
                                                                      'sort'     => 'product_title',
505
                                                                      'order'    => 'DESC',
506
                                                                  ]));
507
        $data       = [];
0 ignored issues
show
The assignment to $data is dead and can be removed.
Loading history...
508
        $criteria   = new \CriteriaCompo();
509
        $criteria->add(new \Criteria('product_online', 1, '='));
510
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
511
            // Ne pas afficher les produits qui ne sont pas publiés
512
            $criteria->add(new \Criteria('product_submitted', time(), '<='));
513
        }
514
        if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
515
            // Se limiter aux seuls produits encore en stock
516
            $criteria->add(new \Criteria('product_stock', 0, '>'));
517
        }
518
        if (is_array($parameters['category'])) {
519
            $criteria->add(new \Criteria('product_cid', '(' . implode(',', $parameters['category']) . ')', 'IN'));
520
        } elseif (0 != $parameters['category']) {
521
            $criteria->add(new \Criteria('product_cid', (int)$parameters['category'], '='));
522
        }
523
        $criteria->add(new \Criteria('product_discount_price', 0, '>'));
524
        $criteria->setLimit($parameters['limit']);
525
        $criteria->setStart($parameters['start']);
526
        $criteria->setSort($parameters['sort']);
527
        $criteria->setOrder($parameters['order']);
528
        $data = $this->getObjects($criteria, true);
529
530
        return $data;
531
    }
532
533
    /**
534
     * Retourne les produits dont les stocks sont bas
535
     *
536
     * @param int $start Début des données
537
     * @param int $limit Nombre maximum d'enregistrements à renvoyer
538
     * @return array   Tableau de produits (sous la forme d'objets)
539
     */
540
    public function getLowStocks($start = 0, $limit = 0)
541
    {
542
        $ret = [];
543
        $sql = 'SELECT * FROM ' . $this->table . ' WHERE product_online = 1';
544
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
545
            // Ne pas afficher les produits qui ne sont pas publiés
546
            $sql .= ' AND product_submitted <= ' . time();
547
        }
548
        $sql    .= ' AND product_stock <= product_alert_stock ';
549
        $sql    .= ' AND product_alert_stock > 0';
550
        $sql    .= ' ORDER BY product_stock';
551
        $result = $this->db->query($sql, $limit, $start);
552
        if (!$result) {
553
            return $ret;
554
        }
555
556
        $ret = $this->convertResultSet($result, true, true);
557
558
        return $ret;
559
    }
560
561
    /**
562
     * Retourne le nombre de produits dont la quantité en stock est inférieure ou égale à la quantité d'alerte
563
     *
564
     * @return array|int Le nombre de produits concernés
565
     */
566
    public function getLowStocksCount()
567
    {
568
        $ret = [];
569
        $sql = 'SELECT Count(*) AS cpt FROM ' . $this->table . ' WHERE product_online = 1';
570
        if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
571
            // Ne pas afficher les produits qui ne sont pas publiés
572
            $sql .= ' AND product_submitted <= ' . time();
573
        }
574
        $sql    .= ' AND product_stock <= product_alert_stock ';
575
        $sql    .= ' AND product_alert_stock > 0';
576
        $result = $this->db->query($sql);
577
        if (!$result) {
578
            return $ret;
579
        }
580
        $count = 0;
0 ignored issues
show
The assignment to $count is dead and can be removed.
Loading history...
581
        list($count) = $this->db->fetchRow($result);
582
583
        return $count;
584
    }
585
586
    /**
587
     * Augmente les quantités en stock d'un produit
588
     *
589
     * @param  Products $product  Objet produit
590
     * @param  int      $quantity $quantity Quantité à rajouter
591
     * @return bool
592
     */
593
    public function increaseStock($product, $quantity = 1)
594
    {
595
        $product->setVar('product_stock', $product->getVar('product_stock') + $quantity);
596
        $this->insert($product, true);
597
598
        return true;
599
    }
600
601
    /**
602
     * Diminue les quantités en stock d'un produit
603
     *
604
     * @param  Products $product  Objet produit
605
     * @param  int      $quantity $quantity Quantité à soustraire
606
     * @return bool
607
     */
608
    public function decreaseStock(&$product, $quantity = 1)
609
    {
610
        if ($product->getVar('product_stock') - $quantity > 0) {
611
            $product->setVar('product_stock', $product->getVar('product_stock') - $quantity);
612
            $this->insert($product, true);
613
        } else {
614
            $product->setVar('product_stock', 0);
615
        }
616
617
        return true;
618
    }
619
620
    /**
621
     * Indique si la quantité d'alerte d'un produit est atteinte
622
     *
623
     * @param Products $product
624
     * @return bool Vrai si la quantité d'alerte est atteinte, sinon faux
625
     * @internal param object $products L'objet produit concerné
626
     */
627
    public function isAlertStockReached(Products $product)
628
    {
629
        return $product->getVar('product_stock') < $product->getVar('product_alert_stock');
630
    }
631
632
    /**
633
     * Méthode chargée de vérifier si le stock d'alerte est atteint et si c'est le cas, d'envoyer une alerte
634
     *
635
     * @param  Products $product Produit dont il faut faire la vérification
636
     * @return bool vrai si l'alerte à du être générée sinon faux
637
     */
638
    public function verifyLowStock(&$product)
639
    {
640
        if ($this->isAlertStockReached($product)) {
641
            $msg                    = [];
642
            $msg['PRODUCT_NAME']    = $product->getVar('product_title');
643
            $msg['ACTUAL_QUANTITY'] = $product->getVar('product_stock');
644
            $msg['ALERT_QUANTITY']  = $product->getVar('product_alert_stock');
645
            $msg['PUBLIC_URL']      = $product->getLink();
646
            $msg['ADMIN_URL']       = OLEDRION_URL . 'admin/index.php?op=editproduct&id=' . $product->getVar('product_id');
647
            Oledrion\Utility::sendEmailFromTpl('shop_lowstock.tpl', Oledrion\Utility::getEmailsFromGroup(Oledrion\Utility::getModuleOption('stock_alert_email')), _OLEDRION_STOCK_ALERT, $msg);
648
649
            return true;
650
        }
651
652
        return false;
653
    }
654
655
    /**
656
     * Retourne la plus petite date de création d'un produit ainsi que la "plus grande" date de création d'un produit
657
     *
658
     * @param int $minDate Date mini (parmètre de sortie)
659
     * @param int $maxDate Date maxi (paramètre de sortie)
660
     * @return bool Vrai si on a pu récupérer ces valeurs, faux sinon
661
     */
662
    public function getMinMaxPublishedDate(&$minDate, &$maxDate)
663
    {
664
        $sql    = 'SELECT Min(product_submitted) AS minDate, Max(product_submitted) AS maxDate FROM ' . $this->table . ' WHERE product_online = 1 ';
665
        $result = $this->db->query($sql);
666
        if (!$result) {
667
            return false;
668
        }
669
        $myrow   = $this->db->fetchArray($result);
670
        $minDate = $myrow['minDate'];
671
        $maxDate = $myrow['maxDate'];
672
673
        return true;
674
    }
675
676
    /**
677
     * Retourne des produits en fonction de leur IDs tout en tenant compte du fait qu'ils sont en ligne et payés !
678
     *
679
     * @param  array $ids     Les identifiants des produits
680
     * @param  bool  $showAll Afficher les produits même s'ils ne sont plus en stock ?
681
     * @return array   Tableau d'objets de type Products, Clé = Id Produit
682
     */
683
    public function getProductsFromIDs($ids, $showAll = false)
684
    {
685
        $ret = [];
686
        if (is_array($ids)) {
0 ignored issues
show
The condition is_array($ids) is always true.
Loading history...
687
            $criteria = new \CriteriaCompo();
688
            if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
689
                // Ne pas afficher les produits qui ne sont pas publiés
690
                $criteria->add(new \Criteria('product_submitted', time(), '<='));
691
            }
692
            if (!$showAll && 0 == Oledrion\Utility::getModuleOption('nostock_display')) {
693
                // Se limiter aux seuls produits encore en stock
694
                $criteria->add(new \Criteria('product_stock', 0, '>'));
695
            }
696
            $criteria->add(new \Criteria('product_id', '(' . implode(',', $ids) . ')', 'IN'));
697
            $ret = $this->getObjects($criteria, true, true, '*', false);
0 ignored issues
show
The call to XoopsPersistableObjectHandler::getObjects() has too many arguments starting with '*'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

697
            /** @scrutinizer ignore-call */ 
698
            $ret = $this->getObjects($criteria, true, true, '*', false);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
698
        }
699
700
        return $ret;
701
    }
702
703
    /**
704
     * Retourne le nombre de produits d'une ou de plusieurs catégories
705
     *
706
     * @param  mixed $cat_cid Soit un ID de catégorie unique soit un tableau d'ID de catégories
707
     * @return int Le nombre de produits associés à cette catégorie
708
     */
709
    public function getCategoryProductsCount($cat_cid)
710
    {
711
        if (is_array($cat_cid)) {
712
            $lst_ids  = implode(',', $cat_cid);
713
            $criteria = new \Criteria('product_cid', '(' . $lst_ids . ')', 'IN');
714
        } else {
715
            $criteria = new \Criteria('product_cid', $cat_cid, '=');
716
        }
717
718
        return $this->getCount($criteria);
719
    }
720
721
    /**
722
     * Retourne le nombre de produits associés à un vendeur
723
     *
724
     * @param int $product_vendor_id L'ID du vendeur
725
     * @return int Le nombre de produits
726
     */
727
    public function getVendorProductsCount($product_vendor_id)
728
    {
729
        $criteria = new \Criteria('product_vendor_id', $product_vendor_id, '=');
730
731
        return $this->getCount($criteria);
732
    }
733
734
    /**
735
     * Retourne le nombre de produits associés à une TVA
736
     *
737
     * @param int $product_vat_id L'identifiant de la TVA
738
     * @return int Le nombre de produits
739
     */
740
    public function getVatProductsCount($product_vat_id)
741
    {
742
        $criteria = new \Criteria('product_vat_id', $product_vat_id, '=');
743
744
        return $this->getCount($criteria);
745
    }
746
747
    /**
748
     * Clone d'un produit
749
     *
750
     * @param  \XoopsModules\Oledrion\Products $originalProduct Le produit à cloner
751
     * @return mixed                    Soit l'objet représentant le nouveau produit soit false
752
     */
753
    public function cloneProduct(\XoopsModules\Oledrion\Products $originalProduct)
754
    {
755
        global $productsmanuHandler, $filesHandler, $productsmanuHandler, $relatedHandler, $oledrionHandlers;
756
        $newProduct = $originalProduct->xoopsClone();
757
        if (OLEDRION_DUPLICATED_PLACE === 'right') {
0 ignored issues
show
The condition XoopsModules\Oledrion\OL...CATED_PLACE === 'right' is always true.
Loading history...
758
            $newProduct->setVar('product_title', $originalProduct->getVar('product_title') . ' ' . _AM_OLEDRION_DUPLICATED);
759
        } else {
760
            $newProduct->setVar('product_title', _AM_OLEDRION_DUPLICATED . ' ' . $originalProduct->getVar('product_title'));
761
        }
762
        $newProduct->setVar('product_id', 0);
763
        $newProduct->setNew();
764
765
        // Copie des 2 images
766
        if ('' !== xoops_trim($originalProduct->getVar('product_image_url'))) {
767
            $resCopy = Oledrion\Utility::duplicateFile(OLEDRION_PICTURES_PATH, $originalProduct->getVar('product_image_url'));
0 ignored issues
show
It seems like $originalProduct->getVar('product_image_url') can also be of type array and array; however, parameter $filename of XoopsModules\Oledrion\Utility::duplicateFile() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

767
            $resCopy = Oledrion\Utility::duplicateFile(OLEDRION_PICTURES_PATH, /** @scrutinizer ignore-type */ $originalProduct->getVar('product_image_url'));
Loading history...
768
            if (false !== $resCopy) {
769
                $newProduct->setVar('product_image_url', $resCopy);
770
            }
771
        }
772
        if ('' !== xoops_trim($originalProduct->getVar('product_thumb_url'))) {
773
            $resCopy = Oledrion\Utility::duplicateFile(OLEDRION_PICTURES_PATH, $originalProduct->getVar('product_thumb_url'));
774
            if (false !== $resCopy) {
775
                $newProduct->setVar('product_thumb_url', $resCopy);
776
            }
777
        }
778
779
        // Copie du fichier attaché
780
        if ('' !== xoops_trim($originalProduct->getVar('product_attachment'))) {
781
            $resCopy = Oledrion\Utility::duplicateFile(OLEDRION_ATTACHED_FILES_PATH, $originalProduct->getVar('product_attachment'));
782
            if (false !== $resCopy) {
783
                $newProduct->setVar('product_attachment', $resCopy);
784
            }
785
        }
786
787
        $res = $this->insert($newProduct, true);
788
        if ($res) {
789
            $newProductId = $newProduct->getVar('product_id');
790
            // Copie des fichiers liés
791
            if ($filesHandler->getProductFilesCount($originalProduct->product_id) > 0) {
0 ignored issues
show
Bug Best Practice introduced by
The property product_id does not exist on XoopsModules\Oledrion\Products. Since you implemented __get, consider adding a @property annotation.
Loading history...
792
                $attachedFiles = [];
0 ignored issues
show
The assignment to $attachedFiles is dead and can be removed.
Loading history...
793
                $attachedFiles = $filesHandler->getProductFiles($originalProduct->product_id);
794
                if (count($attachedFiles) > 0) {
795
                    foreach ($attachedFiles as $oneFile) {
796
                        $newAttachedFile = $oneFile->xoopsClone();
797
                        $newAttachedFile->setVar('file_product_id', $newProductId);
798
                        $resCopy = Oledrion\Utility::duplicateFile(OLEDRION_ATTACHED_FILES_PATH, $oneFile->getVar('file_filename'));
799
                        if (false !== $resCopy) {
800
                            $newAttachedFile->setVar('file_filename', $resCopy);
801
                        }
802
                        $newAttachedFile->setNew();
803
                        $filesHandler->insert($newAttachedFile, true);
804
                    }
805
                }
806
            }
807
808
            // Copie des fabricants
809
            $tblTmp   = [];
0 ignored issues
show
The assignment to $tblTmp is dead and can be removed.
Loading history...
810
            $criteria = new \Criteria('pm_product_id', $originalProduct->getVar('product_id'), '=');
0 ignored issues
show
It seems like $originalProduct->getVar('product_id') can also be of type array and array; however, parameter $value of Criteria::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

810
            $criteria = new \Criteria('pm_product_id', /** @scrutinizer ignore-type */ $originalProduct->getVar('product_id'), '=');
Loading history...
811
            $tblTmp   = $productsmanuHandler->getObjects($criteria);
812
            foreach ($tblTmp as $productAuthor) {
813
                $newProductAuthor = $productAuthor->xoopsClone();
814
                $newProductAuthor->setVar('pm_product_id', $newProductId);
815
                $newProductAuthor->setVar('pm_id', 0);
816
                $newProductAuthor->setNew();
817
                $productsmanuHandler->insert($newProductAuthor, true);
818
            }
819
820
            // Copie des produits relatifs
821
            $tblTmp   = [];
822
            $criteria = new \Criteria('related_product_id', $originalProduct->getVar('product_id'), '=');
823
            $tblTmp   = $relatedHandler->getObjects($criteria);
824
            foreach ($tblTmp as $related) {
825
                $newRelated = $related->xoopsClone();
826
                $newRelated->setVar('related_product_id', $newProductId);
827
                $newRelated->setVar('related_id', 0);
828
                $newRelated->setNew();
829
                $relatedHandler->insert($newRelated, true);
830
            }
831
832
            // Copie des attributs
833
            if ($attributesHandler->getProductAttributesCount($originalProduct->product_id) > 0) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $attributesHandler seems to be never defined.
Loading history...
834
                $criteria = new \Criteria('attribute_product_id', $originalProduct->product_id, '=');
835
                $tblTmp   = $attributesHandler->getObjects($criteria);
836
                foreach ($tblTmp as $attribute) {
837
                    $newAttribute = $attribute->xoopsClone();
838
                    $newAttribute->setVar('attribute_product_id', $newProductId);
839
                    $newAttribute->setVar('attribute_id', 0);
840
                    $newAttribute->setNew();
841
                    $attributesHandler->insert($newAttribute, true);
842
                }
843
            }
844
845
            return $newProduct;
846
        }
847
848
        return false;
849
    }
850
851
    /**
852
     * Construit un sélecteur de produit(s) en fonction des paramètres et en tenant compte du nombre total de produits dans la base
853
     *
854
     * @todo     : Remplacer les paramètres par un objet paramètre et/ou un tableau
855
     * @param  Parameters $parameters
856
     * @return \XoopsFormElementTray|\XoopsFormSelect Retourne soit un objet de type tray <a href='psi_element://XoopsFormElementTray'>XoopsFormElementTray</a> soit un select <a href='psi_element://XoopsFormSelect'>XoopsFormSelect</a>
857
     * @internal param string $caption Le titre du sélecteur
858
     * @internal param string $name Le nom du champ qui receuille les produits
859
     * @internal param mixed $value La valeur sélectionnées
860
     * @internal param int $size Le nombre d'éléments visibles dans le sélecteur
861
     * @internal param bool $multiple Indique si c'est un sélecteur multiple ou pas
862
     * @internal param array $values Les valeurs sélectionnées ou les valeurs qui font le sélecteur
863
     * @internal param bool $showAll Indique s'il faut voir tous les produits ou pas (pas publiés et en stock)
864
     * @internal param string $sort Zone de tri
865
     * @internal param string $order Ordre de tri
866
     * @internal param string $formName Nom du formulaire
867
     * @internal param string $description Description à rajouter à la zone
868
     * @internal param mixed $withNull Option à rajouter en premier
869
     */
870
    public function productSelector(Parameters $parameters)
871
    {
872
        $parameters = $parameters->extend(new Oledrion\Parameters([
873
                                                                      'caption'     => '',
874
                                                                      'name'        => '',
875
                                                                      'value'       => null,
876
                                                                      'size'        => 1,
877
                                                                      'multiple'    => false,
878
                                                                      'values'      => null,
879
                                                                      'showAll'     => true,
880
                                                                      'sort'        => 'product_title',
881
                                                                      'order'       => 'ASC',
882
                                                                      'formName'    => '',
883
                                                                      'description' => '',
884
                                                                      'withNull'    => null,
885
                                                                  ]));
886
        static $jqueryIncluded = null;
887
        require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
888
        $criteria = new \CriteriaCompo();
889
        $criteria->add(new \Criteria('product_id', 0, '<>'));
890
        if (!$parameters['showAll']) {
891
            if (0 == Oledrion\Utility::getModuleOption('show_unpublished')) {
892
                // Ne pas afficher les produits qui ne sont pas publiés
893
                $criteria->add(new \Criteria('product_submitted', time(), '<='));
894
            }
895
            if (0 == Oledrion\Utility::getModuleOption('nostock_display')) {
896
                // Se limiter aux seuls produits encore en stock
897
                $criteria->add(new \Criteria('product_stock', 0, '>'));
898
            }
899
        }
900
        $criteria->setSort($parameters['sort']);
901
        $criteria->setOrder($parameters['order']);
902
        $itemsCount = $this->getCount($criteria);
903
        if ($itemsCount > Oledrion\Utility::getModuleOption('max_products')) {
904
            // Il faut créer notre propre sélecteur
905
            if ($parameters['multiple']) {
906
                if (null === $jqueryIncluded) {
907
                    $jqueryIncluded = true;
908
                    global $xoTheme;
909
                    $xoTheme->addScript('browse.php?Frameworks/jquery/jquery.js');
910
                }
911
                Oledrion\Utility::callJavascriptFile('select/select.js', false, true);
912
                $productTray  = new \XoopsFormElementTray($parameters['caption'], '');
913
                $productsList = new \XoopsFormSelect('', $parameters['name'], $parameters['values'], $parameters['size'], $parameters['multiple']);
914
                // Recherche des produits
915
                $selectedProducts = $this->getList(new \Criteria('product_id', '(' . implode(',', $parameters['values']) . ')', 'IN'));
916
                $productsList->addOptionArray($selectedProducts); // Les valeurs sélectionnées
917
                $productTray->addElement($productsList);
918
                $removeButton = new \XoopsFormButton('', 'removeProduct', _AM_OLEDRION_REMOVE_SELECTED, 'button');
919
                if (Oledrion\Utility::isX20()) {
920
                    $removeButton->setExtra(" onclick=\"removeOptionSelected('" . $parameters['name'] . "[]');\"");
921
                } else {
922
                    $removeButton->setExtra(" onclick=\"removeOptionSelected('" . $parameters['name'] . "');\"");
923
                }
924
                $productTray->addElement($removeButton);
925
                if (Oledrion\Utility::isX20()) {
926
                    $link = "<a href=\"javascript:openWithSelfMain('"
927
                            . OLEDRION_ADMIN_URL
928
                            . 'productsselector.php?mutipleSelect=1&amp;callerName='
929
                            . $parameters['name']
930
                            . "[]', '', "
931
                            . OLEDRION_MAX_PRODUCTS_POPUP_WIDTH
932
                            . ', '
933
                            . OLEDRION_MAX_PRODUCTS_POPUP_HEIGHT
934
                            . ');">'
935
                            . _AM_OLEDRION_SELECT_OTHER_P
936
                            . '</a>';
937
                } else {
938
                    $link = "<a href=\"javascript:openWithSelfMain('"
939
                            . OLEDRION_ADMIN_URL
940
                            . 'productsselector.php?mutipleSelect=1&amp;callerName='
941
                            . $parameters['name']
942
                            . "', '', "
943
                            . OLEDRION_MAX_PRODUCTS_POPUP_WIDTH
944
                            . ', '
945
                            . OLEDRION_MAX_PRODUCTS_POPUP_HEIGHT
946
                            . ');">'
947
                            . _AM_OLEDRION_SELECT_OTHER_P
948
                            . '</a>';
949
                }
950
                $linkLabel = new \XoopsFormLabel('', '<br>' . $link);
951
                $productTray->addElement($linkLabel);
952
                echo "<script type=\"text/javascript\">\n";
953
                echo "jQuery().ready(function($) {\n";
954
                echo '$("#' . $parameters['formName'] . "\").submit( function() {\n";
955
                echo "  selectAll('" . $parameters['name'] . "', true);\n";
956
                echo "} );\n";
957
                echo "});\n";
958
                echo "</script>\n";
959
            } else {
960
                // Pas de sélection multiple
961
                $productTray  = new \XoopsFormElementTray($parameters['caption'], '');
962
                $productsList = new \XoopsFormSelect('', $parameters['name'], $parameters['value'], $parameters['size'], $parameters['multiple']);
963
                // Recherche des produits
964
                if ($parameters['value'] > 0) {
965
                    $selectedProducts = $this->getList(new \Criteria('product_id', $parameters['value'], '='));
966
                    if (null !== $parameters['withNull']) {
967
                        $selectedProducts[0] = $parameters['withNull'];
968
                        ksort($selectedProducts);
969
                    }
970
                    $productsList->addOptionArray($selectedProducts); // Les valeurs sélectionnées
971
                }
972
                $productTray->addElement($productsList);
973
                $link      = "<a href=\"javascript:openWithSelfMain('"
974
                             . OLEDRION_ADMIN_URL
975
                             . 'productsselector.php?mutipleSelect=0&amp;callerName='
976
                             . $parameters['name']
977
                             . "', '', "
978
                             . OLEDRION_MAX_PRODUCTS_POPUP_WIDTH
979
                             . ', '
980
                             . OLEDRION_MAX_PRODUCTS_POPUP_HEIGHT
981
                             . ');">'
982
                             . _AM_OLEDRION_SELECT_PRODUCT
983
                             . '</a>';
984
                $linkLabel = new \XoopsFormLabel('', '<br>' . $link);
985
                $productTray->addElement($linkLabel);
986
            }
987
        } else {
988
            $productTray = new \XoopsFormSelect($parameters['caption'], $parameters['name'], $parameters['value'], $parameters['size'], $parameters['multiple']);
989
            $products    = $this->getList($criteria);
990
            $productTray->addOptionArray($products);
991
        }
992
993
        if ('' !== trim($parameters['description'])) {
994
            $productTray->setDescription($parameters['description']);
995
        }
996
997
        return $productTray;
998
    }
999
}
1000