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/CaddyHandler.php (14 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
use XoopsModules\Oledrion;
24
25
/**
26
 * Gestion des caddy
27
 */
28
29
/**
30
 * Class CaddyHandler
31
 */
32
class CaddyHandler extends OledrionPersistableObjectHandler
33
{
34
    const CADDY_NAME = 'oledrion_caddie'; // Nom du panier en session
35
36
    /**
37
     * Oledrion\CaddyHandler constructor.
38
     * @param \XoopsDatabase|null $db
39
     */
40
    public function __construct(\XoopsDatabase $db = null)
41
    {
42
        //                          Table             Classe          Id
43
        parent::__construct($db, 'oledrion_caddy', Caddy::class, 'caddy_id');
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

43
        parent::__construct(/** @scrutinizer ignore-type */ $db, 'oledrion_caddy', Caddy::class, 'caddy_id');
Loading history...
44
    }
45
46
    /**
47
     * Renvoie, si on en trouve un, un produit qui s'est bien vendu avec un produit particulier
48
     *
49
     * @param  int $caddy_product_id Identifiant du produit dont on recherche le jumeau
50
     * @return int Le n° du produit le plus vendu avec le produit en question
51
     */
52
    public function getBestWith($caddy_product_id)
53
    {
54
        $sql    = 'SELECT caddy_product_id, sum(caddy_qte) mv FROM ' . $this->table . ' WHERE caddy_cmd_id IN (SELECT caddy_cmd_id FROM ' . $this->table . ' WHERE caddy_product_id=' . (int)$caddy_product_id . ') GROUP BY caddy_product_id ORDER BY mv DESC';
55
        $result = $this->db->query($sql, 1);
56
        if (!$result) {
57
            return 0;
58
        }
59
        $myrow = $this->db->fetchArray($result);
60
        $id    = $myrow['caddy_product_id'];
61
        if ($id != $caddy_product_id) {
62
            return $id;
63
        }
64
65
        return 0;
66
    }
67
68
    /**
69
     * Renvoie la liste des produits les plus vendus toutes catégories confondues
70
     *
71
     * @param int       $start Début de la recherche
72
     * @param int       $limit Nombre maximum d'enregistrements à retourner
73
     * @param int|array $product_cid
74
     * @param bool      $withQuantity
75
     * @return array   Les identifiants des X produits les plus vendus dans cette catégorie
76
     */
77
    public function getMostSoldProducts($start = 0, $limit = 0, $product_cid = 0, $withQuantity = false)
78
    {
79
        //require_once __DIR__ . '/lite.php';
80
        $ret = [];
81
        if ($product_cid && is_array($product_cid)) {
82
            $sql = 'SELECT c.caddy_product_id, sum( c.caddy_qte ) AS mv FROM ' . $this->table . ' c, ' . $this->db->prefix('oledrion_products') . ' b WHERE (c.caddy_product_id = b.product_id) AND b.product_cid IN (' . implode(',', $product_cid) . ') GROUP BY c.caddy_product_id ORDER BY mv DESC';
83
        } elseif ($product_cid > 0) {
84
            $sql = 'SELECT c.caddy_product_id, sum( c.caddy_qte ) AS mv FROM ' . $this->table . ' c, ' . $this->db->prefix('oledrion_products') . ' b WHERE (c.caddy_product_id = b.product_id) AND b.product_cid = ' . (int)$product_cid . ' GROUP BY c.caddy_product_id ORDER BY mv DESC';
85
        } else {
86
            $sql = 'SELECT caddy_product_id, sum( caddy_qte ) AS mv FROM ' . $this->table . ' GROUP BY caddy_product_id ORDER BY mv DESC';
87
        }
88
        //$Cache_Lite = new Oledrion_Cache_Lite($this->cacheOptions);
89
        $id = $this->_getIdForCache($sql, $start, $limit);
0 ignored issues
show
The assignment to $id is dead and can be removed.
Loading history...
90
        //$cacheData = $Cache_Lite->get($id);
91
        //if ($cacheData === false) {
92
        $result = $this->db->query($sql, $limit, $start);
93
        if ($result) {
94
            while (false !== ($myrow = $this->db->fetchArray($result))) {
95
                if (!$withQuantity) {
96
                    $ret[$myrow['caddy_product_id']] = $myrow['caddy_product_id'];
97
                } else {
98
                    $ret[$myrow['caddy_product_id']] = $myrow['mv'];
99
                }
100
            }
101
        }
102
103
        //$Cache_Lite->save($ret);
104
        return $ret;
105
        //} else {
106
        //return $cacheData;
107
        //}
108
    }
109
110
    /**
111
     * Retourne la liste des ID de produits vendus récemment
112
     *
113
     * @param  int $start
114
     * @param  int $limit
115
     * @return array
116
     * @since 2.3.2009.04.08
117
     */
118
    public function getRecentlySoldProducts($start = 0, $limit = 0)
119
    {
120
        //require_once __DIR__ . '/lite.php';
121
        $ret = [];
122
        $sql = 'SELECT c.caddy_product_id FROM ' . $this->table . ' c, ' . $this->db->prefix('oledrion_commands') . ' o WHERE (c.caddy_cmd_id = o.cmd_id) AND (o.cmd_state = ' . Constants::OLEDRION_STATE_VALIDATED . ') ORDER BY cmd_date DESC';
123
        //$Cache_Lite = new Oledrion_Cache_Lite($this->cacheOptions);
124
        $id = $this->_getIdForCache($sql, $start, $limit);
0 ignored issues
show
The assignment to $id is dead and can be removed.
Loading history...
125
        //$cacheData = $Cache_Lite->get($id);
126
        //if ($cacheData === false) {
127
        $result = $this->db->query($sql, $limit, $start);
128
        if ($result) {
129
            while (false !== ($row = $this->db->fetchArray($result))) {
130
                $ret[$row['caddy_product_id']] = $row['caddy_product_id'];
131
            }
132
        }
133
134
        //$Cache_Lite->save($ret);
135
        return $ret;
136
        //} else {
137
        //return $cacheData;
138
        //}
139
    }
140
141
    /**
142
     * Indique si le caddy est vide ou pas
143
     *
144
     * @return bool vide, ou pas...
145
     */
146
    public function isCartEmpty()
147
    {
148
        if (isset($_SESSION[self::CADDY_NAME])) {
149
            return false;
150
        }
151
152
        return true;
153
    }
154
155
    /**
156
     * Vidage du caddy, s'il existe
157
     */
158
    public function emptyCart()
159
    {
160
        global $xoopsUser, $persistentCartHandler;
161
        if (isset($_SESSION[self::CADDY_NAME])) {
162
            unset($_SESSION[self::CADDY_NAME]);
163
            if (is_object($xoopsUser)) {
164
                $persistentCartHandler->deleteAllUserProducts();
165
            }
166
        }
167
    }
168
169
    /**
170
     * Recharge le dernier panier de l'utilisateur
171
     *
172
     * @return bool
173
     */
174
    public function reloadPersistentCart()
175
    {
176
        global $xoopsUser, $persistentCartHandler;
177
        if (0 == Oledrion\Utility::getModuleOption('persistent_cart')) {
178
            return false;
179
        }
180
        if (is_object($xoopsUser)) {
181
            $persistent_carts = [];
0 ignored issues
show
The assignment to $persistent_carts is dead and can be removed.
Loading history...
182
            $persistent_carts = $persistentCartHandler->getUserProducts();
183
            if (count($persistent_carts) > 0) {
184
                foreach ($persistent_carts as $persistent_cart) {
185
                    $this->addProduct($persistent_cart->getVar('persistent_product_id'), $persistent_cart->getVar('persistent_qty'), null);
186
                }
187
            }
188
        }
189
190
        return true;
191
    }
192
193
    /**
194
     * Ajout d'un produit au caddy
195
     *
196
     * @param  int   $product_id   Identifiant du produit
197
     * @param  int   $quantity     Quantité à ajouter
198
     * @param  array $attributes   Les attributs du produit
199
     * @note : Structure du panier (tableau en session) :
200
     *                             [clé] = numéro de 1 à N
201
     *                             [valeur] = array (
202
     *                             'number' => numéro de 1 à N
203
     *                             'id' => ID du produit
204
     *                             'qty' => Quantité de produit
205
     *                             'attributes' => array(
206
     *                             'attr_id' => id attribut (son numéro dans la base)
207
     *                             'values' => array(valueId1, valueId2 ...)
208
     *                             )
209
     *                             )
210
     */
211
    public function addProduct($product_id, $quantity, $attributes = null)
212
    {
213
        global $xoopsUser, $persistentCartHandler;
214
        $tbl_caddie = $tbl_caddie2 = [];
215
        if (isset($_SESSION[self::CADDY_NAME])) {
216
            $tbl_caddie = $_SESSION[self::CADDY_NAME];
217
        }
218
        $exists = false;
219
        foreach ($tbl_caddie as $produit) {
220
            if ($produit['id'] == $product_id) {
221
                $exists                = true;
222
                $produit['qty']        += $quantity;
223
                $produit['attributes'] = $attributes;
224
                $newQuantity           = $produit['qty'];
225
            }
226
            $tbl_caddie2[] = $produit;
227
        }
228
        if (!$exists) {
229
            if (is_object($xoopsUser)) {
230
                $persistentCartHandler->addUserProduct($product_id, $quantity);
231
            }
232
            $datas                      = [];
233
            $datas['number']            = count($tbl_caddie) + 1;
234
            $datas['id']                = $product_id;
235
            $datas['qty']               = $quantity;
236
            $datas['attributes']        = $attributes;
237
            $tbl_caddie[]               = $datas;
238
            $_SESSION[self::CADDY_NAME] = $tbl_caddie;
239
        } else {
240
            $_SESSION[self::CADDY_NAME] = $tbl_caddie2;
241
            if (is_object($xoopsUser)) {
242
                // Le produit était déjà dans le panier, on va mettre à jour la quantité
243
                $persistentCartHandler->updateUserProductQuantity($product_id, $newQuantity);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $newQuantity does not seem to be defined for all execution paths leading up to this point.
Loading history...
244
            }
245
        }
246
    }
247
248
    /**
249
     * Inidique si un produit est dans le caddy
250
     *
251
     * @param  int $caddy_product_id Le numéro interne du produit dans la table Produits
252
     * @return mixed   False si le produit n'est pas dans le caddy sinon son indice dans le caddy
253
     * @since 2.3.2009.03.15
254
     */
255
    public function isInCart($caddy_product_id)
256
    {
257
        $cart = [];
0 ignored issues
show
The assignment to $cart is dead and can be removed.
Loading history...
258
        if (isset($_SESSION[self::CADDY_NAME])) {
259
            $cart = $_SESSION[self::CADDY_NAME];
260
        } else {
261
            return false;
262
        }
263
        $counter = 0;
264
        foreach ($cart as $produit) {
265
            if ($produit['id'] == $caddy_product_id) {
266
                return $counter;
267
            }
268
            ++$counter;
269
        }
270
271
        return false;
272
    }
273
274
    /**
275
     * Retourne les attributs d'un produit depuis le panier
276
     *
277
     * @param  int $caddy_product_id Le numéro interne du produit dans la table Produits
278
     * @return mixed   False si le produit n'est pas dans le caddy sinon ses attributs sous la forme d'un tableau
279
     * @since 2.3.2009.03.15
280
     */
281
    public function getProductAttributesFromCart($caddy_product_id)
282
    {
283
        $cart = [];
0 ignored issues
show
The assignment to $cart is dead and can be removed.
Loading history...
284
        if (isset($_SESSION[self::CADDY_NAME])) {
285
            $cart = $_SESSION[self::CADDY_NAME];
286
        } else {
287
            return false;
288
        }
289
        foreach ($cart as $produit) {
290
            if ($produit['id'] == $caddy_product_id) {
291
                return $produit['attributes'];
292
            }
293
        }
294
295
        return false;
296
    }
297
298
    /**
299
     * Renumérotage des produits dans le caddy après une suppression
300
     *
301
     * @param  array $caddy Le caddy actuel
302
     * @return array Le caddy avec 'number' renuméroté
303
     */
304
    private function renumberCart($caddy)
305
    {
306
        $newCaddy = [];
307
        $counter  = 1;
308
        foreach ($caddy as $values) {
309
            $temporary               = [];
310
            $temporary['number']     = $counter;
311
            $temporary['id']         = $values['id'];
312
            $temporary['qty']        = $values['qty'];
313
            $temporary['attributes'] = $values['attributes'];
314
            $newCaddy[]              = $temporary;
315
            ++$counter;
316
        }
317
318
        return $newCaddy;
319
    }
320
321
    /**
322
     * Suppression d'un produit du caddy
323
     *
324
     * @param int $indice Indice de l'élément à supprimer
325
     */
326
    public function deleteProduct($indice)
327
    {
328
        global $xoopsUser, $persistentCartHandler;
329
        $tbl_caddie = [];
0 ignored issues
show
The assignment to $tbl_caddie is dead and can be removed.
Loading history...
330
        if (isset($_SESSION[self::CADDY_NAME])) {
331
            $tbl_caddie = $_SESSION[self::CADDY_NAME];
332
            if (isset($tbl_caddie[$indice])) {
333
                if (is_object($xoopsUser)) {
334
                    $datas = [];
0 ignored issues
show
The assignment to $datas is dead and can be removed.
Loading history...
335
                    $datas = $tbl_caddie[$indice];
336
                    $persistentCartHandler->deleteUserProduct($datas['id']);
337
                }
338
                unset($tbl_caddie[$indice]);
339
                if (count($tbl_caddie) > 0) {
340
                    $tbl_caddie                 = $this->renumberCart($tbl_caddie);
341
                    $_SESSION[self::CADDY_NAME] = $tbl_caddie;
342
                } else {
343
                    unset($_SESSION[self::CADDY_NAME]);
344
                }
345
            }
346
        }
347
    }
348
349
    /**
350
     * Mise à jour des quantités du caddy suite à la validation du formulaire du caddy
351
     */
352
    public function updateQuantites()
353
    {
354
        global $productsHandler, $xoopsUser, $persistentCartHandler;
355
        $tbl_caddie = $tbl_caddie2 = [];
0 ignored issues
show
The assignment to $tbl_caddie is dead and can be removed.
Loading history...
356
        if (isset($_SESSION[self::CADDY_NAME])) {
357
            $tbl_caddie = $_SESSION[self::CADDY_NAME];
358
            foreach ($tbl_caddie as $produit) {
359
                $number = $produit['number'];
360
                $name   = 'qty_' . $number;
361
                if (isset($_POST[$name])) {
362
                    $valeur = \Xmf\Request::getInt($name, 0, 'POST');
363
                    if ($valeur > 0) {
364
                        $product_id = $produit['id'];
365
                        $product    = null;
0 ignored issues
show
The assignment to $product is dead and can be removed.
Loading history...
366
                        $product    = $productsHandler->get($product_id);
367
                        if (is_object($product)) {
368
                            if ($product->getVar('product_stock') - $valeur > 0) {
369
                                $produit['qty'] = $valeur;
370
                                $tbl_caddie2[]  = $produit;
371
                            } else {
372
                                $produit['qty'] = $product->getVar('product_stock');
373
                                $tbl_caddie2[]  = $produit;
374
                            }
375
                            if (is_object($xoopsUser)) {
376
                                $persistentCartHandler->updateUserProductQuantity($product_id, $produit['qty']);
377
                            }
378
                        }
379
                    }
380
                } else {
381
                    $tbl_caddie2[] = $produit;
382
                }
383
            }
384
            if (count($tbl_caddie2) > 0) {
385
                $_SESSION[self::CADDY_NAME] = $tbl_caddie2;
386
            } else {
387
                unset($_SESSION[self::CADDY_NAME]);
388
            }
389
        }
390
    }
391
392
    /**
393
     * Renvoie les éléments constituants une commande
394
     *
395
     * @param  int $caddy_cmd_id Identifiant de la commande
396
     * @return array   Tableau d'objets caddy
397
     */
398
    public function getCaddyFromCommand($caddy_cmd_id)
399
    {
400
        $ret     = [];
0 ignored issues
show
The assignment to $ret is dead and can be removed.
Loading history...
401
        $critere = new \Criteria('caddy_cmd_id', $caddy_cmd_id, '=');
402
        $ret     = $this->getObjects($critere);
403
404
        return $ret;
405
    }
406
407
    /**
408
     * Retourne tous les produits d'un caddy
409
     *
410
     * @param  array $carts Objets de type Caddy
411
     * @return array Tableau d'objets de type oledrion_products, Clé = Id produit
412
     * @since 2.31.2009.07.25
413
     */
414
    public function getProductsFromCaddy($carts)
415
    {
416
        $ret = $productsIds = [];
417
        foreach ($carts as $cart) {
418
            $productsIds[] = $cart->getVar('caddy_product_id');
419
        }
420
        if (count($productsIds) > 0) {
421
            //            $handlers = HandlerManager::getInstance();
422
            $ret = $productsHandler->getProductsFromIDs($productsIds, true);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $productsHandler does not exist. Did you maybe mean $productsIds?
Loading history...
423
        }
424
425
        return $ret;
426
    }
427
428
    /**
429
     * Renvoie les ID de commandes pour un produit acheté
430
     *
431
     * @param  int $product_id Identifiant du produit
432
     * @return array   Les ID des commandes dans lesquelles ce produit a été commandé
433
     */
434
    public function getCommandIdFromProduct($product_id)
435
    {
436
        $ret    = [];
437
        $sql    = 'SELECT caddy_cmd_id FROM ' . $this->table . ' WHERE caddy_product_id=' . (int)$product_id;
438
        $result = $this->db->query($sql);
439
        if (!$result) {
440
            return $ret;
441
        }
442
        while (false !== ($myrow = $this->db->fetchArray($result))) {
443
            $ret[] = $myrow['caddy_cmd_id'];
444
        }
445
446
        return $ret;
447
    }
448
449
    /**
450
     * Retourne un caddy à partir de son mot de passe
451
     *
452
     * @param  string $caddy_pass Le mot de passe à utiliser
453
     * @return mixed  Soit un object de type oledrion_caddy ou null
454
     */
455
    public function getCaddyFromPassword($caddy_pass)
456
    {
457
        $ret     = null;
458
        $caddies = [];
0 ignored issues
show
The assignment to $caddies is dead and can be removed.
Loading history...
459
        $critere = new \Criteria('caddy_pass', $caddy_pass, '=');
460
        $caddies = $this->getObjects($critere);
461
        if (count($caddies) > 0) {
462
            $ret = $caddies[0];
463
        }
464
465
        return $ret;
466
    }
467
468
    /**
469
     * Marque un caddy comme ayant été téléchargé
470
     *
471
     * @param \XoopsModules\Oledrion\Caddy $caddy
472
     * @return bool        Le résultat de la mise à jour
473
     */
474
    public function markCaddyAsNotDownloadableAnyMore(Caddy $caddy)
475
    {
476
        $caddy->setVar('caddy_pass', '');
477
478
        return $this->insert($caddy, true);
479
    }
480
481
    /**
482
     * Supprime les caddies associés à une commande
483
     *
484
     * @param  int $caddy_cmd_id
485
     * @return bool
486
     */
487
    public function removeCartsFromOrderId($caddy_cmd_id)
488
    {
489
        $caddy_cmd_id = (int)$caddy_cmd_id;
490
491
        return $this->deleteAll(new \Criteria('caddy_cmd_id', $caddy_cmd_id, '='));
492
    }
493
}
494