Completed
Push — master ( 00e474...9d3fbd )
by Michael
04:26
created

getRecentlySoldProducts()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 22
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 2
nop 2
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 28 and the first side effect is on line 23.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
/**
13
 * oledrion
14
 *
15
 * @copyright   {@link http://xoops.org/ XOOPS Project}
16
 * @license     {@link http://www.fsf.org/copyleft/gpl.html GNU public license}
17
 * @author      Hervé Thouzard (http://www.herve-thouzard.com/)
18
 */
19
20
/**
21
 * Gestion des caddy
22
 */
23
require __DIR__ . '/classheader.php';
24
25
/**
26
 * Class Oledrion_caddy
27
 */
28
class Oledrion_caddy extends Oledrion_Object
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
29
{
30
    /**
31
     * constructor
32
     *
33
     * normally, this is called from child classes only
34
     *
35
     * @access public
36
     */
37
    public function __construct()
38
    {
39
        $this->initVar('caddy_id', XOBJ_DTYPE_INT, null, false);
40
        $this->initVar('caddy_product_id', XOBJ_DTYPE_INT, null, false);
41
        $this->initVar('caddy_qte', XOBJ_DTYPE_INT, null, false);
42
        $this->initVar('caddy_price', XOBJ_DTYPE_TXTBOX, null, false); // Prix TTC
43
        $this->initVar('caddy_cmd_id', XOBJ_DTYPE_INT, null, false);
44
        $this->initVar('caddy_shipping', XOBJ_DTYPE_TXTBOX, null, false);
45
        $this->initVar('caddy_pass', XOBJ_DTYPE_TXTBOX, null, false);
46
    }
47
48
    /**
49
     * Retourne les éléments du produits formatés pour affichage
50
     *
51
     * @param  string $format Le format à utiliser
52
     * @return array  Les informations formatées
53
     */
54
    public function toArray($format = 's')
55
    {
56
        $ret                              = array();
0 ignored issues
show
Unused Code introduced by
$ret is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
57
        $ret                              = parent::toArray($format);
58
        $oledrion_Currency                = Oledrion_Currency::getInstance();
59
        $ret['caddy_price_fordisplay']    = $oledrion_Currency->amountForDisplay($this->getVar('caddy_price'));
60
        $ret['caddy_shipping_fordisplay'] = $oledrion_Currency->amountForDisplay($this->getVar('caddy_shipping'));
61
62
        return $ret;
63
    }
64
}
65
66
/**
67
 * Class OledrionOledrion_caddyHandler
68
 */
69
class OledrionOledrion_caddyHandler extends Oledrion_XoopsPersistableObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
70
{
71
    const CADDY_NAME = 'oledrion_caddie'; // Nom du panier en session
72
73
    /**
74
     * OledrionOledrion_caddyHandler constructor.
75
     * @param XoopsDatabase|null $db
76
     */
77
    public function __construct(XoopsDatabase $db)
78
    { //                          Table             Classe          Id
79
        parent::__construct($db, 'oledrion_caddy', 'oledrion_caddy', 'caddy_id');
80
    }
81
82
    /**
83
     * Renvoie, si on en trouve un, un produit qui s'est bien vendu avec un produit particulier
84
     *
85
     * @param  integer $caddy_product_id Identifiant du produit dont on recherche le jumeau
86
     * @return integer Le n° du produit le plus vendu avec le produit en question
87
     */
88
    public function getBestWith($caddy_product_id)
89
    {
90
        $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
91
                  . ') GROUP BY caddy_product_id ORDER BY mv DESC';
92
        $result = $this->db->query($sql, 1);
93
        if (!$result) {
94
            return 0;
95
        }
96
        $myrow = $this->db->fetchArray($result);
97
        $id    = $myrow['caddy_product_id'];
98
        if ($id != $caddy_product_id) {
99
            return $id;
100
        } else {
101
            return 0;
102
        }
103
    }
104
105
    /**
106
     * Renvoie la liste des produits les plus vendus toutes catégories confondues
107
     *
108
     * @param  integer $start Début de la recherche
109
     * @param  integer $limit Nombre maximum d'enregistrements à retourner
110
     * @param  int     $product_cid
111
     * @param  bool    $withQuantity
112
     * @return array   Les identifiants des X produits les plus vendus dans cette catégorie
113
     */
114
    public function getMostSoldProducts($start = 0, $limit = 0, $product_cid = 0, $withQuantity = false)
115
    {
116
        //require_once __DIR__ . '/lite.php';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
117
        $ret = array();
118
        if (is_array($product_cid) && count($product_cid) > 0) {
119
            $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)
120
                   . ') GROUP BY c.caddy_product_id ORDER BY mv DESC';
121
        } elseif ($product_cid > 0) {
122
            $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
123
                   . ' GROUP BY c.caddy_product_id ORDER BY mv DESC';
124
        } else {
125
            $sql = 'SELECT caddy_product_id, sum( caddy_qte ) as mv FROM ' . $this->table . ' GROUP BY caddy_product_id ORDER BY mv DESC';
126
        }
127
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
128
        $id = $this->_getIdForCache($sql, $start, $limit);
0 ignored issues
show
Unused Code introduced by
$id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
129
        //$cacheData = $Cache_Lite->get($id);
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
130
        //if ($cacheData === false) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
131
        $result = $this->db->query($sql, $limit, $start);
132
        if ($result) {
133
            while ($myrow = $this->db->fetchArray($result)) {
134
                if (!$withQuantity) {
135
                    $ret[$myrow['caddy_product_id']] = $myrow['caddy_product_id'];
136
                } else {
137
                    $ret[$myrow['caddy_product_id']] = $myrow['mv'];
138
                }
139
            }
140
        }
141
142
        //$Cache_Lite->save($ret);
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
143
        return $ret;
144
        //} else {
145
        //return $cacheData;
146
        //}
147
    }
148
149
    /**
150
     * Retourne la liste des ID de produits vendus récemment
151
     *
152
     * @param  integer $start
153
     * @param  integer $limit
154
     * @return array
155
     * @since 2.3.2009.04.08
156
     */
157
    public function getRecentlySoldProducts($start = 0, $limit = 0)
158
    {
159
        //require_once __DIR__ . '/lite.php';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
160
        $ret = array();
161
        $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 = ' . OLEDRION_STATE_VALIDATED . ') ORDER BY cmd_date DESC';
162
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
163
        $id = $this->_getIdForCache($sql, $start, $limit);
0 ignored issues
show
Unused Code introduced by
$id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
164
        //$cacheData = $Cache_Lite->get($id);
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
165
        //if ($cacheData === false) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
166
        $result = $this->db->query($sql, $limit, $start);
167
        if ($result) {
168
            while ($row = $this->db->fetchArray($result)) {
169
                $ret[$row['caddy_product_id']] = $row['caddy_product_id'];
170
            }
171
        }
172
173
        //$Cache_Lite->save($ret);
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
174
        return $ret;
175
        //} else {
176
        //return $cacheData;
177
        //}
178
    }
179
180
    /**
181
     * Indique si le caddy est vide ou pas
182
     *
183
     * @return boolean vide, ou pas...
184
     */
185
    public function isCartEmpty()
0 ignored issues
show
Coding Style introduced by
isCartEmpty uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
186
    {
187
        if (isset($_SESSION[self::CADDY_NAME])) {
188
            return false;
189
        } else {
190
            return true;
191
        }
192
    }
193
194
    /**
195
     * Vidage du caddy, s'il existe
196
     */
197
    public function emptyCart()
0 ignored issues
show
Coding Style introduced by
emptyCart uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
198
    {
199
        global $xoopsUser, $h_oledrion_persistent_cart;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
200
        if (isset($_SESSION[self::CADDY_NAME])) {
201
            unset($_SESSION[self::CADDY_NAME]);
202
            if (is_object($xoopsUser)) {
203
                $h_oledrion_persistent_cart->deleteAllUserProducts();
204
            }
205
        }
206
    }
207
208
    /**
209
     * Recharge le dernier panier de l'utilisateur
210
     *
211
     * @return boolean
212
     */
213
    public function reloadPersistentCart()
214
    {
215
        global $xoopsUser, $h_oledrion_persistent_cart;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
216
        if (Oledrion_utils::getModuleOption('persistent_cart') == 0) {
217
            return false;
218
        }
219
        if (is_object($xoopsUser)) {
220
            $persistent_carts = array();
0 ignored issues
show
Unused Code introduced by
$persistent_carts is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
221
            $persistent_carts = $h_oledrion_persistent_cart->getUserProducts();
222
            if (count($persistent_carts) > 0) {
223
                foreach ($persistent_carts as $persistent_cart) {
224
                    $this->addProduct($persistent_cart->getVar('persistent_product_id'), $persistent_cart->getVar('persistent_qty'), null);
225
                }
226
            }
227
        }
228
229
        return true;
230
    }
231
232
    /**
233
     * Ajout d'un produit au caddy
234
     *
235
     * @param  integer $product_id Identifiant du produit
236
     * @param  integer $quantity   Quantité à ajouter
237
     * @param  array   $attributes Les attributs du produit
0 ignored issues
show
Documentation introduced by
Should the type for parameter $attributes not be array|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
238
     * @return void
239
     * @note : Structure du panier (tableau en session) :
240
     *                             [clé] = numéro de 1 à N
241
     *                             [valeur] = array (
242
     *                             'number' => numéro de 1 à N
243
     *                             'id' => ID du produit
244
     *                             'qty' => Quantité de produit
245
     *                             'attributes' => array(
246
     *                             'attr_id' => id attribut (son numéro dans la base)
247
     *                             'values' => array(valueId1, valueId2 ...)
248
     *                             )
249
     *                             )
250
     */
251
    public function addProduct($product_id, $quantity, $attributes = null)
0 ignored issues
show
Coding Style introduced by
addProduct uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
252
    {
253
        global $xoopsUser, $h_oledrion_persistent_cart;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
254
        $tbl_caddie = $tbl_caddie2 = array();
255
        if (isset($_SESSION[self::CADDY_NAME])) {
256
            $tbl_caddie = $_SESSION[self::CADDY_NAME];
257
        }
258
        $exists = false;
259
        foreach ($tbl_caddie as $produit) {
260
            if ($produit['id'] == $product_id) {
261
                $exists = true;
262
                $produit['qty'] += $quantity;
263
                $produit['attributes'] = $attributes;
264
                $newQuantity           = $produit['qty'];
265
            }
266
            $tbl_caddie2[] = $produit;
267
        }
268
        if (!$exists) {
269
            if (is_object($xoopsUser)) {
270
                $h_oledrion_persistent_cart->addUserProduct($product_id, $quantity);
271
            }
272
            $datas                      = array();
273
            $datas['number']            = count($tbl_caddie) + 1;
274
            $datas['id']                = $product_id;
275
            $datas['qty']               = $quantity;
276
            $datas['attributes']        = $attributes;
277
            $tbl_caddie[]               = $datas;
278
            $_SESSION[self::CADDY_NAME] = $tbl_caddie;
279
        } else {
280
            $_SESSION[self::CADDY_NAME] = $tbl_caddie2;
281
            if (is_object($xoopsUser)) { // Le produit était déjà dans le panier, on va mettre à jour la quantité
282
                $h_oledrion_persistent_cart->updateUserProductQuantity($product_id, $newQuantity);
0 ignored issues
show
Bug introduced by
The variable $newQuantity does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
283
            }
284
        }
285
    }
286
287
    /**
288
     * Inidique si un produit est dans le caddy
289
     *
290
     * @param  integer $caddy_product_id Le numéro interne du produit dans la table Produits
291
     * @return mixed   False si le produit n'est pas dans le caddy sinon son indice dans le caddy
292
     * @since 2.3.2009.03.15
293
     */
294 View Code Duplication
    public function isInCart($caddy_product_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
isInCart uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
295
    {
296
        $cart = array();
0 ignored issues
show
Unused Code introduced by
$cart is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
297
        if (isset($_SESSION[self::CADDY_NAME])) {
298
            $cart = $_SESSION[self::CADDY_NAME];
299
        } else {
300
            return false;
301
        }
302
        $counter = 0;
303
        foreach ($cart as $produit) {
304
            if ($produit['id'] == $caddy_product_id) {
305
                return $counter;
306
            }
307
            ++$counter;
308
        }
309
310
        return false;
311
    }
312
313
    /**
314
     * Retourne les attributs d'un produit depuis le panier
315
     *
316
     * @param  integer $caddy_product_id Le numéro interne du produit dans la table Produits
317
     * @return mixed   False si le produit n'est pas dans le caddy sinon ses attributs sous la forme d'un tableau
318
     * @since 2.3.2009.03.15
319
     */
320 View Code Duplication
    public function getProductAttributesFromCart($caddy_product_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
getProductAttributesFromCart uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
321
    {
322
        $cart = array();
0 ignored issues
show
Unused Code introduced by
$cart is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
323
        if (isset($_SESSION[self::CADDY_NAME])) {
324
            $cart = $_SESSION[self::CADDY_NAME];
325
        } else {
326
            return false;
327
        }
328
        foreach ($cart as $produit) {
329
            if ($produit['id'] == $caddy_product_id) {
330
                return $produit['attributes'];
331
            }
332
        }
333
334
        return false;
335
    }
336
337
    /**
338
     * Renumérotage des produits dans le caddy après une suppression
339
     *
340
     * @param  array $caddy Le caddy actuel
341
     * @return array Le caddy avec 'number' renuméroté
342
     */
343
    private function renumberCart($caddy)
344
    {
345
        $newCaddy = array();
346
        $counter  = 1;
347
        foreach ($caddy as $values) {
348
            $temporary               = array();
349
            $temporary['number']     = $counter;
350
            $temporary['id']         = $values['id'];
351
            $temporary['qty']        = $values['qty'];
352
            $temporary['attributes'] = $values['attributes'];
353
            $newCaddy[]              = $temporary;
354
            ++$counter;
355
        }
356
357
        return $newCaddy;
358
    }
359
360
    /**
361
     * Suppression d'un produit du caddy
362
     *
363
     * @param integer $indice Indice de l'élément à supprimer
364
     */
365
    public function deleteProduct($indice)
0 ignored issues
show
Coding Style introduced by
deleteProduct uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
366
    {
367
        global $xoopsUser, $h_oledrion_persistent_cart;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
368
        $tbl_caddie = array();
0 ignored issues
show
Unused Code introduced by
$tbl_caddie is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
369
        if (isset($_SESSION[self::CADDY_NAME])) {
370
            $tbl_caddie = $_SESSION[self::CADDY_NAME];
371
            if (isset($tbl_caddie[$indice])) {
372
                if (is_object($xoopsUser)) {
373
                    $datas = array();
0 ignored issues
show
Unused Code introduced by
$datas is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
374
                    $datas = $tbl_caddie[$indice];
375
                    $h_oledrion_persistent_cart->deleteUserProduct($datas['id']);
376
                }
377
                unset($tbl_caddie[$indice]);
378
                if (count($tbl_caddie) > 0) {
379
                    $tbl_caddie                 = $this->renumberCart($tbl_caddie);
380
                    $_SESSION[self::CADDY_NAME] = $tbl_caddie;
381
                } else {
382
                    unset($_SESSION[self::CADDY_NAME]);
383
                }
384
            }
385
        }
386
    }
387
388
    /**
389
     * Mise à jour des quantités du caddy suite à la validation du formulaire du caddy
390
     */
391
    public function updateQuantites()
0 ignored issues
show
Coding Style introduced by
updateQuantites uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
updateQuantites uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
392
    {
393
        global $h_oledrion_products, $xoopsUser, $h_oledrion_persistent_cart;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
394
        $tbl_caddie = $tbl_caddie2 = array();
0 ignored issues
show
Unused Code introduced by
$tbl_caddie is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
395
        if (isset($_SESSION[self::CADDY_NAME])) {
396
            $tbl_caddie = $_SESSION[self::CADDY_NAME];
397
            foreach ($tbl_caddie as $produit) {
398
                $number = $produit['number'];
399
                $name   = 'qty_' . $number;
400
                if (isset($_POST[$name])) {
401
                    $valeur = (int)$_POST[$name];
402
                    if ($valeur > 0) {
403
                        $product_id = $produit['id'];
404
                        $product    = null;
0 ignored issues
show
Unused Code introduced by
$product is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
405
                        $product    = $h_oledrion_products->get($product_id);
406
                        if (is_object($product)) {
407
                            if ($product->getVar('product_stock') - $valeur > 0) {
408
                                $produit['qty'] = $valeur;
409
                                $tbl_caddie2[]  = $produit;
410
                            } else {
411
                                $produit['qty'] = $product->getVar('product_stock');
412
                                $tbl_caddie2[]  = $produit;
413
                            }
414
                            if (is_object($xoopsUser)) {
415
                                $h_oledrion_persistent_cart->updateUserProductQuantity($product_id, $produit['qty']);
416
                            }
417
                        }
418
                    }
419
                } else {
420
                    $tbl_caddie2[] = $produit;
421
                }
422
            }
423
            if (count($tbl_caddie2) > 0) {
424
                $_SESSION[self::CADDY_NAME] = $tbl_caddie2;
425
            } else {
426
                unset($_SESSION[self::CADDY_NAME]);
427
            }
428
        }
429
    }
430
431
    /**
432
     * Renvoie les éléments constituants une commande
433
     *
434
     * @param  integer $caddy_cmd_id Identifiant de la commande
435
     * @return array   Tableau d'objets caddy
436
     */
437
    public function getCaddyFromCommand($caddy_cmd_id)
438
    {
439
        $ret     = array();
0 ignored issues
show
Unused Code introduced by
$ret is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
440
        $critere = new Criteria('caddy_cmd_id', $caddy_cmd_id, '=');
441
        $ret     = $this->getObjects($critere);
442
443
        return $ret;
444
    }
445
446
    /**
447
     * Retourne tous les produits d'un caddy
448
     *
449
     * @param  array $carts Objets de type oledrion_caddy
450
     * @return array Tableau d'objets de type oledrion_products, Clé = Id produit
451
     * @since 2.31.2009.07.25
452
     */
453
    public function getProductsFromCaddy($carts)
454
    {
455
        $ret = $productsIds = array();
456
        foreach ($carts as $cart) {
457
            $productsIds[] = $cart->getVar('caddy_product_id');
458
        }
459
        if (count($productsIds) > 0) {
460
            $handlers = OledrionHandler::getInstance();
461
            $ret      = $handlers->h_oledrion_products->getProductsFromIDs($productsIds, true);
462
        }
463
464
        return $ret;
465
    }
466
467
    /**
468
     * Renvoie les ID de commandes pour un produit acheté
469
     *
470
     * @param  integer $product_id Identifiant du produit
471
     * @return array   Les ID des commandes dans lesquelles ce produit a été commandé
472
     */
473 View Code Duplication
    public function getCommandIdFromProduct($product_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
474
    {
475
        $ret    = array();
476
        $sql    = 'SELECT caddy_cmd_id FROM ' . $this->table . ' WHERE caddy_product_id=' . (int)$product_id;
477
        $result = $this->db->query($sql);
478
        if (!$result) {
479
            return $ret;
480
        }
481
        while ($myrow = $this->db->fetchArray($result)) {
482
            $ret[] = $myrow['caddy_cmd_id'];
483
        }
484
485
        return $ret;
486
    }
487
488
    /**
489
     * Retourne un caddy à partir de son mot de passe
490
     *
491
     * @param  string $caddy_pass Le mot de passe à utiliser
492
     * @return mixed  Soit un object de type oledrion_caddy ou null
493
     */
494
    public function getCaddyFromPassword($caddy_pass)
495
    {
496
        $ret     = null;
497
        $caddies = array();
0 ignored issues
show
Unused Code introduced by
$caddies is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
498
        $critere = new Criteria('caddy_pass', $caddy_pass, '=');
499
        $caddies = $this->getObjects($critere);
500
        if (count($caddies) > 0) {
501
            $ret = $caddies[0];
502
        }
503
504
        return $ret;
505
    }
506
507
    /**
508
     * Marque un caddy comme ayant été téléchargé
509
     *
510
     * @param  oledrion_caddy $caddy
511
     * @return boolean        Le résultat de la mise à jour
512
     */
513
    public function markCaddyAsNotDownloadableAnyMore(Oledrion_caddy $caddy)
514
    {
515
        $caddy->setVar('caddy_pass', '');
516
517
        return $this->insert($caddy, true);
518
    }
519
520
    /**
521
     * Supprime les caddies associés à une commande
522
     *
523
     * @param  integer $caddy_cmd_id
524
     * @return boolean
525
     */
526
    public function removeCartsFromOrderId($caddy_cmd_id)
527
    {
528
        $caddy_cmd_id = (int)$caddy_cmd_id;
529
530
        return $this->deleteAll(new criteria('caddy_cmd_id', $caddy_cmd_id, '='));
531
    }
532
}
533